diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 207699290786..4e88f05b4a24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,6 +127,9 @@ jobs: - pkg/** - *pkg_requirements - *salt_added_modified + nsis_tests: + - added|modified: &nsis_tests + - pkg/windows/nsis/** testrun: - added|modified: - *pkg_requirements @@ -254,6 +257,14 @@ jobs: - prepare-workflow with: changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} + nsis-tests: + name: NSIS Tests + if: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }} + uses: ./.github/workflows/nsis-tests.yml + needs: + - prepare-workflow + with: + changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} prepare-release: name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}" @@ -1516,27 +1527,6 @@ jobs: workflow-slug: ci default-timeout: 180 - archlinux-lts: - name: Arch Linux LTS Test - if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} - needs: - - prepare-workflow - - build-ci-deps - uses: ./.github/workflows/test-action-linux.yml - with: - distro-slug: archlinux-lts - nox-session: ci-test-onedir - platform: linux - arch: x86_64 - nox-version: 2022.8.7 - gh-actions-python-version: "3.10" - testrun: ${{ needs.prepare-workflow.outputs.testrun }} - salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}" - cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}|3.10.14 - skip-code-coverage: ${{ fromJSON(needs.prepare-workflow.outputs.testrun)['skip_code_coverage'] }} - workflow-slug: ci - default-timeout: 180 - debian-11: name: Debian 11 Test if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] && contains(fromJSON(needs.prepare-workflow.outputs.os-labels), 'debian-11') }} @@ -1984,7 +1974,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 @@ -2131,6 +2120,7 @@ jobs: - prepare-workflow - pre-commit - lint + - nsis-tests - build-docs - build-deps-onedir - build-salt-onedir @@ -2151,7 +2141,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 93c4c09f55e8..d7bb49730019 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -176,6 +176,9 @@ jobs: - pkg/** - *pkg_requirements - *salt_added_modified + nsis_tests: + - added|modified: &nsis_tests + - pkg/windows/nsis/** testrun: - added|modified: - *pkg_requirements @@ -303,6 +306,14 @@ jobs: - prepare-workflow with: changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} + nsis-tests: + name: NSIS Tests + if: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }} + uses: ./.github/workflows/nsis-tests.yml + needs: + - prepare-workflow + with: + changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} prepare-release: name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}" @@ -1578,27 +1589,6 @@ jobs: workflow-slug: nightly default-timeout: 360 - archlinux-lts: - name: Arch Linux LTS Test - if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} - needs: - - prepare-workflow - - build-ci-deps - uses: ./.github/workflows/test-action-linux.yml - with: - distro-slug: archlinux-lts - nox-session: ci-test-onedir - platform: linux - arch: x86_64 - nox-version: 2022.8.7 - gh-actions-python-version: "3.10" - testrun: ${{ needs.prepare-workflow.outputs.testrun }} - salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}" - cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}|3.10.14 - skip-code-coverage: false - workflow-slug: nightly - default-timeout: 360 - debian-11: name: Debian 11 Test if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} @@ -2046,7 +2036,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 @@ -2953,7 +2942,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 @@ -3026,6 +3014,7 @@ jobs: - prepare-workflow - pre-commit - lint + - nsis-tests - build-docs - build-deps-onedir - build-salt-onedir diff --git a/.github/workflows/nsis-tests.yml b/.github/workflows/nsis-tests.yml new file mode 100644 index 000000000000..e80ed43f4099 --- /dev/null +++ b/.github/workflows/nsis-tests.yml @@ -0,0 +1,67 @@ +--- +name: Test NSIS Installer + +on: + workflow_call: + inputs: + changed-files: + required: true + type: string + description: JSON string containing information about changed files + +jobs: + Test-NSIS-Logic: + name: Logic Tests + runs-on: + - windows-latest + if: ${{ contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) || fromJSON(inputs.changed-files)['nsis_tests'] }} + + steps: + + - name: Checkout Salt + uses: actions/checkout@v4 + + - name: Set Up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install NSIS + run: .\pkg\windows\install_nsis.cmd -CICD + shell: cmd + + - name: Build Test Installer + run: .\pkg\windows\nsis\tests\setup.cmd -CICD + shell: cmd + + - name: Run Config Tests + run: .\pkg\windows\nsis\tests\test.cmd -CICD .\config_tests + shell: cmd + + Test-NSIS-Stress: + name: Stress Tests + runs-on: + - windows-latest + if: ${{ contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) || fromJSON(inputs.changed-files)['nsis_tests'] }} + + steps: + + - name: Checkout Salt + uses: actions/checkout@v4 + + - name: Set Up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install NSIS + run: .\pkg\windows\install_nsis.cmd -CICD + shell: cmd + + - name: Build Test Installer + run: .\pkg\windows\nsis\tests\setup.cmd -CICD + shell: cmd + + - name: Run Stress Test + run: .\pkg\windows\nsis\tests\test.cmd -CICD .\stress_tests + shell: cmd diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index 2ab7dc11b6d1..86e57fb71a42 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -166,6 +166,9 @@ jobs: - pkg/** - *pkg_requirements - *salt_added_modified + nsis_tests: + - added|modified: &nsis_tests + - pkg/windows/nsis/** testrun: - added|modified: - *pkg_requirements @@ -293,6 +296,14 @@ jobs: - prepare-workflow with: changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} + nsis-tests: + name: NSIS Tests + if: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }} + uses: ./.github/workflows/nsis-tests.yml + needs: + - prepare-workflow + with: + changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} prepare-release: name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}" @@ -1555,27 +1566,6 @@ jobs: workflow-slug: scheduled default-timeout: 360 - archlinux-lts: - name: Arch Linux LTS Test - if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} - needs: - - prepare-workflow - - build-ci-deps - uses: ./.github/workflows/test-action-linux.yml - with: - distro-slug: archlinux-lts - nox-session: ci-test-onedir - platform: linux - arch: x86_64 - nox-version: 2022.8.7 - gh-actions-python-version: "3.10" - testrun: ${{ needs.prepare-workflow.outputs.testrun }} - salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}" - cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}|3.10.14 - skip-code-coverage: false - workflow-slug: scheduled - default-timeout: 360 - debian-11: name: Debian 11 Test if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} @@ -2023,7 +2013,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 @@ -2172,6 +2161,7 @@ jobs: - prepare-workflow - pre-commit - lint + - nsis-tests - build-docs - build-deps-onedir - build-salt-onedir @@ -2192,7 +2182,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 616582c55eca..1c2546357e01 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -157,6 +157,9 @@ jobs: - pkg/** - *pkg_requirements - *salt_added_modified + nsis_tests: + - added|modified: &nsis_tests + - pkg/windows/nsis/** testrun: - added|modified: - *pkg_requirements @@ -293,6 +296,14 @@ jobs: - prepare-workflow with: changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} + nsis-tests: + name: NSIS Tests + if: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }} + uses: ./.github/workflows/nsis-tests.yml + needs: + - prepare-workflow + with: + changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} prepare-release: name: "Prepare Release: ${{ needs.prepare-workflow.outputs.salt-version }}" @@ -1563,27 +1574,6 @@ jobs: workflow-slug: staging default-timeout: 180 - archlinux-lts: - name: Arch Linux LTS Test - if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} - needs: - - prepare-workflow - - build-ci-deps - uses: ./.github/workflows/test-action-linux.yml - with: - distro-slug: archlinux-lts - nox-session: ci-test-onedir - platform: linux - arch: x86_64 - nox-version: 2022.8.7 - gh-actions-python-version: "3.10" - testrun: ${{ needs.prepare-workflow.outputs.testrun }} - salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}" - cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}|3.10.14 - skip-code-coverage: true - workflow-slug: staging - default-timeout: 180 - debian-11: name: Debian 11 Test if: ${{ fromJSON(needs.prepare-workflow.outputs.jobs)['test'] && fromJSON(needs.prepare-workflow.outputs.runners)['self-hosted'] }} @@ -2906,7 +2896,6 @@ jobs: - amazonlinux-2-arm64 - amazonlinux-2023 - amazonlinux-2023-arm64 - - archlinux-lts - debian-11 - debian-11-arm64 - debian-12 @@ -3023,6 +3012,7 @@ jobs: - prepare-workflow - pre-commit - lint + - nsis-tests - build-docs - build-deps-onedir - build-salt-onedir diff --git a/.github/workflows/templates/ci.yml.jinja b/.github/workflows/templates/ci.yml.jinja index eef2e77ba846..91713863f187 100644 --- a/.github/workflows/templates/ci.yml.jinja +++ b/.github/workflows/templates/ci.yml.jinja @@ -39,6 +39,19 @@ <%- endif %> + <%- set job_name = "nsis-tests" %> + <%- if includes.get(job_name, True) %> + <{ job_name }>: + <%- do conclusion_needs.append(job_name) %> + name: NSIS Tests + if: ${{ fromJSON(needs.prepare-workflow.outputs.runners)['github-hosted'] }} + uses: ./.github/workflows/nsis-tests.yml + needs: + - prepare-workflow + with: + changed-files: ${{ needs.prepare-workflow.outputs.changed-files }} + + <%- endif %> <%- set job_name = "prepare-release" %> <%- if includes.get(job_name, True) %> diff --git a/.github/workflows/templates/layout.yml.jinja b/.github/workflows/templates/layout.yml.jinja index 0f0e795c0c63..2259e26bff44 100644 --- a/.github/workflows/templates/layout.yml.jinja +++ b/.github/workflows/templates/layout.yml.jinja @@ -175,6 +175,9 @@ jobs: - pkg/** - *pkg_requirements - *salt_added_modified + nsis_tests: + - added|modified: &nsis_tests + - pkg/windows/nsis/** testrun: - added|modified: - *pkg_requirements diff --git a/.github/workflows/test-installer-action-windows.yml b/.github/workflows/test-installer-action-windows.yml deleted file mode 100644 index cf0b48556bb9..000000000000 --- a/.github/workflows/test-installer-action-windows.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Test Windows Installer - -on: pull_request - -permissions: - contents: read - -jobs: - Test-Windows-Installer: - runs-on: - - windows-latest - - steps: - - - name: Checkout Salt - uses: actions/checkout@v4 - - - name: Set Up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - - name: Install NSIS - run: .\pkg\windows\install_nsis.cmd -CICD - shell: cmd - - - name: Build Test Installer - run: .\pkg\windows\nsis\tests\setup.cmd -CICD - shell: cmd - - - name: Run Stress Test - run: .\pkg\windows\nsis\tests\test.cmd -CICD .\stress_tests - shell: cmd - - - name: Run Config Tests - run: .\pkg\windows\nsis\tests\test.cmd -CICD .\config_tests - shell: cmd diff --git a/.gitignore b/.gitignore index 63b49a644872..73cc51c3d1ce 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,7 @@ tests/unit/templates/roots # Pycharm .idea venv/ +.venv/ # VS Code .vscode diff --git a/changelog/61001.fixed.md b/changelog/61001.fixed.md new file mode 100644 index 000000000000..f9e6acf934d2 --- /dev/null +++ b/changelog/61001.fixed.md @@ -0,0 +1,2 @@ +Fixed an issue uninstalling packages on Windows using pkg.removed where there +are multiple versions of the same software installed diff --git a/changelog/66835.fixed.md b/changelog/66835.fixed.md new file mode 100644 index 000000000000..33d932b7fdf1 --- /dev/null +++ b/changelog/66835.fixed.md @@ -0,0 +1,2 @@ +Removed ``salt.utils.data.decode`` usage from the fileserver. This function was +necessary to support Python 2. This speeds up loading the list cache by 80-90x. diff --git a/changelog/66837.fixed.md b/changelog/66837.fixed.md new file mode 100644 index 000000000000..ccbe4a1155fd --- /dev/null +++ b/changelog/66837.fixed.md @@ -0,0 +1,3 @@ +Issue 66837: Fixes an issue with the `network.local_port_tcp` function +where it was not parsing the IPv4 mapped IPv6 address correctly. The +``::ffff:`` is now removed and only the IP address is returned. diff --git a/changelog/66886.deprecated.md b/changelog/66886.deprecated.md new file mode 100644 index 000000000000..597c0aee10a4 --- /dev/null +++ b/changelog/66886.deprecated.md @@ -0,0 +1 @@ +Drop Arch Linux support diff --git a/cicd/golden-images.json b/cicd/golden-images.json index ca7818fdd6ba..b0504ad777a7 100644 --- a/cicd/golden-images.json +++ b/cicd/golden-images.json @@ -1,8 +1,8 @@ { "amazonlinux-2-arm64": { - "ami": "ami-0c98c023fba59d522", + "ami": "ami-0aab00f54b6cddde6", "ami_description": "CI Image of AmazonLinux 2 arm64", - "ami_name": "salt-project/ci/amazonlinux/2/arm64/20240509.1530", + "ami_name": "salt-project/ci/amazonlinux/2/arm64/20240912.2135", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -10,9 +10,9 @@ "ssh_username": "ec2-user" }, "amazonlinux-2": { - "ami": "ami-02cba95cfd7074794", + "ami": "ami-0fd6cec7bbcf52d36", "ami_description": "CI Image of AmazonLinux 2 x86_64", - "ami_name": "salt-project/ci/amazonlinux/2/x86_64/20240509.1530", + "ami_name": "salt-project/ci/amazonlinux/2/x86_64/20240912.2135", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -20,9 +20,9 @@ "ssh_username": "ec2-user" }, "amazonlinux-2023-arm64": { - "ami": "ami-0609f0e98f5a6b73d", + "ami": "ami-095e9e4757b5fca1a", "ami_description": "CI Image of AmazonLinux 2023 arm64", - "ami_name": "salt-project/ci/amazonlinux/2023/arm64/20240509.1529", + "ami_name": "salt-project/ci/amazonlinux/2023/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -30,29 +30,19 @@ "ssh_username": "ec2-user" }, "amazonlinux-2023": { - "ami": "ami-0554a801eb6dcc42c", + "ami": "ami-002d043f1a36bf06e", "ami_description": "CI Image of AmazonLinux 2023 x86_64", - "ami_name": "salt-project/ci/amazonlinux/2023/x86_64/20240509.1529", + "ami_name": "salt-project/ci/amazonlinux/2023/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", "is_windows": "false", "ssh_username": "ec2-user" }, - "archlinux-lts": { - "ami": "ami-01ad78f19930b9747", - "ami_description": "CI Image of ArchLinux lts x86_64", - "ami_name": "salt-project/ci/archlinux/lts/x86_64/20240509.1530", - "arch": "x86_64", - "cloudwatch-agent-available": "false", - "instance_type": "t3a.large", - "is_windows": "false", - "ssh_username": "arch" - }, "debian-11-arm64": { - "ami": "ami-0eff227d9a94d8692", + "ami": "ami-0ff63235fce7bea1d", "ami_description": "CI Image of Debian 11 arm64", - "ami_name": "salt-project/ci/debian/11/arm64/20240509.1529", + "ami_name": "salt-project/ci/debian/11/arm64/20240912.2135", "arch": "arm64", "cloudwatch-agent-available": "false", "instance_type": "m6g.large", @@ -60,9 +50,9 @@ "ssh_username": "admin" }, "debian-11": { - "ami": "ami-099b2a5a1fb995166", + "ami": "ami-08685bfca48beeb67", "ami_description": "CI Image of Debian 11 x86_64", - "ami_name": "salt-project/ci/debian/11/x86_64/20240509.1529", + "ami_name": "salt-project/ci/debian/11/x86_64/20240912.2135", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -70,9 +60,9 @@ "ssh_username": "admin" }, "debian-12-arm64": { - "ami": "ami-0ab6b0cc8488f8880", + "ami": "ami-07d383138f04b32ba", "ami_description": "CI Image of Debian 12 arm64", - "ami_name": "salt-project/ci/debian/12/arm64/20240509.1529", + "ami_name": "salt-project/ci/debian/12/arm64/20240912.2135", "arch": "arm64", "cloudwatch-agent-available": "false", "instance_type": "m6g.large", @@ -80,9 +70,9 @@ "ssh_username": "admin" }, "debian-12": { - "ami": "ami-0e1f5b55325249c4e", + "ami": "ami-0867ec74072fd97a0", "ami_description": "CI Image of Debian 12 x86_64", - "ami_name": "salt-project/ci/debian/12/x86_64/20240509.1530", + "ami_name": "salt-project/ci/debian/12/x86_64/20240912.2135", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -90,9 +80,9 @@ "ssh_username": "admin" }, "fedora-40-arm64": { - "ami": "ami-064df327a55f83953", + "ami": "ami-03be8e03c17f1abeb", "ami_description": "CI Image of Fedora 40 arm64", - "ami_name": "salt-project/ci/fedora/40/arm64/20240509.1530", + "ami_name": "salt-project/ci/fedora/40/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -100,9 +90,9 @@ "ssh_username": "fedora" }, "fedora-40": { - "ami": "ami-08d8dbd4f063788de", + "ami": "ami-060a59b30809758b2", "ami_description": "CI Image of Fedora 40 x86_64", - "ami_name": "salt-project/ci/fedora/40/x86_64/20240509.1530", + "ami_name": "salt-project/ci/fedora/40/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -110,9 +100,9 @@ "ssh_username": "fedora" }, "opensuse-15": { - "ami": "ami-0f82d5ab3015af6ad", + "ami": "ami-0aaf63315ada5365b", "ami_description": "CI Image of Opensuse 15 x86_64", - "ami_name": "salt-project/ci/opensuse/15/x86_64/20240509.1529", + "ami_name": "salt-project/ci/opensuse/15/x86_64/20240912.2135", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -120,9 +110,9 @@ "ssh_username": "ec2-user" }, "photonos-4-arm64": { - "ami": "ami-0ea152c346cb8e13b", + "ami": "ami-0d425acec9d0d78a5", "ami_description": "CI Image of PhotonOS 4 arm64", - "ami_name": "salt-project/ci/photonos/4/arm64/20240509.1530", + "ami_name": "salt-project/ci/photonos/4/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -130,9 +120,9 @@ "ssh_username": "root" }, "photonos-4": { - "ami": "ami-09b55d0bf3a1aa7e5", + "ami": "ami-056d988807f8b586d", "ami_description": "CI Image of PhotonOS 4 x86_64", - "ami_name": "salt-project/ci/photonos/4/x86_64/20240509.1530", + "ami_name": "salt-project/ci/photonos/4/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -140,9 +130,9 @@ "ssh_username": "root" }, "photonos-5-arm64": { - "ami": "ami-09de4952bc9fc068a", + "ami": "ami-059f47b459d04544a", "ami_description": "CI Image of PhotonOS 5 arm64", - "ami_name": "salt-project/ci/photonos/5/arm64/20240509.1530", + "ami_name": "salt-project/ci/photonos/5/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -150,9 +140,9 @@ "ssh_username": "root" }, "photonos-5": { - "ami": "ami-0c3375a583643fc77", + "ami": "ami-06424daf7c85ffff0", "ami_description": "CI Image of PhotonOS 5 x86_64", - "ami_name": "salt-project/ci/photonos/5/x86_64/20240509.1530", + "ami_name": "salt-project/ci/photonos/5/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -160,9 +150,9 @@ "ssh_username": "root" }, "rockylinux-8-arm64": { - "ami": "ami-0662cc201cada14b8", + "ami": "ami-0a21b175629f1a793", "ami_description": "CI Image of RockyLinux 8 arm64", - "ami_name": "salt-project/ci/rockylinux/8/arm64/20240509.1530", + "ami_name": "salt-project/ci/rockylinux/8/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -170,9 +160,9 @@ "ssh_username": "rocky" }, "rockylinux-8": { - "ami": "ami-071ca70a907d79e05", + "ami": "ami-01032695e18f0fe85", "ami_description": "CI Image of RockyLinux 8 x86_64", - "ami_name": "salt-project/ci/rockylinux/8/x86_64/20240509.1530", + "ami_name": "salt-project/ci/rockylinux/8/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -180,9 +170,9 @@ "ssh_username": "rocky" }, "rockylinux-9-arm64": { - "ami": "ami-065842dfdf03a1a03", + "ami": "ami-0c9147ca5f07effc6", "ami_description": "CI Image of RockyLinux 9 arm64", - "ami_name": "salt-project/ci/rockylinux/9/arm64/20240509.1530", + "ami_name": "salt-project/ci/rockylinux/9/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -190,9 +180,9 @@ "ssh_username": "rocky" }, "rockylinux-9": { - "ami": "ami-09f5d6df00e99ba16", + "ami": "ami-01a72f34d198efc4a", "ami_description": "CI Image of RockyLinux 9 x86_64", - "ami_name": "salt-project/ci/rockylinux/9/x86_64/20240509.1530", + "ami_name": "salt-project/ci/rockylinux/9/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -200,9 +190,9 @@ "ssh_username": "rocky" }, "ubuntu-20.04-arm64": { - "ami": "ami-00171fa604b826054", + "ami": "ami-0bf8ea4c07a88d6c5", "ami_description": "CI Image of Ubuntu 20.04 arm64", - "ami_name": "salt-project/ci/ubuntu/20.04/arm64/20240509.1530", + "ami_name": "salt-project/ci/ubuntu/20.04/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -210,9 +200,9 @@ "ssh_username": "ubuntu" }, "ubuntu-20.04": { - "ami": "ami-07ddfbdc489064022", + "ami": "ami-08a84f7455622c3d5", "ami_description": "CI Image of Ubuntu 20.04 x86_64", - "ami_name": "salt-project/ci/ubuntu/20.04/x86_64/20240509.1530", + "ami_name": "salt-project/ci/ubuntu/20.04/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -220,9 +210,9 @@ "ssh_username": "ubuntu" }, "ubuntu-22.04-arm64": { - "ami": "ami-0e6b6fc1dd298e055", + "ami": "ami-0415a2d2279277d61", "ami_description": "CI Image of Ubuntu 22.04 arm64", - "ami_name": "salt-project/ci/ubuntu/22.04/arm64/20240509.1530", + "ami_name": "salt-project/ci/ubuntu/22.04/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -230,9 +220,9 @@ "ssh_username": "ubuntu" }, "ubuntu-22.04": { - "ami": "ami-0736289579c0d01ba", + "ami": "ami-055513129ce06397c", "ami_description": "CI Image of Ubuntu 22.04 x86_64", - "ami_name": "salt-project/ci/ubuntu/22.04/x86_64/20240509.1530", + "ami_name": "salt-project/ci/ubuntu/22.04/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -240,9 +230,9 @@ "ssh_username": "ubuntu" }, "ubuntu-24.04-arm64": { - "ami": "ami-015058823f69446b3", + "ami": "ami-035ef6d54ec25b0fa", "ami_description": "CI Image of Ubuntu 24.04 arm64", - "ami_name": "salt-project/ci/ubuntu/24.04/arm64/20240509.1530", + "ami_name": "salt-project/ci/ubuntu/24.04/arm64/20240912.2136", "arch": "arm64", "cloudwatch-agent-available": "true", "instance_type": "m6g.large", @@ -250,9 +240,9 @@ "ssh_username": "ubuntu" }, "ubuntu-24.04": { - "ami": "ami-0eb04152e7cafaaf9", + "ami": "ami-0a287b781a487ec65", "ami_description": "CI Image of Ubuntu 24.04 x86_64", - "ami_name": "salt-project/ci/ubuntu/24.04/x86_64/20240509.1530", + "ami_name": "salt-project/ci/ubuntu/24.04/x86_64/20240912.2136", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.large", @@ -260,9 +250,9 @@ "ssh_username": "ubuntu" }, "windows-2016": { - "ami": "ami-06026cb4d83072df5", + "ami": "ami-030cdb60764141f56", "ami_description": "CI Image of Windows 2016 x86_64", - "ami_name": "salt-project/ci/windows/2016/x86_64/20240509.1530", + "ami_name": "salt-project/ci/windows/2016/x86_64/20240913.1756", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.xlarge", @@ -270,9 +260,9 @@ "ssh_username": "Administrator" }, "windows-2019": { - "ami": "ami-095a9256ec0e8261c", + "ami": "ami-08f10b0d4914572de", "ami_description": "CI Image of Windows 2019 x86_64", - "ami_name": "salt-project/ci/windows/2019/x86_64/20240509.1530", + "ami_name": "salt-project/ci/windows/2019/x86_64/20240913.1756", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.xlarge", @@ -280,9 +270,9 @@ "ssh_username": "Administrator" }, "windows-2022": { - "ami": "ami-0d295c0711e513c05", + "ami": "ami-07eda52ffbd76a4c6", "ami_description": "CI Image of Windows 2022 x86_64", - "ami_name": "salt-project/ci/windows/2022/x86_64/20240509.1530", + "ami_name": "salt-project/ci/windows/2022/x86_64/20240913.1756", "arch": "x86_64", "cloudwatch-agent-available": "true", "instance_type": "t3a.xlarge", diff --git a/cicd/shared-gh-workflows-context.yml b/cicd/shared-gh-workflows-context.yml index 9cd0641c739b..038071329d9e 100644 --- a/cicd/shared-gh-workflows-context.yml +++ b/cicd/shared-gh-workflows-context.yml @@ -4,7 +4,6 @@ relenv_version: "0.17.0" mandatory_os_slugs: - rockylinux-9 - amazonlinux-2023-arm64 - - archlinux-lts - photonos-5-arm64 - macos-12 - ubuntu-24.04-arm64 diff --git a/pkg/debian/salt-api.preinst b/pkg/debian/salt-api.preinst index ddc7c9e0ec7b..c063108ea55e 100644 --- a/pkg/debian/salt-api.preinst +++ b/pkg/debian/salt-api.preinst @@ -22,7 +22,6 @@ case "$1" in else db_set salt-api/enabled enabled db_set salt-api/active active - fi ;; esac diff --git a/pkg/debian/salt-syndic.postinst b/pkg/debian/salt-syndic.postinst new file mode 100644 index 000000000000..071ba38e1859 --- /dev/null +++ b/pkg/debian/salt-syndic.postinst @@ -0,0 +1,37 @@ +#!/bin/sh + +. /usr/share/debconf/confmodule + +case "$1" in + configure) + db_get salt-syndic/user + if [ "$RET" != "root" ]; then + if [ ! -e "/var/log/salt/syndic" ]; then + touch /var/log/salt/syndic + chmod 640 /var/log/salt/syndic + fi + chown $RET:$RET /var/log/salt/syndic + fi + if command -v systemctl; then + db_get salt-syndic/active + RESLT=$(echo "$RET" | cut -d ' ' -f 1) + if [ "$RESLT" != 10 ]; then + systemctl daemon-reload + if [ "$RESLT" = "active" ]; then + systemctl restart salt-syndic + fi + db_get salt-syndic/enabled + RESLT=$(echo "$RET" | cut -d ' ' -f 1) + if [ "$RESLT" = "disabled" ]; then + systemctl disable salt-syndic + else + systemctl enable salt-syndic + fi + else + systemctl daemon-reload + systemctl restart salt-syndic + systemctl enable salt-syndic + fi + fi + ;; +esac diff --git a/pkg/debian/salt-syndic.preinst b/pkg/debian/salt-syndic.preinst new file mode 100644 index 000000000000..da43d779163c --- /dev/null +++ b/pkg/debian/salt-syndic.preinst @@ -0,0 +1,27 @@ +#!/bin/sh + +. /usr/share/debconf/confmodule + +case "$1" in + upgrade) + [ -z "$SALT_HOME" ] && SALT_HOME=/opt/saltstack/salt + [ -z "$SALT_USER" ] && SALT_USER=salt + [ -z "$SALT_NAME" ] && SALT_NAME="Salt" + [ -z "$SALT_GROUP" ] && SALT_GROUP=salt + + # Reset permissions to fix previous installs + CUR_USER=$(ls -dl /run/salt-syndic.pid | cut -d ' ' -f 3) + CUR_GROUP=$(ls -dl /run/salt-syndic.pid | cut -d ' ' -f 4) + db_set salt-syndic/user $CUR_USER + chown -R $CUR_USER:$CUR_GROUP /var/log/salt/syndic + if command -v systemctl; then + SM_ENABLED=$(systemctl show -p UnitFileState salt-syndic | cut -d '=' -f 2) + db_set salt-syndic/enabled $SM_ENABLED + SM_ACTIVE=$(systemctl is-active salt-syndic) + db_set salt-syndic/active $SM_ACTIVE + else + db_set salt-syndic/enabled enabled + db_set salt-syndic/active active + fi + ;; +esac diff --git a/pkg/debian/salt-syndic.templates b/pkg/debian/salt-syndic.templates new file mode 100644 index 000000000000..c27859e0a24f --- /dev/null +++ b/pkg/debian/salt-syndic.templates @@ -0,0 +1,17 @@ +Template: salt-syndic/user +Type: string +Default: salt +Description: User for salt-syndic + User to run the salt-syndic process as + +Template: salt-syndic/enabled +Type: string +Default: enabled +Description: Systemd enable state for salt-syndic + default enable state for salt-syndic systemd state + +Template: salt-syndic/active +Type: string +Default: active +Description: Systemd active state for salt-syndic + default active state for salt-syndic systemd state diff --git a/pkg/rpm/salt.spec b/pkg/rpm/salt.spec index 180df99f34b1..f1707cb5dd07 100644 --- a/pkg/rpm/salt.spec +++ b/pkg/rpm/salt.spec @@ -441,6 +441,15 @@ if [ $1 -gt 1 ] ; then %global _MS_CUR_GROUP %{_MS_LCUR_GROUP} fi +%pre syndic +if [ $1 -gt 1 ] ; then + # Reset permissions to match previous installs - performing upgrade + _MS_LCUR_USER=$(ls -dl /run/salt/master | cut -d ' ' -f 3) + _MS_LCUR_GROUP=$(ls -dl /run/salt/master | cut -d ' ' -f 4) + %global _MS_CUR_USER %{_MS_LCUR_USER} + %global _MS_CUR_GROUP %{_MS_LCUR_GROUP} +fi + %pre minion if [ $1 -gt 1 ] ; then # Reset permissions to match previous installs - performing upgrade @@ -463,6 +472,14 @@ if [ $1 -eq 0 ] ; then /bin/systemctl stop salt-syndic.service > /dev/null 2>&1 || : fi +%preun syndic +# %%systemd_preun salt-syndic.service +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable salt-syndic.service > /dev/null 2>&1 || : + /bin/systemctl stop salt-syndic.service > /dev/null 2>&1 || : +fi + %preun minion # %%systemd_preun salt-minion.service if [ $1 -eq 0 ] ; then @@ -471,7 +488,6 @@ if [ $1 -eq 0 ] ; then /bin/systemctl stop salt-minion.service > /dev/null 2>&1 || : fi - %preun api # %%systemd_preun salt-api.service if [ $1 -eq 0 ] ; then @@ -602,6 +618,19 @@ else fi +%posttrans syndic +if [ ! -e "/var/log/salt/syndic" ]; then + touch /var/log/salt/syndic + chmod 640 /var/log/salt/syndic +fi +if [ $1 -gt 1 ] ; then + # Reset permissions to match previous installs - performing upgrade + chown -R %{_MS_CUR_USER}:%{_MS_CUR_GROUP} /var/log/salt/syndic +else + chown -R %{_SALT_USER}:%{_SALT_GROUP} /var/log/salt/syndic +fi + + %posttrans api if [ ! -e "/var/log/salt/api" ]; then touch /var/log/salt/api diff --git a/salt/_logging/impl.py b/salt/_logging/impl.py index 832c72b4769a..2a12ddf3f941 100644 --- a/salt/_logging/impl.py +++ b/salt/_logging/impl.py @@ -157,6 +157,9 @@ def set_log_record_factory(factory): class SaltLoggingClass(LOGGING_LOGGER_CLASS, metaclass=LoggingMixinMeta): + + ONCECACHE = set() + def __new__(cls, *args): """ We override `__new__` in our logging logger class in order to provide @@ -233,10 +236,16 @@ def _log( stack_info=False, stacklevel=1, exc_info_on_loglevel=None, + once=False, ): if extra is None: extra = {} + if once: + if str(args) in self.ONCECACHE: + return + self.ONCECACHE.add(str(args)) + # pylint: disable=no-member current_jid = RequestContext.current.get("data", {}).get("jid", None) log_fmt_jid = RequestContext.current.get("opts", {}).get("log_fmt_jid", None) @@ -265,6 +274,7 @@ def _log( exc_info_on_loglevel ) ) + # XXX: extra is never None if extra is None: extra = {"exc_info_on_loglevel": exc_info_on_loglevel} else: diff --git a/salt/config/__init__.py b/salt/config/__init__.py index 6d0bc947fc22..8226ba452b80 100644 --- a/salt/config/__init__.py +++ b/salt/config/__init__.py @@ -2502,7 +2502,7 @@ def syndic_config( ), ) ), - "user": opts.get("syndic_user", opts["user"]), + "user": opts.get("syndic_user", master_opts["user"]), "sock_dir": os.path.join( opts["cachedir"], opts.get("syndic_sock_dir", opts["sock_dir"]) ), @@ -2510,6 +2510,7 @@ def syndic_config( "cachedir": master_opts["cachedir"], } opts.update(syndic_opts) + # Prepend root_dir to other paths prepend_root_dirs = [ "pki_dir", diff --git a/salt/fileserver/__init__.py b/salt/fileserver/__init__.py index fe4b3b8e4968..b71af97b12b9 100644 --- a/salt/fileserver/__init__.py +++ b/salt/fileserver/__init__.py @@ -11,7 +11,6 @@ from collections.abc import Sequence import salt.loader -import salt.utils.data import salt.utils.files import salt.utils.path import salt.utils.url @@ -147,13 +146,7 @@ def check_file_list_cache(opts, form, list_cache, w_lock): opts.get("fileserver_list_cache_time", 20), list_cache, ) - return ( - salt.utils.data.decode( - salt.payload.load(fp_).get(form, []) - ), - False, - False, - ) + return salt.payload.load(fp_).get(form, []), False, False elif _lock_cache(w_lock): # Set the w_lock and go refresh_cache = True @@ -189,7 +182,7 @@ def check_env_cache(opts, env_cache): try: with salt.utils.files.fopen(env_cache, "rb") as fp_: log.trace("Returning env cache data from %s", env_cache) - return salt.utils.data.decode(salt.payload.load(fp_)) + return salt.payload.load(fp_) except OSError: pass return None diff --git a/salt/grains/core.py b/salt/grains/core.py index 51646f6f9791..119e78c8e9bb 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -1275,6 +1275,7 @@ def _virtual(osdata): "cannot execute it. Grains output might not be " "accurate.", command, + once=True, ) return grains diff --git a/salt/loader/context.py b/salt/loader/context.py index 88a6472a8f3c..38d0093a8baf 100644 --- a/salt/loader/context.py +++ b/salt/loader/context.py @@ -43,6 +43,9 @@ def __init__(self, name, loader_context, default=None): self.loader_context = loader_context self.default = default + def with_default(self, default): + return NamedLoaderContext(self.name, self.loader_context, default=default) + def loader(self): """ The LazyLoader in the current context. This will return None if there @@ -68,10 +71,12 @@ def value(self): loader = self.loader() if loader is None: return self.default - if self.name == "__context__": - return loader.pack[self.name] if self.name == loader.pack_self: return loader + elif self.name == "__context__": + return loader.pack[self.name] + elif self.name == "__opts__": + return loader.pack[self.name] try: return loader.pack[self.name] except KeyError: diff --git a/salt/loader/dunder.py b/salt/loader/dunder.py index d3027098b5ae..3b198b1497f8 100644 --- a/salt/loader/dunder.py +++ b/salt/loader/dunder.py @@ -8,3 +8,7 @@ __file_client__ = loader_context.named_context("__file_client__", default=None) +__opts__ = loader_context.named_context("__opts__") +__context__ = loader_context.named_context("__context__") +__pillar__ = loader_context.named_context("__pillar__") +__grains__ = loader_context.named_context("__grains__") diff --git a/salt/minion.py b/salt/minion.py index cb4ef919b305..2c2585637420 100644 --- a/salt/minion.py +++ b/salt/minion.py @@ -279,6 +279,7 @@ def get_proc_dir(cachedir, **kwargs): made. Same applies if the directory is already owned by this gid. Must be int. Works only on unix/unix like systems. """ + # pylint: disable=logging-fstring-interpolation fn_ = os.path.join(cachedir, "proc") mode = kwargs.pop("mode", None) @@ -305,11 +306,13 @@ def get_proc_dir(cachedir, **kwargs): uid = kwargs.pop("uid", -1) gid = kwargs.pop("gid", -1) + # pylint: disable=logging-fstring-interpolation # if uid and gid are both -1 then go ahead with # no changes at all if (d_stat.st_uid != uid or d_stat.st_gid != gid) and [ i for i in (uid, gid) if i != -1 ]: + # pylint: disable=logging-fstring-interpolation os.chown(fn_, uid, gid) return fn_ diff --git a/salt/modules/cp.py b/salt/modules/cp.py index 25b0fcbae911..503b9976dbe1 100644 --- a/salt/modules/cp.py +++ b/salt/modules/cp.py @@ -20,7 +20,13 @@ import salt.utils.templates import salt.utils.url from salt.exceptions import CommandExecutionError -from salt.loader.dunder import __file_client__ +from salt.loader.dunder import ( + __context__, + __file_client__, + __grains__, + __opts__, + __pillar__, +) log = logging.getLogger(__name__) @@ -167,7 +173,7 @@ def _client(): """ if __file_client__: return __file_client__.value() - return salt.fileclient.get_file_client(__opts__) + return salt.fileclient.get_file_client(__opts__.value()) def _render_filenames(path, dest, saltenv, template, **kw): diff --git a/salt/states/pkg.py b/salt/states/pkg.py index b0ab5f7ef736..1d56b545dc69 100644 --- a/salt/states/pkg.py +++ b/salt/states/pkg.py @@ -2884,7 +2884,7 @@ def _uninstall( try: pkg_params = __salt__["pkg_resource.parse_targets"]( - name, pkgs, normalize=normalize + name, pkgs, normalize=normalize, version=version, **kwargs )[0] except MinionError as exc: return { @@ -2951,7 +2951,7 @@ def _uninstall( new = __salt__["pkg.list_pkgs"](versions_as_list=True, **kwargs) failed = [] for param in pkg_params: - if __grains__["os_family"] in ["Suse", "RedHat"]: + if __grains__["os_family"] in ["Suse", "RedHat", "Windows"]: # Check if the package version set to be removed is actually removed: if param in new and not pkg_params[param]: failed.append(param) diff --git a/salt/utils/network.py b/salt/utils/network.py index f964e25fa54b..bfa38e4fe9ff 100644 --- a/salt/utils/network.py +++ b/salt/utils/network.py @@ -1740,7 +1740,13 @@ def _netlink_tool_remote_on(port, which_end): continue if which_end == "local_port" and int(local_port) != int(port): continue - remotes.add(remote_host.strip("[]")) + + # Interpret IPv4-mapped IPv6 addresses as IPv4 (strip prefix) + remote_host = remote_host.strip("[]").lower() + if remote_host.startswith("::ffff:"): + remote_host = remote_host[7:] + + remotes.add(remote_host) if valid is False: remotes = None diff --git a/tests/pytests/functional/conftest.py b/tests/pytests/functional/conftest.py index 2fb2246b6338..0a8219b8f717 100644 --- a/tests/pytests/functional/conftest.py +++ b/tests/pytests/functional/conftest.py @@ -1,5 +1,6 @@ import logging import shutil +import sys import pytest from saltfactories.utils.functional import Loaders @@ -70,6 +71,17 @@ def minion_opts( }, } ) + + if sys.platform.startswith("win"): + # We need to set up winrepo on Windows + minion_config_overrides.update( + { + "winrepo_source_dir": "salt://winrepo_ng", + "winrepo_dir_ng": str(state_tree / "winrepo_ng"), + "winrepo_dir": str(state_tree / "winrepo"), + } + ) + factory = salt_factories.salt_minion_daemon( minion_id, defaults=minion_config_defaults or None, diff --git a/tests/pytests/functional/loader/test_dunder.py b/tests/pytests/functional/loader/test_dunder.py new file mode 100644 index 000000000000..581d669a12f3 --- /dev/null +++ b/tests/pytests/functional/loader/test_dunder.py @@ -0,0 +1,50 @@ +import salt.loader.context +import salt.loader.lazy +import salt.utils.files +import tests.support.helpers + + +def test_opts_dunder_opts_without_import(tmp_path): + """ + Test __opts__ without being imported. + + When a loaded module uses __opts__ but does not import it from + salt.loader.dunder the __opts__ object will be a dictionary. + """ + opts = {"optimization_order": [0, 1, 2]} + with salt.utils.files.fopen(tmp_path / "mymod.py", "w") as fp: + fp.write( + tests.support.helpers.dedent( + """ + def mymethod(): + return __opts__ + """ + ) + ) + loader = salt.loader.lazy.LazyLoader([tmp_path], opts) + assert type(loader["mymod.mymethod"]()) == dict + + +def test_opts_dunder_opts_with_import(tmp_path): + """ + Test __opts__ when imported. + + When a loaded module uses __opts__ by importing it from + salt.loader.dunder the __opts__ object will be a NamedLoaderContext. + """ + opts = {"optimization_order": [0, 1, 2]} + with salt.utils.files.fopen(tmp_path / "mymod.py", "w") as fp: + fp.write( + tests.support.helpers.dedent( + """ + from salt.loader.dunder import __opts__ + def optstype(): + return type(__opts__) + def opts(): + return __opts__ + """ + ) + ) + loader = salt.loader.lazy.LazyLoader([tmp_path], opts) + assert loader["mymod.optstype"]() == salt.loader.context.NamedLoaderContext + assert loader["mymod.opts"]() == opts diff --git a/tests/pytests/functional/modules/test_aptpkg.py b/tests/pytests/functional/modules/test_aptpkg.py index 41ade2889de3..60b134966feb 100644 --- a/tests/pytests/functional/modules/test_aptpkg.py +++ b/tests/pytests/functional/modules/test_aptpkg.py @@ -13,6 +13,7 @@ import salt.modules.gpg as gpg import salt.utils.files import salt.utils.stringutils +from salt.loader.dunder import __opts__ from tests.support.mock import Mock, patch pytestmark = [ @@ -76,7 +77,7 @@ def configure_loader_modules(minion_opts): }, gpg: {}, cp: { - "__opts__": minion_opts, + "__opts__": __opts__.with_default(minion_opts), }, config: { "__opts__": minion_opts, diff --git a/tests/pytests/functional/modules/test_win_pkg.py b/tests/pytests/functional/modules/test_win_pkg.py index b68895ef6253..6bcfaa9bd849 100644 --- a/tests/pytests/functional/modules/test_win_pkg.py +++ b/tests/pytests/functional/modules/test_win_pkg.py @@ -29,7 +29,7 @@ def pkg(modules): def test_refresh_db(pkg, pkg_def_contents, state_tree, minion_opts): assert len(pkg.get_package_info("my-software")) == 0 - repo_dir = state_tree / "win" / "repo-ng" + repo_dir = state_tree / "winrepo_ng" with pytest.helpers.temp_file("my-software.sls", pkg_def_contents, repo_dir): pkg.refresh_db() assert len(pkg.get_package_info("my-software")) == 1 diff --git a/tests/pytests/functional/states/test_pkg.py b/tests/pytests/functional/states/test_pkg.py index 8bfac2589667..230491d77c60 100644 --- a/tests/pytests/functional/states/test_pkg.py +++ b/tests/pytests/functional/states/test_pkg.py @@ -20,12 +20,17 @@ pytest.mark.slow_test, pytest.mark.skip_if_not_root, pytest.mark.destructive_test, + pytest.mark.windows_whitelisted, pytest.mark.timeout_unless_on_windows(240), ] @pytest.fixture(scope="module", autouse=True) def refresh_db(grains, modules): + + if salt.utils.platform.is_windows(): + modules.winrepo.update_git_repos() + modules.pkg.refresh_db() # If this is Arch Linux, check if pacman is in use by another process @@ -43,7 +48,7 @@ def refresh_db(grains, modules): def refresh_keys(grains, modules): if grains["os_family"] == "Arch": # We should be running this periodically when building new test runner - # images, otherwise this could take several minuets to complete. + # images, otherwise this could take several minutes to complete. proc = subprocess.run(["pacman-key", "--refresh-keys"], check=False) if proc.returncode != 0: pytest.fail("pacman-key --refresh-keys command failed.") @@ -53,7 +58,7 @@ def refresh_keys(grains, modules): def PKG_TARGETS(grains): _PKG_TARGETS = ["figlet", "sl"] if grains["os"] == "Windows": - _PKG_TARGETS = ["vlc", "putty"] + _PKG_TARGETS = ["npp_x64", "winrar"] elif grains["os"] == "Amazon": if grains["osfinger"] == "Amazon Linux-2023": _PKG_TARGETS = ["lynx", "gnuplot-minimal"] @@ -112,6 +117,8 @@ def PKG_32_TARGETS(grains): _PKG_32_TARGETS = ["xz-devel.i386"] else: _PKG_32_TARGETS.append("xz-devel.i686") + elif grains["os"] == "Windows": + _PKG_32_TARGETS = ["npp", "putty"] if not _PKG_32_TARGETS: pytest.skip("No 32 bit packages have been specified for testing") return _PKG_32_TARGETS @@ -205,6 +212,23 @@ def run_command(*names): return run_command +@pytest.fixture(scope="function") +def install_7zip(modules): + try: + modules.pkg.install(name="7zip", version="22.01.00.0") + modules.pkg.install(name="7zip", version="19.00.00.0") + versions = modules.pkg.version("7zip") + assert "19.00.00.0" in versions + assert "22.01.00.0" in versions + yield + finally: + modules.pkg.remove(name="7zip", version="19.00.00.0") + modules.pkg.remove(name="7zip", version="22.01.00.0") + versions = modules.pkg.version("7zip") + assert "19.00.00.0" not in versions + assert "22.01.00.0" not in versions + + @pytest.mark.requires_salt_modules("pkg.version") @pytest.mark.requires_salt_states("pkg.installed", "pkg.removed") @pytest.mark.slow_test @@ -268,7 +292,8 @@ def test_pkg_003_installed_multipkg(caplog, PKG_TARGETS, modules, states, grains try: ret = states.pkg.installed(name=None, pkgs=PKG_TARGETS, refresh=False) assert ret.result is True - assert "WARNING" not in caplog.text + if not salt.utils.platform.is_windows(): + assert "WARNING" not in caplog.text finally: ret = states.pkg.removed(name=None, pkgs=PKG_TARGETS) assert ret.result is True @@ -1091,3 +1116,17 @@ def test_pkg_purged_with_removed_pkg(grains, PKG_TARGETS, states, modules): "installed": {}, "removed": {target: {"new": "", "old": version}}, } + + +@pytest.mark.skip_unless_on_windows() +def test_pkg_removed_with_version_multiple(install_7zip, modules, states): + """ + This tests removing a specific version of a package when multiple versions + are installed. This is specific to Windows. The only version I could find + that allowed multiple installs of differing versions was 7zip, so we'll use + that. + """ + ret = states.pkg.removed(name="7zip", version="19.00.00.0") + assert ret.result is True + current = modules.pkg.version("7zip") + assert "22.01.00.0" in current diff --git a/tests/pytests/pkg/integration/test_salt_api.py b/tests/pytests/pkg/integration/test_salt_api.py index e962fbe32213..b13775bd7942 100644 --- a/tests/pytests/pkg/integration/test_salt_api.py +++ b/tests/pytests/pkg/integration/test_salt_api.py @@ -5,7 +5,7 @@ ] -def test_salt_api(api_request, salt_master, install_salt): +def test_salt_api(api_request, install_salt, salt_master): """ Test running a command against the salt api """ diff --git a/tests/pytests/pkg/integration/test_salt_ufw.py b/tests/pytests/pkg/integration/test_salt_ufw.py index 0e0471aebf24..6c86e0a3339f 100644 --- a/tests/pytests/pkg/integration/test_salt_ufw.py +++ b/tests/pytests/pkg/integration/test_salt_ufw.py @@ -9,8 +9,8 @@ @pytest.fixture def salt_systemd_setup( - salt_call_cli, install_salt, + salt_call_cli, ): """ Fixture to set systemd for salt packages to enabled and active @@ -31,7 +31,7 @@ def salt_systemd_setup( @pytest.mark.skip_if_binaries_missing("ufw") -def test_salt_ufw(salt_systemd_setup, salt_call_cli, install_salt): +def test_salt_ufw(salt_systemd_setup, install_salt, salt_call_cli): """ Test salt.ufw for Debian/Ubuntu salt-master """ diff --git a/tests/pytests/pkg/integration/test_salt_user.py b/tests/pytests/pkg/integration/test_salt_user.py index fb42ae3c9f6b..3978bfe9ca75 100644 --- a/tests/pytests/pkg/integration/test_salt_user.py +++ b/tests/pytests/pkg/integration/test_salt_user.py @@ -2,6 +2,7 @@ import pathlib import subprocess import sys +import time import packaging.version import psutil @@ -15,8 +16,8 @@ @pytest.fixture def salt_systemd_setup( - salt_call_cli, install_salt, + salt_call_cli, ): """ Fixture to set systemd for salt packages to enabled and active @@ -67,8 +68,12 @@ def pkg_paths_salt_user(): "/var/log/salt/master", "/var/log/salt/api", "/var/log/salt/key", + "/var/log/salt/syndic", "/var/cache/salt/master", "/var/run/salt/master", + "/run/salt-master.pid", + "/run/salt-syndic.pid", + "/run/salt-api.pid", ] @@ -83,10 +88,16 @@ def pkg_paths_salt_user_exclusions(): return paths -def test_salt_user_master(salt_master, install_salt): +def test_salt_user_master(install_salt, salt_master): """ Test the correct user is running the Salt Master """ + for count in range(0, 30): + if salt_master.is_running(): + break + else: + time.sleep(2) + assert salt_master.is_running() match = False @@ -158,6 +169,7 @@ def test_pkg_paths( pkg_paths, pkg_paths_salt_user, pkg_paths_salt_user_exclusions, + salt_call_cli, ): """ Test package paths ownership @@ -174,6 +186,7 @@ def test_pkg_paths( assert pkg_path.exists() for dirpath, sub_dirs, files in os.walk(pkg_path): path = pathlib.Path(dirpath) + # Directories owned by salt:salt or their subdirs/files if ( str(path) in pkg_paths_salt_user or str(path) in salt_user_subdirs @@ -206,10 +219,10 @@ def test_pkg_paths( @pytest.mark.skip_if_binaries_missing("logrotate") def test_paths_log_rotation( + install_salt, salt_master, salt_minion, salt_call_cli, - install_salt, pkg_tests_account, ): """ @@ -401,3 +414,7 @@ def test_paths_log_rotation( bkup_count += 1 assert ret.returncode == 0 + + # ensure leave salt_master running + salt_master.start() + assert salt_master.is_running() is True diff --git a/tests/pytests/pkg/integration/test_version.py b/tests/pytests/pkg/integration/test_version.py index b1bee9d60afa..b7fa262fd53b 100644 --- a/tests/pytests/pkg/integration/test_version.py +++ b/tests/pytests/pkg/integration/test_version.py @@ -1,6 +1,7 @@ import os.path import pathlib import subprocess +import time import pytest from pytestskipmarkers.utils import platform @@ -35,6 +36,7 @@ def test_salt_version(version, install_salt): @pytest.mark.skip_on_windows +@pytest.mark.skip_on_darwin def test_salt_versions_report_master(install_salt): """ Test running --versions-report on master @@ -53,17 +55,33 @@ def test_salt_versions_report_master(install_salt): @pytest.mark.skip_on_windows -def test_salt_versions_report_minion(salt_cli, salt_call_cli, salt_minion): +def test_salt_versions_report_minion(salt_cli, salt_call_cli, salt_master, salt_minion): """ Test running test.versions_report on minion """ # Make sure the minion is running + for count in range(0, 30): + if salt_minion.is_running(): + break + else: + time.sleep(2) + assert salt_minion.is_running() + # Make sure the master is running + for count in range(0, 30): + if salt_master.is_running(): + break + else: + time.sleep(2) + + assert salt_master.is_running() + # Make sure we can ping the minion ... ret = salt_cli.run( - "--timeout=300", "test.ping", minion_tgt=salt_minion.id, _timeout=300 + "--timeout=600", "test.ping", minion_tgt=salt_minion.id, _timeout=600 ) + assert ret.returncode == 0 assert ret.data is True ret = salt_cli.run( @@ -77,6 +95,8 @@ def test_salt_versions_report_minion(salt_cli, salt_call_cli, salt_minion): ret.stdout.matcher.fnmatch_lines(["*Salt Version:*"]) +@pytest.mark.skip_on_windows +@pytest.mark.skip_on_darwin @pytest.mark.parametrize( "binary", ["master", "cloud", "syndic", "minion", "call", "api"] ) @@ -104,7 +124,7 @@ def test_compare_versions(binary, install_salt): ) -@pytest.mark.skip_unless_on_darwin() +@pytest.mark.skip_unless_on_darwin @pytest.mark.parametrize( "symlink", [ @@ -132,8 +152,7 @@ def test_symlinks_created(version, symlink, install_salt): ret.stdout.matcher.fnmatch_lines([f"*{version}*"]) -@pytest.mark.skip_on_windows -@pytest.mark.skip_on_darwin +@pytest.mark.skip_unless_on_linux def test_compare_pkg_versions_redhat_rc(version, install_salt): """ Test compare pkg versions for redhat RC packages. A tilde should be included diff --git a/tests/pytests/unit/modules/test_win_pkg.py b/tests/pytests/unit/modules/test_win_pkg.py index 3ae8f24f8dd6..a976b6d6083b 100644 --- a/tests/pytests/unit/modules/test_win_pkg.py +++ b/tests/pytests/unit/modules/test_win_pkg.py @@ -6,6 +6,7 @@ import pytest +import salt.loader.dunder import salt.modules.config as config import salt.modules.cp as cp import salt.modules.pkg_resource as pkg_resource @@ -57,7 +58,7 @@ def configure_loader_modules(minion_opts): opts = minion_opts opts["master_uri"] = "localhost" return { - cp: {"__opts__": opts}, + cp: {"__opts__": salt.loader.dunder.__opts__.with_default(opts)}, win_pkg: { "_get_latest_package_version": MagicMock(return_value="3.03"), "_get_package_info": MagicMock(return_value=pkg_info), diff --git a/tests/pytests/unit/states/test_pkg.py b/tests/pytests/unit/states/test_pkg.py index 0255175005af..f9c566524df7 100644 --- a/tests/pytests/unit/states/test_pkg.py +++ b/tests/pytests/unit/states/test_pkg.py @@ -11,6 +11,7 @@ import salt.states.beacon as beaconstate import salt.states.pkg as pkg import salt.utils.state as state_utils +from salt.loader.dunder import __opts__ from salt.utils.event import SaltEvent from tests.support.mock import MagicMock, patch @@ -21,7 +22,7 @@ def configure_loader_modules(minion_opts): return { cp: { - "__opts__": minion_opts, + "__opts__": __opts__.with_default(minion_opts), }, pkg: { "__env__": "base", diff --git a/tests/pytests/unit/utils/test_network.py b/tests/pytests/unit/utils/test_network.py index 12d545b01545..557f315a3372 100644 --- a/tests/pytests/unit/utils/test_network.py +++ b/tests/pytests/unit/utils/test_network.py @@ -7,11 +7,12 @@ import salt.exceptions import salt.utils.network import salt.utils.network as network +import salt.utils.platform from salt._compat import ipaddress from tests.support.mock import MagicMock, create_autospec, mock_open, patch pytestmark = [ - pytest.mark.skip_on_windows, + pytest.mark.windows_whitelisted, ] @@ -722,13 +723,13 @@ def test_netlink_tool_remote_on_a(): with patch("salt.utils.platform.is_linux", return_value=True): with patch("subprocess.check_output", return_value=LINUX_NETLINK_SS_OUTPUT): remotes = network._netlink_tool_remote_on("4506", "local_port") - assert remotes == {"192.168.122.177", "::ffff:127.0.0.1"} + assert remotes == {"192.168.122.177", "127.0.0.1"} def test_netlink_tool_remote_on_b(): with patch("subprocess.check_output", return_value=LINUX_NETLINK_SS_OUTPUT): remotes = network._netlink_tool_remote_on("4505", "remote_port") - assert remotes == {"127.0.0.1", "::ffff:1.2.3.4"} + assert remotes == {"127.0.0.1", "1.2.3.4"} def test_openbsd_remotes_on(): @@ -1431,7 +1432,11 @@ def test_isportopen_false(): def test_isportopen(): - ret = network.isportopen("127.0.0.1", "22") + if salt.utils.platform.is_windows(): + port = "135" + else: + port = "22" + ret = network.isportopen("127.0.0.1", port) assert ret == 0 @@ -1445,13 +1450,19 @@ def test_get_socket(): assert ret.type == socket.SOCK_STREAM +# @pytest.mark.skip_on_windows(reason="Do not run on Windows") def test_ip_to_host(grains): + if salt.utils.platform.is_windows(): + hostname = socket.gethostname() + else: + hostname = "localhost" + ret = network.ip_to_host("127.0.0.1") - if grains["oscodename"] == "Photon": + if grains.get("oscodename") == "Photon": # Photon returns this for IPv4 assert ret == "ipv6-localhost" else: - assert ret == "localhost" + assert ret == hostname ret = network.ip_to_host("2001:a71::1") assert ret is None @@ -1461,22 +1472,22 @@ def test_ip_to_host(grains): assert ret == "localhost6" elif grains["os_family"] == "Debian": if grains["osmajorrelease"] == 12: - assert ret == "localhost" + assert ret == hostname else: assert ret == "ip6-localhost" elif grains["os_family"] == "RedHat": if grains["oscodename"] == "Photon": assert ret == "ipv6-localhost" else: - assert ret == "localhost" + assert ret == hostname elif grains["os_family"] == "Arch": if grains.get("osmajorrelease", None) is None: # running doesn't have osmajorrelease grains - assert ret == "localhost" + assert ret == hostname else: assert ret == "ip6-localhost" else: - assert ret == "localhost" + assert ret == hostname @pytest.mark.parametrize( @@ -1509,7 +1520,7 @@ def test_rpad_ipv4_network(addr, expected): def test_hw_addr(linux_interfaces_dict, freebsd_interfaces_dict): with patch( - "salt.utils.network.linux_interfaces", + "salt.utils.network.interfaces", MagicMock(return_value=linux_interfaces_dict), ): hw_addrs = network.hw_addr("eth0") @@ -1534,7 +1545,7 @@ def test_hw_addr(linux_interfaces_dict, freebsd_interfaces_dict): def test_interface_and_ip(linux_interfaces_dict): with patch( - "salt.utils.network.linux_interfaces", + "salt.utils.network.interfaces", MagicMock(return_value=linux_interfaces_dict), ): expected = [ @@ -1560,7 +1571,7 @@ def test_interface_and_ip(linux_interfaces_dict): def test_subnets(linux_interfaces_dict): with patch( - "salt.utils.network.linux_interfaces", + "salt.utils.network.interfaces", MagicMock(return_value=linux_interfaces_dict), ): ret = network.subnets() @@ -1583,14 +1594,14 @@ def test_in_subnet(caplog): def test_ip_addrs(linux_interfaces_dict): with patch( - "salt.utils.network.linux_interfaces", + "salt.utils.network.interfaces", MagicMock(return_value=linux_interfaces_dict), ): ret = network.ip_addrs("eth0") assert ret == ["10.10.10.56"] with patch( - "salt.utils.network.linux_interfaces", + "salt.utils.network.interfaces", MagicMock(return_value=linux_interfaces_dict), ): ret = network.ip_addrs6("eth0") diff --git a/tools/ci.py b/tools/ci.py index 391214e69a38..0791fabe90bb 100644 --- a/tools/ci.py +++ b/tools/ci.py @@ -1010,7 +1010,6 @@ def get_pkg_downloads_matrix(ctx: Context): "photon", ) linux_skip_pkg_download_tests = ( - "archlinux-lts", "opensuse-15", "windows", ) diff --git a/tools/precommit/workflows.py b/tools/precommit/workflows.py index aa844b904ccc..b60371aa80cb 100644 --- a/tools/precommit/workflows.py +++ b/tools/precommit/workflows.py @@ -51,7 +51,6 @@ display_name="Amazon Linux 2023 Arm64", arch="arm64", ), - Linux(slug="archlinux-lts", display_name="Arch Linux LTS", arch="x86_64"), Linux(slug="debian-11", display_name="Debian 11", arch="x86_64"), Linux(slug="debian-11-arm64", display_name="Debian 11 Arm64", arch="arm64"), Linux(slug="debian-12", display_name="Debian 12", arch="x86_64"),