Merge pull request #64959 from MKLeb/mf/3006.2/3006.x

[3006.x] Merge 3006.2 into 3006.x
This commit is contained in:
Caleb Beard 2023-08-14 17:30:28 -04:00 committed by GitHub
commit 9e4e36bf0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 832 additions and 355 deletions

View file

@ -22,6 +22,7 @@ env:
permissions:
contents: read # for dorny/paths-filter to fetch a list of changed files
pull-requests: read # for dorny/paths-filter to read pull requests
actions: read # for technote-space/workflow-conclusion-action to get the job statuses
concurrency:
# Concurrency is defined in a way that concurrent builds against branches do
@ -35,7 +36,7 @@ jobs:
prepare-workflow:
name: Prepare Workflow Run
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
outputs:
jobs: ${{ steps.define-jobs.outputs.jobs }}
runners: ${{ steps.runner-types.outputs.runners }}
@ -260,8 +261,7 @@ jobs:
prepare-release:
name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}"
if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['prepare-release'] && fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
needs:
- prepare-workflow
steps:
@ -395,7 +395,7 @@ jobs:
needs:
- prepare-workflow
- prepare-release
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3
@ -442,7 +442,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-salt-onedir:
@ -458,7 +458,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-rpm-pkgs:
@ -470,7 +470,7 @@ jobs:
uses: ./.github/workflows/build-rpm-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-deb-pkgs:
@ -482,7 +482,7 @@ jobs:
uses: ./.github/workflows/build-deb-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-windows-pkgs:
@ -494,7 +494,7 @@ jobs:
uses: ./.github/workflows/build-windows-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-macos-pkgs:
@ -506,7 +506,7 @@ jobs:
uses: ./.github/workflows/build-macos-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
amazonlinux-2-pkg-tests:
@ -1288,7 +1288,7 @@ jobs:
# on a pull request instead of requiring all
name: Set the ${{ github.workflow }} Pipeline Exit Status
if: always()
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- prepare-workflow
- pre-commit

View file

@ -18,19 +18,21 @@ env:
jobs:
Salt:
name: Lint Salt's Source Code
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "large", "x86_64"]') || 'ubuntu-latest' }}
if: ${{ contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) || fromJSON(inputs.changed-files)['salt'] || fromJSON(inputs.changed-files)['lint'] }}
container:
image: python:3.8-slim-buster
image: ghcr.io/saltstack/salt-ci-containers/python:3.8
steps:
- name: Install System Deps
run: |
echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
apt-get update
apt-get install -y enchant git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev
apt-get install -y git/buster-backports
apt-get install -y enchant-2 git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev
- name: Add Git Safe Directory
run: |
git config --global --add safe.directory "$(pwd)"
- uses: actions/checkout@v3
@ -60,19 +62,22 @@ jobs:
Tests:
name: Lint Salt's Test Suite
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "large", "x86_64"]') || 'ubuntu-latest' }}
if: ${{ contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) || fromJSON(inputs.changed-files)['tests'] || fromJSON(inputs.changed-files)['lint'] }}
container:
image: python:3.8-slim-buster
image: ghcr.io/saltstack/salt-ci-containers/python:3.8
steps:
- name: Install System Deps
run: |
echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
echo "deb http://deb.debian.org/debian bookworm-backports main" >> /etc/apt/sources.list
apt-get update
apt-get install -y enchant git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev
apt-get install -y git/buster-backports
apt-get install -y enchant-2 git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev
- name: Add Git Safe Directory
run: |
git config --global --add safe.directory "$(pwd)"
- uses: actions/checkout@v3

View file

@ -38,7 +38,7 @@ jobs:
workflow-requirements:
name: Check Workflow Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
outputs:
requirements-met: ${{ steps.check-requirements.outputs.requirements-met }}
steps:
@ -65,8 +65,7 @@ jobs:
trigger-branch-nightly-builds:
name: Trigger Branch Workflows
if: ${{ github.event_name == 'schedule' && fromJSON(needs.workflow-requirements.outputs.requirements-met) }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- workflow-requirements
steps:
@ -78,7 +77,7 @@ jobs:
prepare-workflow:
name: Prepare Workflow Run
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
if: ${{ fromJSON(needs.workflow-requirements.outputs.requirements-met) }}
needs:
- workflow-requirements
@ -306,8 +305,7 @@ jobs:
prepare-release:
name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}"
if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['prepare-release'] && fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
needs:
- prepare-workflow
steps:
@ -446,7 +444,7 @@ jobs:
needs:
- prepare-workflow
- prepare-release
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3
@ -493,7 +491,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-salt-onedir:
@ -509,7 +507,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-rpm-pkgs:
@ -521,7 +519,7 @@ jobs:
uses: ./.github/workflows/build-rpm-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-deb-pkgs:
@ -533,7 +531,7 @@ jobs:
uses: ./.github/workflows/build-deb-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-windows-pkgs:
@ -545,7 +543,7 @@ jobs:
uses: ./.github/workflows/build-windows-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
environment: nightly
sign-packages: false
@ -560,7 +558,7 @@ jobs:
uses: ./.github/workflows/build-macos-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
environment: nightly
sign-packages: true
@ -2048,7 +2046,7 @@ jobs:
# on a pull request instead of requiring all
name: Set the ${{ github.workflow }} Pipeline Exit Status
if: always()
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: nightly
needs:
- workflow-requirements

View file

@ -21,19 +21,21 @@ jobs:
Pre-Commit:
name: Run Pre-Commit Against Salt
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
container:
image: python:3.10-slim-buster
image: ghcr.io/saltstack/salt-ci-containers/python:3.10
steps:
- name: Install System Deps
run: |
echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
apt-get update
apt-get install -y wget curl enchant git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev
apt-get install -y git/buster-backports
apt-get install -y wget curl enchant-2 git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev
- name: Add Git Safe Directory
run: |
git config --global --add safe.directory "$(pwd)"
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-actionlint

View file

@ -31,7 +31,7 @@ jobs:
permissions:
contents: write # for dev-drprasad/delete-tag-and-release to delete tags or releases
name: Generate Tag and Github Release
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
steps:
- uses: dev-drprasad/delete-tag-and-release@v0.2.0
if: github.event.inputs.reTag == 'true'

View file

@ -19,7 +19,7 @@ permissions:
jobs:
update-winrepo:
name: Update Winrepo
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
steps:
- name: Checkout Salt

View file

@ -35,7 +35,7 @@ jobs:
check-requirements:
name: Check Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: release-check
steps:
- name: Check For Admin Permission
@ -87,6 +87,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tools pkg repo confirm-unreleased --repository ${{ github.repository }} ${{ steps.setup-salt-version.outputs.salt-version }}
if [ "${{ github.event.repository.private }}" = "true" ]; then
tools pkg repo confirm-unreleased --repository saltstack/salt ${{ steps.setup-salt-version.outputs.salt-version }}
fi
- name: Check Release Staged
env:
@ -1057,7 +1060,7 @@ jobs:
# on a pull request instead of requiring all
name: Set the ${{ github.workflow }} Pipeline Exit Status
if: always()
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- check-requirements
- prepare-workflow

View file

@ -28,7 +28,7 @@ jobs:
workflow-requirements:
name: Check Workflow Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
outputs:
requirements-met: ${{ steps.check-requirements.outputs.requirements-met }}
steps:
@ -55,8 +55,7 @@ jobs:
trigger-branch-scheduled-builds:
name: Trigger Branch Workflows
if: ${{ github.event_name == 'schedule' && fromJSON(needs.workflow-requirements.outputs.requirements-met) }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- workflow-requirements
steps:
@ -68,7 +67,7 @@ jobs:
prepare-workflow:
name: Prepare Workflow Run
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
if: ${{ fromJSON(needs.workflow-requirements.outputs.requirements-met) }}
needs:
- workflow-requirements
@ -296,8 +295,7 @@ jobs:
prepare-release:
name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}"
if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['prepare-release'] && fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
needs:
- prepare-workflow
steps:
@ -431,7 +429,7 @@ jobs:
needs:
- prepare-workflow
- prepare-release
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3
@ -478,7 +476,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-salt-onedir:
@ -494,7 +492,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-rpm-pkgs:
@ -506,7 +504,7 @@ jobs:
uses: ./.github/workflows/build-rpm-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-deb-pkgs:
@ -518,7 +516,7 @@ jobs:
uses: ./.github/workflows/build-deb-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-windows-pkgs:
@ -530,7 +528,7 @@ jobs:
uses: ./.github/workflows/build-windows-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-macos-pkgs:
@ -542,7 +540,7 @@ jobs:
uses: ./.github/workflows/build-macos-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
amazonlinux-2-pkg-tests:
@ -1324,7 +1322,7 @@ jobs:
# on a pull request instead of requiring all
name: Set the ${{ github.workflow }} Pipeline Exit Status
if: always()
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- workflow-requirements
- trigger-branch-scheduled-builds

