diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c13c6fffe..71d622007 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,8 +27,6 @@ jobs: separator: "," files: | bootstrap-salt.* - Gemfile - kitchen*.yml tests/** .github/workflows/** files_ignore: | @@ -126,6 +124,7 @@ jobs: with: distro-slug: macos-12 display-name: macOS 12 + container-slug: macos-12 timeout: 20 runs-on: macos-12 instances: '["stable-3006", "stable-3006-8", "stable-3007", "stable-3007-1", "latest"]' @@ -141,27 +140,29 @@ jobs: with: distro-slug: macos-13 display-name: macOS 13 + container-slug: macos-13 timeout: 20 runs-on: macos-13 instances: '["stable-3006", "stable-3006-8", "stable-3007", "stable-3007-1", "latest"]' - - windows-2019: - name: Windows 2019 + macos-14: + name: macOS 14 if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-windows.yml + uses: ./.github/workflows/test-macos.yml needs: - lint - generate-actions-workflow with: - distro-slug: windows-2019 - display-name: Windows 2019 + distro-slug: macos-14 + display-name: macOS 14 + container-slug: macOS 14 timeout: 20 - runs-on: windows-2019 + runs-on: macos-14 instances: '["stable-3006", "stable-3006-8", "stable-3007", "stable-3007-1", "latest"]' + windows-2022: name: Windows 2022 if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' @@ -172,82 +173,28 @@ jobs: with: distro-slug: windows-2022 display-name: Windows 2022 + container-slug: windows-2022 timeout: 20 runs-on: windows-2022 instances: '["stable-3006", "stable-3006-8", "stable-3007", "stable-3007-1", "latest"]' - almalinux-8: - name: AlmaLinux 8 + amazonlinux-2023: + name: Amazon 2023 if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' uses: ./.github/workflows/test-linux.yml needs: - lint - generate-actions-workflow with: - distro-slug: almalinux-8 - display-name: AlmaLinux 8 + distro-slug: amazonlinux-2023 + display-name: Amazon 2023 + container-slug: amazonlinux-2023 timeout: 20 instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' - almalinux-9: - name: AlmaLinux 9 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: almalinux-9 - display-name: AlmaLinux 9 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - - amazon-2: - name: Amazon 2 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: amazon-2 - display-name: Amazon 2 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' - - - arch: - name: Arch - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: arch - display-name: Arch - timeout: 20 - instances: '["git-master", "latest", "default"]' - - - centos-stream9: - name: CentOS Stream 9 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: centos-stream9 - display-name: CentOS Stream 9 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - debian-11: name: Debian 11 if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' @@ -258,8 +205,9 @@ jobs: with: distro-slug: debian-11 display-name: Debian 11 + container-slug: debian-11 timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' + instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' debian-12: @@ -272,120 +220,9 @@ jobs: with: distro-slug: debian-12 display-name: Debian 12 + container-slug: debian-12 timeout: 20 - instances: '["stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - - fedora-39: - name: Fedora 39 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: fedora-39 - display-name: Fedora 39 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "latest", "default"]' - - - fedora-40: - name: Fedora 40 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: fedora-40 - display-name: Fedora 40 - timeout: 20 - instances: '["stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - - gentoo: - name: Gentoo - if: github.event_name == 'push' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: gentoo - display-name: Gentoo - timeout: 90 - instances: '["git-master"]' - - - gentoo-systemd: - name: Gentoo (systemd) - if: github.event_name == 'push' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: gentoo-systemd - display-name: Gentoo (systemd) - timeout: 90 - instances: '["git-master"]' - - - opensuse-15: - name: Opensuse 15 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: opensuse-15 - display-name: Opensuse 15 - timeout: 20 - instances: '["latest", "default"]' - - - oraclelinux-8: - name: Oracle Linux 8 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: oraclelinux-8 - display-name: Oracle Linux 8 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' - - - oraclelinux-9: - name: Oracle Linux 9 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: oraclelinux-9 - display-name: Oracle Linux 9 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - - photon-4: - name: Photon OS 4 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: photon-4 - display-name: Photon OS 4 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "latest", "default"]' + instances: '["stable-3007", "git-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' photon-5: @@ -398,8 +235,9 @@ jobs: with: distro-slug: photon-5 display-name: Photon OS 5 + container-slug: photon-5 timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "latest", "default"]' + instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' rockylinux-8: @@ -412,6 +250,7 @@ jobs: with: distro-slug: rockylinux-8 display-name: Rocky Linux 8 + container-slug: rockylinux-8 timeout: 20 instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' @@ -426,22 +265,9 @@ jobs: with: distro-slug: rockylinux-9 display-name: Rocky Linux 9 + container-slug: rockylinux-9 timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - - ubuntu-2004: - name: Ubuntu 20.04 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: ubuntu-2004 - display-name: Ubuntu 20.04 - timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' + instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "latest", "default"]' ubuntu-2204: @@ -454,22 +280,9 @@ jobs: with: distro-slug: ubuntu-2204 display-name: Ubuntu 22.04 + container-slug: ubuntu-22.04 timeout: 20 - instances: '["stable-3006", "onedir-3006", "stable-3006-8", "stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' - - - ubuntu-2404: - name: Ubuntu 24.04 - if: github.event_name == 'push' || needs.collect-changed-files.outputs.run-tests == 'true' - uses: ./.github/workflows/test-linux.yml - needs: - - lint - - generate-actions-workflow - with: - distro-slug: ubuntu-2404 - display-name: Ubuntu 24.04 - timeout: 20 - instances: '["stable-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' + instances: '["stable-3006", "git-3006", "onedir-3006", "stable-3006-8", "stable-3007", "git-3007", "onedir-3007", "stable-3007-1", "git-master", "latest", "default"]' set-pipeline-exit-status: @@ -482,29 +295,15 @@ jobs: - generate-actions-workflow - macos-12 - macos-13 - - windows-2019 + - macos-14 - windows-2022 - - almalinux-8 - - almalinux-9 - - amazon-2 - - arch - - centos-stream9 + - amazonlinux-2023 - debian-11 - debian-12 - - fedora-39 - - fedora-40 - - gentoo - - gentoo-systemd - - opensuse-15 - - oraclelinux-8 - - oraclelinux-9 - - photon-4 - photon-5 - rockylinux-8 - rockylinux-9 - - ubuntu-2004 - ubuntu-2204 - - ubuntu-2404 if: always() steps: diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bfdb47b13..c776a44cc 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -41,61 +41,3 @@ jobs: echo "${MSG}" >> "${GITHUB_STEP_SUMMARY}" echo "requirements-met=true" >> "${GITHUB_OUTPUT}" fi - - update-s3-bucket: - name: Update S3 Bucket - if: ${{ fromJSON(needs.workflow-requirements.outputs.requirements-met) }} - runs-on: - - self-hosted - - linux - - repo-release - needs: - - workflow-requirements - environment: release - - steps: - - uses: actions/checkout@v4 - - - name: Get Salt Project GitHub Actions Bot Environment - run: | - TOKEN=$(curl -sS -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30") - SPB_ENVIRONMENT=$(curl -sS -f -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/tags/instance/spb:environment) - echo "SPB_ENVIRONMENT=$SPB_ENVIRONMENT" >> "$GITHUB_ENV" - - - name: Setup GnuPG - run: | - sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg - GNUPGHOME="$(mktemp -d -p /run/gpg)" - echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" - cat < "${GNUPGHOME}/gpg.conf" - batch - no-tty - pinentry-mode loopback - EOF - - - name: Get Secrets - id: get-secrets - env: - SECRETS_KEY: ${{ secrets.SECRETS_KEY }} - run: | - SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) - echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text | jq .default_key -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -d - \ - | gpg --import - - sync - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text| jq .default_passphrase -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -o "${GNUPGHOME}/passphrase" -d - - sync - rm "$SECRETS_KEY_FILE" - echo "passphrase-file ${GNUPGHOME}/passphrase" >> "${GNUPGHOME}/gpg.conf" - - - name: Install Requirements - run: | - python3 -m pip install -r requirements/release.txt - - - name: Upload Develop to S3 - run: | - tools release s3-publish --key-id 64CBBC8173D76B3F develop diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aeb362715..f31d6c470 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -51,10 +51,7 @@ jobs: update-develop: name: Update CHANGELOG.md and bootstrap-salt.sh - runs-on: - - self-hosted - - linux - - repo-release + runs-on: ubuntu-latest permissions: contents: write # To be able to publish the release environment: release @@ -74,44 +71,13 @@ jobs: python3 -m pip install -r requirements/release.txt pre-commit install --install-hooks - - name: Setup GnuPG - run: | - sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg - GNUPGHOME="$(mktemp -d -p /run/gpg)" - echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" - cat < "${GNUPGHOME}/gpg.conf" - batch - no-tty - pinentry-mode loopback - EOF - - - name: Get Secrets - id: get-secrets - env: - SECRETS_KEY: ${{ secrets.SECRETS_KEY }} - run: | - SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) - echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text | jq .default_key -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -d - \ - | gpg --import - - sync - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text| jq .default_passphrase -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -o "${GNUPGHOME}/passphrase" -d - - sync - rm "$SECRETS_KEY_FILE" - echo "passphrase-file ${GNUPGHOME}/passphrase" >> "${GNUPGHOME}/gpg.conf" - - name: Configure Git shell: bash run: | git config --global --add safe.directory "$(pwd)" git config --global user.name "Salt Project Packaging" git config --global user.email saltproject-packaging@vmware.com - git config --global user.signingkey 64CBBC8173D76B3F - git config --global commit.gpgsign true + git config --global commit.gpgsign false - name: Update Repository id: update-repo @@ -149,10 +115,7 @@ jobs: merge-develop-into-stable: name: Merge develop into stable - runs-on: - - self-hosted - - linux - - repo-release + runs-on: ubuntu-latest needs: - update-develop environment: release @@ -166,44 +129,13 @@ jobs: ssh-key: ${{ secrets.SALT_BOOTSTRAP_RELEASE_KEY }} fetch-depth: 0 - - name: Setup GnuPG - run: | - sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg - GNUPGHOME="$(mktemp -d -p /run/gpg)" - echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" - cat < "${GNUPGHOME}/gpg.conf" - batch - no-tty - pinentry-mode loopback - EOF - - - name: Get Secrets - id: get-secrets - env: - SECRETS_KEY: ${{ secrets.SECRETS_KEY }} - run: | - SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) - echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text | jq .default_key -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -d - \ - | gpg --import - - sync - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text| jq .default_passphrase -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -o "${GNUPGHOME}/passphrase" -d - - sync - rm "$SECRETS_KEY_FILE" - echo "passphrase-file ${GNUPGHOME}/passphrase" >> "${GNUPGHOME}/gpg.conf" - - name: Configure Git shell: bash run: | git config --global --add safe.directory "$(pwd)" git config --global user.name "Salt Project Packaging" git config --global user.email saltproject-packaging@vmware.com - git config --global user.signingkey 64CBBC8173D76B3F - git config --global commit.gpgsign true + git config --global commit.gpgsign false - name: Download Release Details uses: actions/download-artifact@v4 @@ -227,7 +159,7 @@ jobs: - name: Tag The ${{ needs.update-develop.outputs.release-version }} Release run: | - git tag -m "Release ${{ needs.update-develop.outputs.release-version }}" -as ${{ needs.update-develop.outputs.release-version }} + git tag --no-sign -m "Release ${{ needs.update-develop.outputs.release-version }}" -a ${{ needs.update-develop.outputs.release-version }} - name: Update bootstrap-salt.sh sha256sum's run: | @@ -246,9 +178,7 @@ jobs: publish-release: name: Create GitHub Release - runs-on: - - self-hosted - - linux + runs-on: ubuntu-latest needs: - merge-develop-into-stable environment: release @@ -294,73 +224,9 @@ jobs: name: release-details failOnError: false - update-s3-bucket: - name: Update S3 Bucket - runs-on: - - self-hosted - - linux - - repo-release - needs: - - publish-release - environment: release - - steps: - - uses: actions/checkout@v4 - with: - ref: stable - repository: ${{ github.repository }} - ssh-key: ${{ secrets.SALT_BOOTSTRAP_RELEASE_KEY }} - - - name: Get Salt Project GitHub Actions Bot Environment - run: | - TOKEN=$(curl -sS -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30") - SPB_ENVIRONMENT=$(curl -sS -f -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/tags/instance/spb:environment) - echo "SPB_ENVIRONMENT=$SPB_ENVIRONMENT" >> "$GITHUB_ENV" - - - name: Setup GnuPG - run: | - sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg - GNUPGHOME="$(mktemp -d -p /run/gpg)" - echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" - cat < "${GNUPGHOME}/gpg.conf" - batch - no-tty - pinentry-mode loopback - EOF - - - name: Get Secrets - id: get-secrets - env: - SECRETS_KEY: ${{ secrets.SECRETS_KEY }} - run: | - SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) - echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text | jq .default_key -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -d - \ - | gpg --import - - sync - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text| jq .default_passphrase -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -o "${GNUPGHOME}/passphrase" -d - - sync - rm "$SECRETS_KEY_FILE" - echo "passphrase-file ${GNUPGHOME}/passphrase" >> "${GNUPGHOME}/gpg.conf" - - - name: Install Requirements - run: | - python3 -m pip install -r requirements/release.txt - - - name: Upload Stable Release to S3 - run: | - tools release s3-publish --key-id 64CBBC8173D76B3F stable - update-develop-checksums: name: Update Release Checksums on Develop - runs-on: - - self-hosted - - linux - - repo-release + runs-on: ubuntu-latest needs: - publish-release environment: release @@ -386,44 +252,13 @@ jobs: repository: ${{ github.repository }} ssh-key: ${{ secrets.SALT_BOOTSTRAP_RELEASE_KEY }} - - name: Setup GnuPG - run: | - sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg - GNUPGHOME="$(mktemp -d -p /run/gpg)" - echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" - cat < "${GNUPGHOME}/gpg.conf" - batch - no-tty - pinentry-mode loopback - EOF - - - name: Get Secrets - id: get-secrets - env: - SECRETS_KEY: ${{ secrets.SECRETS_KEY }} - run: | - SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) - echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text | jq .default_key -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -d - \ - | gpg --import - - sync - aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ - --query SecretString --output text| jq .default_passphrase -r | base64 -d \ - | gpg --passphrase-file "${SECRETS_KEY_FILE}" -o "${GNUPGHOME}/passphrase" -d - - sync - rm "$SECRETS_KEY_FILE" - echo "passphrase-file ${GNUPGHOME}/passphrase" >> "${GNUPGHOME}/gpg.conf" - - name: Configure Git shell: bash run: | git config --global --add safe.directory "$(pwd)" git config --global user.name "Salt Project Packaging" git config --global user.email saltproject-packaging@vmware.com - git config --global user.signingkey 64CBBC8173D76B3F - git config --global commit.gpgsign true + git config --global commit.gpgsign false - name: Update Latest Release on README run: | diff --git a/.github/workflows/templates/ci.yml b/.github/workflows/templates/ci.yml index e9c6be7b9..c3c029c98 100644 --- a/.github/workflows/templates/ci.yml +++ b/.github/workflows/templates/ci.yml @@ -27,8 +27,6 @@ jobs: separator: "," files: | bootstrap-salt.* - Gemfile - kitchen*.yml tests/** .github/workflows/** files_ignore: | diff --git a/.github/workflows/templates/generate.py b/.github/workflows/templates/generate.py index 0fb618158..cb0e693ac 100755 --- a/.github/workflows/templates/generate.py +++ b/.github/workflows/templates/generate.py @@ -6,171 +6,128 @@ os.chdir(os.path.abspath(os.path.dirname(__file__))) -## "amazon-2023", -## "opensuse-tumbleweed", +# "amazonlinux-2", +# "debian-13", +# "fedora-40", +# "photon-4", +# "ubuntu-2004", +# "ubuntu-2404", LINUX_DISTROS = [ - "almalinux-8", - "almalinux-9", - "amazon-2", - "arch", - "centos-stream9", + "amazonlinux-2023", "debian-11", "debian-12", - "fedora-39", - "fedora-40", - "gentoo", - "gentoo-systemd", - "opensuse-15", - "oraclelinux-8", - "oraclelinux-9", - "photon-4", "photon-5", "rockylinux-8", "rockylinux-9", - "ubuntu-2004", "ubuntu-2204", - "ubuntu-2404", ] + WINDOWS = [ - "windows-2019", "windows-2022", ] OSX = [ "macos-12", "macos-13", + "macos-14", ] - -## "amazon-2023", -## "opensuse-tumbleweed", +# "amazonlinux-2", +# "debian-13", +# "fedora-40", +# "photon-4", +# "ubuntu-2004", +# "ubuntu-2404", STABLE_DISTROS = [ - "almalinux-8", - "almalinux-9", - "amazon-2", - "arch", - "centos-stream9", + "amazonlinux-2023", "debian-11", "debian-12", - "fedora-39", - "fedora-40", - "opensuse-15", - "oraclelinux-8", - "oraclelinux-9", - "photon-4", "photon-5", "rockylinux-8", "rockylinux-9", - "ubuntu-2004", "ubuntu-2204", - "ubuntu-2404", ] -## "amazon-2023", +# "amazonlinux-2", +# "debian-13", +# "fedora-40", +# "photon-4", +# "ubuntu-2004", +# "ubuntu-2404", ONEDIR_DISTROS = [ - "almalinux-8", - "almalinux-9", - "amazon-2", - "centos-stream9", + "amazonlinux-2023", "debian-11", "debian-12", - "fedora-39", - "fedora-40", - "oraclelinux-8", - "oraclelinux-9", - "photon-4", "photon-5", "rockylinux-8", "rockylinux-9", - "ubuntu-2004", "ubuntu-2204", - "ubuntu-2404", ] +# "amazonlinux-2", +# "amazonlinux-2023", +# "photon-4", +# "photon-5", +# "rockylinux-8", +# "ubuntu-2404", ONEDIR_RC_DISTROS = [ - "almalinux-9", - "amazon-2", - "centos-stream9", "debian-12", - "oraclelinux-9", - "photon-4", "photon-5", "rockylinux-9", - "ubuntu-2404", + "ubuntu-2204", ] -## "opensuse-tumbleweed", BLACKLIST_3006 = [ - "arch", "debian-12", "fedora-40", - "gentoo", - "gentoo-systemd", - "opensuse-15", "ubuntu-2404", ] -## "opensuse-tumbleweed", +# "photon-5", BLACKLIST_3007 = [ - "arch", - "fedora-39", - "gentoo", - "gentoo-systemd", - "opensuse-15", "photon-4", - "photon-5", ] -## "amazon-2023", -## "opensuse-tumbleweed", +# "ubuntu-2204", BLACKLIST_GIT_3006 = [ - "almalinux-9", - "amazon-2", - "arch", - "centos-stream9", + "amazonlinux-2", + "amazonlinux-2023", "debian-11", "debian-12", + "debian-13", "fedora-40", - "gentoo", - "gentoo-systemd", - "opensuse-15", - "oraclelinux-9", "photon-4", "photon-5", "rockylinux-9", "ubuntu-2004", - "ubuntu-2204", "ubuntu-2404", ] -## "amazon-2023", -## "opensuse-tumbleweed", +# "debian-12", +# "ubuntu-2204", BLACKLIST_GIT_3007 = [ - "almalinux-9", - "amazon-2", - "arch", - "centos-stream9", + "amazonlinux-2", + "amazonlinux-2023", "debian-11", - "debian-12", - "fedora-39", + "debian-13", "fedora-40", - "gentoo", - "gentoo-systemd", - "opensuse-15", - "oraclelinux-9", "photon-4", "photon-5", "rockylinux-9", "ubuntu-2004", - "ubuntu-2204", "ubuntu-2404", ] +# "debian-12", BLACKLIST_GIT_MASTER = [ - "amazon-2", - "fedora-39", + "amazonlinux-2", + "amazonlinux-2023", + "debian-11", + "debian-13", + "fedora-40", "photon-4", "photon-5", + "rockylinux-9", ] SALT_VERSIONS = [ @@ -227,35 +184,18 @@ # Use build and pip and other standards-based tools. # GIT_DISTRO_BLACKLIST = [ - "almalinux-8", - "fedora-39", - "opensuse-15", - "oraclelinux-8", "rockylinux-8", ] -LATEST_PKG_BLACKLIST = [ - "gentoo", - "gentoo-systemd", -] +LATEST_PKG_BLACKLIST = [] -## "amazon-2023": "Amazon 2023", -## "opensuse-tumbleweed": "Opensuse Tumbleweed", DISTRO_DISPLAY_NAMES = { - "almalinux-8": "AlmaLinux 8", - "almalinux-9": "AlmaLinux 9", - "amazon-2": "Amazon 2", - "arch": "Arch", - "centos-stream9": "CentOS Stream 9", + "amazonlinux-2": "Amazon 2", + "amazonlinux-2023": "Amazon 2023", "debian-11": "Debian 11", "debian-12": "Debian 12", - "fedora-39": "Fedora 39", + "debian-13": "Debian 13", "fedora-40": "Fedora 40", - "gentoo": "Gentoo", - "gentoo-systemd": "Gentoo (systemd)", - "opensuse-15": "Opensuse 15", - "oraclelinux-8": "Oracle Linux 8", - "oraclelinux-9": "Oracle Linux 9", "photon-4": "Photon OS 4", "photon-5": "Photon OS 5", "rockylinux-8": "Rocky Linux 8", @@ -265,19 +205,33 @@ "ubuntu-2404": "Ubuntu 24.04", "macos-12": "macOS 12", "macos-13": "macOS 13", - "windows-2019": "Windows 2019", + "macos-14": "macOS 14", "windows-2022": "Windows 2022", } -TIMEOUT_DEFAULT = 20 -TIMEOUT_OVERRIDES = { - "gentoo": 90, - "gentoo-systemd": 90, +CONTAINER_SLUG_NAMES = { + "amazonlinux-2": "amazonlinux-2", + "amazonlinux-2023": "amazonlinux-2023", + "debian-11": "debian-11", + "debian-12": "debian-12", + "debian-13": "debian-13", + "fedora-40": "fedora-40", + "photon-4": "photon-4", + "photon-5": "photon-5", + "rockylinux-8": "rockylinux-8", + "rockylinux-9": "rockylinux-9", + "ubuntu-2004": "ubuntu-20.04", + "ubuntu-2204": "ubuntu-22.04", + "ubuntu-2404": "ubuntu-24.04", + "macos-12": "macos-12", + "macos-13": "macos-13", + "macos-14": "macOS 14", + "windows-2022": "windows-2022", } -VERSION_ONLY_OVERRIDES = [ - "gentoo", - "gentoo-systemd", -] + +TIMEOUT_DEFAULT = 20 +TIMEOUT_OVERRIDES = {} +VERSION_ONLY_OVERRIDES = [] TEMPLATE = """ {distro}: @@ -289,6 +243,7 @@ with: distro-slug: {distro} display-name: {display_name} + container-slug: {container_name} timeout: {timeout_minutes}{runs_on} instances: '{instances}' """ @@ -339,6 +294,7 @@ def generate_test_jobs(): ifcheck=ifcheck, instances=json.dumps(instances), display_name=DISTRO_DISPLAY_NAMES[distro], + container_name=CONTAINER_SLUG_NAMES[distro], timeout_minutes=timeout_minutes, ) @@ -384,6 +340,7 @@ def generate_test_jobs(): ifcheck=ifcheck, instances=json.dumps(instances), display_name=DISTRO_DISPLAY_NAMES[distro], + container_name=CONTAINER_SLUG_NAMES[distro], timeout_minutes=timeout_minutes, ) @@ -483,6 +440,7 @@ def generate_test_jobs(): ifcheck=ifcheck, instances=json.dumps(instances), display_name=DISTRO_DISPLAY_NAMES[distro], + container_name=CONTAINER_SLUG_NAMES[distro], timeout_minutes=timeout_minutes, ) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index c15a5bc30..b9c5662ba 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -17,6 +17,11 @@ on: required: true description: The Instances To Test + container-slug: + type: string + required: true + description: The Container Slug + timeout: type: number required: false @@ -26,7 +31,7 @@ on: jobs: Test: name: ${{ matrix.instance }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest timeout-minutes: ${{ inputs.timeout }} strategy: max-parallel: 2 @@ -37,39 +42,48 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.6.10 - ## ruby-version: 3.3.4 - bundler-cache: true + - name: Get Version + run: | + # We need to get the version here and make it an environment variable + # It is used to install via bootstrap and in the test + # The version is in the instance name + # sed 1st - becomes space, 2nd - becomes dot + vt_parm_ver=$(echo "${{ matrix.instance }}" | sed 's/-/ /' | sed 's/-/./' | awk -F ' ' '{print $2}') + echo "SaltVersion=$vt_parm_ver" >> $GITHUB_ENV - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" + - name: "Pull container ${{ inputs.container-slug }}" + run: | + docker pull ghcr.io/saltstack/salt-ci-containers/testing:${{ inputs.container-slug }} - - name: Install Python Dependencies + - name: "Create container ${{ inputs.container-slug }}" run: | - python3 -m pip install -U pip - python3 -m pip install -r tests/requirements.txt + /usr/bin/docker create --name ${{ github.run_id }}_salt-test --workdir /_w/ --privileged -e "HOME=/github/home" -e GITHUB_ACTIONS=true -e CI=true -e $GITHUB_ENV -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work":"/__w" -v "/home/runner/work/_temp":"/__w/_temp" -v "/home/runner/work/_actions":"/__w/_actions" -v "/opt/hostedtoolcache":"/__t" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/salt-bootstrap/salt-bootstrap":"/_w/btstrap" --entrypoint "/usr/lib/systemd/systemd" ghcr.io/saltstack/salt-ci-containers/testing:${{ inputs.container-slug }} --systemd --unit rescue.target - - name: Create Test Instance + - name: "Start container ${{ inputs.container-slug }}" run: | - bundle exec kitchen create ${{ matrix.instance }}-${{ inputs.distro-slug }} || \ - (sleep 10 && bundle exec kitchen create ${{ matrix.instance }}-${{ inputs.distro-slug }}) - sleep 2 + /usr/bin/docker start ${{ github.run_id }}_salt-test - - name: Test Bootstrap + - name: "Install Python Dependencies with pip breakage in container ${{ inputs.container-slug }}" + if: ${{ ( inputs.distro-slug == 'debian-12' ) || ( inputs.distro-slug == 'debian-13' ) || ( inputs.distro-slug == 'ubuntu-2404' ) }} run: | - bundle exec kitchen verify ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 + docker exec ${{ github.run_id}}_salt-test python3 -m pip install --break-system-packages -r /_w/btstrap/tests/requirements.txt - - name: Destroy Test Instance - if: always() + - name: "Install Python Dependencies without pip breakage in container ${{ inputs.container-slug }}" + if: ${{ ( inputs.distro-slug != 'debian-12' ) && ( inputs.distro-slug != 'debian-13' ) && ( inputs.distro-slug != 'ubuntu-2404' ) }} + run: | + docker exec ${{ github.run_id}}_salt-test python3 -m pip install -r /_w/btstrap/tests/requirements.txt + + - name: Bootstrap Salt + run: | + # sed 1st - becomes space, 2nd - becomes dot + bt_arg1=$(echo "${{ matrix.instance }}" | sed 's/-/ /' | sed 's/-/./' | awk -F ' ' '{print $1}') + bt_arg2=$(echo "${{ matrix.instance }}" | sed 's/-/ /' | sed 's/-/./' | awk -F ' ' '{print $2}') + echo "bt parms ,$bt_parms, bt_arg1 ,$bt_arg1, bt_arg2 ,$bt_arg2," + docker exec ${{ github.run_id}}_salt-test sh -x /_w/btstrap/bootstrap-salt.sh "$bt_arg1" "$bt_arg2" + + - name: Test Bootstrap run: | - bundle exec kitchen destroy ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 + docker exec ${{ github.run_id}}_salt-test pytest --cache-clear -v -s -ra --log-cli-level=debug /_w/btstrap/tests/integration/ - name: Set Exit Status if: always() diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index ccabff32a..870fb5965 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -22,19 +22,22 @@ on: required: true description: The Instances To Test + container-slug: + type: string + required: true + description: The Container Slug + timeout: type: number required: false default: 20 description: The timeout(in minutes) for the workflow -env: - KITCHEN_LOCAL_YAML: 'kitchen.macos.yml' - jobs: Test: name: ${{ matrix.instance }} runs-on: ${{ inputs.runs-on }} + ## runs-on: macos-13 timeout-minutes: ${{ inputs.timeout }} strategy: fail-fast: false @@ -44,39 +47,37 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.6.10 - ## ruby-version: 3.3.4 - bundler-cache: true - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" + - name: Install Python Dependencies with pip breakage + if: ${{ ( inputs.distro-slug != 'macos-12' ) && ( inputs.distro-slug != 'macos-13' ) }} + run: | + python3 -m pip install --break-system-packages -r tests/requirements.txt - - name: Install Python Dependencies + - name: Install Python Dependencies without pip breakage + if: ${{ ( inputs.distro-slug == 'macos-12' ) || ( inputs.distro-slug == 'macos-13' ) }} run: | - pip install -U pip - pip install -r tests/requirements.txt + python3 -m pip install -r tests/requirements.txt - - name: Create Test Instance + - name: Get Version run: | - bundle exec kitchen create ${{ matrix.instance }}-${{ inputs.distro-slug }} || \ - (sleep 10 && bundle exec kitchen create ${{ matrix.instance }}-${{ inputs.distro-slug }}) - sleep 2 + # We need to get the version here and make it an environment variable + # It is used to install via bootstrap and in the test + # The version is in the instance name + # sed 1st - becomes space, 2nd - becomes dot + vt_parms=$(echo "${{ matrix.instance }}" | sed 's/-/ /' | sed 's/-/./') + vt_parm_ver=$(echo "$vt_parms" | awk -F ' ' '{print $2}') + echo "SaltVersion=$vt_parm_ver" >> $GITHUB_ENV - - name: Test Bootstrap + - name: Bootstrap Salt run: | - bundle exec kitchen verify ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 + # sed 1st - becomes space, 2nd - becomes dot + bt_parms=$(echo "${{ matrix.instance }}" | sed 's/-/ /' | sed 's/-/./') + bt_arg1=$(echo "$bt_parms" | awk -F ' ' '{print $1}') + bt_arg2=$(echo "$bt_parms" | awk -F ' ' '{print $2}') + sudo sh ./bootstrap-salt.sh "$bt_arg1" "$bt_arg2" - - name: Destroy Test Instance - if: always() + - name: Test Bootstrap run: | - bundle exec kitchen destroy ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 + pytest --cache-clear -v -s -ra --log-cli-level=debug tests/integration/ - name: Set Exit Status if: always() diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 25d300ce8..9515dae8d 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -22,22 +22,21 @@ on: required: true description: The Instances To Test + container-slug: + type: string + required: true + description: The Container Slug + timeout: type: number required: false default: 20 description: The timeout(in minutes) for the workflow -env: - machine_user: kitchen - machine_pass: Password1 - machine_port: 5985 - KITCHEN_LOCAL_YAML: 'kitchen.windows.yml' - jobs: Test: name: ${{ matrix.instance }} - runs-on: ${{ inputs.runs-on }} + runs-on: windows-latest timeout-minutes: ${{ inputs.timeout }} strategy: fail-fast: false @@ -47,39 +46,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.6.10 - ## ruby-version: 3.3.4 - bundler-cache: true - - - name: Install Chef - uses: actionshub/chef-install@1.1.0 - with: - project: chef - version: 16.10.8 - - - name: Add Chef bindir to PATH - uses: myci-actions/export-env-var-powershell@1 - with: - name: PATH - value: "C:\\opscode\\chef\\bin;C:\\opscode\\chef\\embedded\\bin;$env:PATH" - - - name: Setup test user - run: | - $password = ConvertTo-SecureString $env:machine_pass -AsPlainText -Force - New-LocalUser $env:machine_user -Password $password - Add-LocalGroupMember -Group "Administrators" -Member $env:machine_user - Get-LocalUser - Get-LocalGroupMember -Group "Administrators" - - - name: Set up WinRM - run: | - Set-WSManQuickConfig -Force - winrm set winrm/config/service '@{AllowUnencrypted="True"}' - env - - name: Set up Python 3.10 uses: actions/setup-python@v5 with: @@ -87,25 +53,27 @@ jobs: - name: Install Python Dependencies run: | - pip install -U pip - pip install -r tests/requirements.txt + python3 -m pip install -r tests/requirements.txt - - name: Create Test Instance + - name: Get Version run: | - bundle exec kitchen create ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 - - - name: Test Bootstrap + # We need to get the version here and make it an environment variable + # It is used to install via bootstrap and in the test + # The version is in the instance name + $instance = "${{ matrix.instance }}" + $version = $instance -split "-",2 + if ( $version.Count -gt 1 ) { + $version = $version[1].Replace("-", ".") + } + Write-Output "SaltVersion=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Bootstrap Salt run: | - env - bundle exec kitchen verify ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 + . .\bootstrap-salt.ps1 -RunService $false -Version $env:SaltVersion - - name: Destroy Test Instance - if: always() + - name: Test Bootstrap run: | - bundle exec kitchen destroy ${{ matrix.instance }}-${{ inputs.distro-slug }} - sleep 2 + pytest --cache-clear -v -s -ra --log-cli-level=debug tests/integration/ - name: Set Exit Status if: always() diff --git a/.gitignore b/.gitignore index 9b7ebc0b0..f21787dbe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,14 +2,9 @@ *.sw? *.un~ .vagrant +*__pycache__ tools venv # Pycharm .idea - -# test-kitchen -.kitchen.local.yml -kitchen.local.yml -.kitchen/ -.bundle/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9fb6a2607..04a74c18c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,19 +37,14 @@ repos: args: - requirements/release.in -## DGM - repo: https://github.com/asottile/pyupgrade -## DGM rev: v3.15.0 -## DGM hooks: -## DGM - id: pyupgrade -## DGM name: Rewrite Code to be Py3.10+ -## DGM args: [--py310-plus] - - repo: https://github.com/asottile/pyupgrade rev: v3.15.0 hooks: - id: pyupgrade - name: Rewrite Code to be Py3.9+ - args: [--py39-plus] + name: Rewrite Code to be Py3.6+ + args: [--py36-plus] + ## DGM name: Rewrite Code to be Py3.9+ + ## DGM args: [--py39-plus] - repo: https://github.com/asottile/reorder_python_imports rev: v3.12.0 @@ -58,7 +53,7 @@ repos: args: [--py310-plus] - repo: https://github.com/psf/black - rev: 24.1.0 + rev: 24.10.0 hooks: - id: black args: [] diff --git a/CHANGELOG.md b/CHANGELOG.md index 33ee81d93..7b87b2d2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,106 @@ +# v2024.12.12 + +## What's Changed + +- Restrict use of dnf to Fedora only, otherwise use yum when dealing with RedHat family by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2070 +- Updating container usage to that used in new Salt pipelines for CI/CD, fix Amazon Linux by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2071 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.12.09...v2024.12.12 + +# v2024.12.09 + +## What's Changed + +- Fix quickstart for Windows with new repo by @twangboy in https://github.com/saltstack/salt-bootstrap/pull/2065 +- Utilize salt-project packages with SUSE by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2066 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.29...v2024.12.09 + +# v2024.11.29 + +## What's Changed + +- Updated date to overcome issue with existing tag for 2024.11.27 by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2058 +- Fix date tag by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2059 +- Revert forcing git tag, other issues with check sums calculated, easiest solution is wait a day to release by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2060 +- Updated date by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2061 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.27...v2024.11.29 + +# v2024.11.27 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.27...v2024.11.27 + +# v2024.11.27 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.27...v2024.11.27 + +# v2024.11.27 + +## What's Changed + +- Testing git install methods by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2057 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.26...v2024.11.27 + +# v2024.11.27 + +## What's Changed + +- Testing git install methods by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2057 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.26...v2024.11.27 + +# v2024.11.26 + +## What's Changed + +- Updated URLs in README, and fix deps download issue on RedHat family by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2052 +- Update README script help output and scriptversions by @ScriptAutomate in https://github.com/saltstack/salt-bootstrap/pull/2056 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.21...v2024.11.26 + +# v2024.11.21 + +## What's Changed + +- Make universal repo url by @twangboy in https://github.com/saltstack/salt-bootstrap/pull/2045 +- Update bootstrap shell CI/CD to utilize containers and clean up by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2039 +- \[WIP\] hwclock check missing additional condition on major version by @ruslantum in https://github.com/saltstack/salt-bootstrap/pull/2048 + +## New Contributors + +- @ruslantum made their first contribution in https://github.com/saltstack/salt-bootstrap/pull/2048 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.07...v2024.11.21 + +# v2024.11.07 + +## What's Changed + +- Changed release runners and shell script date by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2035 +- Forcing git tag to not sign by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2036 +- Fixing git tag signing issue by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2037 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.06...v2024.11.07 + +# v2024.11.07 + +## What's Changed + +- Changed release runners and shell script date by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2035 +- Forcing git tag to not sign by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2036 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.06...v2024.11.07 + +# v2024.11.07 + +## What's Changed + +- Changed release runners and shell script date by @dmurphy18 in https://github.com/saltstack/salt-bootstrap/pull/2035 + +**Full Changelog**: https://github.com/saltstack/salt-bootstrap/compare/v2024.11.06...v2024.11.07 + # v2024.09.24 ## What's Changed diff --git a/Gemfile b/Gemfile deleted file mode 100644 index a70a9da93..000000000 --- a/Gemfile +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -gem 'test-kitchen', '>= 3.2.2' -gem 'kitchen-salt', '>= 0.7.2' -gem 'kitchen-docker', :git => 'https://github.com/test-kitchen/kitchen-docker.git', :branch => 'main' - -group :vagrant do - gem 'kitchen-vagrant' -end diff --git a/README.rst b/README.rst index aa7609d33..db1baf02e 100644 --- a/README.rst +++ b/README.rst @@ -37,6 +37,13 @@ sum** of the downloaded ``bootstrap-salt.sh`` file. The SHA256 sum of the ``bootstrap-salt.sh`` file, per release, is: +- 2024.12.12: ``7cc91adfa5a15ff57d203dc2b79608c773efc639d4e9bf03861198903e11becd`` +- 2024.12.09: ``44f9405a6d9622ad8fa7c93e83a52e01ca328f27e4e9dea4a52268c6a22dbe6d`` +- 2024.11.29: ``0ac87384dee051aceded69704485a5de0e4a308551a462b10c262111b57acff0`` +- 2024.11.27: ``e972bd1ef01d09cd1d9294374ef974c9e3dd9a2aee37cf3859144585fd8bf1d0`` +- 2024.11.26: ``832c7a20b96e1df171d715323df9afff8a11aef42d15598c007f240bc89d723c`` +- 2024.11.21: ``ddf624c3a94d721da3f7629402a6c7ecc9dd96d13c1ead2a626314e97cee982a`` +- 2024.11.07: ``70a9783649e129985563d1a86cf28b8984499643e62ae1dc47dc008bd204fcbb`` - 2024.09.24: ``88e4e4cad4b115a7b721dd9c21d5ee5df390b5b73b63de48f99399146f43f371`` - 2024.07.23: ``7212b6b497b5c3d2bf15bfe5301625ec7bc1bf3e2949cd47d8e2073614935bf8`` - 2024.07.18: ``92a74e7ff8a9032a7713c2b3955991d66aaca08a4eb9494ce3dd66b5044f6bc3`` @@ -57,8 +64,9 @@ If you're looking for a *one-liner* to install Salt, please scroll to the bottom instructions for `Installing via an Insecure One-Liner`_. There are also .sha256 files for verifying against in the repo for the stable branch. You can also -get the correct sha256 sum for the stable release from https://bootstrap.saltproject.io/sha256 and -https://winbootstrap.saltproject.io/sha256 +get the correct sha256 sum for the stable release from +https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh.sha256 and +https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.ps1.sha256 Contributing ------------ @@ -81,112 +89,123 @@ To view the latest options and descriptions for ``salt-bootstrap``, use ``-h`` a Usage : bootstrap-salt.sh [options] [install-type-args] Installation types: - - stable Install latest stable release. This is the default - install type - - stable [branch] Install latest version on a branch. Only supported - for packages available at repo.saltproject.io - - stable [version] Install a specific version. Only supported for - packages available at repo.saltproject.io - To pin a 3xxx minor version, specify it as 3xxx.0 - - testing RHEL-family specific: configure EPEL testing repo - - git Install from the head of the master branch - - git [ref] Install from any git ref (such as a branch, tag, or - commit) + - stable Install latest stable release. This is the default + install type + - stable [branch] Install latest version on a branch. Only supported + for packages available at packages.broadcom.com + - stable [version] Install a specific version. Only supported for + packages available at packages.broadcom.com + To pin a 3xxx minor version, specify it as 3xxx.0 + - testing RHEL-family specific: configure EPEL testing repo + - git Install from the head of the master branch + - git [ref] Install from any git ref (such as a branch, tag, or + commit) + - onedir Install latest onedir release. + - onedir [version] Install a specific version. Only supported for + onedir packages available at packages.broadcom.com + + - onedir_rc Install latest onedir RC release. + - onedir_rc [version] Install a specific version. Only supported for + onedir RC packages available at packages.broadcom.com Examples: - bootstrap-salt.sh - bootstrap-salt.sh stable - - bootstrap-salt.sh stable 3006.7 - - bootstrap-salt.sh stable v3006.8 + - bootstrap-salt.sh stable 3006 + - bootstrap-salt.sh stable 3006.1 - bootstrap-salt.sh testing - bootstrap-salt.sh git + - bootstrap-salt.sh git 3006.7 + - bootstrap-salt.sh git v3006.8 - bootstrap-salt.sh git 3007.1 - bootstrap-salt.sh git v3007.1 - bootstrap-salt.sh git 06f249901a2e2f1ed310d58ea3921a129f214358 + - bootstrap-salt.sh onedir + - bootstrap-salt.sh onedir 3006 + - bootstrap-salt.sh onedir_rc + - bootstrap-salt.sh onedir_rc 3008 + Options: - -h Display this message - -v Display script version - -n No colours - -D Show debug output + -a Pip install all Python pkg dependencies for Salt. Requires -V to install + all pip pkgs into the virtualenv. + (Only available for Ubuntu based distributions) + -A Pass the salt-master DNS name or IP. This will be stored under + \${BS_SALT_ETC_DIR}/minion.d/99-master-address.conf + -b Assume that dependencies are already installed and software sources are + set up. If git is selected, git tree is still checked out as dependency + step. -c Temporary configuration directory - -g Salt Git repository URL. Default: https://github.com/saltstack/salt.git - -w Install packages from downstream package repository rather than - upstream, saltstack package repository. This is currently only - implemented for SUSE. - -k Temporary directory holding the minion keys which will pre-seed - the master. - -s Sleep time used when waiting for daemons to start, restart and when - checking for the services running. Default: 3 - -L Also install salt-cloud and required python-libcloud package - -M Also install salt-master - -S Also install salt-syndic - -W Also install salt-api - -N Do not install salt-minion - -X Do not start daemons after installation + -C Only run the configuration function. Implies -F (forced overwrite). + To overwrite Master, Syndic or Api configs, -M,-S or -W, respectively, must + also be specified. Salt installation will be ommitted, but some of the + dependencies could be installed to write configuration with -j or -J. -d Disables checking if Salt services are enabled to start on system boot. You can also do this by touching /tmp/disable_salt_checks on the target - host. Default: ${BS_FALSE} - -P Allow pip based installations. On some distributions the required salt - packages or its dependencies are not available as a package for that - distribution. Using this flag allows the script to use pip as a last - resort method. NOTE: This only works for functions which actually - implement pip based installations. - -U If set, fully upgrade the system prior to bootstrapping Salt + host. Default: \${BS_FALSE} + -D Show debug output + -f Force shallow cloning for git installations. + This may result in an "n/a" in the version number. + -F Allow copied files to overwrite existing (config, init.d, etc) + -g Salt Git repository URL. Default: https://github.com/saltstack/salt.git + -h Display this message + -H Use the specified HTTP proxy for all download URLs (including https://). + For example: http://myproxy.example.com:3128 + -i Pass the salt-minion id. This will be stored under + \${BS_SALT_ETC_DIR}/minion_id -I If set, allow insecure connections while downloading any files. For example, pass '--no-check-certificate' to 'wget' or '--insecure' to 'curl'. On Debian and Ubuntu, using this option with -U allows obtaining GnuPG archive keys insecurely if distro has changed release signatures. - -F Allow copied files to overwrite existing (config, init.d, etc) - -K If set, keep the temporary files in the temporary directories specified - with -c and -k - -C Only run the configuration function. Implies -F (forced overwrite). - To overwrite Master or Syndic configs, -M or -S, respectively, must - also be specified. Salt installation will be ommitted, but some of the - dependencies could be installed to write configuration with -j or -J. - -A Pass the salt-master DNS name or IP. This will be stored under - ${BS_SALT_ETC_DIR}/minion.d/99-master-address.conf - -i Pass the salt-minion id. This will be stored under - ${BS_SALT_ETC_DIR}/minion_id - -p Extra-package to install while installing Salt dependencies. One package - per -p flag. You are responsible for providing the proper package name. - -H Use the specified HTTP proxy for all download URLs (including https://). - For example: http://myproxy.example.com:3128 - -b Assume that dependencies are already installed and software sources are - set up. If git is selected, git tree is still checked out as dependency - step. - -f Force shallow cloning for git installations. - This may result in an "n/a" in the version number. - -l Disable ssl checks. When passed, switches "https" calls to "http" where - possible. - -V Install Salt into virtualenv - (only available for Ubuntu based distributions) - -a Pip install all Python pkg dependencies for Salt. Requires -V to install - all pip pkgs into the virtualenv. - (Only available for Ubuntu based distributions) - -r Disable all repository configuration performed by this script. This - option assumes all necessary repository configuration is already present - on the system. - -R Specify a custom repository URL. Assumes the custom repository URL - points to a repository that mirrors Salt packages located at - repo.saltproject.io. The option passed with -R replaces the - "repo.saltproject.io". If -R is passed, -r is also set. Currently only - works on CentOS/RHEL and Debian based distributions. - -J Replace the Master config file with data passed in as a JSON string. If - a Master config file is found, a reasonable effort will be made to save + -j Replace the Minion config file with data passed in as a JSON string. If + a Minion config file is found, a reasonable effort will be made to save the file with a ".bak" extension. If used in conjunction with -C or -F, no ".bak" file will be created as either of those options will force a complete overwrite of the file. - -j Replace the Minion config file with data passed in as a JSON string. If - a Minion config file is found, a reasonable effort will be made to save + -J Replace the Master config file with data passed in as a JSON string. If + a Master config file is found, a reasonable effort will be made to save the file with a ".bak" extension. If used in conjunction with -C or -F, no ".bak" file will be created as either of those options will force a complete overwrite of the file. + -k Temporary directory holding the minion keys which will pre-seed + the master. + -K If set, keep the temporary files in the temporary directories specified + with -c and -k + -l Disable ssl checks. When passed, switches "https" calls to "http" where + possible. + -L Also install salt-cloud and required python-libcloud package + -M Also install salt-master + -n No colours + -N Do not install salt-minion + -p Extra-package to install while installing Salt dependencies. One package + per -p flag. You are responsible for providing the proper package name. + -P Allow pip based installations. On some distributions the required salt + packages or its dependencies are not available as a package for that + distribution. Using this flag allows the script to use pip as a last + resort method. NOTE: This only works for functions which actually + implement pip based installations. -q Quiet salt installation from git (setup.py install -q) - -x Changes the Python version used to install Salt (default: Python 3) - Python 2.7 is not longer supported. -Q Quickstart, install the Salt master and the Salt minion. And automatically accept the minion key. + -R Specify a custom repository URL. Assumes the custom repository URL + points to a repository that mirrors Salt packages located at + packages.broadcom.com. The option passed with -R replaces the + "packages.broadcom.com". If -R is passed, -r is also set. Currently only + works on CentOS/RHEL and Debian based distributions and macOS. + -s Sleep time used when waiting for daemons to start, restart and when + checking for the services running. Default: 3 + -S Also install salt-syndic + -r Disable all repository configuration performed by this script. This + option assumes all necessary repository configuration is already present + on the system. + -U If set, fully upgrade the system prior to bootstrapping Salt + -v Display script version + -V Install Salt into virtualenv + (only available for Ubuntu based distributions) + -W Also install salt-api + -x Changes the Python version used to install Salt (default: Python 3). + Python 2.7 is no longer supported. + -X Do not start daemons after installation The Salt Bootstrap script has a wide variety of options that can be passed as well as several ways of obtaining the bootstrap script itself. Note that the use of ``sudo`` @@ -206,35 +225,35 @@ If you want to install a package of a specific release version, from the Salt Pr .. code:: console - curl -o bootstrap-salt.sh -L https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh -P stable 3006.1 If you want to install a specific release version, based on the Git tags: .. code:: console - curl -o bootstrap-salt.sh -L https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh git v3006.1 Using ``curl`` to install latest development version from GitHub: .. code:: console - curl -o bootstrap-salt.sh -L https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh git master To install a specific branch from a Git fork: .. code:: console - curl -o bootstrap-salt.sh -L https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh -g https://github.com/myuser/salt.git git mybranch If all you want is to install a ``salt-master`` using latest Git: .. code:: console - curl -o bootstrap-salt.sh -L https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh -M -N git master If your host has Internet access only via HTTP proxy, from the Salt Project repo: @@ -242,7 +261,7 @@ If your host has Internet access only via HTTP proxy, from the Salt Project repo .. code:: console PROXY='http://user:password@myproxy.example.com:3128' - curl -o bootstrap-salt.sh -L -x "$PROXY" https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L -x "$PROXY" https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh -P -H "$PROXY" stable If your host has Internet access only via HTTP proxy, installing via Git: @@ -250,7 +269,7 @@ If your host has Internet access only via HTTP proxy, installing via Git: .. code:: console PROXY='http://user:password@myproxy.example.com:3128' - curl -o bootstrap-salt.sh -L -x "$PROXY" https://bootstrap.saltproject.io + curl -o bootstrap-salt.sh -L -x "$PROXY" https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh -H "$PROXY" git @@ -261,22 +280,22 @@ Using ``wget`` to install your distribution's stable packages: .. code:: console - wget -O bootstrap-salt.sh https://bootstrap.saltproject.io + wget -O bootstrap-salt.sh https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh sudo sh bootstrap-salt.sh Installing a specific version from git using ``wget``: .. code:: console - wget -O bootstrap-salt.sh https://bootstrap.saltproject.io - sudo sh bootstrap-salt.sh git v3004.1 + wget -O bootstrap-salt.sh https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh + sudo sh bootstrap-salt.sh git v3006.8 Installing a specific version package from the Salt Project repo using ``wget``: .. code:: console - wget -O bootstrap-salt.sh https://bootstrap.saltproject.io - sudo sh bootstrap-salt.sh -P stable 3006.1 + wget -O bootstrap-salt.sh https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh + sudo sh bootstrap-salt.sh -P stable 3006.8 **NOTE** @@ -291,14 +310,14 @@ If you already have Python installed, ``python 3.10``, then it's as easy as: .. code:: console - python -m urllib "https://bootstrap.saltproject.io" > bootstrap-salt.sh + python -m urllib "https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh" > bootstrap-salt.sh sudo sh bootstrap-salt.sh -P stable 3006.1 With python version 3: .. code:: console - python3 -c 'import urllib.request; print(urllib.request.urlopen("https://bootstrap.saltproject.io").read().decode("ascii"))' > bootstrap-salt.sh + python3 -c 'import urllib.request; print(urllib.request.urlopen("https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh").read().decode("ascii"))' > bootstrap-salt.sh sudo sh bootstrap-salt.sh git v3006.1 Note: Python 2.x is no longer supported given it reached it's End-Of-Life Jan. 1st, 2020 @@ -321,25 +340,25 @@ Installing the latest stable release of Salt (default): .. code:: console - curl -L https://bootstrap.saltproject.io | sudo sh + curl -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh | sudo sh Using ``wget`` to install your distribution's stable packages: .. code:: console - wget -O - https://bootstrap.saltproject.io | sudo sh + wget -O - https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh | sudo sh Installing a target version package of Salt from the Salt Project repo: .. code:: console - curl -L https://bootstrap.saltproject.io | sudo sh -s -- stable 3006.8 + curl -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh | sudo sh -s -- stable 3006.8 Installing the latest master branch of Salt from git: .. code:: console - curl -L https://bootstrap.saltproject.io | sudo sh -s -- git master + curl -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.sh | sudo sh -s -- git master Note: use of git is recommended for development environments, for example: testing new features of Salt which have not yet been released. @@ -354,9 +373,8 @@ Using ``PowerShell`` to install latest stable version: .. code:: powershell [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls12' - Invoke-WebRequest -Uri https://winbootstrap.saltproject.io -OutFile "$env:TEMP\bootstrap-salt.ps1" - Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser - & "$env:TEMP\bootstrap-salt.ps1" + Invoke-WebRequest -Uri https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.ps1 -OutFile "$env:TEMP\bootstrap-salt.ps1" + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser & "$env:TEMP\bootstrap-salt.ps1" Display information about the install script parameters: @@ -368,7 +386,7 @@ Using ``cygwin`` to install latest stable version: .. code:: console - curl -o bootstrap-salt.ps1 -L https://winbootstrap.saltproject.io + curl -o bootstrap-salt.ps1 -L https://github.com/saltstack/salt-bootstrap/releases/latest/download/bootstrap-salt.ps1 "/cygdrive/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "[System.Net.ServicePointManager]::SecurityProtocol = 3072; iex ./bootstrap-salt.ps1" @@ -378,13 +396,13 @@ Supported Operating Systems The salt-bootstrap script officially supports the distributions outlined in `Salt's Supported Operating Systems `_ -document, (BSD-based OSs, Solaris and AIX are no longer -supported). The operating systems listed below should reflect this document but may become out of -date. If an operating system is listed below, but is not listed on the official supported operating +document, (BSD-based OSs, Solaris and AIX are no longer supported). +The operating systems listed below should reflect this document but may become out of date. +If an operating system is listed below, but is not listed on the official supported operating systems document, the level of support is "best-effort". Since Salt is written in Python, the packages available from the `Salt Project's repository -`_ are +`_ are CPU architecture independent and could be installed on any hardware supported by Linux kernel. However, the Salt Project does package Salt's binary dependencies only for ``x86_64`` (``amd64``) and ``AArch64`` (``arm64``). @@ -413,21 +431,19 @@ Debian and derivatives - Devuan GNU/Linux 1/2/3/4/5 - Kali Linux 1.0 (based on Debian 7) - Linux Mint Debian Edition 1 (based on Debian 8) -- Raspbian 8 (``armhf`` packages) and 9 (using ``git`` installation mode only) Red Hat family ~~~~~~~~~~~~~~ -- Amazon Linux 2012.3 and later - Amazon Linux 2 - Amazon Linux 2023 -- CentOS 7/8/9 +- CentOS 8/9 - Cloud Linux 6/7 -- Fedora 38/39/40 (install latest stable from standard repositories) -- Oracle Linux 7/8/9 -- Red Hat Enterprise Linux 7/8/9 -- Scientific Linux 7/8/9 +- Fedora 40 (install latest stable from standard repositories) +- Oracle Linux 8/9 +- Red Hat Enterprise Linux 8/9 +- Scientific Linux 8/9 SUSE family @@ -460,8 +476,8 @@ repositories are not provided on the `Salt Project's Ubuntu repository`_ for the the bootstrap script will attempt to install the packages for the most closely related LTS Ubuntu release instead. -For example, when installing Salt on Ubuntu 21.10, the bootstrap script will setup the repository -for Ubuntu 20.04 from the `Salt Project's Ubuntu repository`_ and install the 20.04 packages. +For example, when installing Salt on Ubuntu 24.10, the bootstrap script will setup the repository +for Ubuntu 24.04 from the `Salt Project's Ubuntu repository`_ and install the 24.04 packages. Non-LTS Ubuntu releases are not supported once the release reaches End-of-Life as defined by `Ubuntu's release schedule`_. diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 4a8a57f57..000000000 --- a/Vagrantfile +++ /dev/null @@ -1,119 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - # All Vagrant configuration is done here. The most common configuration - # options are documented and commented below. For a complete reference, - # please see the online documentation at vagrantup.com. - - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = "ubuntu/focal64" - - # The url from where the 'config.vm.box' box will be fetched if it - # doesn't already exist on the user's system. - # config.vm.box_url = "http://domain.com/path/to/above.box" - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # config.vm.network :forwarded_port, guest: 80, host: 8080 - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network :private_network, ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network :public_network - - # If true, then any SSH connections made will enable agent forwarding. - # Default value: false - # config.ssh.forward_agent = true - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - config.vm.synced_folder ".", "/salt_bootstrap" - - config.vm.provision "shell", path: "bootstrap-salt.sh" - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider :virtualbox do |vb| - # # Don't boot with headless mode - # vb.gui = true - # - # # Use VBoxManage to customize the VM. For example to change memory: - # vb.customize ["modifyvm", :id, "--memory", "1024"] - # end - # - # View the documentation for the provider you're using for more - # information on available options. - - # Enable provisioning with Puppet stand alone. Puppet manifests - # are contained in a directory path relative to this Vagrantfile. - # You will need to create the manifests directory and a manifest in - # the file precise64.pp in the manifests_path directory. - # - # An example Puppet manifest to provision the message of the day: - # - # # group { "puppet": - # # ensure => "present", - # # } - # # - # # File { owner => 0, group => 0, mode => 0644 } - # # - # # file { '/etc/motd': - # # content => "Welcome to your Vagrant-built virtual machine! - # # Managed by Puppet.\n" - # # } - # - # config.vm.provision :puppet do |puppet| - # puppet.manifests_path = "manifests" - # puppet.manifest_file = "site.pp" - # end - - # Enable provisioning with chef solo, specifying a cookbooks path, roles - # path, and data_bags path (all relative to this Vagrantfile), and adding - # some recipes and/or roles. - # - # config.vm.provision :chef_solo do |chef| - # chef.cookbooks_path = "../my-recipes/cookbooks" - # chef.roles_path = "../my-recipes/roles" - # chef.data_bags_path = "../my-recipes/data_bags" - # chef.add_recipe "mysql" - # chef.add_role "web" - # - # # You may also specify custom JSON attributes: - # chef.json = { :mysql_password => "foo" } - # end - - # Enable provisioning with chef server, specifying the chef server URL, - # and the path to the validation key (relative to this Vagrantfile). - # - # The Opscode Platform uses HTTPS. Substitute your organization for - # ORGNAME in the URL and validation key. - # - # If you have your own Chef Server, use the appropriate URL, which may be - # HTTP instead of HTTPS depending on your configuration. Also change the - # validation key to validation.pem. - # - # config.vm.provision :chef_client do |chef| - # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" - # chef.validation_key_path = "ORGNAME-validator.pem" - # end - # - # If you're using the Opscode platform, your validator client is - # ORGNAME-validator, replacing ORGNAME with your organization name. - # - # If you have your own Chef Server, the default validation client name is - # chef-validator, unless you changed the configuration. - # - # chef.validation_client_name = "ORGNAME-validator" -end diff --git a/bootstrap-salt.ps1 b/bootstrap-salt.ps1 index eccbb3526..8b1bb3a38 100644 --- a/bootstrap-salt.ps1 +++ b/bootstrap-salt.ps1 @@ -18,7 +18,7 @@ Specifies a particular version of the installer. .EXAMPLE - ./bootstrap-salt.ps1 -RunService false + ./bootstrap-salt.ps1 -RunService $false Specifies the salt-minion service to stop and be set to manual. Useful for testing locally from the command line with the --local switch @@ -28,7 +28,7 @@ installer values of host name for the minion id and "salt" for the master. .EXAMPLE - ./bootstrap-salt.ps1 -Minion minion-box -Master master-box -Version 3006.7 -RunService false + ./bootstrap-salt.ps1 -Minion minion-box -Master master-box -Version 3006.7 -RunService $false Specifies all the optional parameters in no particular order. .NOTES @@ -39,7 +39,8 @@ Salt Bootstrap GitHub Project (script home) - https://github.com/saltstack/salt-bootstrap Original Vagrant Provisioner Project - https://github.com/saltstack/salty-vagrant Vagrant Project (utilizes this script) - https://github.com/mitchellh/vagrant - Salt Download Location - https://repo.saltproject.io/salt/py3/windows + Salt Download Location - https://packages.broadcom.com/artifactory/saltproject-generic/windows/ + Salt Manual Install Directions (Windows) - https://docs.saltproject.io/salt/install-guide/en/latest/topics/install-by-operating-system/windows.html #> #=============================================================================== @@ -48,7 +49,6 @@ [CmdletBinding()] param( [Parameter(Mandatory=$false, ValueFromPipeline=$True)] - [ValidatePattern('^(\d{4}(\.\d{1,2}){0,2}(\-\d{1})?)|(latest)$', Options=1)] [Alias("v")] # The version of the Salt minion to install. Default is "latest" which will # install the latest version of Salt minion available. Doesn't support @@ -56,12 +56,11 @@ param( [String]$Version = "latest", [Parameter(Mandatory=$false, ValueFromPipeline=$True)] - [ValidateSet("true","false")] [Alias("s")] - # Boolean flag to start or stop the minion service. True will start the - # minion service. False will stop the minion service and set it to "manual". + # Boolean flag to start or stop the minion service. $true will start the + # minion service. $false will stop the minion service and set it to "manual". # The installer starts it by default. - [String]$RunService = "true", + [Bool]$RunService = $true, [Parameter(Mandatory=$false, ValueFromPipeline=$True)] [Alias("m")] @@ -76,12 +75,11 @@ param( [Parameter(Mandatory=$false, ValueFromPipeline=$True)] [Alias("r")] - # URL to the windows packages. Will look for a file named repo.json at the - # root of the URL. This file is used to determine the name and location of - # the installer in the repo. If repo.json is not found, it will look for the - # file under the minor directory. - # Default is "https://repo.saltproject.io/salt/py3/windows" - [String]$RepoUrl = "https://repo.saltproject.io/salt/py3/windows", + # URL to the windows packages. Will look for the installer at the root of + # the URL/Version. Place a folder for each version of Salt in this directory + # and place the installer binary for each version in its folder. + # Default is "https://packages.broadcom.com/artifactory/saltproject-generic/windows/" + [String]$RepoUrl = "https://packages.broadcom.com/artifactory/saltproject-generic/windows/", [Parameter(Mandatory=$false, ValueFromPipeline=$True)] [Alias("c")] @@ -110,7 +108,7 @@ if ($help) { exit 0 } -$__ScriptVersion = "2024.09.24" +$__ScriptVersion = "2024.12.12" $ScriptName = $myInvocation.MyCommand.Name # We'll check for the Version next, because it also has no requirements @@ -155,34 +153,116 @@ function Get-MajorVersion { return ( $Version -split "\." )[0] } -function Convert-PSObjectToHashtable { - param ( - [Parameter(ValueFromPipeline)] - $InputObject - ) - if ($null -eq $InputObject) { return $null } - - $is_enum = $InputObject -is [System.Collections.IEnumerable] - $not_string = $InputObject -isnot [string] - if ($is_enum -and $not_string) { - $collection = @( - foreach ($object in $InputObject) { - Convert-PSObjectToHashtable $object - } - ) +function Get-AvailableVersions { + # Get available versions from a remote location specified in the Source + # Parameter + Write-Verbose "Getting version information from the repo" + Write-Verbose "base_url: $base_url" - Write-Host -NoEnumerate $collection - } elseif ($InputObject -is [PSObject]) { - $hash = @{} + $available_versions = [System.Collections.ArrayList]@() - foreach ($property in $InputObject.PSObject.Properties) { - $hash[$property.Name] = Convert-PSObjectToHashtable $property.Value + if ( $base_url.StartsWith("http") -or $base_url.StartsWith("ftp") ) { + # We're dealing with HTTP, HTTPS, or FTP + $response = Invoke-WebRequest "$base_url" -UseBasicParsing + try { + $response = Invoke-WebRequest "$base_url" -UseBasicParsing + } catch { + Write-Host "Failed to get version information" -ForegroundColor Red + exit 1 } - $hash + if ( $response.StatusCode -ne 200 ) { + Write-Host "There was an error getting version information" -ForegroundColor Red + Write-Host "Error: $($response.StatusCode)" -ForegroundColor red + exit 1 + } + + $response.links | ForEach-Object { + if ( $_.href.Length -gt 8) { + Write-Host "The content at this location is unexpected" -ForegroundColor Red + Write-Host "Should be a list of directories where the name is a version of Salt" -ForegroundColor Red + exit 1 + } + } + + # Getting available versions from response + Write-Verbose "Getting available versions from response" + $filtered = $response.Links | Where-Object -Property href -NE "../" + $filtered | Select-Object -Property href | ForEach-Object { + $available_versions.Add($_.href.Trim("/")) | Out-Null + } + } elseif ( $base_url.StartsWith("\\") -or $base_url -match "^[A-Za-z]:\\" ) { + # We're dealing with a local directory or SMB source + Get-ChildItem -Path $base_url -Directory | ForEach-Object { + $available_versions.Add($_.Name) | Out-Null + } } else { - $InputObject + Write-Host "Unknown Source Type" -ForegroundColor Red + Write-Host "Must be one of HTTP, HTTPS, FTP, SMB Share, Local Directory" -ForegroundColor Red + exit 1 + } + + Write-Verbose "Available versions:" + $available_versions | ForEach-Object { + Write-Verbose "- $_" } + + # Get the latest version, should be the last in the list + Write-Verbose "Getting latest available version" + $latest = $available_versions | Select-Object -Last 1 + Write-Verbose "Latest available version: $latest" + + # Create a versions table + # This will have the latest version available, the latest version available + # for each major version, and every version available. This makes the + # version lookup logic easier. The contents of the versions table can be + # found by running -Verbose + Write-Verbose "Populating the versions table" + $versions_table = [ordered]@{"latest"=$latest} + $available_versions | ForEach-Object { + $versions_table[$(Get-MajorVersion $_)] = $_ + $versions_table[$_.ToLower()] = $_.ToLower() + } + + Write-Verbose "Versions Table:" + $versions_table | Sort-Object Name | Out-String | ForEach-Object { + Write-Verbose "$_" + } + + return $versions_table +} + +function Get-HashFromArtifactory { + # This function uses the artifactory API to get the SHA265 Hash for the file + # If Source is NOT artifactory, the sha will not be checked + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)] + [String] $SaltVersion, + + [Parameter(Mandatory=$true)] + [String] $SaltFileName + ) + if ( $api_url ) { + $full_url = "$api_url/$SaltVersion/$SaltFileName" + Write-Verbose "Querying Artifactory API for hash:" + Write-Verbose $full_url + try { + $response = Invoke-RestMethod $full_url -UseBasicParsing + return $response.checksums.sha256 + } catch { + Write-Verbose "Artifactory API Not available or file not" + Write-Verbose "available at specified location" + Write-Verbose "Hash will not be checked" + return "" + } + Write-Verbose "No hash found for this file: $SaltFileName" + Write-Verbose "Hash will not be checked" + return "" + } + Write-Verbose "No artifactory API defined" + Write-Verbose "Hash will not be checked" + return "" } function Get-FileHash { @@ -301,19 +381,42 @@ if (!(Get-IsAdministrator)) { } #=============================================================================== -# Change RepoUrl for older versions +# Check for older versions #=============================================================================== -$defaultUrl = "https://repo.saltproject.io/salt/py3/windows" -$oldRepoUrl = "https://repo.saltproject.io/windows" $majorVersion = Get-MajorVersion -Version $Version -if ( [Uri]($RepoUrl).AbsoluteUri -eq $defaultUrl ) { - # No customURL passed, let's check for a pre 3006 version - if ($majorVersion -lt "3006") { - # This is an older version, use the old URL - $RepoUrl = $oldRepoUrl +if ($majorVersion -lt "3006") { + # This is an older version, use the old URL + Write-Host "Versions older than 3006 are not available" -ForegroundColor Red + exit 1 +} + +#=============================================================================== +# Declare variables +#=============================================================================== +$ConfDir = "$RootDir\conf" +$PkiDir = "$ConfDir\pki\minion" + +$RootDir = "$env:ProgramData\Salt Project\Salt" +# Check for existing installation where RootDir is stored in the registry +$SaltRegKey = "HKLM:\SOFTWARE\Salt Project\Salt" +if (Test-Path -Path $SaltRegKey) { + if ($null -ne (Get-ItemProperty $SaltRegKey).root_dir) { + $RootDir = (Get-ItemProperty $SaltRegKey).root_dir } } +# Get repo and api URLs. An artifactory URL will have "artifactory" in it +$domain, $target = $RepoUrl -split "/artifactory/" +if ( $target ) { + # Create $base_url and $api_url + $base_url = "$domain/artifactory/$target" + $api_url = "$domain/artifactory/api/storage/$target" +} else { + # This is a non-artifactory url, there is no api + $base_url = $domain + $api_url = "" +} + #=============================================================================== # Verify Parameters #=============================================================================== @@ -324,49 +427,25 @@ Write-Verbose "version: $Version" Write-Verbose "runservice: $RunService" Write-Verbose "master: $Master" Write-Verbose "minion: $Minion" -Write-Verbose "repourl: $RepoUrl" +Write-Verbose "repourl: $base_url" +Write-Verbose "apiurl: $api_url" +Write-Verbose "ConfDir: $ConfDir" +Write-Verbose "RootDir: $RootDir" -if ($RunService.ToLower() -eq "true") { +if ($RunService) { Write-Verbose "Windows service will be set to run" [bool]$RunService = $True -} elseif ($RunService.ToLower() -eq "false") { +} else { Write-Verbose "Windows service will be stopped and set to manual" [bool]$RunService = $False -} else { - # Param passed in wasn't clear so defaulting to true. - Write-Verbose "Windows service defaulting to run automatically" - [bool]$RunService = $True } #=============================================================================== -# Ensure Directories are present, copy Vagrant Configs if found +# Copy Vagrant Files to their proper location. #=============================================================================== $ConfiguredAnything = $False -# Detect older version of Salt to determing default RootDir -if ($majorVersion -lt 3004) { - $RootDir = "$env:SystemDrive`:\salt" -} else { - $RootDir = "$env:ProgramData\Salt Project\Salt" -} - -# Check for existing installation where RootDir is stored in the registry -$SaltRegKey = "HKLM:\SOFTWARE\Salt Project\Salt" -if (Test-Path -Path $SaltRegKey) { - if ($null -ne (Get-ItemProperty $SaltRegKey).root_dir) { - $RootDir = (Get-ItemProperty $SaltRegKey).root_dir - } -} - -$ConfDir = "$RootDir\conf" -$PkiDir = "$ConfDir\pki\minion" -Write-Verbose "ConfDir: $ConfDir" - -#=============================================================================== -# Copy Vagrant Files to their proper location. -#=============================================================================== - # Vagrant files will be placed in C:\tmp # Check if minion keys have been uploaded, copy to correct location if (Test-Path C:\tmp\minion.pem) { @@ -406,152 +485,33 @@ if ( $ConfigureOnly ) { #=============================================================================== # Detect architecture #=============================================================================== -if ([IntPtr]::Size -eq 4) { - $arch = "x86" -} else { - $arch = "AMD64" -} +if ([IntPtr]::Size -eq 4) { $arch = "x86" } else { $arch = "AMD64" } #=============================================================================== -# Get file name to download -#=============================================================================== -$saltFileName = "" -$saltVersion = "" -$saltSha512= "" -$saltFileUrl = "" -# Look for a repo.json file -try { - Write-Verbose "Looking for $RepoUrl/repo.json" - $response = Invoke-WebRequest "$RepoUrl/repo.json" ` - -DisableKeepAlive ` - -UseBasicParsing ` - -Method Head - if ( $response.StatusCode -eq "200" ) { - Write-Verbose "Found $RepoUrl/repo.json" - # This URL contains a repo.json file, let's use it - $use_repo_json = $true - } else { - Write-Verbose "Did not find $RepoUrl/repo.json" - # No repo.json file found at the default location - $use_repo_json = $false - } -} catch { - Write-Verbose "There was an error looking up $RepoUrl/repo.json" - Write-Verbose "ERROR: $_" - $use_repo_json = $false -} -if ( $use_repo_json ) { - # We will use the json file to get the name of the installer - $enc = [System.Text.Encoding]::UTF8 - try { - Write-Verbose "Downloading $RepoUrl/repo.json" - $response = Invoke-WebRequest -Uri "$RepoUrl/repo.json" -UseBasicParsing - if ($response.Content.GetType().Name -eq "Byte[]") { - $psobj = $enc.GetString($response.Content) | ConvertFrom-Json - } else { - $psobj = $response.Content | ConvertFrom-Json - } - $hash = Convert-PSObjectToHashtable $psobj - } catch { - Write-Verbose "repo.json not found at: $RepoUrl" - Write-Host "ERROR: $_" - $hash = @{} - } - - $searchVersion = $Version.ToLower() - if ( $hash.Contains($searchVersion)) { - Write-Verbose "Found $searchVersion in $RepoUrl/repo.json" - foreach ($item in $hash.($searchVersion).Keys) { - if ( $item.ToLower().EndsWith(".exe") ) { - if ( $item.ToLower().Contains($arch.ToLower()) ) { - $saltFileName = $hash.($searchVersion).($item).name - $saltVersion = $hash.($searchVersion).($item).version - $saltSha512 = $hash.($searchVersion).($item).SHA512 - } - } - } - } else { - try { - Write-Verbose "Searching for $searchVersion in $RepoUrl/minor/repo.json" - $response = Invoke-WebRequest -Uri "$RepoUrl/minor/repo.json" -UseBasicParsing - if ($response.Content.GetType().Name -eq "Byte[]") { - $psobj = $enc.GetString($response.Content) | ConvertFrom-Json - } else { - $psobj = $response.Content | ConvertFrom-Json - } - $hash = Convert-PSObjectToHashtable $psobj - } catch { - Write-Verbose "repo.json not found at: $RepoUrl/minor/repo.json" - Write-Verbose "ERROR: $_" - $hash = @{} - } - if ( $hash.Contains($searchVersion)) { - Write-Verbose "Found $searchVersion in $RepoUrl/minor/repo.json" - foreach ($item in $hash.($searchVersion).Keys) { - if ( $item.ToLower().EndsWith(".exe") ) { - if ( $item.ToLower().Contains($arch.ToLower()) ) { - $saltFileName = $hash.($searchVersion).($item).name - $saltVersion = $hash.($searchVersion).($item).version - $saltSha512 = $hash.($searchVersion).($item).SHA512 - } - } - } - } else { - Write-Verbose "Version not found in $RepoUrl/minor/repo.json" - } - } -} +# Getting version information from the repo +#=============================================================================== +$versions = Get-AvailableVersions -if ( $saltFileName -and $saltVersion -and $saltSha512 ) { - Write-Verbose "Found Name, Version, and Sha" +#=============================================================================== +# Validate passed version +#=============================================================================== +Write-Verbose "Looking up version: $Version" +if ( $versions.Contains($Version.ToLower()) ) { + $Version = $versions[$Version.ToLower()] + Write-Verbose "Found version: $Version" } else { - # We will guess the name of the installer - Write-Verbose "Failed to get Name, Version, and Sha from repo.json" - Write-Verbose "We'll try to find the file in standard paths" - $saltFileName = "Salt-Minion-$Version-Py3-$arch-Setup.exe" - $saltVersion = $Version -} - -Write-Verbose "Creating list of urls using the following:" -Write-Verbose "RepoUrl: $RepoUrl" -Write-Verbose "Version: $saltVersion" -Write-Verbose "File Name: $saltFileName" -$urls = $(@($RepoUrl, $saltVersion, $saltFileName) -join "/"), - $(@($RepoUrl, "minor", $saltVersion, $saltFileName) -join "/"), - $(@($RepoUrl, $saltFileName) -join "/"), - $(@($oldRepoUrl, $saltFileName) -join "/") - -$saltFileUrl = $null - -foreach ($url in $urls) { - try { - Write-Verbose "Looking for installer at: $url" - $response = Invoke-WebRequest "$url" ` - -DisableKeepAlive ` - -UseBasicParsing ` - -Method Head - if ( $response.StatusCode -eq "200" ) { - Write-Verbose "Found installer" - # This URL contains a repo.json file, let's use it - $saltFileUrl = $url - break - } else { - Write-Verbose "Installer not found: $url" - } - } catch { - Write-Verbose "ERROR: $url" - } -} - -if ( !$saltFileUrl ) { - Write-Host "Could not find an installer:" - Write-Verbose "Here are the urls searched:" - foreach ($url in $urls) { - Write-Verbose $url - } + Write-Host "Version $Version is not available" -ForegroundColor Red + Write-Host "Available versions are:" -ForegroundColor Yellow + $versions exit 1 } +#=============================================================================== +# Get file url and sha256 +#=============================================================================== +$saltFileName = "Salt-Minion-$Version-Py3-$arch-Setup.exe" +$saltFileUrl = "$base_url/$Version/$saltFileName" +$saltSha256 = Get-HashFromArtifactory -SaltVersion $Version -SaltFileName $saltFileName #=============================================================================== # Download minion setup file @@ -560,7 +520,8 @@ Write-Host "==================================================================== Write-Host " Bootstrapping Salt Minion" -ForegroundColor Green Write-Host " - version: $Version" Write-Host " - file name: $saltFileName" -Write-Host " - file url: $saltFileUrl" +Write-Host " - file url : $saltFileUrl" +Write-Host " - file hash: $saltSha256" Write-Host " - master: $Master" Write-Host " - minion id: $Minion" Write-Host " - start service: $RunService" @@ -573,22 +534,26 @@ Write-Verbose "" Write-Verbose "Salt File URL: $saltFileUrl" Write-Verbose "Local File: $localFile" -$webclient = New-Object System.Net.WebClient -$webclient.DownloadFile($saltFileUrl, $localFile) +# Remove existing local file +if ( Test-Path -Path $localFile ) { Remove-Item -Path $localFile -Force } +# Download the file +Invoke-WebRequest -Uri $saltFileUrl -OutFile $localFile if ( Test-Path -Path $localFile ) { Write-Host "Success" -ForegroundColor Green } else { Write-Host "Failed" -ForegroundColor Red + exit 1 } -if ( $saltSha512 ) { - $localSha512 = (Get-FileHash -Path $localFile -Algorithm SHA512).Hash +# Compare the hash if there is a hash to compare +if ( $saltSha256 ) { + $localSha256 = (Get-FileHash -Path $localFile -Algorithm SHA256).Hash Write-Host "Comparing Hash: " -NoNewline Write-Verbose "" - Write-Verbose "Local Hash: $localSha512" - Write-Verbose "Remote Hash: $saltSha512" - if ( $localSha512 -eq $saltSha512 ) { + Write-Verbose "Local Hash: $localSha256" + Write-Verbose "Remote Hash: $saltSha256" + if ( $localSha256 -eq $saltSha256 ) { Write-Host "Success" -ForegroundColor Green } else { Write-Host "Failed" -ForegroundColor Red @@ -620,13 +585,13 @@ $process = Start-Process $localFile ` -NoNewWindow -PassThru # Sometimes the installer hangs... we'll wait 5 minutes and then kill it -Write-Verbose "" Write-Verbose "Waiting for installer to finish" $process | Wait-Process -Timeout 300 -ErrorAction SilentlyContinue $process.Refresh() if ( !$process.HasExited ) { - Write-Host "Timedout" -ForegroundColor Yellow + Write-Verbose "Installer Timeout" + Write-Host "" Write-Host "Killing hung installer: " -NoNewline $process | Stop-Process $process.Refresh() @@ -636,8 +601,6 @@ if ( !$process.HasExited ) { Write-Host "Failed" -ForegroundColor Red exit 1 } - - Write-Host "Checking installed service: " -NoNewline } # Wait for salt-minion service to be registered to verify successful @@ -658,7 +621,7 @@ while ( ! $service ) { # probably went wrong and user intervention is required - report # failure. Write-Host "Failed" -ForegroundColor Red - Write-Host "Timed out waiting for the salt-minion service to be installed" + Write-Host "Timeout waiting for the salt-minion service to be installed" exit 1 } } @@ -676,27 +639,31 @@ if( $RunService ) { # We'll try for 2 minutes, sometimes the minion takes that long to start as # it compiles python code for the first time $max_tries = 60 - while ( $service.Status -ne "Running" ) { - if ( $service.Status -eq "Stopped" ) { - Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue - } - Start-Sleep -Seconds 2 - Write-Verbose "Checking the service status" - $service.Refresh() - if ( $service.Status -eq "Running" ) { - Write-Host "Success" -ForegroundColor Green - } else { - if ( $tries -le $max_tries ) { - $tries += 1 + if ( $service.Status -ne "Running" ) { + while ( $service.Status -ne "Running" ) { + if ( $service.Status -eq "Stopped" ) { + Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue + } + Start-Sleep -Seconds 2 + Write-Verbose "Checking the service status" + $service.Refresh() + if ( $service.Status -eq "Running" ) { + Write-Host "Success" -ForegroundColor Green } else { - # If the salt-minion service is still not running, something - # probably went wrong and user intervention is required - report - # failure. - Write-Host "Failed" -ForegroundColor Red - Write-Host "Timed out waiting for the salt-minion service to start" - exit 1 + if ( $tries -le $max_tries ) { + $tries += 1 + } else { + # If the salt-minion service is still not running, something + # probably went wrong and user intervention is required - report + # failure. + Write-Host "Failed" -ForegroundColor Red + Write-Host "Timed out waiting for the salt-minion service to start" + exit 1 + } } } + } else { + Write-Host "Success" -ForegroundColor Green } } else { # Set the service to manual start diff --git a/bootstrap-salt.sh b/bootstrap-salt.sh index 3d36708a8..6a73f9d7c 100755 --- a/bootstrap-salt.sh +++ b/bootstrap-salt.sh @@ -26,7 +26,7 @@ #====================================================================================================================== set -o nounset # Treat unset variables as an error -__ScriptVersion="2024.09.24" +__ScriptVersion="2024.12.12" __ScriptName="bootstrap-salt.sh" __ScriptFullName="$0" @@ -124,6 +124,28 @@ __check_command_exists() { command -v "$1" > /dev/null 2>&1 } +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: __check_services_systemd_functional +# DESCRIPTION: Set _SYSTEMD_FUNCTIONAL = BS_TRUE or BS_FALSE case where systemd is functional (for example: container may not have systemd) +#---------------------------------------------------------------------------------------------------------------------- +__check_services_systemd_functional() { + + # check if systemd is functional, having systemctl present is insufficient + + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_FALSE ]; then + # already determined systemd is not functional, default is 1 + return + fi + + if __check_command_exists systemctl; then + # shellcheck disable=SC2034 + _SYSTEMD_HELP="$(systemctl --help)" + else + _SYSTEMD_FUNCTIONAL=$BS_FALSE + echoerror "systemctl: command not found, assume systemd not implemented, _SYSTEMD_FUNCTIONAL $_SYSTEMD_FUNCTIONAL" + fi +} # ---------- end of function __check_services_systemd_functional ---------- + #--- FUNCTION ------------------------------------------------------------------------------------------------------- # NAME: __check_pip_allowed # DESCRIPTION: Simple function to let the users know that -P needs to be used. @@ -199,6 +221,7 @@ __check_config_dir() { # DESCRIPTION: Checks the placed after the install arguments #---------------------------------------------------------------------------------------------------------------------- __check_unparsed_options() { + shellopts="$1" # grep alternative for SunOS if [ -f /usr/xpg4/bin/grep ]; then @@ -267,9 +290,7 @@ _CUSTOM_REPO_URL="null" _CUSTOM_MASTER_CONFIG="null" _CUSTOM_MINION_CONFIG="null" _QUIET_GIT_INSTALLATION=$BS_FALSE -_REPO_URL="repo.saltproject.io" -_ONEDIR_DIR="salt" -_ONEDIR_NIGHTLY_DIR="salt-dev/${_ONEDIR_DIR}" +_REPO_URL="packages.broadcom.com/artifactory" _PY_EXE="python3" _MINIMUM_PIP_VERSION="9.0.1" _MINIMUM_SETUPTOOLS_VERSION="65.6.3" @@ -278,6 +299,7 @@ _PIP_INSTALL_ARGS="--prefix=/usr" _PIP_DOWNLOAD_ARGS="" _QUICK_START="$BS_FALSE" _AUTO_ACCEPT_MINION_KEYS="$BS_FALSE" +_SYSTEMD_FUNCTIONAL=$BS_TRUE # Defaults for install arguments ITYPE="stable" @@ -296,9 +318,9 @@ __usage() { - stable Install latest stable release. This is the default install type - stable [branch] Install latest version on a branch. Only supported - for packages available at repo.saltproject.io + for packages available at packages.broadcom.com - stable [version] Install a specific version. Only supported for - packages available at repo.saltproject.io + packages available at packages.broadcom.com To pin a 3xxx minor version, specify it as 3xxx.0 - testing RHEL-family specific: configure EPEL testing repo - git Install from the head of the master branch @@ -306,11 +328,11 @@ __usage() { commit) - onedir Install latest onedir release. - onedir [version] Install a specific version. Only supported for - onedir packages available at repo.saltproject.io + onedir packages available at packages.broadcom.com - onedir_rc Install latest onedir RC release. - onedir_rc [version] Install a specific version. Only supported for - onedir RC packages available at repo.saltproject.io + onedir RC packages available at packages.broadcom.com Examples: - ${__ScriptName} @@ -393,8 +415,8 @@ __usage() { And automatically accept the minion key. -R Specify a custom repository URL. Assumes the custom repository URL points to a repository that mirrors Salt packages located at - repo.saltproject.io. The option passed with -R replaces the - "repo.saltproject.io". If -R is passed, -r is also set. Currently only + packages.broadcom.com. The option passed with -R replaces the + "packages.broadcom.com". If -R is passed, -r is also set. Currently only works on CentOS/RHEL and Debian based distributions and macOS. -s Sleep time used when waiting for daemons to start, restart and when checking for the services running. Default: ${__DEFAULT_SLEEP} @@ -522,8 +544,8 @@ __exit_cleanup() { echodebug "Cleaning up the Salt Temporary Git Repository" # shellcheck disable=SC2164 cd "${__SALT_GIT_CHECKOUT_PARENT_DIR}" - rm -rf "${_SALT_GIT_CHECKOUT_DIR}" - #rm -rf "${_SALT_GIT_CHECKOUT_DIR}/deps" + rm -fR "${_SALT_GIT_CHECKOUT_DIR}" + #rm -fR "${_SALT_GIT_CHECKOUT_DIR}/deps" else echowarn "Not cleaning up the Salt Temporary git repository on request" echowarn "Note that if you intend to re-run this script using the git approach, you might encounter some issues" @@ -579,7 +601,15 @@ fi echoinfo "Running version: ${__ScriptVersion}" echoinfo "Executed by: ${CALLER}" echoinfo "Command line: '${__ScriptFullName} ${__ScriptArgs}'" -echowarn "Running the unstable version of ${__ScriptName}" + +# Defaults +STABLE_REV="latest" +ONEDIR_REV="latest" +_ONEDIR_REV="latest" +YUM_REPO_FILE="/etc/yum.repos.d/salt.repo" + +# check if systemd is functional +__check_services_systemd_functional # Define installation type if [ "$#" -gt 0 ];then @@ -589,13 +619,24 @@ if [ "$#" -gt 0 ];then fi # Check installation type -if [ "$(echo "$ITYPE" | grep -E '(stable|testing|git|onedir|onedir_rc)')" = "" ]; then +if [ "$(echo "$ITYPE" | grep -E '(latest|default|stable|testing|git|onedir|onedir_rc)')" = "" ]; then echoerror "Installation type \"$ITYPE\" is not known..." exit 1 fi +## allows GitHub Actions CI/CD easier handling of latest and default +if [ "$ITYPE" = "latest" ] || [ "$ITYPE" = "default" ]; then + STABLE_REV="latest" + ONEDIR_REV="latest" + _ONEDIR_REV="latest" + ITYPE="onedir" + if [ "$#" -gt 0 ];then + shift + fi + echodebug "using ITYPE onedir for input 'latest' or 'default', cmd args left ,$#," + # If doing a git install, check what branch/tag/sha will be checked out -if [ "$ITYPE" = "git" ]; then +elif [ "$ITYPE" = "git" ]; then if [ "$#" -eq 0 ];then GIT_REV="master" else @@ -609,22 +650,25 @@ if [ "$ITYPE" = "git" ]; then # If doing stable install, check if version specified elif [ "$ITYPE" = "stable" ]; then if [ "$#" -eq 0 ];then + STABLE_REV="latest" ONEDIR_REV="latest" _ONEDIR_REV="latest" ITYPE="onedir" else - if [ "$(echo "$1" | grep -E '^(nightly|latest|3006|3007)$')" != "" ]; then + if [ "$(echo "$1" | grep -E '^(latest|3006|3007)$')" != "" ]; then + STABLE_REV="$1" ONEDIR_REV="$1" _ONEDIR_REV="$1" ITYPE="onedir" shift - elif [ "$(echo "$1" | grep -E '^([3-9][0-5]{2}[5-9](\.[0-9]*)?)')" != "" ]; then - ONEDIR_REV="minor/$1" + elif [ "$(echo "$1" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + STABLE_REV="$1" + ONEDIR_REV="$1" _ONEDIR_REV="$1" ITYPE="onedir" shift else - echo "Unknown stable version: $1 (valid: 3006, 3007, latest)" + echo "Unknown stable version: $1 (valid: 3006, 3007, latest), versions older than 3006 are not available" exit 1 fi fi @@ -632,47 +676,54 @@ elif [ "$ITYPE" = "stable" ]; then elif [ "$ITYPE" = "onedir" ]; then if [ "$#" -eq 0 ];then ONEDIR_REV="latest" + STABLE_REV="latest" else - if [ "$(echo "$1" | grep -E '^(nightly|latest|3006|3007)$')" != "" ]; then + if [ "$(echo "$1" | grep -E '^(latest|3006|3007)$')" != "" ]; then ONEDIR_REV="$1" + STABLE_REV="$1" shift elif [ "$(echo "$1" | grep -E '^([3-9][0-9]{3}(\.[0-9]*)?)')" != "" ]; then - ONEDIR_REV="minor/$1" + ONEDIR_REV="$1" + STABLE_REV="$1" shift else - echo "Unknown onedir version: $1 (valid: 3006, 3007, latest, nightly.)" + echo "Unknown onedir version: $1 (valid: 3006, 3007, latest), versions older than 3006 are not available" exit 1 fi fi elif [ "$ITYPE" = "onedir_rc" ]; then - # Change the _ONEDIR_DIR to be the location for the RC packages - _ONEDIR_DIR="salt_rc/salt" - - # Change ITYPE to onedir so we use the regular onedir functions - ITYPE="onedir" - - if [ "$#" -eq 0 ];then - ONEDIR_REV="latest" - else - if [ "$(echo "$1" | grep -E '^(latest)$')" != "" ]; then - ONEDIR_REV="$1" - shift - elif [ "$(echo "$1" | grep -E '^([3-9][0-9]{3}?rc[0-9]-[0-9]$)')" != "" ]; then - # Handle the 3xxx.0 version as 3xxx archive (pin to minor) and strip the fake ".0" suffix - #ONEDIR_REV=$(echo "$1" | sed -E 's/^([3-9][0-9]{3})\.0$/\1/') - ONEDIR_REV="minor/$1" - shift - elif [ "$(echo "$1" | grep -E '^([3-9][0-9]{3}\.[0-9]?rc[0-9]$)')" != "" ]; then - # Handle the 3xxx.0 version as 3xxx archive (pin to minor) and strip the fake ".0" suffix - #ONEDIR_REV=$(echo "$1" | sed -E 's/^([3-9][0-9]{3})\.0$/\1/') - ONEDIR_REV="minor/$1" - shift - else - echo "Unknown onedir_rc version: $1 (valid: 3006-8, 3007-1, latest)" - exit 1 - fi - fi + echoerror "RC Releases are not supported at this time" + +## # Change the _ONEDIR_DIR to be the location for the RC packages +## _ONEDIR_DIR="salt_rc/salt" +## +## # Change ITYPE to onedir so we use the regular onedir functions +## ITYPE="onedir" +## +## if [ "$#" -eq 0 ];then +## ONEDIR_REV="latest" +## else +## if [ "$(echo "$1" | grep -E '^(latest)$')" != "" ]; then +## ONEDIR_REV="$1" +## shift +## elif [ "$(echo "$1" | grep -E '^([3-9][0-9]{3}?rc[0-9]-[0-9]$)')" != "" ]; then +## # Handle the 3xxx.0 version as 3xxx archive (pin to minor) and strip the fake ".0" suffix +## #ONEDIR_REV=$(echo "$1" | sed -E 's/^([3-9][0-9]{3})\.0$/\1/') +## ## ONEDIR_REV="minor/$1" don't have minor directory anymore +## ONEDIR_REV="$1" +## shift +## elif [ "$(echo "$1" | grep -E '^([3-9][0-9]{3}\.[0-9]?rc[0-9]$)')" != "" ]; then +## # Handle the 3xxx.0 version as 3xxx archive (pin to minor) and strip the fake ".0" suffix +## #ONEDIR_REV=$(echo "$1" | sed -E 's/^([3-9][0-9]{3})\.0$/\1/') +## ## ONEDIR_REV="minor/$1" don't have minor directory anymore +## ONEDIR_REV="$1" +## shift +## else +## echo "Unknown onedir_rc version: $1 (valid: 3006-8, 3007-1, latest)" +## exit 1 +## fi +## fi fi # Doing a quick start, so install master @@ -760,7 +811,6 @@ fi PY_PKG_VER=3 _PY_PKG_VER="python3" _PY_MAJOR_VERSION="3" -__PY_VERSION_REPO="py3" # Check if we're installing via a different Python executable and set major version variables if [ -n "$_PY_EXE" ]; then @@ -811,7 +861,7 @@ if [ "$ITYPE" != "git" ]; then fi fi -# Set the _REPO_URL value based on if -R was passed or not. Defaults to repo.saltproject.io. +# Set the _REPO_URL value based on if -R was passed or not. Defaults to packages.broadcom.com/artifactory if [ "$_CUSTOM_REPO_URL" != "null" ]; then _REPO_URL="$_CUSTOM_REPO_URL" @@ -882,6 +932,7 @@ fi # DESCRIPTION: Retrieves a URL and writes it to a given path #---------------------------------------------------------------------------------------------------------------------- __fetch_url() { + # shellcheck disable=SC2086 curl $_CURL_ARGS -L -s -f -o "$1" "$2" >/dev/null 2>&1 || wget $_WGET_ARGS -q -O "$1" "$2" >/dev/null 2>&1 || @@ -896,6 +947,7 @@ __fetch_url() { # DESCRIPTION: Retrieves a URL, verifies its content and writes it to standard output #---------------------------------------------------------------------------------------------------------------------- __fetch_verify() { + fetch_verify_url="$1" fetch_verify_sum="$2" fetch_verify_size="$3" @@ -917,6 +969,7 @@ __fetch_verify() { # DESCRIPTION: Checks if a URL exists #---------------------------------------------------------------------------------------------------------------------- __check_url_exists() { + _URL="$1" if curl --output /dev/null --silent --fail "${_URL}"; then return 0 @@ -1340,8 +1393,6 @@ __check_dpkg_architecture() { return 1 fi - __REPO_ARCH="$DPKG_ARCHITECTURE" - __REPO_ARCH_DEB='deb [signed-by=/usr/share/keyrings/salt-archive-keyring.gpg]' __return_code=0 case $DPKG_ARCHITECTURE in @@ -1356,8 +1407,6 @@ __check_dpkg_architecture() { "arm64") # Saltstack official repository has full arm64 support since 3006 error_msg="" - __REPO_ARCH="arm64" - __REPO_ARCH_DEB="deb [signed-by=/usr/share/keyrings/salt-archive-keyring.gpg arch=$__REPO_ARCH]" ;; "armhf") error_msg="$_REPO_URL doesn't have packages for your system architecture: $DPKG_ARCHITECTURE." @@ -1888,6 +1937,7 @@ __function_defined() { # process is finished so the script doesn't exit on a locked proc. #---------------------------------------------------------------------------------------------------------------------- __wait_for_apt(){ + # Timeout set at 15 minutes WAIT_TIMEOUT=900 @@ -1925,6 +1975,7 @@ __wait_for_apt(){ # PARAMETERS: packages #---------------------------------------------------------------------------------------------------------------------- __apt_get_install_noinput() { + __wait_for_apt apt-get install -y -o DPkg::Options::=--force-confold "${@}"; return $? } # ---------- end of function __apt_get_install_noinput ---------- @@ -1934,6 +1985,7 @@ __apt_get_install_noinput() { # DESCRIPTION: (DRY) apt-get upgrade with noinput options #---------------------------------------------------------------------------------------------------------------------- __apt_get_upgrade_noinput() { + __wait_for_apt apt-get upgrade -y -o DPkg::Options::=--force-confold; return $? } # ---------- end of function __apt_get_upgrade_noinput ---------- @@ -1968,9 +2020,9 @@ __apt_key_fetch() { url=$1 tempfile="$(__temp_gpg_pub)" - __fetch_url "$tempfile" "$url" || return 1 - cp -f "$tempfile" /usr/share/keyrings/salt-archive-keyring.gpg && chmod 644 /usr/share/keyrings/salt-archive-keyring.gpg || return 1 + mkdir -p /etc/apt/keyrings + cp -f "$tempfile" /etc/apt/keyrings/salt-archive-keyring.pgp && chmod 644 /etc/apt/keyrings/salt-archive-keyring.pgp || return 1 rm -f "$tempfile" return 0 @@ -1983,6 +2035,7 @@ __apt_key_fetch() { # PARAMETERS: url #---------------------------------------------------------------------------------------------------------------------- __rpm_import_gpg() { + url=$1 tempfile="$(__temp_gpg_pub)" @@ -2006,6 +2059,7 @@ __rpm_import_gpg() { # DESCRIPTION: (DRY) yum install with noinput options #---------------------------------------------------------------------------------------------------------------------- __yum_install_noinput() { + if [ "$DISTRO_NAME_L" = "oracle_linux" ]; then # We need to install one package at a time because --enablerepo=X disables ALL OTHER REPOS!!!! for package in "${@}"; do @@ -2021,6 +2075,7 @@ __yum_install_noinput() { # DESCRIPTION: (DRY) dnf install with noinput options #---------------------------------------------------------------------------------------------------------------------- __dnf_install_noinput() { + dnf -y install "${@}" || return $? } # ---------- end of function __dnf_install_noinput ---------- @@ -2029,6 +2084,7 @@ __dnf_install_noinput() { # DESCRIPTION: (DRY) tdnf install with noinput options #---------------------------------------------------------------------------------------------------------------------- __tdnf_install_noinput() { + tdnf -y install "${@}" || return $? } # ---------- end of function __tdnf_install_noinput ---------- @@ -2037,13 +2093,21 @@ __tdnf_install_noinput() { # DESCRIPTION: (DRY) Helper function to clone and checkout salt to a # specific revision. #---------------------------------------------------------------------------------------------------------------------- +# shellcheck disable=SC2120 __git_clone_and_checkout() { + echodebug "Installed git version: $(git --version | awk '{ print $3 }')" # Turn off SSL verification if -I flag was set for insecure downloads if [ "$_INSECURE_DL" -eq $BS_TRUE ]; then export GIT_SSL_NO_VERIFY=1 fi + if [ "$(echo "$GIT_REV" | grep -E '^(3006|3007)$')" != "" ]; then + GIT_REV_ADJ="$GIT_REV.x" # branches are 3006.x or 3007.x + else + GIT_REV_ADJ="$GIT_REV" + fi + __SALT_GIT_CHECKOUT_PARENT_DIR=$(dirname "${_SALT_GIT_CHECKOUT_DIR}" 2>/dev/null) __SALT_GIT_CHECKOUT_PARENT_DIR="${__SALT_GIT_CHECKOUT_PARENT_DIR:-/tmp/git}" __SALT_CHECKOUT_REPONAME="$(basename "${_SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)" @@ -2072,15 +2136,15 @@ __git_clone_and_checkout() { git fetch --tags upstream fi - echodebug "Hard reseting the cloned repository to ${GIT_REV}" - git reset --hard "$GIT_REV" || return 1 + echodebug "Hard reseting the cloned repository to ${GIT_REV_ADJ}" + git reset --hard "$GIT_REV_ADJ" || return 1 - # Just calling `git reset --hard $GIT_REV` on a branch name that has + # Just calling `git reset --hard $GIT_REV_ADJ` on a branch name that has # already been checked out will not update that branch to the upstream # HEAD; instead it will simply reset to itself. Check the ref to see # if it is a branch name, check out the branch, and pull in the # changes. - if git branch -a | grep -q "${GIT_REV}"; then + if git branch -a | grep -q "${GIT_REV_ADJ}"; then echodebug "Rebasing the cloned repository branch" git pull --rebase || return 1 fi @@ -2102,14 +2166,14 @@ __git_clone_and_checkout() { # Test for "--filter" option introduced in git 2.19, the minimal version of git where the treeless # cloning we need actually works if [ "$(git clone 2>&1 | grep 'filter')" != "" ]; then - # The "--filter" option is supported, attempt treeless cloning - echoinfo "Attempting to shallow clone $GIT_REV from Salt's repository ${_SALT_REPO_URL}" - echodebug "git command, git clone --filter=tree:0 --branch $GIT_REV $_SALT_REPO_URL $__SALT_CHECKOUT_REPONAME" - if git clone --filter=tree:0 --branch "$GIT_REV" "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME"; then + # The "--filter" option is supported: attempt treeless cloning + echoinfo "Attempting to shallow clone $GIT_REV_ADJ from Salt's repository ${_SALT_REPO_URL}" + echodebug "git command, git clone --filter=tree:0 --branch $GIT_REV_ADJ $_SALT_REPO_URL $__SALT_CHECKOUT_REPONAME" + if git clone --filter=tree:0 --branch "$GIT_REV_ADJ" "$_SALT_REPO_URL" "$__SALT_CHECKOUT_REPONAME"; then # shellcheck disable=SC2164 cd "${_SALT_GIT_CHECKOUT_DIR}" __SHALLOW_CLONE=$BS_TRUE - echoinfo "shallow path git cloned $GIT_REV, version $(python3 salt/version.py)" + echoinfo "shallow path git cloned $GIT_REV_ADJ, version $(python3 salt/version.py)" else # Shallow clone above failed(missing upstream tags???), let's resume the old behaviour. echowarn "Failed to shallow clone." @@ -2128,7 +2192,7 @@ __git_clone_and_checkout() { # shellcheck disable=SC2164 cd "${_SALT_GIT_CHECKOUT_DIR}" - echoinfo "git cloned $GIT_REV, version $(python3 salt/version.py)" + echoinfo "git cloned $GIT_REV_ADJ, version $(python3 salt/version.py)" if ! echo "$_SALT_REPO_URL" | grep -q -F -w "${_SALTSTACK_REPO_URL#*://}"; then # We need to add the saltstack repository as a remote and fetch tags for proper versioning @@ -2138,14 +2202,14 @@ __git_clone_and_checkout() { echodebug "Fetching upstream (SaltStack's Salt repository) git tags" git fetch --tags upstream || return 1 - # Check if GIT_REV is a remote branch or just a commit hash - if git branch -r | grep -q -F -w "origin/$GIT_REV"; then - GIT_REV="origin/$GIT_REV" + # Check if GIT_REV_ADJ is a remote branch or just a commit hash + if git branch -r | grep -q -F -w "origin/$GIT_REV_ADJ"; then + GIT_REV_ADJ="origin/$GIT_REV_ADJ" fi fi - echodebug "Checking out $GIT_REV" - git checkout "$GIT_REV" || return 1 + echodebug "Checking out $GIT_REV_ADJ" + git checkout "$GIT_REV_ADJ" || return 1 fi fi @@ -2374,6 +2438,7 @@ __overwriteconfig() { # PARAMETERS: servicename #---------------------------------------------------------------------------------------------------------------------- __check_services_systemd() { + if [ $# -eq 0 ]; then echoerror "You need to pass a service name to check!" exit 1 @@ -2381,6 +2446,23 @@ __check_services_systemd() { echoerror "You need to pass a service name to check as the single argument to the function" fi + # check if systemd is functional, having systemctl present is insufficient + + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_FALSE ]; then + # already determined systemd is not functional, default is 1 + return 1 + fi + + _SYSTEMD_ACTIVE=$(/bin/systemctl daemon-reload 2>&1 | grep 'System has not been booted with systemd') + echodebug "__check_services_systemd _SYSTEMD_ACTIVE result ,$_SYSTEMD_ACTIVE," + if [ -n "$_SYSTEMD_ACTIVE" ]; then + _SYSTEMD_FUNCTIONAL=$BS_FALSE + echodebug "systemd is not functional, despite systemctl being present, setting _SYSTEMD_FUNCTIONAL false, $_SYSTEMD_FUNCTIONAL" + return 1 + else + echodebug "systemd is functional, _SYSTEMD_FUNCTIONAL true, $_SYSTEMD_FUNCTIONAL" + fi + servicename=$1 echodebug "Checking if service ${servicename} is enabled" @@ -2400,6 +2482,7 @@ __check_services_systemd() { # PARAMETERS: servicename #---------------------------------------------------------------------------------------------------------------------- __check_services_upstart() { + if [ $# -eq 0 ]; then echoerror "You need to pass a service name to check!" exit 1 @@ -2427,6 +2510,7 @@ __check_services_upstart() { # PARAMETERS: servicename #---------------------------------------------------------------------------------------------------------------------- __check_services_sysvinit() { + if [ $# -eq 0 ]; then echoerror "You need to pass a service name to check!" exit 1 @@ -2453,6 +2537,7 @@ __check_services_sysvinit() { # PARAMETERS: servicename #---------------------------------------------------------------------------------------------------------------------- __check_services_debian() { + if [ $# -eq 0 ]; then echoerror "You need to pass a service name to check!" exit 1 @@ -2480,6 +2565,7 @@ __check_services_debian() { # PARAMETERS: servicename #---------------------------------------------------------------------------------------------------------------------- __check_services_openrc() { + if [ $# -eq 0 ]; then echoerror "You need to pass a service name to check!" exit 1 @@ -2506,6 +2592,7 @@ __check_services_openrc() { # DESCRIPTION: Return 0 or 1 depending on successful creation of virtualenv #---------------------------------------------------------------------------------------------------------------------- __create_virtualenv() { + if [ ! -d "$_VIRTUALENV_DIR" ]; then echoinfo "Creating virtualenv ${_VIRTUALENV_DIR}" if [ "$_PIP_ALL" -eq $BS_TRUE ]; then @@ -2523,6 +2610,7 @@ __create_virtualenv() { # DESCRIPTION: Return 0 or 1 depending on successful activation of virtualenv #---------------------------------------------------------------------------------------------------------------------- __activate_virtualenv() { + set +o nounset # Is virtualenv empty if [ -z "$_VIRTUALENV_DIR" ]; then @@ -2543,6 +2631,7 @@ __activate_virtualenv() { #---------------------------------------------------------------------------------------------------------------------- __install_pip_pkgs() { + _pip_pkgs="$1" _py_exe="$2" _py_pkg=$(echo "$_py_exe" | sed -E "s/\\.//g") @@ -2564,8 +2653,10 @@ __install_pip_pkgs() { else __PACKAGES="${__PACKAGES} ${_py_pkg}-devel" if [ "$DISTRO_NAME_L" = "fedora" ];then + dnf makecache || return 1 __dnf_install_noinput ${__PACKAGES} || return 1 else + yum makecache || return 1 __yum_install_noinput ${__PACKAGES} || return 1 fi fi @@ -2584,6 +2675,7 @@ __install_pip_pkgs() { # PARAMETERS: requirements_file #---------------------------------------------------------------------------------------------------------------------- __install_pip_deps() { + # Install virtualenv to system pip before activating virtualenv if thats going to be used # We assume pip pkg is installed since that is distro specific if [ "$_VIRTUALENV_DIR" != "null" ]; then @@ -2620,6 +2712,7 @@ __install_pip_deps() { # PARAMETERS: py_exe #---------------------------------------------------------------------------------------------------------------------- __install_salt_from_repo() { + _py_exe="$1" if [ "${_py_exe}" = "" ]; then @@ -2647,44 +2740,6 @@ __install_salt_from_repo() { echodebug "Installed pip version: $(${_pip_cmd} --version)" - CHECK_PIP_VERSION_SCRIPT=$(cat << EOM -import sys -try: - import pip - installed_pip_version=tuple([int(part.strip()) for part in pip.__version__.split('.') if part.isdigit()]) - desired_pip_version=($(echo ${_MINIMUM_PIP_VERSION} | sed 's/\./, /g' )) - if installed_pip_version < desired_pip_version: - print('Desired pip version {!r} > Installed pip version {!r}'.format('.'.join(map(str, desired_pip_version)), '.'.join(map(str, installed_pip_version)))) - sys.exit(1) - print('Desired pip version {!r} < Installed pip version {!r}'.format('.'.join(map(str, desired_pip_version)), '.'.join(map(str, installed_pip_version)))) - sys.exit(0) -except ImportError: - print('Failed to import pip') - sys.exit(1) -EOM -) - if ! ${_py_exe} -c "$CHECK_PIP_VERSION_SCRIPT"; then - # Upgrade pip to at least 1.2 which is when we can start using "python3 -m pip" - echodebug "Running '${_pip_cmd} install ${_PIP_INSTALL_ARGS} pip>=${_MINIMUM_PIP_VERSION}'" - ${_pip_cmd} install ${_PIP_INSTALL_ARGS} -v "pip>=${_MINIMUM_PIP_VERSION}" - sleep 1 - echodebug "PATH: ${PATH}" - _pip_cmd="pip${_py_version}" - if ! __check_command_exists "${_pip_cmd}"; then - echodebug "The pip binary '${_pip_cmd}' was not found in PATH" - _pip_cmd="pip$(echo "${_py_version}" | cut -c -1)" - if ! __check_command_exists "${_pip_cmd}"; then - echodebug "The pip binary '${_pip_cmd}' was not found in PATH" - _pip_cmd="pip" - if ! __check_command_exists "${_pip_cmd}"; then - echoerror "Unable to find a pip binary" - return 1 - fi - fi - fi - echodebug "Installed pip version: $(${_pip_cmd} --version)" - fi - _setuptools_dep="setuptools>=${_MINIMUM_SETUPTOOLS_VERSION},<${_MAXIMUM_SETUPTOOLS_VERSION}" if [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" @@ -2707,25 +2762,37 @@ EOM mkdir -p /tmp/git/deps echodebug "Created directory /tmp/git/deps" - echodebug "Installing Salt dependencies for Salt version $(python3 salt/version.py)" if [ ${DISTRO_NAME_L} = "ubuntu" ] && [ "$DISTRO_MAJOR_VERSION" -eq 22 ]; then echodebug "Ubuntu 22.04 has problem with base.txt requirements file, not parsing sys_platform == 'win32', upgrading from default pip works" echodebug "${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --upgrade pip" - ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --upgrade pip || (echo "Failed to upgrade pip" && return 1) + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --upgrade pip + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + echo "Failed to upgrade pip" + return 1 + fi fi - echoinfo "Downloading Salt Dependencies from PyPi" - echodebug "Running '${_pip_cmd} download -d /tmp/git/deps ${_PIP_DOWNLOAD_ARGS} .'" - ${_pip_cmd} download -d /tmp/git/deps ${_PIP_DOWNLOAD_ARGS} . || (echo "Failed to download salt dependencies" && return 1) - - echoinfo "Installing Downloaded Salt Dependencies" - echodebug "Running '${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} /tmp/git/deps/*'" - ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} /tmp/git/deps/* || return 1 rm -f /tmp/git/deps/* - echoinfo "Building Salt Python Wheel" + echodebug "Installing Salt requirements from PyPi, ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} -r requirements/static/ci/py${_py_version}/linux.txt" + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} -r "requirements/static/ci/py${_py_version}/linux.txt" + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + echo "Failed to install salt requirements for the version of Python ${_py_version}" + return 1 + fi + if [ "${OS_NAME}" = "Linux" ]; then + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed --upgrade ${_PIP_INSTALL_ARGS} "jaraco.functools==4.1.0" || return 1 + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed --upgrade ${_PIP_INSTALL_ARGS} "jaraco.text==4.0.0" || return 1 + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed --upgrade ${_PIP_INSTALL_ARGS} "jaraco.collections==5.1.0" || return 1 + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed --upgrade ${_PIP_INSTALL_ARGS} "jaraco.context==6.0.1" || return 1 + ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed --upgrade ${_PIP_INSTALL_ARGS} "jaraco.classes==3.4.0" || return 1 + fi + + echoinfo "Building Salt Python Wheel" if [ "$_ECHO_DEBUG" -eq $BS_TRUE ]; then SETUP_PY_INSTALL_ARGS="-v" fi @@ -2783,6 +2850,7 @@ if [ "x${_PY_MAJOR_VERSION}" = "x" ]; then _PY_MAJOR_VERSION=3 fi + ####################################################################################################################### # # Distribution install functions @@ -2866,6 +2934,9 @@ fi # Ubuntu Install Functions # __enable_universe_repository() { + + echodebug "__enable_universe_repository() entry" + if [ "$(grep -R universe /etc/apt/sources.list /etc/apt/sources.list.d/ | grep -v '#')" != "" ]; then # The universe repository is already enabled return 0 @@ -2879,18 +2950,15 @@ __enable_universe_repository() { } __install_saltstack_ubuntu_repository() { + # Workaround for latest non-LTS Ubuntu echodebug "__install_saltstack_ubuntu_repository() entry" if { [ "$DISTRO_MAJOR_VERSION" -eq 20 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \ { [ "$DISTRO_MAJOR_VERSION" -eq 22 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \ - [ "$DISTRO_MAJOR_VERSION" -eq 21 ] || [ "$DISTRO_MAJOR_VERSION" -eq 23 ]; then + { [ "$DISTRO_MAJOR_VERSION" -eq 24 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \ + [ "$DISTRO_MAJOR_VERSION" -eq 21 ] || [ "$DISTRO_MAJOR_VERSION" -eq 23 ] || [ "$DISTRO_MAJOR_VERSION" -eq 25 ]; then echowarn "Non-LTS Ubuntu detected, but stable packages requested. Trying packages for previous LTS release. You may experience problems." - UBUNTU_VERSION=24.04 - UBUNTU_CODENAME="noble" - else - UBUNTU_VERSION=${DISTRO_VERSION} - UBUNTU_CODENAME=${DISTRO_CODENAME} fi # Install downloader backend for GPG keys fetching @@ -2920,24 +2988,34 @@ __install_saltstack_ubuntu_repository() { fi # SaltStack's stable Ubuntu repository: - SALTSTACK_UBUNTU_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/ubuntu/${UBUNTU_VERSION}/${__REPO_ARCH}/${STABLE_REV}" - echo "$__REPO_ARCH_DEB $SALTSTACK_UBUNTU_URL $UBUNTU_CODENAME main" > /etc/apt/sources.list.d/salt.list - __apt_key_fetch "$SALTSTACK_UBUNTU_URL/SALT-PROJECT-GPG-PUBKEY-2023.gpg" || return 1 - + __fetch_url "/etc/apt/sources.list.d/salt.sources" "https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources" + __apt_key_fetch "${HTTP_VAL}://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" || return 1 __wait_for_apt apt-get update || return 1 + + if [ "$STABLE_REV" != "latest" ]; then + # latest is default + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $STABLE_REV.*" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $STABLE_REV" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + fi + fi + } __install_saltstack_ubuntu_onedir_repository() { + + echodebug "__install_saltstack_ubuntu_onedir_repository() entry" + # Workaround for latest non-LTS Ubuntu if { [ "$DISTRO_MAJOR_VERSION" -eq 20 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \ { [ "$DISTRO_MAJOR_VERSION" -eq 22 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \ - [ "$DISTRO_MAJOR_VERSION" -eq 21 ] || [ "$DISTRO_MAJOR_VERSION" -eq 23 ]; then + [ "$DISTRO_MAJOR_VERSION" -eq 21 ] || [ "$DISTRO_MAJOR_VERSION" -eq 23 ] || [ "$DISTRO_MAJOR_VERSION" -eq 25 ]; then echowarn "Non-LTS Ubuntu detected, but stable packages requested. Trying packages for previous LTS release. You may experience problems." - UBUNTU_VERSION=24.04 - UBUNTU_CODENAME="noble" - else - UBUNTU_VERSION=${DISTRO_VERSION} - UBUNTU_CODENAME=${DISTRO_CODENAME} fi # Install downloader backend for GPG keys fetching @@ -2954,7 +3032,7 @@ __install_saltstack_ubuntu_onedir_repository() { fi ## include hwclock if not part of base OS (23.10 and up) - if [ ! -f /usr/sbin/hwclock ]; then + if [ "$DISTRO_MAJOR_VERSION" -ge 23 ] && [ ! -f /usr/sbin/hwclock ]; then __PACKAGES="${__PACKAGES} util-linux-extra" fi @@ -2962,18 +3040,28 @@ __install_saltstack_ubuntu_onedir_repository() { __apt_get_install_noinput ${__PACKAGES} || return 1 # SaltStack's stable Ubuntu repository: - SALTSTACK_UBUNTU_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/ubuntu/${UBUNTU_VERSION}/${__REPO_ARCH}/${ONEDIR_REV}/" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - SALTSTACK_UBUNTU_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/ubuntu/${UBUNTU_VERSION}/${__REPO_ARCH}/" - fi - echo "$__REPO_ARCH_DEB $SALTSTACK_UBUNTU_URL $UBUNTU_CODENAME main" > /etc/apt/sources.list.d/salt.list - - __apt_key_fetch "${SALTSTACK_UBUNTU_URL}SALT-PROJECT-GPG-PUBKEY-2023.gpg" || return 1 - + __fetch_url "/etc/apt/sources.list.d/salt.sources" "https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources" + __apt_key_fetch "${HTTP_VAL}://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" || return 1 __wait_for_apt apt-get update || return 1 + + if [ "$ONEDIR_REV" != "latest" ]; then + # latest is default + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $ONEDIR_REV.*" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $ONEDIR_REV_DOT" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + fi + fi } install_ubuntu_deps() { + + echodebug "install_ubuntu_deps() entry" if [ "$_DISABLE_REPOS" -eq $BS_FALSE ]; then # Install add-apt-repository if ! __check_command_exists add-apt-repository; then @@ -3012,6 +3100,9 @@ install_ubuntu_deps() { # Additionally install procps and pciutils which allows for Docker bootstraps. See 366#issuecomment-39666813 __PACKAGES="${__PACKAGES} procps pciutils" + # ensure sudo, ps installed + __PACKAGES="${__PACKAGES} sudo" + ## include hwclock if not part of base OS (23.10 and up) if [ ! -f /usr/sbin/hwclock ]; then __PACKAGES="${__PACKAGES} util-linux-extra" @@ -3030,6 +3121,7 @@ install_ubuntu_deps() { } install_ubuntu_stable_deps() { + echodebug "install_ubuntu_stable_deps() entry" if [ "$_START_DAEMONS" -eq $BS_FALSE ]; then @@ -3044,7 +3136,7 @@ install_ubuntu_stable_deps() { if [ "${_UPGRADE_SYS}" -eq $BS_TRUE ]; then if [ "${_INSECURE_DL}" -eq $BS_TRUE ]; then ## apt-key is deprecated - if [ "$DISTRO_MAJOR_VERSION" -ge 20 ] || [ "$DISTRO_MAJOR_VERSION" -ge 21 ] || [ "$DISTRO_MAJOR_VERSION" -ge 22 ] || [ "$DISTRO_MAJOR_VERSION" -ge 23 ] || [ "$DISTRO_MAJOR_VERSION" -ge 24 ]; then + if [ "$DISTRO_MAJOR_VERSION" -ge 20 ]; then __apt_get_install_noinput --allow-unauthenticated debian-archive-keyring && apt-get update || return 1 else __apt_get_install_noinput --allow-unauthenticated debian-archive-keyring && @@ -3064,6 +3156,7 @@ install_ubuntu_stable_deps() { } install_ubuntu_git_deps() { + echodebug "install_ubuntu_git_deps() entry" __wait_for_apt apt-get update || return 1 @@ -3076,6 +3169,7 @@ install_ubuntu_git_deps() { __apt_get_install_noinput ca-certificates fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then @@ -3093,6 +3187,9 @@ install_ubuntu_git_deps() { __PACKAGES="${__PACKAGES} util-linux-extra" fi + # Additionally install procps pciutils and sudo which allows for Docker bootstraps. See 366#issuecomment-39666813 + __PACKAGES="${__PACKAGES} procps pciutils sudo" + # shellcheck disable=SC2086 __apt_get_install_noinput ${__PACKAGES} || return 1 @@ -3106,6 +3203,7 @@ install_ubuntu_git_deps() { } install_ubuntu_onedir_deps() { + if [ "$_START_DAEMONS" -eq $BS_FALSE ]; then echowarn "Not starting daemons on Debian based distributions is not working mostly because starting them is the default behaviour." fi @@ -3118,7 +3216,7 @@ install_ubuntu_onedir_deps() { if [ "${_UPGRADE_SYS}" -eq $BS_TRUE ]; then if [ "${_INSECURE_DL}" -eq $BS_TRUE ]; then ## apt-key is deprecated - if [ "$DISTRO_MAJOR_VERSION" -ge 20 ] || [ "$DISTRO_MAJOR_VERSION" -ge 21 ] || [ "$DISTRO_MAJOR_VERSION" -ge 22 ] || [ "$DISTRO_MAJOR_VERSION" -ge 23 ] || [ "$DISTRO_MAJOR_VERSION" -ge 24 ]; then + if [ "$DISTRO_MAJOR_VERSION" -ge 20 ]; then __apt_get_install_noinput --allow-unauthenticated debian-archive-keyring && apt-get update || return 1 else __apt_get_install_noinput --allow-unauthenticated debian-archive-keyring && @@ -3138,6 +3236,9 @@ install_ubuntu_onedir_deps() { } install_ubuntu_stable() { + + __wait_for_apt apt-get update || return 1 + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then @@ -3164,6 +3265,7 @@ install_ubuntu_stable() { } install_ubuntu_git() { + # Activate virtualenv before install if [ "${_VIRTUALENV_DIR}" != "null" ]; then __activate_virtualenv || return 1 @@ -3193,6 +3295,9 @@ install_ubuntu_git() { } install_ubuntu_onedir() { + + __wait_for_apt apt-get update || return 1 + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then @@ -3219,6 +3324,7 @@ install_ubuntu_onedir() { } install_ubuntu_stable_post() { + for fname in api master minion syndic; do # Skip salt-api since the service should be opt-in and not necessarily started on boot [ $fname = "api" ] && continue @@ -3228,7 +3334,7 @@ install_ubuntu_stable_post() { [ $fname = "master" ] && [ "$_INSTALL_MASTER" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then # Using systemd /bin/systemctl is-enabled salt-$fname.service > /dev/null 2>&1 || ( /bin/systemctl preset salt-$fname.service > /dev/null 2>&1 && @@ -3245,6 +3351,7 @@ install_ubuntu_stable_post() { } install_ubuntu_git_post() { + for fname in api master minion syndic; do # Skip if not meant to be installed [ $fname = "api" ] && \ @@ -3260,7 +3367,7 @@ install_ubuntu_git_post() { _SERVICE_DIR="${_SALT_GIT_CHECKOUT_DIR}/pkg" fi - if [ -f /bin/systemctl ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then __copyfile "${_SERVICE_DIR}/salt-${fname}.service" "/lib/systemd/system/salt-${fname}.service" # Skip salt-api since the service should be opt-in and not necessarily started on boot @@ -3269,21 +3376,6 @@ install_ubuntu_git_post() { systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service) sleep 1 systemctl daemon-reload - elif [ -f /sbin/initctl ]; then - _upstart_conf="/etc/init/salt-$fname.conf" - # We have upstart support - echodebug "There's upstart support" - if [ ! -f $_upstart_conf ]; then - # upstart does not know about our service, let's copy the proper file - echowarn "Upstart does not appear to know about salt-$fname" - echodebug "Copying ${_SERVICE_DIR}/salt-$fname.upstart to $_upstart_conf" - __copyfile "${_SERVICE_DIR}/salt-${fname}.upstart" "$_upstart_conf" - # Set service to know about virtualenv - if [ "${_VIRTUALENV_DIR}" != "null" ]; then - echo "SALT_USE_VIRTUALENV=${_VIRTUALENV_DIR}" > /etc/default/salt-${fname} - fi - /sbin/initctl reload-configuration || return 1 - fi # No upstart support in Ubuntu!? elif [ -f "${_SALT_GIT_CHECKOUT_DIR}/pkg/salt-${fname}.init" ]; then echodebug "There's NO upstart support!?" @@ -3296,7 +3388,7 @@ install_ubuntu_git_post() { update-rc.d salt-$fname defaults else - echoerror "Neither upstart nor init.d was setup for salt-$fname" + echoerror "No init.d was setup for salt-$fname" fi done @@ -3304,13 +3396,12 @@ install_ubuntu_git_post() { } install_ubuntu_restart_daemons() { + [ "$_START_DAEMONS" -eq $BS_FALSE ] && return - # Ensure upstart configs / systemd units are loaded - if [ -f /bin/systemctl ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then + # Ensure systemd units are loaded + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then systemctl daemon-reload - elif [ -f /sbin/initctl ]; then - /sbin/initctl reload-configuration fi for fname in api master minion syndic; do @@ -3322,7 +3413,7 @@ install_ubuntu_restart_daemons() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then echodebug "There's systemd support while checking salt-$fname" systemctl stop salt-$fname > /dev/null 2>&1 systemctl start salt-$fname.service && continue @@ -3334,18 +3425,6 @@ install_ubuntu_restart_daemons() { fi fi - if [ -f /sbin/initctl ]; then - echodebug "There's upstart support while checking salt-$fname" - - if status salt-$fname 2>/dev/null | grep -q running; then - stop salt-$fname || (echodebug "Failed to stop salt-$fname" && return 1) - fi - - start salt-$fname && continue - # We failed to start the service, let's test the SysV code below - echodebug "Failed to start salt-$fname using Upstart" - fi - if [ ! -f /etc/init.d/salt-$fname ]; then echoerror "No init.d support for salt-$fname was found" return 1 @@ -3359,6 +3438,7 @@ install_ubuntu_restart_daemons() { } install_ubuntu_check_services() { + for fname in api master minion syndic; do # Skip salt-api since the service should be opt-in and not necessarily started on boot [ $fname = "api" ] && continue @@ -3368,7 +3448,7 @@ install_ubuntu_check_services() { [ $fname = "master" ] && [ "$_INSTALL_MASTER" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ] && [ "$DISTRO_MAJOR_VERSION" -ge 16 ]; then __check_services_systemd salt-$fname || return 1 elif [ -f /etc/init.d/salt-$fname ]; then __check_services_debian salt-$fname || return 1 @@ -3387,10 +3467,8 @@ install_ubuntu_check_services() { # Debian Install Functions # __install_saltstack_debian_repository() { - echodebug "__install_saltstack_debian_repository() entry" - DEBIAN_RELEASE="$DISTRO_MAJOR_VERSION" - DEBIAN_CODENAME="$DISTRO_CODENAME" + echodebug "__install_saltstack_debian_repository() entry" if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" @@ -3413,19 +3491,29 @@ __install_saltstack_debian_repository() { # shellcheck disable=SC2086,SC2090 __apt_get_install_noinput ${__PACKAGES} || return 1 - SALTSTACK_DEBIAN_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/debian/${DEBIAN_RELEASE}/${__REPO_ARCH}/${STABLE_REV}" - echo "$__REPO_ARCH_DEB $SALTSTACK_DEBIAN_URL $DEBIAN_CODENAME main" > "/etc/apt/sources.list.d/salt.list" - - __apt_key_fetch "$SALTSTACK_DEBIAN_URL/SALT-PROJECT-GPG-PUBKEY-2023.gpg" || return 1 - + __fetch_url "/etc/apt/sources.list.d/salt.sources" "https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources" + __apt_key_fetch "${HTTP_VAL}://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" || return 1 __wait_for_apt apt-get update || return 1 + + if [ "$STABLE_REV" != "latest" ]; then + # latest is default + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $STABLE_REV.*" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + STABLE_REV_DOT=$(echo "$STABLE_REV" | sed 's/-/\./') + MINOR_VER_STRG="-$STABLE_REV_DOT" + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $STABLE_REV_DOT" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + fi + fi } __install_saltstack_debian_onedir_repository() { - echodebug "__install_saltstack_debian_onedir_repository() entry" - DEBIAN_RELEASE="$DISTRO_MAJOR_VERSION" - DEBIAN_CODENAME="$DISTRO_CODENAME" + echodebug "__install_saltstack_debian_onedir_repository() entry" if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" @@ -3448,19 +3536,27 @@ __install_saltstack_debian_onedir_repository() { # shellcheck disable=SC2086,SC2090 __apt_get_install_noinput ${__PACKAGES} || return 1 - # amd64 is just a part of repository URI - SALTSTACK_DEBIAN_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/debian/${DEBIAN_RELEASE}/${__REPO_ARCH}/${ONEDIR_REV}" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - SALTSTACK_DEBIAN_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/debian/${DEBIAN_RELEASE}/${__REPO_ARCH}" - fi - echo "$__REPO_ARCH_DEB $SALTSTACK_DEBIAN_URL $DEBIAN_CODENAME main" > "/etc/apt/sources.list.d/salt.list" - - __apt_key_fetch "${SALTSTACK_DEBIAN_URL}/SALT-PROJECT-GPG-PUBKEY-2023.gpg" || return 1 - + __fetch_url "/etc/apt/sources.list.d/salt.sources" "https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources" + __apt_key_fetch "${HTTP_VAL}://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" || return 1 __wait_for_apt apt-get update || return 1 + + if [ "$ONEDIR_REV" != "latest" ]; then + # latest is default + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $ONEDIR_REV.*" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "Package: salt-*" > /etc/apt/preferences.d/salt-pin-1001 + echo "Pin: version $ONEDIR_REV_DOT" >> /etc/apt/preferences.d/salt-pin-1001 + echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/salt-pin-1001 + fi + fi } install_debian_onedir_deps() { + echodebug "install_debian_onedir_git_deps() entry" if [ "$_START_DAEMONS" -eq $BS_FALSE ]; then @@ -3491,8 +3587,8 @@ install_debian_onedir_deps() { return 1 fi - # Additionally install procps and pciutils which allows for Docker bootstraps. See 366#issuecomment-39666813 - __PACKAGES='procps pciutils' + # Additionally install procps, pciutils and sudo which allows for Docker bootstraps. See 366#issuecomment-39666813 + __PACKAGES='procps pciutils sudo' # YAML module is used for generating custom master/minion configs __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-yaml" @@ -3515,6 +3611,7 @@ install_debian_onedir_deps() { } install_debian_git_deps() { + echodebug "install_debian_git_deps() entry" __wait_for_apt apt-get update || return 1 @@ -3527,6 +3624,7 @@ install_debian_git_deps() { __apt_get_install_noinput ca-certificates fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then @@ -3537,6 +3635,9 @@ install_debian_git_deps() { __PACKAGES="python${PY_PKG_VER}-dev python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc" echodebug "install_debian_git_deps() Installing ${__PACKAGES}" + # Additionally install procps, pciutils and sudo which allows for Docker bootstraps. See 366#issuecomment-39666813 + __PACKAGES="${__PACKAGES} procps pciutils sudo" + # shellcheck disable=SC2086 __apt_get_install_noinput ${__PACKAGES} || return 1 @@ -3550,6 +3651,9 @@ install_debian_git_deps() { } install_debian_stable() { + + __wait_for_apt apt-get update || return 1 + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then @@ -3588,6 +3692,7 @@ install_debian_12_git_deps() { } install_debian_git() { + if [ -n "$_PY_EXE" ]; then _PYEXE=${_PY_EXE} else @@ -3615,16 +3720,21 @@ install_debian_git() { } install_debian_11_git() { + install_debian_git || return 1 return 0 } install_debian_12_git() { + install_debian_git || return 1 return 0 } install_debian_onedir() { + + __wait_for_apt apt-get update || return 1 + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then @@ -3651,6 +3761,7 @@ install_debian_onedir() { } install_debian_git_post() { + for fname in api master minion syndic; do # Skip if not meant to be installed [ "$fname" = "api" ] && \ @@ -3667,7 +3778,7 @@ install_debian_git_post() { fi # Configure SystemD for Debian 8 "Jessie" and later - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then if [ ! -f /lib/systemd/system/salt-${fname}.service ] || \ { [ -f /lib/systemd/system/salt-${fname}.service ] && [ $_FORCE_OVERWRITE -eq $BS_TRUE ]; }; then if [ -f "${_SERVICE_DIR}/salt-${fname}.service" ]; then @@ -3690,6 +3801,7 @@ install_debian_git_post() { } install_debian_2021_post() { + # Kali 2021 (debian derivative) disables all network services by default # Using archlinux post function to enable salt systemd services install_arch_linux_post || return 1 @@ -3697,6 +3809,7 @@ install_debian_2021_post() { } install_debian_restart_daemons() { + [ "$_START_DAEMONS" -eq $BS_FALSE ] && return 0 for fname in api master minion syndic; do @@ -3708,7 +3821,7 @@ install_debian_restart_daemons() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then # Debian 8 and above uses systemd /bin/systemctl stop salt-$fname > /dev/null 2>&1 /bin/systemctl start salt-$fname.service && continue @@ -3725,6 +3838,7 @@ install_debian_restart_daemons() { } install_debian_check_services() { + for fname in api master minion syndic; do # Skip salt-api since the service should be opt-in and not necessarily started on boot [ $fname = "api" ] && continue @@ -3734,7 +3848,7 @@ install_debian_check_services() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then __check_services_systemd salt-$fname || return 1 elif [ -f /etc/init.d/salt-$fname ]; then __check_services_debian salt-$fname || return 1 @@ -3753,43 +3867,57 @@ install_debian_check_services() { # __install_saltstack_fedora_onedir_repository() { - if [ "$ITYPE" = "stable" ]; then - REPO_REV="$ONEDIR_REV" - else - REPO_REV="latest" - fi if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" return 1 fi - __PY_VERSION_REPO="py3" - - GPG_KEY="SALT-PROJECT-GPG-PUBKEY-2023.pub" - - REPO_FILE="/etc/yum.repos.d/salt.repo" - - if [ ! -s "$REPO_FILE" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then - FETCH_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/fedora/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/${ONEDIR_REV}" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - FETCH_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/fedora/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/" + if [ ! -s "$YUM_REPO_FILE" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then + FETCH_URL="https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo" + __fetch_url "${YUM_REPO_FILE}" "${FETCH_URL}" + if [ "$ONEDIR_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$ONEDIR_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + dnf config-manager --set-disable salt-repo-* + dnf config-manager --set-enabled salt-repo-3007-sts + fi + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "[salt-repo-${ONEDIR_REV_DOT}-lts]" > "${YUM_REPO_FILE}" + # shellcheck disable=SC2129 + echo "name=Salt Repo for Salt v${ONEDIR_REV_DOT} LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + else + # Enable the Salt LATEST repo + dnf config-manager --set-disable salt-repo-* + dnf config-manager --set-enabled salt-repo-latest fi + dnf clean expire-cache || return 1 + dnf makecache || return 1 - __fetch_url "${REPO_FILE}" "${FETCH_URL}.repo" - - __rpm_import_gpg "${FETCH_URL}/${GPG_KEY}" || return 1 - - yum clean metadata || return 1 - elif [ "$REPO_REV" != "latest" ]; then + elif [ "$ONEDIR_REV" != "latest" ]; then echowarn "salt.repo already exists, ignoring salt version argument." - echowarn "Use -F (forced overwrite) to install $REPO_REV." + echowarn "Use -F (forced overwrite) to install $ONEDIR_REV." fi return 0 } install_fedora_deps() { + if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then dnf -y update || return 1 fi @@ -3808,7 +3936,7 @@ install_fedora_deps() { __PACKAGES="${__PACKAGES} dnf-utils libyaml procps-ng python${PY_PKG_VER}-crypto python${PY_PKG_VER}-jinja2" __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-msgpack python${PY_PKG_VER}-requests python${PY_PKG_VER}-zmq" __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-pip python${PY_PKG_VER}-m2crypto python${PY_PKG_VER}-pyyaml" - __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-systemd" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-systemd sudo" if [ "${_EXTRA_PACKAGES}" != "" ]; then echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}" fi @@ -3820,6 +3948,7 @@ install_fedora_deps() { } install_fedora_git_deps() { + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" return 1 @@ -3839,9 +3968,11 @@ install_fedora_git_deps() { __PACKAGES="" fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 - __PACKAGES="python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc gcc-c++" + __PACKAGES="python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc gcc-c++ sudo" + # shellcheck disable=SC2086 __dnf_install_noinput ${__PACKAGES} || return 1 @@ -3859,6 +3990,7 @@ install_fedora_git_deps() { } install_fedora_git() { + if [ "${_PY_EXE}" != "" ]; then _PYEXE=${_PY_EXE} echoinfo "Using the following python version: ${_PY_EXE} to install salt" @@ -3873,6 +4005,7 @@ install_fedora_git() { } install_fedora_git_post() { + for fname in api master minion syndic; do # Skip if not meant to be installed [ $fname = "api" ] && \ @@ -3900,10 +4033,12 @@ install_fedora_git_post() { systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service) sleep 1 systemctl daemon-reload + done } install_fedora_restart_daemons() { + [ $_START_DAEMONS -eq $BS_FALSE ] && return for fname in api master minion syndic; do @@ -3926,6 +4061,7 @@ install_fedora_restart_daemons() { } install_fedora_check_services() { + for fname in api master minion syndic; do # Skip salt-api since the service should be opt-in and not necessarily started on boot [ $fname = "api" ] && continue @@ -3942,6 +4078,7 @@ install_fedora_check_services() { } install_fedora_onedir_deps() { + if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then yum -y update || return 1 fi @@ -3963,7 +4100,7 @@ install_fedora_onedir_deps() { __install_saltstack_fedora_onedir_repository || return 1 fi - __PACKAGES="dnf-utils chkconfig procps-ng" + __PACKAGES="dnf-utils chkconfig procps-ng sudo" # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -3980,35 +4117,48 @@ install_fedora_onedir_deps() { install_fedora_onedir() { + STABLE_REV=$ONEDIR_REV #install_fedora_stable || return 1 + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # Major version Salt, config and repo already setup + MINOR_VER_STRG="" + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # Minor version Salt, need to add specific minor version + STABLE_REV_DOT=$(echo "$STABLE_REV" | sed 's/-/\./') + MINOR_VER_STRG="-$STABLE_REV_DOT" + else + MINOR_VER_STRG="" + fi __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-cloud" + __PACKAGES="${__PACKAGES} salt-cloud$MINOR_VER_STRG" fi if [ "$_INSTALL_MASTER" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-master" + __PACKAGES="${__PACKAGES} salt-master$MINOR_VER_STRG" fi if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-minion" + __PACKAGES="${__PACKAGES} salt-minion$MINOR_VER_STRG" fi if [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-syndic" + __PACKAGES="${__PACKAGES} salt-syndic$MINOR_VER_STRG" fi if [ "$_INSTALL_SALT_API" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-api" + __PACKAGES="${__PACKAGES} salt-api$MINOR_VER_STRG" fi # shellcheck disable=SC2086 + dnf makecache || return 1 __yum_install_noinput ${__PACKAGES} || return 1 return 0 } install_fedora_onedir_post() { + STABLE_REV=$ONEDIR_REV for fname in api master minion syndic; do @@ -4038,63 +4188,56 @@ install_fedora_onedir_post() { # CentOS Install Functions # __install_saltstack_rhel_onedir_repository() { - if [ "$ITYPE" = "stable" ]; then - repo_rev="$ONEDIR_REV" - else - repo_rev="latest" - fi if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" return 1 fi - # Avoid using '$releasever' variable for yum. - # Instead, this should work correctly on all RHEL variants. - base_url="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/redhat/${DISTRO_MAJOR_VERSION}/\$basearch/${ONEDIR_REV}/" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - base_url="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/redhat/${DISTRO_MAJOR_VERSION}/\$basearch/" - fi - - gpg_key="SALT-PROJECT-GPG-PUBKEY-2023.pub" - - gpg_key_urls="" - for key in $gpg_key; do - gpg_key_urls=$(printf "${base_url}${key},%s" "$gpg_key_urls") - done - - repo_file="/etc/yum.repos.d/salt.repo" - - if [ ! -s "$repo_file" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then - cat <<_eof > "$repo_file" -[saltstack] -name=SaltStack ${repo_rev} Release Channel for RHEL/CentOS \$releasever -baseurl=${base_url} -skip_if_unavailable=True -gpgcheck=1 -gpgkey=${gpg_key_urls} -enabled=1 -enabled_metadata=1 -_eof - - fetch_url="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/redhat/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/${ONEDIR_REV}/" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - fetch_url="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/redhat/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/" + if [ ! -s "$YUM_REPO_FILE" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then + FETCH_URL="https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo" + __fetch_url "${YUM_REPO_FILE}" "${FETCH_URL}" + if [ "$ONEDIR_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$ONEDIR_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + yum config-manager --set-disable salt-repo-* + yum config-manager --set-enabled salt-repo-3007-sts + fi + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "[salt-repo-${ONEDIR_REV_DOT}-lts]" > "${YUM_REPO_FILE}" + # shellcheck disable=SC2129 + echo "name=Salt Repo for Salt v${ONEDIR_REV_DOT} LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + else + # Enable the Salt LATEST repo + yum config-manager --set-disable salt-repo-* + yum config-manager --set-enabled salt-repo-latest fi - for key in $gpg_key; do - __rpm_import_gpg "${fetch_url}${key}" || return 1 - done - - yum clean metadata || return 1 - elif [ "$repo_rev" != "latest" ]; then + yum clean expire-cache || return 1 + yum makecache || return 1 + elif [ "$ONEDIR_REV" != "latest" ]; then echowarn "salt.repo already exists, ignoring salt version argument." - echowarn "Use -F (forced overwrite) to install $repo_rev." + echowarn "Use -F (forced overwrite) to install $ONEDIR_REV." fi return 0 } install_centos_stable_deps() { + if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then yum -y update || return 1 fi @@ -4117,7 +4260,7 @@ install_centos_stable_deps() { __install_saltstack_rhel_onedir_repository || return 1 fi - __PACKAGES="yum-utils chkconfig procps-ng findutils" + __PACKAGES="yum-utils chkconfig procps-ng findutils sudo" # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -4132,26 +4275,39 @@ install_centos_stable_deps() { } install_centos_stable() { + + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # Major version Salt, config and repo already setup + MINOR_VER_STRG="" + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # Minor version Salt, need to add specific minor version + STABLE_REV_DOT=$(echo "$STABLE_REV" | sed 's/-/\./') + MINOR_VER_STRG="-$STABLE_REV_DOT" + else + MINOR_VER_STRG="" + fi + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-cloud" + __PACKAGES="${__PACKAGES} salt-cloud$MINOR_VER_STRG" fi if [ "$_INSTALL_MASTER" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-master" + __PACKAGES="${__PACKAGES} salt-master$MINOR_VER_STRG" fi if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-minion" + __PACKAGES="${__PACKAGES} salt-minion$MINOR_VER_STRG" fi if [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-syndic" + __PACKAGES="${__PACKAGES} salt-syndic$MINOR_VER_STRG" fi if [ "$_INSTALL_SALT_API" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-api" + __PACKAGES="${__PACKAGES} salt-api$MINOR_VER_STRG" fi # shellcheck disable=SC2086 + yum makecache || return 1 __yum_install_noinput ${__PACKAGES} || return 1 # Workaround for 3.11 broken on CentOS Stream 8.x @@ -4165,6 +4321,7 @@ install_centos_stable() { } install_centos_stable_post() { + SYSTEMD_RELOAD=$BS_FALSE for fname in api master minion syndic; do @@ -4176,7 +4333,7 @@ install_centos_stable_post() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then /bin/systemctl is-enabled salt-${fname}.service > /dev/null 2>&1 || ( /bin/systemctl preset salt-${fname}.service > /dev/null 2>&1 && /bin/systemctl enable salt-${fname}.service > /dev/null 2>&1 @@ -4196,6 +4353,7 @@ install_centos_stable_post() { } install_centos_git_deps() { + # First try stable deps then fall back to onedir deps if that one fails # if we're installing on a Red Hat based host that doesn't have the classic # package repos available. @@ -4212,6 +4370,7 @@ install_centos_git_deps() { __yum_install_noinput git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 __PACKAGES="" @@ -4225,7 +4384,7 @@ install_centos_git_deps() { return 1 fi - __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc sudo" # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -4241,6 +4400,7 @@ install_centos_git_deps() { } install_centos_git() { + if [ "${_PY_EXE}" != "" ]; then _PYEXE=${_PY_EXE} echoinfo "Using the following python version: ${_PY_EXE} to install salt" @@ -4256,6 +4416,7 @@ install_centos_git() { } install_centos_git_post() { + SYSTEMD_RELOAD=$BS_FALSE for fname in api master minion syndic; do @@ -4272,7 +4433,8 @@ install_centos_git_post() { else _SERVICE_FILE="${_SALT_GIT_CHECKOUT_DIR}/pkg/rpm/salt-${fname}.service" fi - if [ -f /bin/systemctl ]; then + + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then if [ ! -f "/usr/lib/systemd/system/salt-${fname}.service" ] || \ { [ -f "/usr/lib/systemd/system/salt-${fname}.service" ] && [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; }; then __copyfile "${_SERVICE_FILE}" /usr/lib/systemd/system @@ -4296,6 +4458,7 @@ install_centos_git_post() { } install_centos_onedir_deps() { + if [ "$_UPGRADE_SYS" -eq "$BS_TRUE" ]; then yum -y update || return 1 fi @@ -4317,7 +4480,7 @@ install_centos_onedir_deps() { __install_saltstack_rhel_onedir_repository || return 1 fi - __PACKAGES="yum-utils chkconfig procps-ng findutils" + __PACKAGES="yum-utils chkconfig procps-ng findutils sudo" # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -4332,32 +4495,47 @@ install_centos_onedir_deps() { } install_centos_onedir() { + + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # Major version Salt, config and repo already setup + MINOR_VER_STRG="" + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # Minor version Salt, need to add specific minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + MINOR_VER_STRG="-$ONEDIR_REV_DOT" + else + MINOR_VER_STRG="" + fi + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-cloud" + __PACKAGES="${__PACKAGES} salt-cloud$MINOR_VER_STRG" fi if [ "$_INSTALL_MASTER" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-master" + __PACKAGES="${__PACKAGES} salt-master$MINOR_VER_STRG" fi if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-minion" + __PACKAGES="${__PACKAGES} salt-minion$MINOR_VER_STRG" fi if [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-syndic" + __PACKAGES="${__PACKAGES} salt-syndic$MINOR_VER_STRG" fi if [ "$_INSTALL_SALT_API" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-api" + __PACKAGES="${__PACKAGES} salt-api$MINOR_VER_STRG" fi # shellcheck disable=SC2086 + yum makecache || return 1 + yum list salt-minion || return 1 __yum_install_noinput ${__PACKAGES} || return 1 return 0 } install_centos_onedir_post() { + SYSTEMD_RELOAD=$BS_FALSE for fname in api master minion syndic; do @@ -4369,7 +4547,7 @@ install_centos_onedir_post() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then /bin/systemctl is-enabled salt-${fname}.service > /dev/null 2>&1 || ( /bin/systemctl preset salt-${fname}.service > /dev/null 2>&1 && /bin/systemctl enable salt-${fname}.service > /dev/null 2>&1 @@ -4389,6 +4567,7 @@ install_centos_onedir_post() { } install_centos_restart_daemons() { + [ "$_START_DAEMONS" -eq $BS_FALSE ] && return for fname in api master minion syndic; do @@ -4400,26 +4579,11 @@ install_centos_restart_daemons() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /sbin/initctl ] && [ -f /etc/init/salt-${fname}.conf ]; then - # We have upstart support and upstart knows about our service - if ! /sbin/initctl status salt-$fname > /dev/null 2>&1; then - # Everything is in place and upstart gave us an error code? Fail! - return 1 - fi - - # upstart knows about this service. - # Let's try to stop it, and then start it - /sbin/initctl stop salt-$fname > /dev/null 2>&1 - # Restart service - if ! /sbin/initctl start salt-$fname > /dev/null 2>&1; then - # Failed the restart?! - return 1 - fi - elif [ -f /etc/init.d/salt-$fname ]; then + if [ -f /etc/init.d/salt-$fname ]; then # Disable stdin to fix shell session hang on killing tee pipe service salt-$fname stop < /dev/null > /dev/null 2>&1 service salt-$fname start < /dev/null - elif [ -f /usr/bin/systemctl ]; then + elif [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then # CentOS 7 uses systemd /usr/bin/systemctl stop salt-$fname > /dev/null 2>&1 /usr/bin/systemctl start salt-$fname.service && continue @@ -4433,21 +4597,25 @@ install_centos_restart_daemons() { } install_centos_testing_deps() { + install_centos_stable_deps || return 1 return 0 } install_centos_testing() { + install_centos_stable || return 1 return 0 } install_centos_testing_post() { + install_centos_stable_post || return 1 return 0 } install_centos_check_services() { + for fname in api master minion syndic; do # Skip salt-api since the service should be opt-in and not necessarily started on boot [ $fname = "api" ] && continue @@ -4459,7 +4627,7 @@ install_centos_check_services() { if [ -f "/etc/init.d/salt-$fname" ]; then __check_services_sysvinit "salt-$fname" || return 1 - elif [ -f /usr/bin/systemctl ]; then + elif [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then __check_services_systemd "salt-$fname" || return 1 fi done @@ -4476,286 +4644,343 @@ install_centos_check_services() { # RedHat Install Functions # install_red_hat_linux_stable_deps() { + install_centos_stable_deps || return 1 return 0 } install_red_hat_linux_git_deps() { + install_centos_git_deps || return 1 return 0 } install_red_hat_linux_onedir_deps() { + install_centos_onedir_deps || return 1 return 0 } install_red_hat_enterprise_stable_deps() { + install_red_hat_linux_stable_deps || return 1 return 0 } install_red_hat_enterprise_git_deps() { + install_red_hat_linux_git_deps || return 1 return 0 } install_red_hat_enterprise_onedir_deps() { + install_red_hat_linux_onedir_deps || return 1 return 0 } install_red_hat_enterprise_linux_stable_deps() { + install_red_hat_linux_stable_deps || return 1 return 0 } install_red_hat_enterprise_linux_git_deps() { + install_red_hat_linux_git_deps || return 1 return 0 } install_red_hat_enterprise_linux_onedir_deps() { + install_red_hat_linux_onedir_deps || return 1 return 0 } install_red_hat_enterprise_server_stable_deps() { + install_red_hat_linux_stable_deps || return 1 return 0 } install_red_hat_enterprise_server_git_deps() { + install_red_hat_linux_git_deps || return 1 return 0 } install_red_hat_enterprise_server_onedir_deps() { + install_red_hat_linux_onedir_deps || return 1 return 0 } install_red_hat_enterprise_workstation_stable_deps() { + install_red_hat_linux_stable_deps || return 1 return 0 } install_red_hat_enterprise_workstation_git_deps() { + install_red_hat_linux_git_deps || return 1 return 0 } install_red_hat_enterprise_workstation_onedir_deps() { + install_red_hat_linux_timat_deps || return 1 return 0 } install_red_hat_linux_stable() { + install_centos_stable || return 1 return 0 } install_red_hat_linux_git() { + install_centos_git || return 1 return 0 } install_red_hat_linux_onedir() { + install_centos_onedir || return 1 return 0 } install_red_hat_enterprise_stable() { + install_red_hat_linux_stable || return 1 return 0 } install_red_hat_enterprise_git() { + install_red_hat_linux_git || return 1 return 0 } install_red_hat_enterprise_onedir() { + install_red_hat_linux_onedir || return 1 return 0 } install_red_hat_enterprise_linux_stable() { + install_red_hat_linux_stable || return 1 return 0 } install_red_hat_enterprise_linux_git() { + install_red_hat_linux_git || return 1 return 0 } install_red_hat_enterprise_linux_onedir() { + install_red_hat_linux_onedir || return 1 return 0 } install_red_hat_enterprise_server_stable() { + install_red_hat_linux_stable || return 1 return 0 } install_red_hat_enterprise_server_git() { + install_red_hat_linux_git || return 1 return 0 } install_red_hat_enterprise_server_onedir() { + install_red_hat_linux_onedir || return 1 return 0 } install_red_hat_enterprise_workstation_stable() { + install_red_hat_linux_stable || return 1 return 0 } install_red_hat_enterprise_workstation_git() { + install_red_hat_linux_git || return 1 return 0 } install_red_hat_enterprise_workstation_onedir() { + install_red_hat_linux_onedir || return 1 return 0 } install_red_hat_linux_stable_post() { + install_centos_stable_post || return 1 return 0 } install_red_hat_linux_restart_daemons() { + install_centos_restart_daemons || return 1 return 0 } install_red_hat_linux_git_post() { + install_centos_git_post || return 1 return 0 } install_red_hat_enterprise_stable_post() { + install_red_hat_linux_stable_post || return 1 return 0 } install_red_hat_enterprise_restart_daemons() { + install_red_hat_linux_restart_daemons || return 1 return 0 } install_red_hat_enterprise_git_post() { + install_red_hat_linux_git_post || return 1 return 0 } install_red_hat_enterprise_linux_stable_post() { + install_red_hat_linux_stable_post || return 1 return 0 } install_red_hat_enterprise_linux_restart_daemons() { + install_red_hat_linux_restart_daemons || return 1 return 0 } install_red_hat_enterprise_linux_git_post() { + install_red_hat_linux_git_post || return 1 return 0 } install_red_hat_enterprise_server_stable_post() { + install_red_hat_linux_stable_post || return 1 return 0 } install_red_hat_enterprise_server_restart_daemons() { + install_red_hat_linux_restart_daemons || return 1 return 0 } install_red_hat_enterprise_server_git_post() { + install_red_hat_linux_git_post || return 1 return 0 } install_red_hat_enterprise_workstation_stable_post() { + install_red_hat_linux_stable_post || return 1 return 0 } install_red_hat_enterprise_workstation_restart_daemons() { + install_red_hat_linux_restart_daemons || return 1 return 0 } install_red_hat_enterprise_workstation_git_post() { + install_red_hat_linux_git_post || return 1 return 0 } install_red_hat_linux_testing_deps() { + install_centos_testing_deps || return 1 return 0 } install_red_hat_linux_testing() { + install_centos_testing || return 1 return 0 } install_red_hat_linux_testing_post() { + install_centos_testing_post || return 1 return 0 } install_red_hat_enterprise_testing_deps() { + install_centos_testing_deps || return 1 return 0 } install_red_hat_enterprise_testing() { + install_centos_testing || return 1 return 0 } install_red_hat_enterprise_testing_post() { + install_centos_testing_post || return 1 return 0 } install_red_hat_enterprise_server_testing_deps() { + install_centos_testing_deps || return 1 return 0 } install_red_hat_enterprise_server_testing() { + install_centos_testing || return 1 return 0 } install_red_hat_enterprise_server_testing_post() { + install_centos_testing_post || return 1 return 0 } install_red_hat_enterprise_workstation_testing_deps() { + install_centos_testing_deps || return 1 return 0 } install_red_hat_enterprise_workstation_testing() { + install_centos_testing || return 1 return 0 } install_red_hat_enterprise_workstation_testing_post() { + install_centos_testing_post || return 1 return 0 } @@ -4769,6 +4994,7 @@ install_red_hat_enterprise_workstation_testing_post() { # Oracle Linux Install Functions # install_oracle_linux_stable_deps() { + # Install Oracle's EPEL. if [ "${_EPEL_REPOS_INSTALLED}" -eq $BS_FALSE ]; then _EPEL_REPO=oracle-epel-release-el${DISTRO_MAJOR_VERSION} @@ -4854,7 +5080,7 @@ install_oracle_linux_check_services() { ####################################################################################################################### # -# AlmaLinux Install Functions +# ALmaLinux Install Functions # install_almalinux_stable_deps() { install_centos_stable_deps || return 1 @@ -5185,6 +5411,7 @@ install_alpine_linux_git_deps() { apk -U add git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 apk -U add python3 python3-dev py3-pip py3-setuptools g++ linux-headers zeromq-dev openrc || return 1 @@ -5351,9 +5578,10 @@ install_amazon_linux_ami_2_git_deps() { __yum_install_noinput git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 - __PACKAGES="python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools python${PY_PKG_VER}-devel gcc" + __PACKAGES="python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools python${PY_PKG_VER}-devel gcc sudo" # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -5373,15 +5601,11 @@ install_amazon_linux_ami_2_deps() { return 1 fi - if [ "$ITYPE" = "stable" ]; then - repo_rev="$STABLE_REV" - else - repo_rev="latest" - fi - # We need to install yum-utils before doing anything else when installing on # Amazon Linux ECS-optimized images. See issue #974. - __yum_install_noinput yum-utils + __PACKAGES="yum-utils sudo" + + __yum_install_noinput ${__PACKAGES} # Do upgrade early if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then @@ -5389,30 +5613,69 @@ install_amazon_linux_ami_2_deps() { fi if [ $_DISABLE_REPOS -eq $BS_FALSE ] || [ "$_CUSTOM_REPO_URL" != "null" ]; then - __REPO_FILENAME="salt.repo" - PY_PKG_VER=3 - __PY_VERSION_REPO="py3" - repo_label="saltstack-py3-repo" - repo_name="SaltStack Python 3 repo for Amazon Linux 2" - - base_url="$HTTP_VAL://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/amazon/2/\$basearch/$repo_rev/" - gpg_key="${base_url}SALT-PROJECT-GPG-PUBKEY-2023.gpg" - - # This should prob be refactored to use __install_saltstack_rhel_onedir_repository() - # With args passed in to do the right thing. Reformatted to be more like the - # amazon linux yum file. - if [ ! -s "/etc/yum.repos.d/${__REPO_FILENAME}" ]; then - cat <<_eof > "/etc/yum.repos.d/${__REPO_FILENAME}" -[$repo_label] -name=$repo_name -failovermethod=priority -priority=10 -gpgcheck=1 -gpgkey=$gpg_key -baseurl=$base_url -_eof + if [ ! -s "${YUM_REPO_FILE}" ]; then + ## Amazon Linux yum (v3) doesn't support config-manager + ## FETCH_URL="https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo" + ## __fetch_url "${YUM_REPO_FILE}" "${FETCH_URL}" + # shellcheck disable=SC2129 + if [ "$STABLE_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$STABLE_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + echo "[salt-repo-3007-sts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3007 STS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3006* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + else + # Salt 3006 repo + echo "[salt-repo-3006-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3006 LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3007* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + STABLE_REV_DOT=$(echo "$STABLE_REV" | sed 's/-/\./') + echo "[salt-repo-${STABLE_REV_DOT}-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v${STABLE_REV_DOT} LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + else + # Enable the Salt LATEST repo + echo "[salt-repo-latest]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt LATEST release" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + yum clean expire-cache || return 1 + yum makecache || return 1 fi - fi if [ "${_EXTRA_PACKAGES}" != "" ]; then @@ -5428,15 +5691,11 @@ install_amazon_linux_ami_2_onedir_deps() { return 1 fi - if [ "$ITYPE" = "onedir" ]; then - repo_rev="$ONEDIR_REV" - else - repo_rev="latest" - fi - # We need to install yum-utils before doing anything else when installing on # Amazon Linux ECS-optimized images. See issue #974. - __yum_install_noinput yum-utils + __PACKAGES="yum-utils chkconfig procps-ng findutils sudo" + + __yum_install_noinput ${__PACKAGES} # Do upgrade early if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then @@ -5444,33 +5703,70 @@ install_amazon_linux_ami_2_onedir_deps() { fi if [ $_DISABLE_REPOS -eq $BS_FALSE ] || [ "$_CUSTOM_REPO_URL" != "null" ]; then - __REPO_FILENAME="salt.repo" - __PY_VERSION_REPO="py3" - PY_PKG_VER=3 - repo_label="saltstack-py3-repo" - repo_name="SaltStack Python 3 repo for Amazon Linux 2" - fi - - base_url="$HTTP_VAL://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/amazon/2/\$basearch/$repo_rev/" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - base_url="$HTTP_VAL://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/amazon/2/\$basearch/" - fi - - gpg_key="${base_url}SALT-PROJECT-GPG-PUBKEY-2023.pub" - - # With args passed in to do the right thing. Reformatted to be more like the - # amazon linux yum file. - if [ ! -s "/etc/yum.repos.d/${__REPO_FILENAME}" ]; then - cat <<_eof > "/etc/yum.repos.d/${__REPO_FILENAME}" -[$repo_label] -name=$repo_name -failovermethod=priority -priority=10 -gpgcheck=1 -gpgkey=$gpg_key -baseurl=$base_url -_eof + if [ ! -s "${YUM_REPO_FILE}" ]; then + ## Amazon Linux yum (v3) doesn't support config-manager + ## FETCH_URL="https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo" + ## __fetch_url "${YUM_REPO_FILE}" "${FETCH_URL}" + # shellcheck disable=SC2129 + if [ "$ONEDIR_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$ONEDIR_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + echo "[salt-repo-3007-sts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3007 STS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3006* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + else + # Salt 3006 repo + echo "[salt-repo-3006-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3006 LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3007* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "[salt-repo-${ONEDIR_REV_DOT}-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v${ONEDIR_REV_DOT} LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + else + # Enable the Salt LATEST repo + echo "[salt-repo-latest]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt LATEST release" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + yum clean expire-cache || return 1 + yum makecache || return 1 fi + fi if [ "${_EXTRA_PACKAGES}" != "" ]; then echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}" @@ -5551,9 +5847,10 @@ install_amazon_linux_ami_2023_git_deps() { __yum_install_noinput git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 - __PACKAGES="python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools python${PY_PKG_VER}-devel gcc" + __PACKAGES="python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools python${PY_PKG_VER}-devel gcc sudo" # shellcheck disable=SC2086 __yum_install_noinput ${__PACKAGES} || return 1 @@ -5567,49 +5864,89 @@ install_amazon_linux_ami_2023_git_deps() { return 0 } +install_amazon_linux_ami_2023_deps() { + + # Set ONEDIR_REV to STABLE_REV + ONEDIR_REV=${STABLE_REV} + install_amazon_linux_ami_2023_onedir_deps || return 1 +} + install_amazon_linux_ami_2023_onedir_deps() { - if [ "$ITYPE" = "onedir" ]; then - repo_rev="$ONEDIR_REV" - else - repo_rev="latest" - fi # We need to install yum-utils before doing anything else when installing on # Amazon Linux ECS-optimized images. See issue #974. - __yum_install_noinput yum-utils + __PACKAGES="yum-utils chkconfig procps-ng findutils sudo" + + __yum_install_noinput ${__PACKAGES} # Do upgrade early if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then yum -y update || return 1 fi - if [ "$_DISABLE_REPOS" -eq $BS_FALSE ] || [ "$_CUSTOM_REPO_URL" != "null" ]; then - __REPO_FILENAME="salt.repo" - __PY_VERSION_REPO="py3" - PY_PKG_VER=3 - repo_label="saltstack-py3-repo" - repo_name="SaltStack Python 3 repo for Amazon Linux 2023" - - base_url="$HTTP_VAL://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/amazon/2023/\$basearch/$repo_rev/" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - base_url="$HTTP_VAL://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/amazon/2023/\$basearch/" - fi - - gpg_key="${base_url}SALT-PROJECT-GPG-PUBKEY-2023.pub" - - # This should prob be refactored to use __install_saltstack_rhel_onedir_repository() - # With args passed in to do the right thing. Reformatted to be more like the - # amazon linux yum file. - if [ ! -s "/etc/yum.repos.d/${__REPO_FILENAME}" ]; then - cat <<_eof > "/etc/yum.repos.d/${__REPO_FILENAME}" -[$repo_label] -name=$repo_name -failovermethod=priority -priority=10 -gpgcheck=1 -gpgkey=$gpg_key -baseurl=$base_url -_eof + if [ $_DISABLE_REPOS -eq $BS_FALSE ] || [ "$_CUSTOM_REPO_URL" != "null" ]; then + if [ ! -s "${YUM_REPO_FILE}" ]; then + ## Amazon Linux yum (v3) doesn't support config-manager + ## FETCH_URL="https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo" + ## __fetch_url "${YUM_REPO_FILE}" "${FETCH_URL}" + # shellcheck disable=SC2129 + if [ "$ONEDIR_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$ONEDIR_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + echo "[salt-repo-3007-sts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3007 STS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3006* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + else + # Salt 3006 repo + echo "[salt-repo-3006-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3006 LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3007* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "[salt-repo-${ONEDIR_REV_DOT}-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v${ONEDIR_REV_DOT} LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + else + # Enable the Salt LATEST repo + echo "[salt-repo-latest]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt LATEST release" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + yum clean expire-cache || return 1 + yum makecache || return 1 fi fi @@ -5728,6 +6065,7 @@ install_arch_linux_git_deps() { pacman -Sy --noconfirm --needed git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -eq 2 ]; then @@ -5805,7 +6143,7 @@ install_arch_linux_post() { # Skip salt-api since the service should be opt-in and not necessarily started on boot [ $fname = "api" ] && continue - if [ -f /usr/bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then # Using systemd /usr/bin/systemctl is-enabled salt-$fname.service > /dev/null 2>&1 || ( /usr/bin/systemctl preset salt-$fname.service > /dev/null 2>&1 && @@ -5836,7 +6174,7 @@ install_arch_linux_git_post() { _SERVICE_DIR="${_SALT_GIT_CHECKOUT_DIR}/pkg/rpm" fi - if [ -f /usr/bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then __copyfile "${_SERVICE_DIR}/salt-${fname}.service" "/lib/systemd/system/salt-${fname}.service" # Skip salt-api since the service should be opt-in and not necessarily started on boot @@ -5869,7 +6207,7 @@ install_arch_linux_restart_daemons() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /usr/bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then /usr/bin/systemctl stop salt-$fname.service > /dev/null 2>&1 /usr/bin/systemctl start salt-$fname.service && continue echodebug "Failed to start salt-$fname using systemd" @@ -5885,7 +6223,7 @@ install_arch_linux_restart_daemons() { } install_arch_check_services() { - if [ ! -f /usr/bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then # Not running systemd!? Don't check! return 0 fi @@ -5926,40 +6264,113 @@ install_arch_linux_onedir_post() { # Photon OS Install Functions # -__install_saltstack_photon_onedir_repository() { - echodebug "__install_saltstack_photon_onedir_repository() entry" +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: __rpm_get_packagesite_onedir_latest +# DESCRIPTION: Set _GENERIC_PKG_VERSION to the latest for RPM or latest for major version input +#---------------------------------------------------------------------------------------------------------------------- +__get_packagesite_onedir_latest() { - if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then - echoerror "Python version is no longer supported, only Python 3" - return 1 - fi + echodebug "Find latest rpm release from repository" + + # get dir listing from url, sort and pick highest + generic_versions_tmpdir=$(mktemp -d) + curr_pwd=$(pwd) + cd ${generic_versions_tmpdir} || return 1 - if [ "$ITYPE" = "stable" ]; then - REPO_REV="$ONEDIR_REV" + # leverage the windows directories since release Windows and Linux + wget -q -r -np -nH --exclude-directories=onedir,relenv,macos -x -l 1 "https://${_REPO_URL}/saltproject-generic/windows/" + if [ "$#" -gt 0 ] && [ -n "$1" ]; then + MAJOR_VER="$1" + # shellcheck disable=SC2010 + _GENERIC_PKG_VERSION=$(ls artifactory/saltproject-generic/windows/ | grep -v 'index.html' | sort -V -u | grep -E "$MAJOR_VER" | tail -n 1) else - REPO_REV="latest" + # shellcheck disable=SC2010 + _GENERIC_PKG_VERSION=$(ls artifactory/saltproject-generic/windows/ | grep -v 'index.html' | sort -V -u | tail -n 1) fi + cd ${curr_pwd} || return "${_GENERIC_PKG_VERSION}" + rm -fR ${generic_versions_tmpdir} - __PY_VERSION_REPO="py3" - REPO_FILE="/etc/yum.repos.d/salt.repo" + echodebug "latest rpm release from repository found ${_GENERIC_PKG_VERSION}" - if [ ! -s "$REPO_FILE" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then - ## salt repo 4 & 5 have issues, need the Major version dot Zero, eg: 4.0, 5.0 - FETCH_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/photon/${DISTRO_MAJOR_VERSION}.0/${CPU_ARCH_L}/${ONEDIR_REV}" - if [ "${ONEDIR_REV}" = "nightly" ] ; then - FETCH_URL="${HTTP_VAL}://${_REPO_URL}/${_ONEDIR_NIGHTLY_DIR}/${__PY_VERSION_REPO}/photon/${DISTRO_MAJOR_VERSION}.0/${CPU_ARCH_L}/" - fi +} - __fetch_url "${REPO_FILE}" "${FETCH_URL}.repo" - GPG_KEY="SALT-PROJECT-GPG-PUBKEY-2023.pub" +__install_saltstack_photon_onedir_repository() { + echodebug "__install_saltstack_photon_onedir_repository() entry" - __rpm_import_gpg "${FETCH_URL}/${GPG_KEY}" || return 1 + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then + echoerror "Python version is no longer supported, only Python 3" + return 1 + fi + if [ ! -s "$YUM_REPO_FILE" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then + ## Photon tdnf doesn't support config-manager + ## FETCH_URL="https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo" + ## __fetch_url "${YUM_REPO_FILE}" "${FETCH_URL}" + # shellcheck disable=SC2129 + if [ "$ONEDIR_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$ONEDIR_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + ## tdnf config-manager --set-disable salt-repo-* + ## tdnf config-manager --set-enabled salt-repo-3007-sts + echo "[salt-repo-3007-sts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3007 STS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3006* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + else + # Salt 3006 repo + echo "[salt-repo-3006-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v3006 LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "exclude=*3007* *3008* *3009* *3010*" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "[salt-repo-${ONEDIR_REV_DOT}-lts]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt v${ONEDIR_REV_DOT} LTS" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi + else + # Enable the Salt LATEST repo + ## tdnf config-manager --set-disable salt-repo-* + ## tdnf config-manager --set-enabled salt-repo-latest + echo "[salt-repo-latest]" > "${YUM_REPO_FILE}" + echo "name=Salt Repo for Salt LATEST release" >> "${YUM_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${YUM_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${YUM_REPO_FILE}" + echo "priority=10" >> "${YUM_REPO_FILE}" + echo "enabled=1" >> "${YUM_REPO_FILE}" + echo "enabled_metadata=1" >> "${YUM_REPO_FILE}" + echo "gpgcheck=1" >> "${YUM_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${YUM_REPO_FILE}" + fi tdnf makecache || return 1 - elif [ "$REPO_REV" != "latest" ]; then + elif [ "$ONEDIR_REV" != "latest" ]; then echowarn "salt.repo already exists, ignoring salt version argument." - echowarn "Use -F (forced overwrite) to install $REPO_REV." + echowarn "Use -F (forced overwrite) to install $ONEDIR_REV." fi return 0 @@ -5983,7 +6394,7 @@ install_photon_deps() { __PACKAGES="${__PACKAGES} libyaml procps-ng python${PY_PKG_VER}-crypto python${PY_PKG_VER}-jinja2" __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-msgpack python${PY_PKG_VER}-requests python${PY_PKG_VER}-zmq" __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-pip python${PY_PKG_VER}-m2crypto python${PY_PKG_VER}-pyyaml" - __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-systemd" + __PACKAGES="${__PACKAGES} python${PY_PKG_VER}-systemd sudo shadow" if [ "${_EXTRA_PACKAGES}" != "" ]; then echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}" @@ -6033,12 +6444,21 @@ install_photon_git_deps() { __PACKAGES="${__PACKAGES} git" fi + if ! __check_command_exists sudo; then + __PACKAGES="${__PACKAGES} sudo" + fi + + if ! __check_command_exists usermod; then + __PACKAGES="${__PACKAGES} shadow" + fi + if [ -n "${__PACKAGES}" ]; then # shellcheck disable=SC2086 __tdnf_install_noinput ${__PACKAGES} || return 1 __PACKAGES="" fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 __PACKAGES="python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc glibc-devel linux-devel.x86_64 cython${PY_PKG_VER}" @@ -6080,6 +6500,8 @@ install_photon_git() { return 1 fi + install_photon_git_deps + if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then ${_PYEXE} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --prefix=/usr || return 1 else @@ -6188,7 +6610,7 @@ install_photon_onedir_deps() { __install_saltstack_photon_onedir_repository || return 1 fi - __PACKAGES="procps-ng" + __PACKAGES="procps-ng sudo shadow" # shellcheck disable=SC2086 __tdnf_install_noinput ${__PACKAGES} || return 1 @@ -6205,27 +6627,43 @@ install_photon_onedir_deps() { install_photon_onedir() { + echodebug "install_photon_onedir() entry" STABLE_REV=$ONEDIR_REV + _GENERIC_PKG_VERSION="" + + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # Major version Salt, config and repo already setup + __get_packagesite_onedir_latest "$STABLE_REV" + MINOR_VER_STRG="-$_GENERIC_PKG_VERSION" + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # Minor version Salt, need to add specific minor version + STABLE_REV_DOT=$(echo "$STABLE_REV" | sed 's/-/\./') + MINOR_VER_STRG="-$STABLE_REV_DOT" + else + # default to latest version Salt, config and repo already setup + __get_packagesite_onedir_latest + MINOR_VER_STRG="-$_GENERIC_PKG_VERSION" + fi __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-cloud" + __PACKAGES="${__PACKAGES} salt-cloud$MINOR_VER_STRG" fi if [ "$_INSTALL_MASTER" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-master" + __PACKAGES="${__PACKAGES} salt-master$MINOR_VER_STRG" fi if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-minion" + __PACKAGES="${__PACKAGES} salt-minion$MINOR_VER_STRG" fi if [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-syndic" + __PACKAGES="${__PACKAGES} salt-syndic$MINOR_VER_STRG" fi if [ "$_INSTALL_SALT_API" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-api" + __PACKAGES="${__PACKAGES} salt-api$MINOR_VER_STRG" fi # shellcheck disable=SC2086 @@ -6252,38 +6690,85 @@ install_photon_onedir_post() { # __ZYPPER_REQUIRES_REPLACE_FILES=-1 -__set_suse_pkg_repo() { - - # Set distro repo variable - if [ "${DISTRO_MAJOR_VERSION}" -gt 2015 ]; then - DISTRO_REPO="openSUSE_Tumbleweed" - elif [ "${DISTRO_MAJOR_VERSION}" -eq 15 ] && [ "${DISTRO_MINOR_VERSION}" -ge 4 ]; then - DISTRO_REPO="${DISTRO_MAJOR_VERSION}.${DISTRO_MINOR_VERSION}" - elif [ "${DISTRO_MAJOR_VERSION}" -ge 42 ] || [ "${DISTRO_MAJOR_VERSION}" -eq 15 ]; then - DISTRO_REPO="openSUSE_Leap_${DISTRO_MAJOR_VERSION}.${DISTRO_MINOR_VERSION}" - else - DISTRO_REPO="SLE_${DISTRO_MAJOR_VERSION}_SP${SUSE_PATCHLEVEL}" - fi - - suse_pkg_url_base="https://download.opensuse.org/repositories/systemsmanagement:/saltstack" - suse_pkg_url_path="${DISTRO_REPO}/systemsmanagement:saltstack.repo" - SUSE_PKG_URL="$suse_pkg_url_base/$suse_pkg_url_path" -} __check_and_refresh_suse_pkg_repo() { # Check to see if systemsmanagement_saltstack exists - __zypper repos | grep -q systemsmanagement_saltstack + __zypper repos | grep -q 'salt.repo' if [ $? -eq 1 ]; then - # zypper does not yet know anything about systemsmanagement_saltstack - __zypper addrepo --refresh "${SUSE_PKG_URL}" || return 1 + # zypper does not yet know anything about salt.repo + # zypper does not support exclude similar to Photon, hence have to do following + ZYPPER_REPO_FILE="/etc/zypp/repos.d/salt.repo" + # shellcheck disable=SC2129 + if [ "$ONEDIR_REV" != "latest" ]; then + # 3006.x is default, and latest for 3006.x branch + if [ "$(echo "$ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # latest version for branch 3006 | 3007 + REPO_REV_MAJOR=$(echo "$ONEDIR_REV" | cut -d '.' -f 1) + if [ "$REPO_REV_MAJOR" -eq "3007" ]; then + # Enable the Salt 3007 STS repo + echo "[salt-repo-3007-sts]" > "${ZYPPER_REPO_FILE}" + echo "name=Salt Repo for Salt v3007 STS" >> "${ZYPPER_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${ZYPPER_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${ZYPPER_REPO_FILE}" + echo "priority=10" >> "${ZYPPER_REPO_FILE}" + echo "enabled=1" >> "${ZYPPER_REPO_FILE}" + echo "enabled_metadata=1" >> "${ZYPPER_REPO_FILE}" + echo "exclude=*3006* *3008* *3009* *3010*" >> "${ZYPPER_REPO_FILE}" + echo "gpgcheck=1" >> "${ZYPPER_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${ZYPPER_REPO_FILE}" + zypper addlock "salt-* < 3007" && zypper addlock "salt-* >= 3008" + else + # Salt 3006 repo + echo "[salt-repo-3006-lts]" > "${ZYPPER_REPO_FILE}" + echo "name=Salt Repo for Salt v3006 LTS" >> "${ZYPPER_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${ZYPPER_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${ZYPPER_REPO_FILE}" + echo "priority=10" >> "${ZYPPER_REPO_FILE}" + echo "enabled=1" >> "${ZYPPER_REPO_FILE}" + echo "enabled_metadata=1" >> "${ZYPPER_REPO_FILE}" + echo "exclude=*3007* *3008* *3009* *3010*" >> "${ZYPPER_REPO_FILE}" + echo "gpgcheck=1" >> "${ZYPPER_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${ZYPPER_REPO_FILE}" + zypper addlock "salt-* < 3006" && zypper addlock "salt-* >= 3007" + fi + elif [ "$(echo "$ONEDIR_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # using minor version + ONEDIR_REV_DOT=$(echo "$ONEDIR_REV" | sed 's/-/\./') + echo "[salt-repo-${ONEDIR_REV_DOT}-lts]" > "${ZYPPER_REPO_FILE}" + echo "name=Salt Repo for Salt v${ONEDIR_REV_DOT} LTS" >> "${ZYPPER_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${ZYPPER_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${ZYPPER_REPO_FILE}" + echo "priority=10" >> "${ZYPPER_REPO_FILE}" + echo "enabled=1" >> "${ZYPPER_REPO_FILE}" + echo "enabled_metadata=1" >> "${ZYPPER_REPO_FILE}" + echo "gpgcheck=1" >> "${ZYPPER_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${ZYPPER_REPO_FILE}"a + ONEDIR_MAJ_VER=$(echo "${ONEDIR_REV_DOT}" | awk -F '.' '{print $1}') + # shellcheck disable=SC2004 + ONEDIR_MAJ_VER_PLUS=$((${ONEDIR_MAJ_VER} + 1)) + zypper addlock "salt-* < ${ONEDIR_MAJ_VER}" && zypper addlock "salt-* >= ${ONEDIR_MAJ_VER_PLUS}" + fi + else + # Enable the Salt LATEST repo + echo "[salt-repo-latest]" > "${ZYPPER_REPO_FILE}" + echo "name=Salt Repo for Salt LATEST release" >> "${ZYPPER_REPO_FILE}" + echo "baseurl=https://${_REPO_URL}/saltproject-rpm/" >> "${ZYPPER_REPO_FILE}" + echo "skip_if_unavailable=True" >> "${ZYPPER_REPO_FILE}" + echo "priority=10" >> "${ZYPPER_REPO_FILE}" + echo "enabled=1" >> "${ZYPPER_REPO_FILE}" + echo "enabled_metadata=1" >> "${ZYPPER_REPO_FILE}" + echo "gpgcheck=1" >> "${ZYPPER_REPO_FILE}" + echo "gpgkey=https://${_REPO_URL}/api/security/keypair/SaltProjectKey/public" >> "${ZYPPER_REPO_FILE}" + fi + __zypper addrepo --refresh "${ZYPPER_REPO_FILE}" || return 1 fi } __version_lte() { - if ! __check_command_exists python; then - zypper --non-interactive install --replacefiles --auto-agree-with-licenses python || \ - zypper --non-interactive install --auto-agree-with-licenses python || return 1 + if ! __check_command_exists python3; then + zypper --non-interactive install --replacefiles --auto-agree-with-licenses python3 || \ + zypper --non-interactive install --auto-agree-with-licenses python3 || return 1 fi if [ "$(${_PY_EXE} -c 'import sys; V1=tuple([int(i) for i in sys.argv[1].split(".")]); V2=tuple([int(i) for i in sys.argv[2].split(".")]); print(V1<=V2)' "$1" "$2")" = "True" ]; then @@ -6327,8 +6812,6 @@ __zypper_install() { __opensuse_prep_install() { # DRY function for common installation preparatory steps for SUSE if [ "$_DISABLE_REPOS" -eq $BS_FALSE ]; then - # Is the repository already known - __set_suse_pkg_repo # Check zypper repos and refresh if necessary __check_and_refresh_suse_pkg_repo fi @@ -6383,6 +6866,7 @@ install_opensuse_git_deps() { __zypper_install git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 # Check for Tumbleweed @@ -6409,23 +6893,34 @@ install_opensuse_onedir_deps() { } install_opensuse_stable() { + if [ "$(echo "$STABLE_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # Major version Salt, config and repo already setup + MINOR_VER_STRG="" + elif [ "$(echo "$STABLE_REV" | grep -E '^([3-9][0-5]{2}[6-9](\.[0-9]*)?)')" != "" ]; then + # Minor version Salt, need to add specific minor version + STABLE_REV_DOT=$(echo "$STABLE_REV" | sed 's/-/\./') + MINOR_VER_STRG="-$STABLE_REV_DOT" + else + MINOR_VER_STRG="" + fi + __PACKAGES="" if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ];then - __PACKAGES="${__PACKAGES} salt-cloud" + __PACKAGES="${__PACKAGES} salt-cloud$MINOR_VER_STRG" fi if [ "$_INSTALL_MASTER" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-master" + __PACKAGES="${__PACKAGES} salt-master$MINOR_VER_STRG" fi if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-minion" + __PACKAGES="${__PACKAGES} salt-minion$MINOR_VER_STRG" fi if [ "$_INSTALL_SYNDIC" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-syndic" + __PACKAGES="${__PACKAGES} salt-syndic$MINOR_VER_STRG" fi if [ "$_INSTALL_SALT_API" -eq $BS_TRUE ]; then - __PACKAGES="${__PACKAGES} salt-api" + __PACKAGES="${__PACKAGES} salt-api$MINOR_VER_STRG" fi # shellcheck disable=SC2086 @@ -6453,7 +6948,7 @@ install_opensuse_stable_post() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ] || [ -f /usr/bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service) sleep 1 systemctl daemon-reload @@ -6476,7 +6971,7 @@ install_opensuse_git_post() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if command -v systemctl; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then use_usr_lib=$BS_FALSE if [ "${DISTRO_MAJOR_VERSION}" -ge 15 ]; then @@ -6528,7 +7023,7 @@ install_opensuse_restart_daemons() { [ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue [ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue - if [ -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then systemctl stop salt-$fname > /dev/null 2>&1 systemctl start salt-$fname.service && continue echodebug "Failed to start salt-$fname using systemd" @@ -6544,7 +7039,7 @@ install_opensuse_restart_daemons() { } install_opensuse_check_services() { - if [ ! -f /bin/systemctl ]; then + if [ "$_SYSTEMD_FUNCTIONAL" -eq $BS_TRUE ]; then # Not running systemd!? Don't check! return 0 fi @@ -6607,6 +7102,7 @@ install_opensuse_15_git_deps() { __zypper_install git || return 1 fi + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then @@ -6718,12 +7214,94 @@ install_suse_15_restart_daemons() { return 0 } +install_suse_15_check_services() { + install_opensuse_check_services || return 1 + return 0 +} + # # End of SUSE Enterprise 15 # ####################################################################################################################### +####################################################################################################################### +# +# SUSE Enterprise 15, now has ID sled +# + +install_sled_15_stable_deps() { + __opensuse_prep_install || return 1 + install_opensuse_15_stable_deps || return 1 + + return 0 +} + +install_sled_15_git_deps() { + install_suse_15_stable_deps || return 1 + + if ! __check_command_exists git; then + __zypper_install git-core || return 1 + fi + + install_opensuse_15_git_deps || return 1 + + return 0 +} + +install_sled_15_onedir_deps() { + __opensuse_prep_install || return 1 + install_opensuse_15_onedir_deps || return 1 + + return 0 +} + +install_sled_15_stable() { + install_opensuse_stable || return 1 + return 0 +} + +install_sled_15_git() { + install_opensuse_15_git || return 1 + return 0 +} + +install_sled_15_onedir() { + install_opensuse_stable || return 1 + return 0 +} + +install_sled_15_stable_post() { + install_opensuse_stable_post || return 1 + return 0 +} + +install_sled_15_git_post() { + install_opensuse_git_post || return 1 + return 0 +} + +install_sled_15_onedir_post() { + install_opensuse_stable_post || return 1 + return 0 +} + +install_sled_15_restart_daemons() { + install_opensuse_restart_daemons || return 1 + return 0 +} + +install_sled_15_check_services() { + install_opensuse_check_services || return 1 + return 0 +} + +# +# End of SUSE Enterprise 15 aka sled +# +####################################################################################################################### + + ####################################################################################################################### # # Gentoo Install Functions. @@ -6862,6 +7440,7 @@ install_gentoo_git_deps() { echoinfo "Running emerge -v1 setuptools" __emerge -v1 setuptools || return 1 + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 __gentoo_post_dep || return 1 } @@ -7130,58 +7709,87 @@ daemons_running_voidlinux() { # OS X / Darwin Install Functions # -__parse_repo_json_python() { - - # Using latest, grab the right - # version from the repo.json - _JSON_VERSION=$(python - <<-EOF -import json, urllib.request -url = "https://repo.saltproject.io/salt/py3/macos/repo.json" -response = urllib.request.urlopen(url) -data = json.loads(response.read()) -version = data["${_ONEDIR_REV}"][list(data["${_ONEDIR_REV}"])[0]]['version'] -print(version) -EOF -) -echo "${_JSON_VERSION}" +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: __macosx_get_packagesite_onedir_latest +# DESCRIPTION: Set _PKG_VERSION to the latest for MacOS or latest for major version input +#---------------------------------------------------------------------------------------------------------------------- +__macosx_get_packagesite_onedir_latest() { + + echodebug "Find latest MacOS release from repository" + + # get dir listing from url, sort and pick highest + macos_versions_tmpdir=$(mktemp -d) + curr_pwd=$(pwd) + cd ${macos_versions_tmpdir} || return 1 + wget -q -r -np -nH --exclude-directories=onedir,relenv,windows -x -l 1 "$SALT_MACOS_PKGDIR_URL/" + if [ "$#" -gt 0 ] && [ -n "$1" ]; then + MAJOR_VER="$1" + # shellcheck disable=SC2010 + _PKG_VERSION=$(ls artifactory/saltproject-generic/macos/ | grep -v 'index.html' | sort -V -u | grep -E "$MAJOR_VER" | tail -n 1) + else + # shellcheck disable=SC2010 + _PKG_VERSION=$(ls artifactory/saltproject-generic/macos/ | grep -v 'index.html' | sort -V -u | tail -n 1) + fi + cd ${curr_pwd} || return "${_PKG_VERSION}" + rm -fR ${macos_versions_tmpdir} + + echodebug "latest MacOS release from repository found ${_PKG_VERSION}" + } + __macosx_get_packagesite_onedir() { + + echodebug "Get package site for onedir from repository" + if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then echoerror "Python version is no longer supported, only Python 3" return 1 fi DARWIN_ARCH=${CPU_ARCH_L} + _PKG_VERSION="" + _ONEDIR_TYPE="saltproject-generic" + SALT_MACOS_PKGDIR_URL="https://${_REPO_URL}/${_ONEDIR_TYPE}/macos" if [ "$(echo "$_ONEDIR_REV" | grep -E '^(latest)$')" != "" ]; then - _PKG_VERSION=$(__parse_repo_json_python) - elif [ "$(echo "$_ONEDIR_REV" | grep -E '^([3-9][0-9]{3}(\.[0-9]*))')" != "" ]; then - _PKG_VERSION=$_ONEDIR_REV + __macosx_get_packagesite_onedir_latest + elif [ "$(echo "$_ONEDIR_REV" | grep -E '^(3006|3007)$')" != "" ]; then + # need to get latest for major version + __macosx_get_packagesite_onedir_latest "$_ONEDIR_REV" + elif [ "$(echo "$_ONEDIR_REV" | grep -E '^([3-9][0-9]{3}(\.[0-9]*)?)')" != "" ]; then + _PKG_VERSION=$_ONEDIR_REV else - _PKG_VERSION=$(__parse_repo_json_python) + # default to getting latest + __macosx_get_packagesite_onedir_latest fi - PKG="salt-${_PKG_VERSION}-${__PY_VERSION_REPO}-${DARWIN_ARCH}.pkg" - SALTPKGCONFURL="https://${_REPO_URL}/${_ONEDIR_DIR}/${__PY_VERSION_REPO}/macos/${ONEDIR_REV}/${PKG}" + PKG="salt-${_PKG_VERSION}-py3-${DARWIN_ARCH}.pkg" + SALTPKGCONFURL="${SALT_MACOS_PKGDIR_URL}/${_PKG_VERSION}/${PKG}" + + } __configure_macosx_pkg_details_onedir() { + __macosx_get_packagesite_onedir || return 1 return 0 } install_macosx_stable_deps() { + __configure_macosx_pkg_details_onedir || return 1 return 0 } install_macosx_onedir_deps() { + __configure_macosx_pkg_details_onedir || return 1 return 0 } install_macosx_git_deps() { + install_macosx_stable_deps || return 1 if ! echo "$PATH" | grep -q /usr/local/bin; then @@ -7201,12 +7809,14 @@ install_macosx_git_deps() { # Install PIP $_PYEXE /tmp/get-pip.py || return 1 + # shellcheck disable=SC2119 __git_clone_and_checkout || return 1 return 0 } install_macosx_stable() { + install_macosx_stable_deps || return 1 __fetch_url "/tmp/${PKG}" "${SALTPKGCONFURL}" || return 1 @@ -7217,6 +7827,7 @@ install_macosx_stable() { } install_macosx_onedir() { + install_macosx_onedir_deps || return 1 __fetch_url "/tmp/${PKG}" "${SALTPKGCONFURL}" || return 1 @@ -7228,6 +7839,7 @@ install_macosx_onedir() { install_macosx_git() { + if [ -n "$_PY_EXE" ]; then _PYEXE="${_PY_EXE}" else @@ -7240,6 +7852,7 @@ install_macosx_git() { } install_macosx_stable_post() { + if [ ! -f /etc/paths.d/salt ]; then print "%s\n" "/opt/salt/bin" "/usr/local/sbin" > /etc/paths.d/salt fi @@ -7255,16 +7868,19 @@ install_macosx_stable_post() { } install_macosx_onedir_post() { + install_macosx_stable_post || return 1 return 0 } install_macosx_git_post() { + install_macosx_stable_post || return 1 return 0 } install_macosx_restart_daemons() { + [ "$_START_DAEMONS" -eq $BS_FALSE ] && return if [ "$_INSTALL_MINION" -eq $BS_TRUE ]; then @@ -7290,6 +7906,7 @@ install_macosx_restart_daemons() { # the -c options is passed. # config_salt() { + # If the configuration directory is not passed, return [ "$_TEMP_CONFIG_DIR" = "null" ] && return @@ -7451,6 +8068,7 @@ config_salt() { # as long as the -k option is passed. # preseed_master() { + # Create the PKI directory if [ "$(find "$_TEMP_KEYS_DIR" -maxdepth 1 -type f | wc -l)" -lt 1 ]; then @@ -7485,6 +8103,7 @@ preseed_master() { # This function checks if all of the installed daemons are running or not. # daemons_running_onedir() { + [ "$_START_DAEMONS" -eq $BS_FALSE ] && return 0 FAILED_DAEMONS=0 @@ -7522,6 +8141,7 @@ daemons_running_onedir() { # This function checks if all of the installed daemons are running or not. # daemons_running() { + [ "$_START_DAEMONS" -eq $BS_FALSE ] && return 0 FAILED_DAEMONS=0 @@ -7726,6 +8346,7 @@ fi if [ "${ITYPE}" = "git" ] && [ ${_NO_DEPS} -eq ${BS_TRUE} ]; then + # shellcheck disable=SC2119 if ! __git_clone_and_checkout; then echo "Failed to clone and checkout git repository." exit 1 diff --git a/kitchen.macos.yml b/kitchen.macos.yml deleted file mode 100644 index 616a489e0..000000000 --- a/kitchen.macos.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -driver: - name: exec - -provisioner: - sudo: true - salt_bootstrap_options: -MP stable %s - init_environment: | - echo 'auto_accept: true' > /tmp/auto-accept-keys.conf - sudo mkdir -p /etc/salt/master.d - sudo mv /tmp/auto-accept-keys.conf /etc/salt/master.d/auto-accept-keys.conf - brew install coreutils - sh -c 't=$(gshuf -i 1-15 -n 1); echo Sleeping $t seconds; sleep $t' - -platforms: - - name: macos-12 - - name: macos-13 - -suites: - - name: stable-3006 - provisioner: - salt_version: 3006 - salt_call_command: /opt/salt/salt-call - - name: stable-3006-8 - provisioner: - salt_version: 3006.8 - salt_call_command: /opt/salt/salt-call - - name: stable-3007 - provisioner: - salt_version: 3007 - salt_call_command: /opt/salt/salt-call - - name: stable-3007-1 - provisioner: - salt_version: 3007.1 - salt_call_command: /opt/salt/salt-call - - name: latest - provisioner: - salt_version: latest - salt_call_command: /opt/salt/salt-call - -verifier: - command: pytest --cache-clear -v -s -ra --log-cli-level=debug -k "not test_ping" tests/integration/ diff --git a/kitchen.windows.yml b/kitchen.windows.yml deleted file mode 100644 index a2b88e2e3..000000000 --- a/kitchen.windows.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -driver: - name: proxy - host: localhost - reset_command: "exit 0" - port: 5985 - username: kitchen - password: Password1 - -provisioner: - salt_bootstrap_url: D:/a/salt-bootstrap/salt-bootstrap/bootstrap-salt.ps1 - salt_bootstrap_options: -Version %s -Verbose - init_environment: '' - -platforms: - - name: windows-2022 - - name: windows-2019 - -suites: - - name: stable-3006 - provisioner: - salt_version: 3006 - salt_call_command: c:\Program Files\Salt Project\Salt\salt-call.exe - - name: stable-3006-8 - provisioner: - salt_version: 3006.8 - salt_call_command: c:\Program Files\Salt Project\Salt\salt-call.exe - - name: stable-3007 - provisioner: - salt_version: 3007 - salt_call_command: c:\Program Files\Salt Project\Salt\salt-call.exe - - name: stable-3007-1 - provisioner: - salt_version: 3007.1 - salt_call_command: c:\Program Files\Salt Project\Salt\salt-call.exe - - name: latest - provisioner: - salt_version: latest - salt_call_command: c:\Program Files\Salt Project\Salt\salt-call.exe - -verifier: - command: pytest --cache-clear -v -s -ra --log-cli-level=debug -k "not test_ping" tests/integration/ diff --git a/kitchen.yml b/kitchen.yml deleted file mode 100644 index 62cc73808..000000000 --- a/kitchen.yml +++ /dev/null @@ -1,296 +0,0 @@ ---- -driver: - name: docker - use_sudo: false - hostname: salt - privileged: true - username: root - cap_add: - - sys_admin - disable_upstart: false - use_internal_docker_network: false - run_command: /usr/lib/systemd/systemd - -provisioner: - name: salt_solo - salt_install: bootstrap - salt_bootstrap_url: bootstrap-salt.sh - salt_bootstrap_options: -MPfq git %s - install_after_init_environment: true - log_level: info - sudo: false - require_chef: false - formula: tests - run_salt_call: false - init_environment: | - echo 'auto_accept: true' > /tmp/auto-accept-keys.conf - mkdir -p /etc/salt/master.d - mv /tmp/auto-accept-keys.conf /etc/salt/master.d/auto-accept-keys.conf - sh -c 't=$(shuf -i 1-15 -n 1); echo Sleeping $t seconds; sleep $t' - - -## - name: amazon-2023 -## driver: -## image: amazonlinux:2023 -## provision_command: -## - yum -y install --allowerasing procps-ng curl -## - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - -## - name: opensuse-tumbleweed -## driver: -## image: opensuse/tumbleweed:latest -## provision_command: -## - *opensuse_provision_command_01 -## - *opensuse_provision_command_02 -## - *opensuse_provision_command_03 -## - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - -platforms: - - name: almalinux-9 - driver: - provision_command: - - dnf -y install crypto-policies-scripts procps-ng - - update-crypto-policies --set DEFAULT:SHA1 - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: almalinux-8 - - name: amazon-2 - driver: - image: amazonlinux:2 - platform: rhel - provision_command: - - yum -y install procps-ng - - name: arch - driver: - image: archlinux/archlinux - provision_command: - - pacman -Syu --noconfirm --needed systemd grep awk procps which - - systemctl enable sshd - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: centos-stream9 - driver: - platform: centosstream - image: quay.io/centos/centos:stream9 - provision_command: - - dnf -y install crypto-policies-scripts procps-ng - - update-crypto-policies --set DEFAULT:SHA1 - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: debian-11 - driver: - image: debian:bullseye - run_command: /lib/systemd/systemd - - name: debian-12 - driver: - image: debian:bookworm - run_command: /lib/systemd/systemd - provision_command: - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: fedora-39 - driver: - provision_command: &fedora_provision_command - - dnf -y install procps-ng crypto-policies-scripts - - update-crypto-policies --set LEGACY - - name: fedora-40 - driver: - provision_command: *fedora_provision_command - - name: gentoo - driver: - image: gentoo/stage3:latest - run_command: /sbin/init - provision_command: - - rc-update add sshd default - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: gentoo-systemd - driver: - image: gentoo/stage3:systemd - run_command: /lib/systemd/systemd - provision_command: - - systemctl enable sshd.service - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: opensuse-15 - driver: - image: opensuse/leap:15.4 - provision_command: - - &opensuse_provision_command_01 zypper --non-interactive install --auto-agree-with-licenses dbus-1 - - &opensuse_provision_command_02 zypper --non-interactive install --auto-agree-with-licenses sudo openssh which curl systemd - - &opensuse_provision_command_03 systemctl enable sshd.service - - name: rockylinux-9 - driver: - platform: centosstream - run_command: /usr/lib/systemd/systemd - provision_command: - - dnf -y install crypto-policies-scripts procps-ng - - update-crypto-policies --set DEFAULT:SHA1 - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: oraclelinux-9 - driver: - run_command: /usr/lib/systemd/systemd - provision_command: - - dnf -y install crypto-policies-scripts procps-ng - - update-crypto-policies --set DEFAULT:SHA1 - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: rockylinux-8 - - name: oraclelinux-8 - - name: ubuntu-24.04 - driver: - run_command: /lib/systemd/systemd - provision_command: - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: ubuntu-22.04 - driver: - run_command: /lib/systemd/systemd - provision_command: - - echo "PubkeyAcceptedAlgorithms +ssh-rsa" | tee -a /etc/ssh/sshd_config - - name: ubuntu-20.04 - driver: - run_command: /lib/systemd/systemd - - name: photon-4 - driver: - image: photon:4.0 - provision_command: - - tdnf -y install rpm procps-ng coreutils gawk systemd - - echo "PubkeyAcceptedKeyTypes +ssh-rsa" | tee -a /etc/ssh/sshd_config - - sed -ie 's/PermitRootLogin no/PermitRootLogin yes/' /etc/ssh/sshd_config - - systemctl enable sshd.service - - name: photon-5 - driver: - image: photon:5.0 - provision_command: - - tdnf -y install rpm procps-ng coreutils gawk systemd - - echo "PubkeyAcceptedKeyTypes +ssh-rsa" | tee -a /etc/ssh/sshd_config - - sed -ie 's/PermitRootLogin no/PermitRootLogin yes/' /etc/ssh/sshd_config - - systemctl enable sshd.service - -suites: - - name: git-3006 - provisioner: - salt_version: v3006 - salt_bootstrap_options: -x python3 -MPfq git %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - debian-11 - - debian-12 - - arch - - gentoo - - gentoo-systemd - - name: git-3006x - provisioner: - salt_version: 3006.x - salt_bootstrap_options: -x python3 -MPfq git %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - debian-11 - - debian-12 - - arch - - gentoo - - gentoo-systemd - - name: git-3007 - provisioner: - salt_version: v3007 - salt_bootstrap_options: -x python3 -MPfq git %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - debian-11 - - arch - - gentoo - - gentoo-systemd - - name: git-3007x - provisioner: - salt_version: 3007.x - salt_bootstrap_options: -x python3 -MPfq git %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - debian-11 - - arch - - gentoo - - gentoo-systemd - - name: stable-3006 - provisioner: - salt_version: 3006 - salt_bootstrap_options: -x python3 -MP stable %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - arch - - name: stable-3006-8 - provisioner: - salt_version: 3006.8 - salt_bootstrap_options: -x python3 -MP stable %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - arch - - name: stable-3007 - provisioner: - salt_version: 3007 - salt_bootstrap_options: -x python3 -MP stable %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - arch - - name: stable-3007-1 - provisioner: - salt_version: 3007.1 - salt_bootstrap_options: -x python3 -MP stable %s - excludes: - - opensuse-15 - - opensuse-tumbleweed - - arch - - name: git-master - provisioner: - salt_version: master - salt_bootstrap_options: -x python3 -MPfq -D git %s - - - name: latest - provisioner: - salt_version: latest - salt_bootstrap_options: -MP stable %s - - - name: default - provisioner: - salt_version: latest - salt_bootstrap_options: -MP - - - name: onedir-nightly - provisioner: - salt_version: nightly - salt_bootstrap_options: -MP onedir %s - - - name: onedir-latest - provisioner: - salt_version: latest - salt_bootstrap_options: -MP onedir %s - - - name: onedir-3006 - provisioner: - salt_version: 3006 - salt_bootstrap_options: -MP onedir %s - - - name: onedir-3007 - provisioner: - salt_version: 3007 - salt_bootstrap_options: -MP onedir %s - - - name: onedir-rc-3008-0rc1 - provisioner: - salt_version: 3008.0rc1 - salt_bootstrap_options: -R staging.repo.saltproject.io -MP onedir_rc %s - excludes: - - arch - - gentoo - - opensuse-15 - - opensuse-tumbleweed - - ubuntu-2004 - - ubuntu-2204 - - - name: quickstart - provisioner: - salt_bootstrap_options: -Q - -verifier: - name: shell - remote_exec: false - command: pytest --cache-clear -v -s -ra --log-cli-level=info tests/integration/ diff --git a/salt-quick-start.ps1 b/salt-quick-start.ps1 index 16c705554..f6f79c724 100644 --- a/salt-quick-start.ps1 +++ b/salt-quick-start.ps1 @@ -1,39 +1,31 @@ -function Convert-PSObjectToHashtable { - param ( - [Parameter(ValueFromPipeline)] - $InputObject - ) - if ($null -eq $InputObject) { return $null } - - $is_enum = $InputObject -is [System.Collections.IEnumerable] - $not_string = $InputObject -isnot [string] - if ($is_enum -and $not_string) { - $collection = @( - foreach ($object in $InputObject) { - Convert-PSObjectToHashtable $object - } - ) +<# +.SYNOPSIS + A simple Powershell script to quickly start using Salt. - Write-Host -NoEnumerate $collection - } elseif ($InputObject -is [PSObject]) { - $hash = @{} +.DESCRIPTION + This script will download the latest onedir version of Salt and extract it + into the same directory where the script is run. The script sets up an + environment that will allow you to run salt-call commands. To remove, just + delete the `salt` directory. The environment variables will only be set for + the current powershell session. - foreach ($property in $InputObject.PSObject.Properties) { - $hash[$property.Name] = Convert-PSObjectToHashtable $property.Value - } +.EXAMPLE + ./salt-quick-start.ps1 - $hash - } else { - $InputObject - } -} +.LINK + Salt Bootstrap GitHub Project (script home) - https://github.com/saltstack/salt-bootstrap + Original Vagrant Provisioner Project - https://github.com/saltstack/salty-vagrant + Vagrant Project (utilizes this script) - https://github.com/mitchellh/vagrant + Salt Download Location - https://packages.broadcom.com/artifactory/saltproject-generic/windows/ + Salt Manual Install Directions (Windows) - https://docs.saltproject.io/salt/install-guide/en/latest/topics/install-by-operating-system/windows.html +#> + +# This is so the -Verbose parameter will work +[CmdletBinding()] param() function Expand-ZipFile { # Extract a zip file # - # Used by: - # - Install-SaltMinion - # # Args: # ZipFile (string): The file to extract # Destination (string): The location to extract to @@ -81,60 +73,151 @@ function Expand-ZipFile { Write-Debug "Finished unzipping '$ZipFile' to '$Destination'" } +function Get-FileHash { + # Get-FileHash is a built-in cmdlet in powershell 5+ but we need to support + # powershell 3. This will overwrite the powershell 5 commandlet only for + # this script. But it will provide the missing cmdlet for powershell 3 + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)] + [String] $Path, -[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls12' + [Parameter(Mandatory=$false)] + [ValidateSet( + "SHA1", + "SHA256", + "SHA384", + "SHA512", + # https://serverfault.com/questions/820300/ + # why-isnt-mactripledes-algorithm-output-in-powershell-stable + "MACTripleDES", # don't use + "MD5", + "RIPEMD160", + IgnoreCase=$true)] + [String] $Algorithm = "SHA256" + ) -$global:ProgressPreference = 'SilentlyContinue' + if ( !(Test-Path $Path) ) { + Write-Verbose "Invalid path for hashing: $Path" + return @{} + } -$RepoUrl = "https://repo.saltproject.io/salt/py3/onedir" + if ( (Get-Item -Path $Path) -isnot [System.IO.FileInfo]) { + Write-Verbose "Not a file for hashing: $Path" + return @{} + } -if ([IntPtr]::Size -eq 4) { - $arch = "x86" -} else { - $arch = "amd64" -} -$enc = [System.Text.Encoding]::UTF8 -try { - $response = Invoke-WebRequest -Uri "$RepoUrl/repo.json" -UseBasicParsing - if ($response.Content.GetType().Name -eq "Byte[]") { - $psobj = $enc.GetString($response.Content) | ConvertFrom-Json + $Path = Resolve-Path -Path $Path - } else { - $psobj = $response.Content | ConvertFrom-Json - } - $hash = Convert-PSObjectToHashtable $psobj -} catch { - Write-Host "repo.json not found at: $RepoUrl" - $hash = @{} -} -$searchVersion = "latest" -if ( $hash.Contains($searchVersion)) { - foreach ($item in $hash.($searchVersion).Keys) { - if ( $item.EndsWith(".zip") ) { - if ( $item.Contains($arch) ) { - $saltFileName = $hash.($searchVersion).($item).name - $saltVersion = $hash.($searchVersion).($item).version - $saltSha512 = $hash.($searchVersion).($item).SHA512 - } + Switch ($Algorithm) { + SHA1 { + $hasher = [System.Security.Cryptography.SHA1CryptoServiceProvider]::Create() + } + SHA256 { + $hasher = [System.Security.Cryptography.SHA256]::Create() + } + SHA384 { + $hasher = [System.Security.Cryptography.SHA384]::Create() + } + SHA512 { + $hasher = [System.Security.Cryptography.SHA512]::Create() + } + MACTripleDES { + $hasher = [System.Security.Cryptography.MACTripleDES]::Create() + } + MD5 { + $hasher = [System.Security.Cryptography.MD5]::Create() + } + RIPEMD160 { + $hasher = [System.Security.Cryptography.RIPEMD160]::Create() } } -} -if ( $saltFileName -and $saltVersion -and $saltSha512 ) { - if ( $RepoUrl.Contains("minor") ) { - $saltFileUrl = @($RepoUrl, $saltVersion, $saltFileName) -join "/" - } else { - $saltFileUrl = @($RepoUrl, "minor", $saltVersion, $saltFileName) -join "/" + + Write-Verbose "Hashing using $Algorithm algorithm" + try { + $data = [System.IO.File]::OpenRead($Path) + $hash = $hasher.ComputeHash($data) + $hash = [System.BitConverter]::ToString($hash) -replace "-","" + return @{ + Path = $Path; + Algorithm = $Algorithm.ToUpper(); + Hash = $hash + } + } catch { + Write-Verbose "Error hashing: $Path" + Write-Verbose "ERROR: $_" + return @{} + } finally { + if ($null -ne $data) { + $data.Close() + } } } -Write-Host "* INFO: Downloading Salt" +#=============================================================================== +# Script settings +#=============================================================================== +[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls12' +$global:ProgressPreference = 'SilentlyContinue' + +#=============================================================================== +# Declare Variables +#=============================================================================== +$ApiUrl = "https://packages.broadcom.com/artifactory/api/storage/saltproject-generic/onedir" +# Detect architecture ($arch) +if ([IntPtr]::Size -eq 4) { $arch = "x86" } else { $arch = "amd64" } + +#=============================================================================== +# Setting up quickstart environment +#=============================================================================== +Write-Host "" +Write-Host "Setting up quickstart environment for Salt" -ForegroundColor Cyan + +Write-Verbose "Getting version information from Artifactory" +$response = Invoke-WebRequest $ApiUrl -UseBasicParsing +# Convert the output to a powershell object +$psobj = $response.ToString() | ConvertFrom-Json +$Version = $psobj.children[-1].uri.Trim("/") + +Write-Verbose "Getting sha256 hash and download url from Artifactory" +$saltFileName = "salt-$Version-onedir-windows-$arch.zip" +$response = Invoke-WebRequest "$ApiUrl/$Version/$saltFileName" -UseBasicParsing +$psobj = $response.ToString() | ConvertFrom-Json +$saltFileUrl = $psobj.downloadUri +$saltSha256 = $psobj.checksums.sha256 + +Write-Verbose "URL: $saltFileUrl" +Write-Host "* INFO: Downloading Salt: " -NoNewline Invoke-WebRequest -Uri $saltFileUrl -OutFile .\salt.zip +if ( Test-Path -Path .\salt.zip ) { + Write-Host "Success" -ForegroundColor Green +} else { + Write-Host "Failed" -ForegroundColor Red + exit 1 +} +$localSha256 = (Get-FileHash -Path .\salt.zip -Algorithm SHA256).Hash +Write-Verbose "Local Hash: $localSha256" +Write-Verbose "Remote Hash: $saltSha256" + +Write-Host "* INFO: Comparing Hash: " -NoNewline +if ( $localSha256 -eq $saltSha256 ) { + Write-Host "Success" -ForegroundColor Green +} else { + Write-Host "Failed" -ForegroundColor Red + exit 1 +} -Write-Host "* INFO: Extracting Salt" +Write-Host "* INFO: Extracting Salt: " -NoNewline Expand-ZipFile -ZipFile .\salt.zip -Destination . +if ( Test-Path -Path .\salt\Scripts\python.exe ) { + Write-Host "Success" -ForegroundColor Green +} else { + Write-Host "Failed" -ForegroundColor Red + exit 1 +} +Write-Host "* INFO: Creating Saltfile: " -NoNewline $PATH = $(Get-Location).Path - $saltfile_contents = @" salt-call: local: True @@ -143,20 +226,42 @@ salt-call: cachedir: $PATH\salt\var\cache\salt file_root: $PATH\salt\srv\salt "@ - Set-Content -Path .\salt\Saltfile -Value $saltfile_contents +if ( Test-Path -Path .\salt\Saltfile ) { + Write-Host "Success" -ForegroundColor Green +} else { + Write-Host "Failed" -ForegroundColor Red + exit 1 +} New-Item -Path "$PATH\salt\var\log\salt" -Type Directory -Force | Out-Null New-Item -Path "$PATH\salt\conf" -Type Directory -Force | Out-Null New-Item -Path "$PATH\salt\var\cache\salt" -Type Directory -Force | Out-Null New-Item -Path "$PATH\salt\srv\salt" -Type Directory -Force | Out-Null -Write-Host "* INFO: Adding Salt to current path" -Write-Host "* INFO: $PATH\salt" +Write-Host "* INFO: Adding Salt to current path: " -NoNewline $env:Path = "$PATH\salt;$env:PATH" +Write-Verbose $env:Path +if ( $env:PATH -Like "*$PATH\salt*" ) { + Write-Host "Success" -ForegroundColor Green +} else { + Write-Host "Failed" -ForegroundColor Red + exit 1 +} +Write-Host "* INFO: $PATH\salt" -Write-Host "* INFO: Setting the SALT_SALTFILE environment variable" -Write-Host "* INFO: $PATH\salt\Saltfile" +Write-Host "* INFO: Setting the SALT_SALTFILE environment variable: "-NoNewline $env:SALT_SALTFILE="$PATH\salt\Saltfile" +if ( Test-Path -Path $env:SALT_SALTFILE ) { + Write-Host "Success" -ForegroundColor Green +} else { + Write-Host "Failed" -ForegroundColor Red + exit 1 +} +Write-Host "* INFO: $PATH\salt\Saltfile" +Write-Host "" +Write-Host "You can now run simple salt-call commands" -ForegroundColor Cyan Write-Host "* INFO: Create Salt states in $PATH\salt\srv\salt" +Write-Host "* INFO: Try running salt-call test.ping" +Write-Host "" diff --git a/salt-quick-start.sh b/salt-quick-start.sh index 8449abbf0..d4727ed27 100755 --- a/salt-quick-start.sh +++ b/salt-quick-start.sh @@ -1,7 +1,7 @@ #!/bin/sh __ScriptName="salt-quick-start.sh" -SALT_REPO_URL="https://repo.saltproject.io/salt/py3/onedir" +SALT_REPO_URL="https://packages.broadcom.com/artifactory/salt-project-generic/onedir" _COLORS=${QS_COLORS:-$(tput colors 2>/dev/null || echo 0)} _LOCAL=0 @@ -89,8 +89,20 @@ if [[ "$_LOCAL" == "1" && "$_FULL" == "1" ]]; then fi __parse_repo_json_jq() { - _JSON_FILE="${SALT_REPO_URL}/repo.json" - _JSON_VERSION=$(curl -s ${_JSON_FILE} | jq -sr ".[].latest[] | select(.os == \"$1\") | select(.arch == \"$2\").version") + + # $1 is OS_NAME + # $2 is ARCH + + # get dir listing from url, sort and pick highest + onedir_versions_tmpf=$(mktemp) + curr_pwd=$(pwd) + cd ${onedir_versions_tmpf} || return 1 + wget -r -np -nH --exclude-directories=onedir,relenv,windows -x -l 1 "$SALT_REPO_URL/" + # shellcheck disable=SC2010 + LATEST_VERSION=$(ls artifactory/saltproject-generic/onedir/ | grep -v 'index.html' | sort -V -u | tail -n 1) + cd ${curr_pwd} || return "${LATEST_VERSION}" + rm -fR ${onedir_versions_tmpf} + _JSON_VERSION="${LATEST_VERSION}" } __fetch_url() { @@ -146,7 +158,7 @@ fi __parse_repo_json_jq ${OS_NAME} ${CPU_ARCH_L} FILE="salt-${_JSON_VERSION}-onedir-${OS_NAME_L}-${CPU_ARCH_L}.tar.xz" -URL="${SALT_REPO_URL}/latest/${FILE}" +URL="${SALT_REPO_URL}/${_JSON_VERSION}/${FILE}" if [[ ! -f ${FILE} ]]; then echoinfo "Downloading Salt" diff --git a/tests/conftest.py b/tests/conftest.py index 864307c03..5d5702c12 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,43 +1,12 @@ -import logging +import json import os -import pprint import pytest -import testinfra +import requests -log = logging.getLogger(__name__) - - -@pytest.fixture(scope="session") -def host(): - if ( - os.environ.get("RUNNER_OS", "") == "macOS" - and os.environ.get("KITCHEN_LOCAL_YAML", "") == "kitchen.macos.yml" - ): - # Adjust the `PATH` so that the `salt-call` executable can be found - os.environ["PATH"] = "/opt/salt/bin{}{}".format(os.pathsep, os.environ["PATH"]) - return testinfra.get_host("local://", sudo=True) - - if os.environ.get("KITCHEN_USERNAME") == "vagrant" or "windows" in os.environ.get( - "KITCHEN_INSTANCE" - ): - if "windows" in os.environ.get("KITCHEN_INSTANCE"): - _url = "winrm://{KITCHEN_USERNAME}:{KITCHEN_PASSWORD}@{KITCHEN_HOSTNAME}:{KITCHEN_PORT}".format( - **os.environ - ) - return testinfra.get_host( - _url, - no_ssl=True, - ) - return testinfra.get_host( - "paramiko://{KITCHEN_USERNAME}@{KITCHEN_HOSTNAME}:{KITCHEN_PORT}".format( - **os.environ - ), - ssh_identity_file=os.environ.get("KITCHEN_SSH_KEY"), - ) - return testinfra.get_host( - "docker://{KITCHEN_USERNAME}@{KITCHEN_CONTAINER_ID}".format(**os.environ) - ) +API_URL = ( + "https://packages.broadcom.com/artifactory/api/storage/saltproject-generic/windows" +) @pytest.fixture(scope="session") @@ -47,21 +16,33 @@ def target_python_version(): @pytest.fixture(scope="session") def target_salt_version(): - bootstrap_types = ("git", "stable", "onedir", "onedir_rc") - # filter out any bootstrap types and then join - target_salt = ".".join( - [ - item - for item in os.environ["KITCHEN_SUITE"].split("-") - if item not in bootstrap_types - ] - ) - - # target_salt = os.environ["KITCHEN_SUITE"].split("-", 1)[-1].replace("-", ".") + target_salt = os.environ.get("SaltVersion", "") + html_response = requests.get(API_URL) + content = json.loads(html_response.text) + folders = content["children"] + versions = {} + for folder in folders: + if folder["folder"]: + version = folder["uri"].strip("/") + versions[version] = version + # We're trying to get the latest major version and latest overall + maj_version = version.split(".")[0] + versions[maj_version] = version + versions["latest"] = version if target_salt.startswith("v"): target_salt = target_salt[1:] - if target_salt in ("default", "latest", "master", "nightly"): + if target_salt not in versions: + pytest.skip(f"Invalid testing version: {target_salt}") + if target_salt in ( + "default", + "latest", + "master", + "nightly", + "stable", + "onedir", + "git", + ): pytest.skip("Don't have a specific salt version to test against") - return target_salt + return versions[target_salt] diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py deleted file mode 100644 index 40a96afc6..000000000 --- a/tests/integration/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# -*- coding: utf-8 -*- diff --git a/tests/integration/test_installation.py b/tests/integration/test_installation.py index 9ee18d49c..2bc739489 100644 --- a/tests/integration/test_installation.py +++ b/tests/integration/test_installation.py @@ -1,31 +1,82 @@ +import json import logging import os -from contextlib import nullcontext +import platform +import subprocess + +import pytest log = logging.getLogger(__name__) -def selected_context_manager(host): - if "windows" in os.environ.get("KITCHEN_INSTANCE"): - return nullcontext() - return host.sudo() +@pytest.fixture +def path(): + if platform.system() == "Windows": + salt_path = "C:\\Program Files\\Salt Project\\Salt" + if salt_path not in os.environ["path"]: + os.environ["path"] = f'{os.environ["path"]};{salt_path}' + yield os.environ["path"] + else: + yield "" -def test_ping(host): - with selected_context_manager(host): - assert host.salt("test.ping", "--timeout=120") +def run_salt_call(cmd): + """ + Runs salt call command and returns a dictionary + Accepts cmd as a list + """ + json_data = {"local": {}} + if platform.system() == "Windows": + cmd.append("--out=json") + result = subprocess.run(cmd, capture_output=True, text=True) + if 0 == result.returncode: + json_data = json.loads(result.stdout) + else: + log.error(f"failed to produce output result, '{result}'") + else: + if platform.system() == "Darwin": + cmdl = ["sudo"] + else: + cmdl = [] + cmdl.extend(cmd) + cmdl.append("--out=json") + try: + result = subprocess.run(cmdl, capture_output=True, text=True) + except TypeError: + result = subprocess.run( + cmdl, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + ) + if 0 == result.returncode: + json_data = json.loads(result.stdout) + else: + log.error(f"failed to produce output result, '{result}'") -def test_target_python_version(host, target_python_version): - with selected_context_manager(host): - ret = host.salt("grains.item", "pythonversion", "--timeout=120") - assert ret["pythonversion"][0] == target_python_version + return json_data["local"] -def test_target_salt_version(host, target_salt_version): - with selected_context_manager(host): - ret = host.salt("grains.item", "saltversion", "--timeout=120") - if target_salt_version.endswith(".0") or target_salt_version.endswith(".x"): - assert ret["saltversion"] == ".".join(target_salt_version.split(".")[:-1]) - else: - assert ret["saltversion"].startswith(target_salt_version) +def test_ping(path): + cmd = ["salt-call", "--local", "test.ping"] + result = run_salt_call(cmd) + assert result == True + + +def test_target_python_version(path, target_python_version): + cmd = ["salt-call", "--local", "grains.item", "pythonversion", "--timeout=120"] + result = run_salt_call(cmd) + # Returns: {'pythonversion': [3, 10, 11, 'final', 0]} + py_maj_ver = result["pythonversion"][0] + assert py_maj_ver == target_python_version + + +def test_target_salt_version(path, target_salt_version): + if not target_salt_version: + pytest.skip(f"No target version specified") + cmd = ["salt-call", "--local", "grains.item", "saltversion", "--timeout=120"] + result = run_salt_call(cmd) + # Returns: {'saltversion': '3006.9+217.g53cfa53040'} + adj_saltversion = result["saltversion"].split("+")[0] + assert adj_saltversion == target_salt_version diff --git a/tests/requirements.txt b/tests/requirements.txt index 21d133da8..547de5c5b 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,5 +1,2 @@ -pytest-testinfra -paramiko -requests-ntlm==1.1.0; sys.platform == 'win32' -pywinrm; sys.platform == 'win32' -six>=1.10.0 +pytest +requests