View file

@ -18,6 +18,10 @@ on:
type: boolean
default: false
description: Sign Windows Packages
skip-test-pypi-publish:
type: boolean
default: false
description: Skip publishing the source package to Test PyPi(For example, CVE releases)
skip-salt-test-suite:
type: boolean
default: false
@ -39,6 +43,7 @@ env:
permissions:
contents: read # for dorny/paths-filter to fetch a list of changed files
pull-requests: read # for dorny/paths-filter to read pull requests
actions: read # for technote-space/workflow-conclusion-action to get the job statuses
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.repository }}
@ -48,7 +53,7 @@ jobs:
check-requirements:
name: Check Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: staging-check
steps:
- name: Check For Admin Permission
@ -59,7 +64,7 @@ jobs:
prepare-workflow:
name: Prepare Workflow Run
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- check-requirements
outputs:
@ -191,6 +196,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tools pkg repo confirm-unreleased --repository ${{ github.repository }} ${{ steps.setup-salt-version.outputs.salt-version }}
if [ "${{ github.event.repository.private }}" = "true" ]; then
tools pkg repo confirm-unreleased --repository saltstack/salt ${{ steps.setup-salt-version.outputs.salt-version }}
fi
- name: Write Changed Files To A Local File
run:
@ -431,7 +439,7 @@ jobs:
needs:
- prepare-workflow
- prepare-release
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3
@ -478,7 +486,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-salt-onedir:
@ -494,7 +502,7 @@ jobs:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
self-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }}
github-hosted-runners: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-rpm-pkgs:
@ -506,7 +514,7 @@ jobs:
uses: ./.github/workflows/build-rpm-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-deb-pkgs:
@ -518,7 +526,7 @@ jobs:
uses: ./.github/workflows/build-deb-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
build-windows-pkgs:
@ -530,7 +538,7 @@ jobs:
uses: ./.github/workflows/build-windows-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
environment: staging
sign-packages: ${{ inputs.sign-windows-packages }}
@ -545,7 +553,7 @@ jobs:
uses: ./.github/workflows/build-macos-packages.yml
with:
salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}"
relenv-version: "0.13.2"
relenv-version: "0.13.3"
python-version: "3.10.12"
environment: staging
sign-packages: true
@ -2682,7 +2690,7 @@ jobs:
publish-pypi:
name: Publish to PyPi(test)
if: ${{ github.event.repository.fork != true }}
if: ${{ inputs.skip-test-pypi-publish != true && github.event.repository.fork != true }}
needs:
- prepare-workflow
- upload-release-artifacts
@ -2813,7 +2821,7 @@ jobs:
# on a pull request instead of requiring all
name: Set the ${{ github.workflow }} Pipeline Exit Status
if: always()
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- check-requirements
- prepare-workflow

View file

@ -52,8 +52,7 @@
- x86_64
<%- else %>
if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['<{ job_name }>'] && fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
<%- endif %>
needs:
- prepare-workflow
@ -214,7 +213,7 @@
needs:
- prepare-workflow
- prepare-release
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "medium", "x86_64"]') || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3

View file

@ -43,6 +43,9 @@ env:
permissions:
contents: read # for dorny/paths-filter to fetch a list of changed files
pull-requests: read # for dorny/paths-filter to read pull requests
<%- if workflow_slug not in ("nightly", "scheduled") %>
actions: read # for technote-space/workflow-conclusion-action to get the job statuses
<%- endif %>
<%- endblock permissions %>
@ -71,7 +74,7 @@ jobs:
prepare-workflow:
name: Prepare Workflow Run
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
<%- if prepare_workflow_if_check %>
if: <{ prepare_workflow_if_check }>
<%- endif %>
@ -212,6 +215,10 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tools pkg repo confirm-unreleased --repository ${{ github.repository }} ${{ steps.setup-salt-version.outputs.salt-version }}
if [ "${{ github.event.repository.private }}" = "true" ]; then
tools pkg repo confirm-unreleased --repository saltstack/salt ${{ steps.setup-salt-version.outputs.salt-version }}
fi
<%- endif %>
@ -304,7 +311,7 @@ jobs:
# on a pull request instead of requiring all
name: Set the ${{ github.workflow }} Pipeline Exit Status
if: always()
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
<%- if workflow_slug == "nightly" %>
environment: <{ workflow_slug }>
<%- endif %>

View file

@ -58,7 +58,7 @@ concurrency:
<%- do conclusion_needs.append('notify-slack') %>
notify-slack:
name: Notify Slack
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: <{ gh_environment }>
needs:
<%- for need in prepare_workflow_needs.iter(consume=False) %>

View file

@ -52,7 +52,7 @@ permissions:
<{ job_name }>:
<%- do prepare_workflow_needs.append(job_name) %>
name: Check Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: <{ gh_environment }>-check
steps:
- name: Check For Admin Permission
@ -115,6 +115,9 @@ permissions:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tools pkg repo confirm-unreleased --repository ${{ github.repository }} ${{ steps.setup-salt-version.outputs.salt-version }}
if [ "${{ github.event.repository.private }}" = "true" ]; then
tools pkg repo confirm-unreleased --repository saltstack/salt ${{ steps.setup-salt-version.outputs.salt-version }}
fi
- name: Check Release Staged
env:

View file

@ -31,6 +31,10 @@ on:
type: boolean
default: false
description: Sign Windows Packages
skip-test-pypi-publish:
type: boolean
default: false
description: Skip publishing the source package to Test PyPi(For example, CVE releases)
skip-salt-test-suite:
type: boolean
default: false
@ -62,7 +66,7 @@ concurrency:
<{ job_name }>:
<%- do prepare_workflow_needs.append(job_name) %>
name: Check Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: <{ gh_environment }>-check
steps:
- name: Check For Admin Permission
@ -160,7 +164,7 @@ concurrency:
publish-pypi:
<%- do conclusion_needs.append('publish-pypi') %>
name: Publish to PyPi(test)
if: ${{ github.event.repository.fork != true }}
if: ${{ inputs.skip-test-pypi-publish != true && github.event.repository.fork != true }}
needs:
- prepare-workflow
- upload-release-artifacts

View file

@ -7,8 +7,7 @@
<%- do conclusion_needs.append(job_name) %>
name: Trigger Branch Workflows
if: ${{ github.event_name == 'schedule' && fromJSON(needs.workflow-requirements.outputs.requirements-met) }}
runs-on:
- ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- workflow-requirements
steps:

View file

@ -4,7 +4,7 @@
<{ job_name }>:
<%- do prepare_workflow_needs.append(job_name) %>
name: Check Workflow Requirements
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
outputs:
requirements-met: ${{ steps.check-requirements.outputs.requirements-met }}
steps:

View file

@ -64,7 +64,7 @@ jobs:
generate-matrix:
name: Generate Test Matrix
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
outputs:
matrix-include: ${{ steps.generate-matrix.outputs.matrix }}
transport-matrix-include: ${{ steps.generate-transport-matrix.outputs.matrix }}
@ -445,7 +445,7 @@ jobs:
report:
name: Reports for ${{ inputs.distro-slug }}(${{ matrix.transport }})
if: always() && (inputs.skip-code-coverage == false || inputs.skip-junit-reports == false) && needs.test.result != 'cancelled' && needs.test.result != 'skipped'
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
needs:
- generate-matrix
- test

View file

@ -259,7 +259,7 @@ jobs:
report:
name: Reports for ${{ inputs.distro-slug }}(${{ inputs.arch }})
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
environment: ${{ inputs.environment }}
if: always() && needs.test.result != 'cancelled' && needs.test.result != 'skipped'
needs:

View file

@ -70,7 +70,7 @@ jobs:
generate-matrix:
name: Generate Package Test Matrix
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
outputs:
pkg-matrix-include: ${{ steps.generate-pkg-matrix.outputs.matrix }}
steps:
@ -275,7 +275,7 @@ jobs:
report:
name: Reports for ${{ inputs.distro-slug }}(${{ matrix.test-chunk }})
runs-on: ubuntu-latest
runs-on: ${{ github.event.repository.private && fromJSON('["self-hosted", "linux", "x86_64"]') || 'ubuntu-latest' }}
if: always() && (inputs.skip-code-coverage == false || inputs.skip-junit-reports == false) && needs.test.result != 'cancelled' && needs.test.result != 'skipped'
needs:
- test

View file

@ -7,6 +7,41 @@ Versions are `MAJOR.PATCH`.
# Changelog
## 3006.2 (2023-08-09)
### Fixed
- In scenarios where PythonNet fails to load, Salt will now fall back to WMI for
gathering grains information [#64897](https://github.com/saltstack/salt/issues/64897)
### Security
- fix CVE-2023-20897 by catching exception instead of letting exception disrupt connection [#cve-2023-20897](https://github.com/saltstack/salt/issues/cve-2023-20897)
- Fixed gitfs cachedir_basename to avoid hash collisions. Added MP Lock to gitfs. These changes should stop race conditions. [#cve-2023-20898](https://github.com/saltstack/salt/issues/cve-2023-20898)
- Upgrade to `requests==2.31.0`
Due to:
* https://github.com/advisories/GHSA-j8r2-6x86-q33q [#64336](https://github.com/saltstack/salt/issues/64336)
- Upgrade to `cryptography==41.0.3`(and therefor `pyopenssl==23.2.0` due to https://github.com/advisories/GHSA-jm77-qphf-c4w8)
This only really impacts pip installs of Salt and the windows onedir since the linux and macos onedir build every package dependency from source, not from pre-existing wheels.
Also resolves the following cryptography advisories:
Due to:
* https://github.com/advisories/GHSA-5cpq-8wj7-hf2v
* https://github.com/advisories/GHSA-x4qr-2fvf-3mr5
* https://github.com/advisories/GHSA-w7pp-m8wf-vj6r
There is no security upgrade available for Py3.5 [#64595](https://github.com/saltstack/salt/issues/64595)
- Bump to `certifi==2023.07.22` due to https://github.com/advisories/GHSA-xqr8-7jwr-rhp7 [#64718](https://github.com/saltstack/salt/issues/64718)
- Upgrade `relenv` to `0.13.2` and Python to `3.10.12`
Addresses multiple CVEs in Python's dependencies: https://docs.python.org/release/3.10.12/whatsnew/changelog.html#python-3-10-12 [#64719](https://github.com/saltstack/salt/issues/64719)
## 3006.1 (2023-05-05)

View file

@ -1,2 +1,2 @@
python_version: "3.10.12"
relenv_version: "0.13.2"
relenv_version: "0.13.3"

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-API" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-API" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-api \- salt-api Command
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-CALL" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-CALL" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-call \- salt-call Documentation
.SH SYNOPSIS

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-CLOUD" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-CLOUD" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-cloud \- Salt Cloud Command
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-CP" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-CP" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-cp \- salt-cp Documentation
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-KEY" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-KEY" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-key \- salt-key Documentation
.SH SYNOPSIS

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-MASTER" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-MASTER" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-master \- salt-master Documentation
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-MINION" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-MINION" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-minion \- salt-minion Documentation
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-PROXY" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-PROXY" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-proxy \- salt-proxy Documentation
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-RUN" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-RUN" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-run \- salt-run Documentation
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-SSH" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-SSH" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-ssh \- salt-ssh Documentation
.SH SYNOPSIS

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT-SYNDIC" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT-SYNDIC" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt-syndic \- salt-syndic Documentation
.sp

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt \- salt
.SH SYNOPSIS

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SALT" "7" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SALT" "7" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
salt \- Salt Documentation
.SH SALT PROJECT
@ -193937,7 +193937,7 @@ Passes through all the parameters described in the
\fI\%utils.http.query function\fP:
.INDENT 7.0
.TP
.B salt.utils.http.query(url, method=\(aqGET\(aq, params=None, data=None, data_file=None, header_dict=None, header_list=None, header_file=None, username=None, password=None, auth=None, decode=False, decode_type=\(aqauto\(aq, status=False, headers=False, text=False, cookies=None, cookie_jar=None, cookie_format=\(aqlwp\(aq, persist_session=False, session_cookie_jar=None, data_render=False, data_renderer=None, header_render=False, header_renderer=None, template_dict=None, test=False, test_url=None, node=\(aqminion\(aq, port=80, opts=None, backend=None, ca_bundle=None, verify_ssl=None, cert=None, text_out=None, headers_out=None, decode_out=None, stream=False, streaming_callback=None, header_callback=None, handle=False, agent=\(aqSalt/3006.1\(aq, hide_fields=None, raise_error=True, formdata=False, formdata_fieldname=None, formdata_filename=None, decode_body=True, **kwargs)
.B salt.utils.http.query(url, method=\(aqGET\(aq, params=None, data=None, data_file=None, header_dict=None, header_list=None, header_file=None, username=None, password=None, auth=None, decode=False, decode_type=\(aqauto\(aq, status=False, headers=False, text=False, cookies=None, cookie_jar=None, cookie_format=\(aqlwp\(aq, persist_session=False, session_cookie_jar=None, data_render=False, data_renderer=None, header_render=False, header_renderer=None, template_dict=None, test=False, test_url=None, node=\(aqminion\(aq, port=80, opts=None, backend=None, ca_bundle=None, verify_ssl=None, cert=None, text_out=None, headers_out=None, decode_out=None, stream=False, streaming_callback=None, header_callback=None, handle=False, agent=\(aqSalt/3006.2\(aq, hide_fields=None, raise_error=True, formdata=False, formdata_fieldname=None, formdata_filename=None, decode_body=True, **kwargs)
Query a resource, and decode the return data
.UNINDENT
.INDENT 7.0
@ -380698,12 +380698,12 @@ It also use C bindings if they are available.
.INDENT 0.0
.TP
.B salt.serializers.yaml.BaseDumper
alias of \fBSafeDumper\fP
alias of \fBCSafeDumper\fP
.UNINDENT
.INDENT 0.0
.TP
.B salt.serializers.yaml.BaseLoader
alias of \fBSafeLoader\fP
alias of \fBCSafeLoader\fP
.UNINDENT
.INDENT 0.0
.TP
@ -380976,7 +380976,7 @@ alias of \fBSafeDumper\fP
.INDENT 0.0
.TP
.B salt.serializers.yamlex.BaseLoader
alias of \fBSafeLoader\fP
alias of \fBCSafeLoader\fP
.UNINDENT
.INDENT 0.0
.TP
@ -457275,7 +457275,7 @@ installed2
.UNINDENT
.INDENT 0.0
.TP
.B salt.states.zcbuildout.installed(name, config=\(aqbuildout.cfg\(aq, quiet=False, parts=None, user=None, env=(), buildout_ver=None, test_release=False, distribute=None, new_st=None, offline=False, newest=False, python=\(aq/opt/actions\-runner/_work/salt/salt/.tools\-venvs/docs/bin/python\(aq, debug=False, verbose=False, unless=None, onlyif=None, use_vt=False, loglevel=\(aqdebug\(aq, **kwargs)
.B salt.states.zcbuildout.installed(name, config=\(aqbuildout.cfg\(aq, quiet=False, parts=None, user=None, env=(), buildout_ver=None, test_release=False, distribute=None, new_st=None, offline=False, newest=False, python=\(aq/opt/actions\-runner/_work/salt\-priv/salt\-priv/.tools\-venvs/docs/bin/python\(aq, debug=False, verbose=False, unless=None, onlyif=None, use_vt=False, loglevel=\(aqdebug\(aq, **kwargs)
Install buildout in a specific directory
.sp
It is a thin wrapper to modules.buildout.buildout
@ -476693,6 +476693,54 @@ Cloud deployment directories are owned by salt user and group \fI\%#64204\fP
.IP \(bu 2
\fBlgpo_reg\fP state now enforces and reports changes to the registry \fI\%#64222\fP
.UNINDENT
(release\-3006.2)=
.SS Salt 3006.2 release notes
.SS Changelog
.SS Fixed
.INDENT 0.0
.IP \(bu 2
In scenarios where PythonNet fails to load, Salt will now fall back to WMI for
gathering grains information \fI\%#64897\fP
.UNINDENT
.SS Security
.INDENT 0.0
.IP \(bu 2
fix CVE\-2023\-20897 by catching exception instead of letting exception disrupt connection \fI\%#cve\-2023\-20897\fP
.IP \(bu 2
Fixed gitfs cachedir_basename to avoid hash collisions. Added MP Lock to gitfs. These changes should stop race conditions. \fI\%#cve\-2023\-20898\fP
.IP \(bu 2
Upgrade to \fBrequests==2.31.0\fP
.sp
Due to:
.INDENT 2.0
.IP \(bu 2
\fI\%https://github.com/advisories/GHSA\-j8r2\-6x86\-q33q\fP \fI\%#64336\fP
.UNINDENT
.IP \(bu 2
Upgrade to \fBcryptography==41.0.3\fP(and therefor \fBpyopenssl==23.2.0\fP due to \fI\%https://github.com/advisories/GHSA\-jm77\-qphf\-c4w8\fP)
.sp
This only really impacts pip installs of Salt and the windows onedir since the linux and macos onedir build every package dependency from source, not from pre\-existing wheels.
.sp
Also resolves the following cryptography advisories:
.sp
Due to:
.INDENT 2.0
.IP \(bu 2
\fI\%https://github.com/advisories/GHSA\-5cpq\-8wj7\-hf2v\fP
.IP \(bu 2
\fI\%https://github.com/advisories/GHSA\-x4qr\-2fvf\-3mr5\fP
.IP \(bu 2
\fI\%https://github.com/advisories/GHSA\-w7pp\-m8wf\-vj6r\fP
.UNINDENT
.sp
There is no security upgrade available for Py3.5 \fI\%#64595\fP
.IP \(bu 2
Bump to \fBcertifi==2023.07.22\fP due to \fI\%https://github.com/advisories/GHSA\-xqr8\-7jwr\-rhp7\fP \fI\%#64718\fP
.IP \(bu 2
Upgrade \fBrelenv\fP to \fB0.13.2\fP and Python to \fB3.10.12\fP
.sp
Addresses multiple CVEs in Python\(aqs dependencies: \fI\%https://docs.python.org/release/3.10.12/whatsnew/changelog.html#python\-3\-10\-12\fP \fI\%#64719\fP
.UNINDENT
.sp
See \fI\%Install a release candidate\fP
for more information about installing an RC when one is available.

View file

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SPM" "1" "Generated on May 05, 2023 at 05:45:04 PM UTC." "3006.1" "Salt"
.TH "SPM" "1" "Generated on August 09, 2023 at 12:02:24 PM UTC." "3006.2" "Salt"
.SH NAME
spm \- Salt Package Manager Command
.sp

View file

@ -0,0 +1,50 @@
(release-3006.2)=
# Salt 3006.2 release notes
<!---
Do not edit this file. This is auto generated.
Edit the templates in doc/topics/releases/templates/
for a given release.
-->
<!--
Add release specific details below
-->
<!--
Do not edit the changelog below.
This is auto generated.
-->
## Changelog
### Fixed
- In scenarios where PythonNet fails to load, Salt will now fall back to WMI for
gathering grains information [#64897](https://github.com/saltstack/salt/issues/64897)
### Security
- fix CVE-2023-20897 by catching exception instead of letting exception disrupt connection [#cve-2023-20897](https://github.com/saltstack/salt/issues/cve-2023-20897)
- Fixed gitfs cachedir_basename to avoid hash collisions. Added MP Lock to gitfs. These changes should stop race conditions. [#cve-2023-20898](https://github.com/saltstack/salt/issues/cve-2023-20898)
- Upgrade to `requests==2.31.0`
Due to:
* https://github.com/advisories/GHSA-j8r2-6x86-q33q [#64336](https://github.com/saltstack/salt/issues/64336)
- Upgrade to `cryptography==41.0.3`(and therefor `pyopenssl==23.2.0` due to https://github.com/advisories/GHSA-jm77-qphf-c4w8)
This only really impacts pip installs of Salt and the windows onedir since the linux and macos onedir build every package dependency from source, not from pre-existing wheels.
Also resolves the following cryptography advisories:
Due to:
* https://github.com/advisories/GHSA-5cpq-8wj7-hf2v
* https://github.com/advisories/GHSA-x4qr-2fvf-3mr5
* https://github.com/advisories/GHSA-w7pp-m8wf-vj6r
There is no security upgrade available for Py3.5 [#64595](https://github.com/saltstack/salt/issues/64595)
- Bump to `certifi==2023.07.22` due to https://github.com/advisories/GHSA-xqr8-7jwr-rhp7 [#64718](https://github.com/saltstack/salt/issues/64718)
- Upgrade `relenv` to `0.13.2` and Python to `3.10.12`
Addresses multiple CVEs in Python's dependencies: https://docs.python.org/release/3.10.12/whatsnew/changelog.html#python-3-10-12 [#64719](https://github.com/saltstack/salt/issues/64719)

View file

@ -0,0 +1,14 @@
(release-3006.2)=
# Salt 3006.2 release notes{{ unreleased }}
{{ warning }}
<!--
Add release specific details below
-->
<!--
Do not edit the changelog below.
This is auto generated.
-->
## Changelog
{{ changelog }}

View file

@ -1,3 +1,39 @@
salt (3006.2) stable; urgency=medium
# Fixed
* In scenarios where PythonNet fails to load, Salt will now fall back to WMI for
gathering grains information [#64897](https://github.com/saltstack/salt/issues/64897)
# Security
* fix CVE-2023-20897 by catching exception instead of letting exception disrupt connection [#cve-2023-20897](https://github.com/saltstack/salt/issues/cve-2023-20897)
* Fixed gitfs cachedir_basename to avoid hash collisions. Added MP Lock to gitfs. These changes should stop race conditions. [#cve-2023-20898](https://github.com/saltstack/salt/issues/cve-2023-20898)
* Upgrade to `requests==2.31.0`
Due to:
* https://github.com/advisories/GHSA*j8r2-6x86-q33q [#64336](https://github.com/saltstack/salt/issues/64336)
* Upgrade to `cryptography==41.0.3`(and therefor `pyopenssl==23.2.0` due to https://github.com/advisories/GHSA-jm77-qphf-c4w8)
This only really impacts pip installs of Salt and the windows onedir since the linux and macos onedir build every package dependency from source, not from pre*existing wheels.
Also resolves the following cryptography advisories:
Due to:
* https://github.com/advisories/GHSA*5cpq-8wj7-hf2v
* https://github.com/advisories/GHSA*x4qr-2fvf-3mr5
* https://github.com/advisories/GHSA*w7pp-m8wf-vj6r
There is no security upgrade available for Py3.5 [#64595](https://github.com/saltstack/salt/issues/64595)
* Bump to `certifi==2023.07.22` due to https://github.com/advisories/GHSA-xqr8-7jwr-rhp7 [#64718](https://github.com/saltstack/salt/issues/64718)
* Upgrade `relenv` to `0.13.2` and Python to `3.10.12`
Addresses multiple CVEs in Python's dependencies: https://docs.python.org/release/3.10.12/whatsnew/changelog.html#python*3-10-12 [#64719](https://github.com/saltstack/salt/issues/64719)
-- Salt Project Packaging <saltproject-packaging@vmware.com> Wed, 09 Aug 2023 12:01:52 +0000
salt (3006.1) stable; urgency=medium

View file

@ -17,6 +17,7 @@ Vcs-Git: git://github.com/saltstack/salt.git
Package: salt-common
Architecture: amd64 arm64
Depends: ${misc:Depends}
Breaks: salt-minion (<= 3006.1)
Suggests: ifupdown
Recommends: lsb-release
Description: shared libraries that salt requires for all packages
@ -42,8 +43,8 @@ Description: shared libraries that salt requires for all packages
Package: salt-master
Architecture: amd64 arm64
Replaces: salt-common (<= 3005.1+ds-4)
Breaks: salt-common (<= 3005.1+ds-4)
Replaces: salt-common (<= 3006.1)
Breaks: salt-common (<= 3006.1)
Depends: salt-common (= ${source:Version}),
${misc:Depends}
Description: remote manager to administer servers via salt

View file

@ -25,7 +25,7 @@
%define fish_dir %{_datadir}/fish/vendor_functions.d
Name: salt
Version: 3006.1
Version: 3006.2
Release: 0
Summary: A parallel remote execution system
Group: System Environment/Daemons
@ -512,6 +512,39 @@ fi
%changelog
* Wed Aug 09 2023 Salt Project Packaging <saltproject-packaging@vmware.com> - 3006.2
# Fixed
- In scenarios where PythonNet fails to load, Salt will now fall back to WMI for
gathering grains information [#64897](https://github.com/saltstack/salt/issues/64897)
# Security
- fix CVE-2023-20897 by catching exception instead of letting exception disrupt connection [#cve-2023-20897](https://github.com/saltstack/salt/issues/cve-2023-20897)
- Fixed gitfs cachedir_basename to avoid hash collisions. Added MP Lock to gitfs. These changes should stop race conditions. [#cve-2023-20898](https://github.com/saltstack/salt/issues/cve-2023-20898)
- Upgrade to `requests==2.31.0`
Due to:
* https://github.com/advisories/GHSA-j8r2-6x86-q33q [#64336](https://github.com/saltstack/salt/issues/64336)
- Upgrade to `cryptography==41.0.3`(and therefor `pyopenssl==23.2.0` due to https://github.com/advisories/GHSA-jm77-qphf-c4w8)
This only really impacts pip installs of Salt and the windows onedir since the linux and macos onedir build every package dependency from source, not from pre-existing wheels.
Also resolves the following cryptography advisories:
Due to:
* https://github.com/advisories/GHSA-5cpq-8wj7-hf2v
* https://github.com/advisories/GHSA-x4qr-2fvf-3mr5
* https://github.com/advisories/GHSA-w7pp-m8wf-vj6r
There is no security upgrade available for Py3.5 [#64595](https://github.com/saltstack/salt/issues/64595)
- Bump to `certifi==2023.07.22` due to https://github.com/advisories/GHSA-xqr8-7jwr-rhp7 [#64718](https://github.com/saltstack/salt/issues/64718)
- Upgrade `relenv` to `0.13.2` and Python to `3.10.12`
Addresses multiple CVEs in Python's dependencies: https://docs.python.org/release/3.10.12/whatsnew/changelog.html#python-3-10-12 [#64719](https://github.com/saltstack/salt/issues/64719)
* Fri May 05 2023 Salt Project Packaging <saltproject-packaging@vmware.com> - 3006.1
# Fixed

View file

@ -11,7 +11,7 @@ idna>=2.8
linode-python>=1.1.1
pyasn1>=0.4.8
pycparser>=2.21
pyopenssl>=19.0.0
pyopenssl>=23.2.0
python-dateutil>=2.8.0
python-gnupg>=0.4.4
setproctitle>=1.2.3

View file

@ -3,7 +3,7 @@
cherrypy
backports.ssl_match_hostname>=3.7.0.1; python_version < '3.7'
pycparser>=2.21; python_version >= '3.9'
pyopenssl>=19.0.0
pyopenssl>=23.2.0
python-dateutil>=2.8.0
python-gnupg>=0.4.4
rpm-vercmp

View file

@ -10,7 +10,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -13,7 +13,7 @@ cffi==1.14.6
# -r requirements/windows.txt
# clr-loader
# cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -13,7 +13,7 @@ cffi==1.14.6
# -r requirements/windows.txt
# clr-loader
# cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -13,7 +13,7 @@ cffi==1.14.6
# -r requirements/windows.txt
# clr-loader
# cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -10,7 +10,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -8,7 +8,7 @@ certifi==2023.07.22
# via requests
cffi==1.14.6
# via cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -13,7 +13,7 @@ cffi==1.14.6
# -r requirements/windows.txt
# clr-loader
# cryptography
charset-normalizer==3.1.0
charset-normalizer==3.2.0
# via requests
cheroot==8.5.2
# via cherrypy

View file

@ -18,7 +18,7 @@ pyasn1>=0.4.8
pycparser>=2.21
pymssql>=2.2.1
pymysql>=1.0.2
pyopenssl>=20.0.1
pyopenssl>=23.2.0
python-dateutil>=2.8.1
python-gnupg>=0.4.7
requests>=2.25.1

View file

@ -428,7 +428,11 @@ class RequestServer(salt.transport.base.DaemonizedRequestServer):
@salt.ext.tornado.gen.coroutine
def handle_message(self, stream, payload):
payload = self.decode_payload(payload)
try:
payload = self.decode_payload(payload)
except salt.exceptions.SaltDeserializationError:
self.stream.send(self.encode_payload({"msg": "bad load"}))
return
# XXX: Is header really needed?
reply = yield self.message_handler(payload)
self.stream.send(self.encode_payload(reply))

View file

@ -3,6 +3,7 @@ Classes which provide the shared base for GitFS, git_pillar, and winrepo
"""
import base64
import contextlib
import copy
import errno
@ -11,10 +12,12 @@ import glob
import hashlib
import io
import logging
import multiprocessing
import os
import shlex
import shutil
import stat
import string
import subprocess
import time
import weakref
@ -225,6 +228,10 @@ class GitProvider:
invoking the parent class' __init__.
"""
# master lock should only be locked for very short periods of times "seconds"
# the master lock should be used when ever git provider reads or writes to one if it locks
_master_lock = multiprocessing.Lock()
def __init__(
self,
opts,
@ -451,13 +458,44 @@ class GitProvider:
failhard(self.role)
hash_type = getattr(hashlib, self.opts.get("hash_type", "md5"))
# Generate full id.
# Full id helps decrease the chances of collections in the gitfs cache.
try:
target = str(self.get_checkout_target())
except AttributeError:
target = ""
self._full_id = "-".join(
[
getattr(self, "name", ""),
self.id,
getattr(self, "env", ""),
getattr(self, "_root", ""),
self.role,
getattr(self, "base", ""),
getattr(self, "branch", ""),
target,
]
)
# We loaded this data from yaml configuration files, so, its safe
# to use UTF-8
self.hash = hash_type(self.id.encode("utf-8")).hexdigest()
self.cachedir_basename = getattr(self, "name", self.hash)
base64_hash = str(
base64.b64encode(hash_type(self._full_id.encode("utf-8")).digest()),
encoding="ascii", # base64 only outputs ascii
).replace(
"/", "_"
) # replace "/" with "_" to not cause trouble with file system
# limit name length to 19, so we don't eat up all the path length for windows
# this is due to pygit2 limitations
# replace any unknown char with "_" to not cause trouble with file system
name_chars = string.ascii_letters + string.digits + "-"
cache_name = "".join(
c if c in name_chars else "_" for c in getattr(self, "name", "")[:19]
)
self.cachedir_basename = f"{cache_name}-{base64_hash}"
self.cachedir = salt.utils.path.join(cache_root, self.cachedir_basename)
self.linkdir = salt.utils.path.join(cache_root, "links", self.cachedir_basename)
if not os.path.isdir(self.cachedir):
os.makedirs(self.cachedir)
@ -472,6 +510,12 @@ class GitProvider:
log.critical(msg, exc_info=True)
failhard(self.role)
def full_id(self):
return self._full_id
def get_cachedir_basename(self):
return self.cachedir_basename
def _get_envs_from_ref_paths(self, refs):
"""
Return the names of remote refs (stripped of the remote name) and tags
@ -662,6 +706,19 @@ class GitProvider:
"""
Clear update.lk
"""
if self.__class__._master_lock.acquire(timeout=60) is False:
# if gitfs works right we should never see this timeout error.
log.error("gitfs master lock timeout!")
raise TimeoutError("gitfs master lock timeout!")
try:
return self._clear_lock(lock_type)
finally:
self.__class__._master_lock.release()
def _clear_lock(self, lock_type="update"):
"""
Clear update.lk without MultiProcessing locks
"""
lock_file = self._get_lock_file(lock_type=lock_type)
def _add_error(errlist, exc):
@ -837,6 +894,20 @@ class GitProvider:
"""
Place a lock file if (and only if) it does not already exist.
"""
if self.__class__._master_lock.acquire(timeout=60) is False:
# if gitfs works right we should never see this timeout error.
log.error("gitfs master lock timeout!")
raise TimeoutError("gitfs master lock timeout!")
try:
return self.__lock(lock_type, failhard)
finally:
self.__class__._master_lock.release()
def __lock(self, lock_type="update", failhard=False):
"""
Place a lock file if (and only if) it does not already exist.
Without MultiProcessing locks.
"""
try:
fh_ = os.open(
self._get_lock_file(lock_type), os.O_CREAT | os.O_EXCL | os.O_WRONLY
@ -903,9 +974,9 @@ class GitProvider:
lock_type,
lock_file,
)
success, fail = self.clear_lock()
success, fail = self._clear_lock()
if success:
return self._lock(lock_type="update", failhard=failhard)
return self.__lock(lock_type="update", failhard=failhard)
elif failhard:
raise
return

View file

@ -20,6 +20,7 @@ depending on the version of Windows this is run on. Once support for Windows
"""
# https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.networkinterface.getallnetworkinterfaces?view=netframework-4.7.2
import logging
import platform
import salt.utils.win_reg
@ -27,6 +28,8 @@ from salt._compat import ipaddress
IS_WINDOWS = platform.system() == "Windows"
log = logging.getLogger(__name__)
__virtualname__ = "win_network"
if IS_WINDOWS:
@ -53,9 +56,23 @@ if IS_WINDOWS:
import salt.utils.winapi
else:
# This uses .NET to get network settings and is faster than WMI
# We need the clr import for the `System.Net` import
import clr # pylint: disable=unused-import
from System.Net import NetworkInformation
try:
# pylint: disable=unused-import
import clr
# pylint: enable=unused-import
from System.Net import NetworkInformation
except RuntimeError:
# In some environments, using the Relenv OneDir package, we can't
# load pythonnet. Uninstalling and reinstalling pythonnet fixes the
# issue, but it is a manual step. Until we figure it out, we are
# just going to fall back to WMI. I was able to reproduce a failing
# system using Windows 10 Home Edition
log.debug("Failed to load pythonnet. Falling back to WMI")
USE_WMI = True
import wmi
import salt.utils.winapi
# TODO: Should we deprecate support for pythonnet 2.5.2, these enumerations can
# TODO: be deleted

View file

@ -11,6 +11,7 @@ import threading
import time
import uuid
import msgpack
import pytest
import salt.channel.client
@ -1404,3 +1405,32 @@ async def test_req_chan_auth_v2_new_minion_without_master_pub(pki_dir, io_loop):
assert "sig" in ret
ret = client.auth.handle_signin_response(signin_payload, ret)
assert ret == "retry"
async def test_req_server_garbage_request(io_loop):
"""
Validate invalid msgpack messages will not raise exceptions in the
RequestServers's message handler.
"""
opts = salt.config.master_config("")
request_server = salt.transport.zeromq.RequestServer(opts)
def message_handler(payload):
return payload
request_server.post_fork(message_handler, io_loop)
byts = msgpack.dumps({"foo": "bar"})
badbyts = byts[:3] + b"^M" + byts[3:]
valid_response = msgpack.dumps({"msg": "bad load"})
stream = MagicMock()
request_server.stream = stream
try:
await request_server.handle_message(stream, badbyts)
except Exception as exc: # pylint: disable=broad-except
pytest.fail("Exception was raised {}".format(exc))
request_server.stream.send.assert_called_once_with(valid_response)

View file

@ -0,0 +1,263 @@
import os
import string
import time
import pytest
import salt.config
import salt.fileserver.gitfs
import salt.utils.gitfs
from salt.exceptions import FileserverConfigError
from tests.support.mock import MagicMock, patch
try:
HAS_PYGIT2 = (
salt.utils.gitfs.PYGIT2_VERSION
and salt.utils.gitfs.PYGIT2_VERSION >= salt.utils.gitfs.PYGIT2_MINVER
and salt.utils.gitfs.LIBGIT2_VERSION
and salt.utils.gitfs.LIBGIT2_VERSION >= salt.utils.gitfs.LIBGIT2_MINVER
)
except AttributeError:
HAS_PYGIT2 = False
if HAS_PYGIT2:
import pygit2
@pytest.fixture
def minion_opts(tmp_path):
"""
Default minion configuration with relative temporary paths to not require root permissions.
"""
root_dir = tmp_path / "minion"
opts = salt.config.DEFAULT_MINION_OPTS.copy()
opts["__role"] = "minion"
opts["root_dir"] = str(root_dir)
for name in ("cachedir", "pki_dir", "sock_dir", "conf_dir"):
dirpath = root_dir / name
dirpath.mkdir(parents=True)
opts[name] = str(dirpath)
opts["log_file"] = "logs/minion.log"
return opts
@pytest.mark.parametrize(
"role_name,role_class",
(
("gitfs", salt.utils.gitfs.GitFS),
("git_pillar", salt.utils.gitfs.GitPillar),
("winrepo", salt.utils.gitfs.WinRepo),
),
)
def test_provider_case_insensitive_gitfs_provider(minion_opts, role_name, role_class):
"""
Ensure that both lowercase and non-lowercase values are supported
"""
provider = "GitPython"
key = "{}_provider".format(role_name)
with patch.object(role_class, "verify_gitpython", MagicMock(return_value=True)):
with patch.object(role_class, "verify_pygit2", MagicMock(return_value=False)):
args = [minion_opts, {}]
kwargs = {"init_remotes": False}
if role_name == "winrepo":
kwargs["cache_root"] = "/tmp/winrepo-dir"
with patch.dict(minion_opts, {key: provider}):
# Try to create an instance with uppercase letters in
# provider name. If it fails then a
# FileserverConfigError will be raised, so no assert is
# necessary.
role_class(*args, **kwargs)
# Now try to instantiate an instance with all lowercase
# letters. Again, no need for an assert here.
role_class(*args, **kwargs)
@pytest.mark.parametrize(
"role_name,role_class",
(
("gitfs", salt.utils.gitfs.GitFS),
("git_pillar", salt.utils.gitfs.GitPillar),
("winrepo", salt.utils.gitfs.WinRepo),
),
)
def test_valid_provider_gitfs_provider(minion_opts, role_name, role_class):
"""
Ensure that an invalid provider is not accepted, raising a
FileserverConfigError.
"""
def _get_mock(verify, provider):
"""
Return a MagicMock with the desired return value
"""
return MagicMock(return_value=verify.endswith(provider))
key = "{}_provider".format(role_name)
for provider in salt.utils.gitfs.GIT_PROVIDERS:
verify = "verify_gitpython"
mock1 = _get_mock(verify, provider)
with patch.object(role_class, verify, mock1):
verify = "verify_pygit2"
mock2 = _get_mock(verify, provider)
with patch.object(role_class, verify, mock2):
args = [minion_opts, {}]
kwargs = {"init_remotes": False}
if role_name == "winrepo":
kwargs["cache_root"] = "/tmp/winrepo-dir"
with patch.dict(minion_opts, {key: provider}):
role_class(*args, **kwargs)
with patch.dict(minion_opts, {key: "foo"}):
# Set the provider name to a known invalid provider
# and make sure it raises an exception.
with pytest.raises(FileserverConfigError):
role_class(*args, **kwargs)
@pytest.fixture
def _prepare_remote_repository_pygit2(tmp_path):
remote = os.path.join(tmp_path, "pygit2-repo")
filecontent = "This is an empty README file"
filename = "README"
signature = pygit2.Signature(
"Dummy Commiter", "dummy@dummy.com", int(time.time()), 0
)
repository = pygit2.init_repository(remote, False)
builder = repository.TreeBuilder()
tree = builder.write()
commit = repository.create_commit(
"HEAD", signature, signature, "Create master branch", tree, []
)
repository.create_reference("refs/tags/simple_tag", commit)
with salt.utils.files.fopen(
os.path.join(repository.workdir, filename), "w"
) as file:
file.write(filecontent)
blob = repository.create_blob_fromworkdir(filename)
builder = repository.TreeBuilder()
builder.insert(filename, blob, pygit2.GIT_FILEMODE_BLOB)
tree = builder.write()
repository.index.read()
repository.index.add(filename)
repository.index.write()
commit = repository.create_commit(
"HEAD",
signature,
signature,
"Added a README",
tree,
[repository.head.target],
)
repository.create_tag(
"annotated_tag", commit, pygit2.GIT_OBJ_COMMIT, signature, "some message"
)
return remote
@pytest.fixture
def _prepare_provider(tmp_path, minion_opts, _prepare_remote_repository_pygit2):
cache = tmp_path / "pygit2-repo-cache"
minion_opts.update(
{
"cachedir": str(cache),
"gitfs_disable_saltenv_mapping": False,
"gitfs_base": "master",
"gitfs_insecure_auth": False,
"gitfs_mountpoint": "",
"gitfs_passphrase": "",
"gitfs_password": "",
"gitfs_privkey": "",
"gitfs_provider": "pygit2",
"gitfs_pubkey": "",
"gitfs_ref_types": ["branch", "tag", "sha"],
"gitfs_refspecs": [
"+refs/heads/*:refs/remotes/origin/*",
"+refs/tags/*:refs/tags/*",
],
"gitfs_root": "",
"gitfs_saltenv_blacklist": [],
"gitfs_saltenv_whitelist": [],
"gitfs_ssl_verify": True,
"gitfs_update_interval": 3,
"gitfs_user": "",
"verified_gitfs_provider": "pygit2",
}
)
per_remote_defaults = {
"base": "master",
"disable_saltenv_mapping": False,
"insecure_auth": False,
"ref_types": ["branch", "tag", "sha"],
"passphrase": "",
"mountpoint": "",
"password": "",
"privkey": "",
"pubkey": "",
"refspecs": [
"+refs/heads/*:refs/remotes/origin/*",
"+refs/tags/*:refs/tags/*",
],
"root": "",
"saltenv_blacklist": [],
"saltenv_whitelist": [],
"ssl_verify": True,
"update_interval": 60,
"user": "",
}
per_remote_only = ("all_saltenvs", "name", "saltenv")
override_params = tuple(per_remote_defaults)
cache_root = cache / "gitfs"
role = "gitfs"
provider = salt.utils.gitfs.Pygit2(
minion_opts,
_prepare_remote_repository_pygit2,
per_remote_defaults,
per_remote_only,
override_params,
str(cache_root),
role,
)
return provider
@pytest.mark.skipif(not HAS_PYGIT2, reason="This host lacks proper pygit2 support")
@pytest.mark.skip_on_windows(
reason="Skip Pygit2 on windows, due to pygit2 access error on windows"
)
def test_checkout_pygit2(_prepare_provider):
provider = _prepare_provider
provider.remotecallbacks = None
provider.credentials = None
provider.init_remote()
provider.fetch()
provider.branch = "master"
assert provider.cachedir in provider.checkout()
provider.branch = "simple_tag"
assert provider.cachedir in provider.checkout()
provider.branch = "annotated_tag"
assert provider.cachedir in provider.checkout()
provider.branch = "does_not_exist"
assert provider.checkout() is None
@pytest.mark.skipif(not HAS_PYGIT2, reason="This host lacks proper pygit2 support")
@pytest.mark.skip_on_windows(
reason="Skip Pygit2 on windows, due to pygit2 access error on windows"
)
def test_full_id_pygit2(_prepare_provider):
assert _prepare_provider.full_id().startswith("-")
assert _prepare_provider.full_id().endswith("/pygit2-repo---gitfs-master--")
@pytest.mark.skipif(not HAS_PYGIT2, reason="This host lacks proper pygit2 support")
@pytest.mark.skip_on_windows(
reason="Skip Pygit2 on windows, due to pygit2 access error on windows"
)
def test_get_cachedir_basename_pygit2(_prepare_provider):
basename = _prepare_provider.get_cachedir_basename()
# Note: if you are changing the length of basename
# keep in mind that pygit2 will error out on large file paths on Windows
assert len(basename) == 45
assert basename[0] == "-"
# check that a valid base64 is given '/' -> '_'
assert all(c in string.ascii_letters + string.digits + "+_=" for c in basename[1:])

View file

@ -2,36 +2,20 @@
These only test the provider selection and verification logic, they do not init
any remotes.
"""
import os
import shutil
from time import time
import tempfile
import pytest
import salt.ext.tornado.ioloop
import salt.fileserver.gitfs
import salt.utils.files
import salt.utils.gitfs
import salt.utils.path
import salt.utils.platform
import tests.support.paths
from salt.exceptions import FileserverConfigError
from tests.support.mixins import AdaptedConfigurationTestCaseMixin
from tests.support.mock import MagicMock, patch
from tests.support.unit import TestCase
try:
HAS_PYGIT2 = (
salt.utils.gitfs.PYGIT2_VERSION
and salt.utils.gitfs.PYGIT2_VERSION >= salt.utils.gitfs.PYGIT2_MINVER
and salt.utils.gitfs.LIBGIT2_VERSION
and salt.utils.gitfs.LIBGIT2_VERSION >= salt.utils.gitfs.LIBGIT2_MINVER
)
except AttributeError:
HAS_PYGIT2 = False
if HAS_PYGIT2:
import pygit2
def _clear_instance_map():
try:
@ -44,6 +28,9 @@ def _clear_instance_map():
class TestGitBase(TestCase, AdaptedConfigurationTestCaseMixin):
def setUp(self):
self._tmp_dir = tempfile.TemporaryDirectory()
tmp_name = self._tmp_dir.name
class MockedProvider(
salt.utils.gitfs.GitProvider
): # pylint: disable=abstract-method
@ -70,6 +57,7 @@ class TestGitBase(TestCase, AdaptedConfigurationTestCaseMixin):
)
def init_remote(self):
self.gitdir = salt.utils.path.join(tmp_name, ".git")
self.repo = True
new = False
return new
@ -106,6 +94,7 @@ class TestGitBase(TestCase, AdaptedConfigurationTestCaseMixin):
for remote in self.main_class.remotes:
remote.fetched = False
del self.main_class
self._tmp_dir.cleanup()
def test_update_all(self):
self.main_class.update()
@ -125,213 +114,73 @@ class TestGitBase(TestCase, AdaptedConfigurationTestCaseMixin):
self.assertTrue(self.main_class.remotes[0].fetched)
self.assertFalse(self.main_class.remotes[1].fetched)
def test_full_id(self):
self.assertEqual(
self.main_class.remotes[0].full_id(), "-file://repo1.git---gitfs-master--"
)
class TestGitFSProvider(TestCase):
def setUp(self):
self.opts = {"cachedir": "/tmp/gitfs-test-cache"}
def test_full_id_with_name(self):
self.assertEqual(
self.main_class.remotes[1].full_id(),
"repo2-file://repo2.git---gitfs-master--",
)
def tearDown(self):
self.opts = None
def test_get_cachedir_basename(self):
self.assertEqual(
self.main_class.remotes[0].get_cachedir_basename(),
"-jXhnbGDemchtZwTwaD2s6VOaVvs98a7w+AtiYlmOVb0=",
)
def test_provider_case_insensitive(self):
def test_get_cachedir_base_with_name(self):
self.assertEqual(
self.main_class.remotes[1].get_cachedir_basename(),
"repo2-nuezpiDtjQRFC0ZJDByvi+F6Vb8ZhfoH41n_KFxTGsU=",
)
def test_git_provider_mp_lock(self):
"""
Ensure that both lowercase and non-lowercase values are supported
Check that lock is released after provider.lock()
"""
provider = "GitPython"
for role_name, role_class in (
("gitfs", salt.utils.gitfs.GitFS),
("git_pillar", salt.utils.gitfs.GitPillar),
("winrepo", salt.utils.gitfs.WinRepo),
):
provider = self.main_class.remotes[0]
provider.lock()
# check that lock has been released
self.assertTrue(provider._master_lock.acquire(timeout=5))
provider._master_lock.release()
key = "{}_provider".format(role_name)
with patch.object(
role_class, "verify_gitpython", MagicMock(return_value=True)
):
with patch.object(
role_class, "verify_pygit2", MagicMock(return_value=False)
):
args = [self.opts, {}]
kwargs = {"init_remotes": False}
if role_name == "winrepo":
kwargs["cache_root"] = "/tmp/winrepo-dir"
with patch.dict(self.opts, {key: provider}):
# Try to create an instance with uppercase letters in
# provider name. If it fails then a
# FileserverConfigError will be raised, so no assert is
# necessary.
role_class(*args, **kwargs)
# Now try to instantiate an instance with all lowercase
# letters. Again, no need for an assert here.
role_class(*args, **kwargs)
def test_valid_provider(self):
def test_git_provider_mp_clear_lock(self):
"""
Ensure that an invalid provider is not accepted, raising a
FileserverConfigError.
Check that lock is released after provider.clear_lock()
"""
provider = self.main_class.remotes[0]
provider.clear_lock()
# check that lock has been released
self.assertTrue(provider._master_lock.acquire(timeout=5))
provider._master_lock.release()
def _get_mock(verify, provider):
"""
Return a MagicMock with the desired return value
"""
return MagicMock(return_value=verify.endswith(provider))
@pytest.mark.slow_test
def test_git_provider_mp_lock_timeout(self):
"""
Check that lock will time out if master lock is locked.
"""
provider = self.main_class.remotes[0]
# Hijack the lock so git provider is fooled into thinking another instance is doing somthing.
self.assertTrue(provider._master_lock.acquire(timeout=5))
try:
# git provider should raise timeout error to avoid lock race conditions
self.assertRaises(TimeoutError, provider.lock)
finally:
provider._master_lock.release()
for role_name, role_class in (
("gitfs", salt.utils.gitfs.GitFS),
("git_pillar", salt.utils.gitfs.GitPillar),
("winrepo", salt.utils.gitfs.WinRepo),
):
key = "{}_provider".format(role_name)
for provider in salt.utils.gitfs.GIT_PROVIDERS:
verify = "verify_gitpython"
mock1 = _get_mock(verify, provider)
with patch.object(role_class, verify, mock1):
verify = "verify_pygit2"
mock2 = _get_mock(verify, provider)
with patch.object(role_class, verify, mock2):
args = [self.opts, {}]
kwargs = {"init_remotes": False}
if role_name == "winrepo":
kwargs["cache_root"] = "/tmp/winrepo-dir"
with patch.dict(self.opts, {key: provider}):
role_class(*args, **kwargs)
with patch.dict(self.opts, {key: "foo"}):
# Set the provider name to a known invalid provider
# and make sure it raises an exception.
self.assertRaises(
FileserverConfigError, role_class, *args, **kwargs
)
@pytest.mark.skipif(not HAS_PYGIT2, reason="This host lacks proper pygit2 support")
@pytest.mark.skip_on_windows(
reason="Skip Pygit2 on windows, due to pygit2 access error on windows"
)
class TestPygit2(TestCase):
def _prepare_remote_repository(self, path):
shutil.rmtree(path, ignore_errors=True)
filecontent = "This is an empty README file"
filename = "README"
signature = pygit2.Signature(
"Dummy Commiter", "dummy@dummy.com", int(time()), 0
)
repository = pygit2.init_repository(path, False)
builder = repository.TreeBuilder()
tree = builder.write()
commit = repository.create_commit(
"HEAD", signature, signature, "Create master branch", tree, []
)
repository.create_reference("refs/tags/simple_tag", commit)
with salt.utils.files.fopen(
os.path.join(repository.workdir, filename), "w"
) as file:
file.write(filecontent)
blob = repository.create_blob_fromworkdir(filename)
builder = repository.TreeBuilder()
builder.insert(filename, blob, pygit2.GIT_FILEMODE_BLOB)
tree = builder.write()
repository.index.read()
repository.index.add(filename)
repository.index.write()
commit = repository.create_commit(
"HEAD",
signature,
signature,
"Added a README",
tree,
[repository.head.target],
)
repository.create_tag(
"annotated_tag", commit, pygit2.GIT_OBJ_COMMIT, signature, "some message"
)
def _prepare_cache_repository(self, remote, cache):
opts = {
"cachedir": cache,
"__role": "minion",
"gitfs_disable_saltenv_mapping": False,
"gitfs_base": "master",
"gitfs_insecure_auth": False,
"gitfs_mountpoint": "",
"gitfs_passphrase": "",
"gitfs_password": "",
"gitfs_privkey": "",
"gitfs_provider": "pygit2",
"gitfs_pubkey": "",
"gitfs_ref_types": ["branch", "tag", "sha"],
"gitfs_refspecs": [
"+refs/heads/*:refs/remotes/origin/*",
"+refs/tags/*:refs/tags/*",
],
"gitfs_root": "",
"gitfs_saltenv_blacklist": [],
"gitfs_saltenv_whitelist": [],
"gitfs_ssl_verify": True,
"gitfs_update_interval": 3,
"gitfs_user": "",
"verified_gitfs_provider": "pygit2",
}
per_remote_defaults = {
"base": "master",
"disable_saltenv_mapping": False,
"insecure_auth": False,
"ref_types": ["branch", "tag", "sha"],
"passphrase": "",
"mountpoint": "",
"password": "",
"privkey": "",
"pubkey": "",
"refspecs": [
"+refs/heads/*:refs/remotes/origin/*",
"+refs/tags/*:refs/tags/*",
],
"root": "",
"saltenv_blacklist": [],
"saltenv_whitelist": [],
"ssl_verify": True,
"update_interval": 60,
"user": "",
}
per_remote_only = ("all_saltenvs", "name", "saltenv")
override_params = tuple(per_remote_defaults.keys())
cache_root = os.path.join(cache, "gitfs")
role = "gitfs"
shutil.rmtree(cache_root, ignore_errors=True)
provider = salt.utils.gitfs.Pygit2(
opts,
remote,
per_remote_defaults,
per_remote_only,
override_params,
cache_root,
role,
)
return provider
def test_checkout(self):
remote = os.path.join(tests.support.paths.TMP, "pygit2-repo")
cache = os.path.join(tests.support.paths.TMP, "pygit2-repo-cache")
self._prepare_remote_repository(remote)
provider = self._prepare_cache_repository(remote, cache)
provider.remotecallbacks = None
provider.credentials = None
provider.init_remote()
provider.fetch()
provider.branch = "master"
self.assertIn(provider.cachedir, provider.checkout())
provider.branch = "simple_tag"
self.assertIn(provider.cachedir, provider.checkout())
provider.branch = "annotated_tag"
self.assertIn(provider.cachedir, provider.checkout())
provider.branch = "does_not_exist"
self.assertIsNone(provider.checkout())
@pytest.mark.slow_test
def test_git_provider_mp_clear_lock_timeout(self):
"""
Check that clear lock will time out if master lock is locked.
"""
provider = self.main_class.remotes[0]
# Hijack the lock so git provider is fooled into thinking another instance is doing somthing.
self.assertTrue(provider._master_lock.acquire(timeout=5))
try:
# git provider should raise timeout error to avoid lock race conditions
self.assertRaises(TimeoutError, provider.clear_lock)
finally:
provider._master_lock.release()