diff --git a/.github/actions/cleanup-files/action.yaml b/.github/actions/cleanup-files/action.yaml index d466daf3a8..1818d6094f 100644 --- a/.github/actions/cleanup-files/action.yaml +++ b/.github/actions/cleanup-files/action.yaml @@ -15,7 +15,6 @@ runs: echo "removing zarf sboms, packages, cache" sudo rm -rf zarf-sbom /tmp/zarf-* - sudo env "PATH=$PATH" CI=true make delete-packages sudo build/zarf tools clear-cache lsblk -f diff --git a/.github/actions/golang/action.yaml b/.github/actions/golang/action.yaml deleted file mode 100644 index 890c4bb3cd..0000000000 --- a/.github/actions/golang/action.yaml +++ /dev/null @@ -1,10 +0,0 @@ -name: setup-go -description: "Setup Go binary and caching" - -runs: - using: composite - steps: - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 - with: - go-version-file: 'go.mod' - cache: true diff --git a/.github/workflows/build-rust-injector.yml b/.github/workflows/build-rust-injector.yml index 386d5dcaa9..caa7899b4e 100644 --- a/.github/workflows/build-rust-injector.yml +++ b/.github/workflows/build-rust-injector.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout Repo" - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install tools uses: ./.github/actions/install-tools diff --git a/.github/workflows/check-go-mod.yml b/.github/workflows/check-go-mod.yml index 8efdd95beb..d86dc390a3 100644 --- a/.github/workflows/check-go-mod.yml +++ b/.github/workflows/check-go-mod.yml @@ -11,10 +11,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Test go mod run: | diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 4e02728407..caacf811c4 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -16,12 +16,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 - name: Install commitlint run: npm install --save-dev @commitlint/{config-conventional,cli} diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 7f00db8a43..f58b17ac01 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -10,6 +10,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Dependency Review - uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4 + uses: actions/dependency-review-action@a6993e2c61fd5dc440b409aa1d6904921c5e1894 # v4.3.5 diff --git a/.github/workflows/nightly-ecr.yml b/.github/workflows/nightly-ecr.yml index 4be6e1ebcb..e4fdb3b431 100644 --- a/.github/workflows/nightly-ecr.yml +++ b/.github/workflows/nightly-ecr.yml @@ -19,10 +19,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Build the Zarf binary run: make build-cli-linux-amd diff --git a/.github/workflows/nightly-eks.yml b/.github/workflows/nightly-eks.yml index fa347c2a8c..262e4b00c2 100644 --- a/.github/workflows/nightly-eks.yml +++ b/.github/workflows/nightly-eks.yml @@ -27,10 +27,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Build binary and zarf packages uses: ./.github/actions/packages diff --git a/.github/workflows/publish-application-packages.yml b/.github/workflows/publish-application-packages.yml index 5ee5625f70..6a2a7d2f6e 100644 --- a/.github/workflows/publish-application-packages.yml +++ b/.github/workflows/publish-application-packages.yml @@ -14,7 +14,7 @@ jobs: packages: write steps: - name: "Checkout Repo" - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Auth with AWS uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3ec2f6839c..71cf344d29 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,12 +17,14 @@ jobs: steps: # Checkout the repo and setup the tooling for this job - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Install tools uses: ./.github/actions/install-tools @@ -96,7 +98,7 @@ jobs: steps: # Checkout the repo and setup the tooling for this job - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 @@ -107,7 +109,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Make Zarf executable run: | @@ -135,12 +139,14 @@ jobs: steps: # Checkout the repo and setup the tooling for this job - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Install tools uses: ./.github/actions/install-tools diff --git a/.github/workflows/scan-codeql.yml b/.github/workflows/scan-codeql.yml index 58e3596fea..db48b69e47 100644 --- a/.github/workflows/scan-codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -36,14 +36,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: languages: ${{ matrix.language }} config-file: ./.github/codeql.yaml @@ -52,6 +54,6 @@ jobs: run: make build-cli-linux-amd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scan-docs-and-schema.yml b/.github/workflows/scan-docs-and-schema.yml index d1228c2fd4..5ec403ec20 100644 --- a/.github/workflows/scan-docs-and-schema.yml +++ b/.github/workflows/scan-docs-and-schema.yml @@ -11,10 +11,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Docs and schemas run: "make test-docs-and-schema" diff --git a/.github/workflows/scan-lint.yml b/.github/workflows/scan-lint.yml index a4ac5b28cf..ba430af3af 100644 --- a/.github/workflows/scan-lint.yml +++ b/.github/workflows/scan-lint.yml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Run golangci-lint uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 4a8ab4470b..9c3e8dff39 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -22,7 +22,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: results.sarif diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index ae4d719f1f..ca7ca3be7a 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -35,10 +35,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Build binary and zarf packages uses: ./.github/actions/packages @@ -58,7 +60,7 @@ jobs: needs: build-e2e steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download build artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -67,7 +69,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Make Zarf executable run: | @@ -93,7 +97,7 @@ jobs: needs: build-e2e steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download build artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -102,7 +106,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Setup K3d uses: ./.github/actions/k3d @@ -135,7 +141,7 @@ jobs: needs: build-e2e steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download build artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -144,7 +150,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Make Zarf executable run: | @@ -173,7 +181,7 @@ jobs: needs: build-e2e steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download build artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -182,7 +190,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Setup Kind run: | @@ -217,7 +227,7 @@ jobs: needs: build-e2e steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download build artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -226,7 +236,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Setup Minikube run: minikube start --driver=docker diff --git a/.github/workflows/test-external.yml b/.github/workflows/test-external.yml index 1dc1b5b641..2ce95335f2 100644 --- a/.github/workflows/test-external.yml +++ b/.github/workflows/test-external.yml @@ -34,10 +34,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Build binary and zarf packages uses: ./.github/actions/packages diff --git a/.github/workflows/test-import.yaml b/.github/workflows/test-import.yaml index 201eb2f7db..512c08e50b 100644 --- a/.github/workflows/test-import.yaml +++ b/.github/workflows/test-import.yaml @@ -15,13 +15,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Go - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: - go-version-file: 'go.mod' - cache: true + go-version-file: go.mod - name: Run test Go program that imports Zarf run: | diff --git a/.github/workflows/test-package-create.yml b/.github/workflows/test-package-create.yml new file mode 100644 index 0000000000..583a0aa864 --- /dev/null +++ b/.github/workflows/test-package-create.yml @@ -0,0 +1,48 @@ +name: Test Package Create Checksums + +on: + pull_request: + merge_group: + +permissions: + contents: read + +concurrency: + group: package-create-${{ github.ref }} + cancel-in-progress: true + +jobs: + test-checksums: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod + + - name: Build Zarf + run: make build + + - name: Build examples + run: make build-examples ARCH=amd64 + + - name: Compare checksums + run: | + set -e + + for f in hack/examples-checksums/*.txt + do + NAME=$(basename $f .txt) + CHECKSUM=$(tar Oxf build/$NAME.tar.zst checksums.txt | grep -v sboms.tar) + EXPECTED_CHECKSUM=$(cat $f | grep -v sboms.tar) + if [[ "$CHECKSUM" != "$EXPECTED_CHECKSUM" ]] + then + echo "Package $f does not have expected checksum." + echo "$CHECKSUM" + echo "-----" + echo "$EXPECTED_CHECKSUM" + exit 1 + fi + done diff --git a/.github/workflows/test-site.yml b/.github/workflows/test-site.yml index 2f6aa0adb1..e5f592ab4f 100644 --- a/.github/workflows/test-site.yml +++ b/.github/workflows/test-site.yml @@ -19,10 +19,10 @@ jobs: working-directory: ./site steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 - name: npm ci run: npm ci diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml index cec2d23eda..a9915a9309 100644 --- a/.github/workflows/test-unit.yml +++ b/.github/workflows/test-unit.yml @@ -38,10 +38,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Run unit tests run: make test-unit diff --git a/.github/workflows/test-upgrade.yml b/.github/workflows/test-upgrade.yml index 8922a88cb0..43a4ffe519 100644 --- a/.github/workflows/test-upgrade.yml +++ b/.github/workflows/test-upgrade.yml @@ -34,10 +34,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Build PR binary and zarf init package uses: ./.github/actions/packages @@ -57,7 +59,7 @@ jobs: needs: build-upgrade steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download build artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -66,7 +68,9 @@ jobs: path: build/ - name: Setup golang - uses: ./.github/actions/golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Make Zarf executable run: | diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 21cca72af2..babba0aabc 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -34,7 +34,12 @@ jobs: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Run Windows unit tests run: make test-unit @@ -44,7 +49,12 @@ jobs: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup golang + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version-file: go.mod - name: Build Windows binary and zarf packages uses: ./.github/actions/packages diff --git a/.golangci.yaml b/.golangci.yaml index c947d98999..5aac2153f3 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -66,6 +66,9 @@ linters-settings: - (*github.com/spf13/cobra.Command).MarkFlagRequired - (*github.com/spf13/pflag.FlagSet).MarkHidden - (*github.com/spf13/pflag.FlagSet).MarkDeprecated + sloglint: + no-mixed-args: true + key-naming-case: camel issues: # Revive rules that are disabled by default. include: diff --git a/Makefile b/Makefile index 860fdf2333..9c3ac5ea18 100644 --- a/Makefile +++ b/Makefile @@ -72,9 +72,6 @@ destroy: ## Run `zarf destroy` on the current cluster $(ZARF_BIN) destroy --confirm --remove-components rm -fr build -delete-packages: ## Delete all Zarf package tarballs in the project recursively - find . -type f -name 'zarf-package-*' -not -path '*/testdata/*' -print -delete - # Note: the path to the main.go file is not used due to https://github.com/golang/go/issues/51831#issuecomment-1074188363 .PHONY: build build: ## Build the Zarf CLI for the machines OS and architecture diff --git a/examples/dos-games/zarf.yaml b/examples/dos-games/zarf.yaml index 87042ca58d..f3319f8ea7 100644 --- a/examples/dos-games/zarf.yaml +++ b/examples/dos-games/zarf.yaml @@ -15,15 +15,6 @@ components: - manifests/service.yaml images: - ghcr.io/zarf-dev/doom-game:0.0.1 - actions: - onDeploy: - after: - - wait: - cluster: - kind: deployment - name: game - namespace: dos-games - condition: available # YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI # The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples diff --git a/examples/helm-charts/zarf.yaml b/examples/helm-charts/zarf.yaml index e5e3757717..dbb2648204 100644 --- a/examples/helm-charts/zarf.yaml +++ b/examples/helm-charts/zarf.yaml @@ -56,33 +56,6 @@ components: - ghcr.io/stefanprodan/podinfo:6.4.0 # This is the cosign signature for the podinfo image for image signature verification - ghcr.io/stefanprodan/podinfo:sha256-57a654ace69ec02ba8973093b6a786faa15640575fbf0dbb603db55aca2ccec8.sig - actions: - onDeploy: - after: - - wait: - cluster: - kind: deployment - name: podinfo-local - namespace: podinfo-from-local-chart - condition: available - - wait: - cluster: - kind: deployment - name: podinfo-oci - namespace: podinfo-from-oci - condition: available - - wait: - cluster: - kind: deployment - name: podinfo-git - namespace: podinfo-from-git - condition: available - - wait: - cluster: - kind: deployment - name: cool-release-name-podinfo - namespace: podinfo-from-repo - condition: available # YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI # The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples diff --git a/examples/manifests/zarf.yaml b/examples/manifests/zarf.yaml index 092f6ca684..7855f0a02b 100644 --- a/examples/manifests/zarf.yaml +++ b/examples/manifests/zarf.yaml @@ -12,17 +12,6 @@ components: files: # local manifests are specified relative to the `zarf.yaml` that uses them: - httpd-deployment.yaml - actions: - onDeploy: - # the following checks were computed by viewing the success state of the package deployment - # and creating `wait` actions that match - after: - - wait: - cluster: - kind: deployment - name: httpd-deployment - namespace: httpd - condition: "{.status.readyReplicas}=2" # image discovery is supported in all manifests and charts using: # zarf prepare find-images images: @@ -38,17 +27,6 @@ components: - https://k8s.io/examples/application/deployment.yaml@c57f73449b26eae02ca2a549c388807d49ef6d3f2dc040a9bbb1290128d97157 # this sha256 can be discovered using: # zarf prepare sha256sum https://k8s.io/examples/application/deployment.yaml - actions: - onDeploy: - # the following checks were computed by viewing the success state of the package deployment - # and creating `wait` actions that match - after: - - wait: - cluster: - kind: deployment - name: nginx-deployment - namespace: nginx - condition: available # image discovery is supported in all manifests and charts using: # zarf prepare find-images images: @@ -64,17 +42,6 @@ components: - github.com/stefanprodan/podinfo//kustomize?ref=6.4.0 # while ?ref= is not a requirement, it is recommended to use a specific commit hash / git tag to # ensure that the kustomization is not changed in a way that breaks your deployment. - actions: - onDeploy: - # the following checks were computed by viewing the success state of the package deployment - # and creating `wait` actions that match - after: - - wait: - cluster: - kind: deployment - name: podinfo - namespace: podinfo - condition: available # image discovery is supported in all manifests and charts using: # zarf prepare find-images images: diff --git a/examples/podinfo-flux/git/podinfo-kustomization.yaml b/examples/podinfo-flux/git/podinfo-kustomization.yaml index aa251f98ce..bc72ee0aa0 100644 --- a/examples/podinfo-flux/git/podinfo-kustomization.yaml +++ b/examples/podinfo-flux/git/podinfo-kustomization.yaml @@ -12,3 +12,4 @@ spec: kind: GitRepository name: podinfo targetNamespace: podinfo-git + wait: true diff --git a/examples/podinfo-flux/oci/podinfo-kustomization.yaml b/examples/podinfo-flux/oci/podinfo-kustomization.yaml index 57f290e7b6..7acd41f327 100644 --- a/examples/podinfo-flux/oci/podinfo-kustomization.yaml +++ b/examples/podinfo-flux/oci/podinfo-kustomization.yaml @@ -12,3 +12,4 @@ spec: kind: OCIRepository name: podinfo targetNamespace: podinfo-oci + wait: true diff --git a/examples/podinfo-flux/zarf.yaml b/examples/podinfo-flux/zarf.yaml index 6e94a715d0..16b25e3e59 100644 --- a/examples/podinfo-flux/zarf.yaml +++ b/examples/podinfo-flux/zarf.yaml @@ -33,16 +33,6 @@ components: - https://github.com/stefanprodan/podinfo.git images: - ghcr.io/stefanprodan/podinfo:6.4.0 - actions: - onDeploy: - after: - - description: Podinfo pods to be ready via wait action - wait: - cluster: - kind: pod - name: app=podinfo - namespace: podinfo-git - condition: ready - name: podinfo-via-flux-helm description: Example deployment via flux (helm oci) using the famous podinfo example @@ -57,16 +47,6 @@ components: - ghcr.io/stefanprodan/podinfo:6.4.0 # Note: this is a helm OCI artifact rather than a container image - ghcr.io/stefanprodan/charts/podinfo:6.4.0 - actions: - onDeploy: - after: - - description: Podinfo pods to be ready via wait action - wait: - cluster: - kind: pod - name: app.kubernetes.io/name=podinfo - namespace: podinfo-helm - condition: ready - name: podinfo-via-flux-oci description: Example deployment via flux (native oci) using the famous podinfo example @@ -81,17 +61,6 @@ components: - ghcr.io/stefanprodan/podinfo:6.4.0 # Note: this is a flux kustomize OCI artifact rather than a container image - ghcr.io/stefanprodan/manifests/podinfo:6.4.0 - actions: - onDeploy: - after: - # This will use a wait action to wait for the podinfo pod to be ready - - description: Podinfo pods to be ready via wait action - wait: - cluster: - kind: pod - name: app=podinfo - namespace: podinfo-oci - condition: ready # YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI # The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples diff --git a/examples/variables/zarf.yaml b/examples/variables/zarf.yaml index df2873b1c4..e180acdaa8 100644 --- a/examples/variables/zarf.yaml +++ b/examples/variables/zarf.yaml @@ -81,15 +81,6 @@ components: - nginx-configmap.yaml - nginx-deployment.yaml - nginx-service.yaml - actions: - onDeploy: - after: - - wait: - cluster: - kind: pod - namespace: nginx - name: app=nginx - condition: Ready # YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI # The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples diff --git a/examples/yolo/zarf.yaml b/examples/yolo/zarf.yaml index dfa4cf65f1..71a3f7aa95 100644 --- a/examples/yolo/zarf.yaml +++ b/examples/yolo/zarf.yaml @@ -13,15 +13,6 @@ components: files: - ../dos-games/manifests/deployment.yaml - ../dos-games/manifests/service.yaml - actions: - onDeploy: - after: - - wait: - cluster: - kind: deployment - name: game - namespace: zarf-yolo-example - condition: available # YAML keys starting with `x-` are custom keys that are ignored by the Zarf CLI # The `x-mdx` key is used to render the markdown content for https://docs.zarf.dev/ref/examples diff --git a/go.mod b/go.mod index 75c52d5f4f..d289ea2d49 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/zarf-dev/zarf -go 1.22.7 +go 1.22.8 // TODO (@AABRO): Pending merge into github.com/gojsonschema/gojsonschema (https://github.com/gojsonschema/gojsonschema/pull/5) replace github.com/xeipuuv/gojsonschema => github.com/defenseunicorns/gojsonschema v0.0.0-20231116163348-e00f069122d6 @@ -13,38 +13,39 @@ require ( github.com/Masterminds/semver/v3 v3.3.0 github.com/agnivade/levenshtein v1.2.0 github.com/anchore/clio v0.0.0-20240705045624-ac88e09ad9d0 - github.com/anchore/stereoscope v0.0.4-0.20241005180410-efa76446cc1c - github.com/anchore/syft v1.14.0 + github.com/anchore/stereoscope v0.0.5 + github.com/anchore/syft v1.14.2 github.com/avast/retry-go/v4 v4.6.0 github.com/defenseunicorns/pkg/helpers/v2 v2.0.1 - github.com/defenseunicorns/pkg/kubernetes v0.3.0 github.com/defenseunicorns/pkg/oci v1.0.2 github.com/derailed/k9s v0.32.5 github.com/distribution/distribution/v3 v3.0.0-beta.1 github.com/distribution/reference v0.6.0 github.com/fairwindsops/pluto/v5 v5.20.3 - github.com/fatih/color v1.17.0 + github.com/fatih/color v1.18.0 github.com/fluxcd/gitkit v0.6.0 github.com/fluxcd/pkg/apis/meta v1.6.1 github.com/fluxcd/source-controller/api v1.4.1 github.com/go-git/go-git/v5 v5.12.0 - github.com/goccy/go-yaml v1.12.0 + github.com/goccy/go-yaml v1.13.0 github.com/gofrs/flock v0.12.1 + github.com/golang-cz/devslog v0.0.11 github.com/google/go-containerregistry v0.20.2 github.com/gosuri/uitable v0.0.4 github.com/invopop/jsonschema v0.12.0 github.com/mholt/archiver/v3 v3.5.1 github.com/moby/moby v27.3.1+incompatible github.com/opencontainers/image-spec v1.1.0 + github.com/phsym/console-slog v0.3.1 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.20.4 + github.com/prometheus/client_golang v1.20.5 github.com/pterm/pterm v0.12.79 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 github.com/sigstore/cosign/v2 v2.4.1 - github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9 - github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.9 - github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9 - github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.9 + github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10 + github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.10 + github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10 + github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.10 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 @@ -54,16 +55,16 @@ require ( golang.org/x/sync v0.8.0 golang.org/x/term v0.25.0 helm.sh/helm/v3 v3.16.2 - k8s.io/api v0.31.1 - k8s.io/apimachinery v0.31.1 - k8s.io/client-go v0.31.1 - k8s.io/component-base v0.31.1 + k8s.io/api v0.31.2 + k8s.io/apimachinery v0.31.2 + k8s.io/client-go v0.31.2 + k8s.io/component-base v0.31.2 k8s.io/klog/v2 v2.130.1 - k8s.io/kubectl v0.31.1 + k8s.io/kubectl v0.31.2 oras.land/oras-go/v2 v2.5.0 sigs.k8s.io/cli-utils v0.37.2 - sigs.k8s.io/kustomize/api v0.17.3 - sigs.k8s.io/kustomize/kyaml v0.17.2 + sigs.k8s.io/kustomize/api v0.18.0 + sigs.k8s.io/kustomize/kyaml v0.18.1 sigs.k8s.io/yaml v1.4.0 ) @@ -75,7 +76,7 @@ require ( github.com/charmbracelet/x/ansi v0.2.3 // indirect github.com/charmbracelet/x/term v0.2.0 // indirect github.com/containerd/containerd/api v1.7.19 // indirect - github.com/containerd/errdefs v0.1.0 // indirect + github.com/containerd/errdefs v0.3.0 // indirect github.com/containerd/platforms v0.2.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -91,14 +92,14 @@ require ( github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/in-toto/attestation v1.1.0 // indirect - github.com/jedib0t/go-pretty/v6 v6.6.0 // indirect + github.com/jedib0t/go-pretty/v6 v6.6.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/onsi/gomega v1.34.1 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect - github.com/redis/go-redis/v9 v9.5.1 // indirect + github.com/redis/go-redis/v9 v9.6.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect github.com/sigstore/protobuf-specs v0.3.2 // indirect @@ -124,12 +125,12 @@ require ( atomicgo.dev/keyboard v0.2.9 // indirect atomicgo.dev/schedule v0.1.0 // indirect cloud.google.com/go v0.115.1 // indirect - cloud.google.com/go/auth v0.9.3 // indirect + cloud.google.com/go/auth v0.9.8 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect - cloud.google.com/go/compute/metadata v0.5.0 // indirect - cloud.google.com/go/iam v1.2.0 // indirect - cloud.google.com/go/kms v1.19.0 // indirect - cloud.google.com/go/longrunning v0.6.0 // indirect + cloud.google.com/go/compute/metadata v0.5.2 // indirect + cloud.google.com/go/iam v1.2.1 // indirect + cloud.google.com/go/kms v1.20.0 // indirect + cloud.google.com/go/longrunning v0.6.1 // indirect cloud.google.com/go/storage v1.43.0 // indirect cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 // indirect cuelang.org/go v0.9.2 // indirect @@ -138,8 +139,8 @@ require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.15.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect @@ -169,7 +170,7 @@ require ( github.com/a8m/envsubst v1.4.2 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/acobaugh/osrelease v0.1.0 // indirect - github.com/adrg/xdg v0.5.0 // indirect + github.com/adrg/xdg v0.5.1 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect @@ -189,7 +190,7 @@ require ( github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 // indirect github.com/anchore/grype v0.77.0 // indirect - github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f // indirect + github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect @@ -197,22 +198,22 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect - github.com/aws/aws-sdk-go-v2 v1.30.5 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.33 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.32 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 // indirect + github.com/aws/aws-sdk-go-v2 v1.32.2 // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.43 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.41 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.35.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 // indirect - github.com/aws/smithy-go v1.20.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.37.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 // indirect + github.com/aws/smithy-go v1.22.0 // indirect github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect @@ -222,12 +223,11 @@ require ( github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bmatcuk/doublestar/v2 v2.0.4 // indirect - github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/buildkite/agent/v3 v3.81.0 // indirect github.com/buildkite/go-pipeline v0.13.1 // indirect github.com/buildkite/interpolate v0.1.3 // indirect - github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect @@ -242,7 +242,7 @@ require ( github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/containerd/containerd v1.7.21 // indirect + github.com/containerd/containerd v1.7.23 // indirect github.com/containerd/continuity v0.4.2 // indirect github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/log v0.1.0 // indirect @@ -262,7 +262,7 @@ require ( github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/docker/cli v27.2.1+incompatible // indirect + github.com/docker/cli v27.3.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker v27.3.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.0 // indirect @@ -286,7 +286,7 @@ require ( github.com/fluxcd/pkg/apis/acl v0.3.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.4 // indirect + github.com/gabriel-vasile/mimetype v1.4.6 // indirect github.com/gdamore/encoding v1.0.0 // indirect github.com/github/go-spdx/v2 v2.3.2 // indirect github.com/glebarez/go-sqlite v1.21.2 // indirect @@ -294,7 +294,7 @@ require ( github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 + github.com/go-git/go-billy/v5 v5.6.0 github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect @@ -332,7 +332,7 @@ require ( github.com/google/s2a-go v0.1.8 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.3 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect github.com/gookit/color v1.5.4 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -351,7 +351,7 @@ require ( github.com/hashicorp/go-sockaddr v1.0.5 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hashicorp/vault/api v1.14.0 // indirect + github.com/hashicorp/vault/api v1.15.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect @@ -470,7 +470,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sigstore/fulcio v1.6.3 // indirect github.com/sigstore/rekor v1.3.6 // indirect - github.com/sigstore/sigstore v1.8.9 // indirect + github.com/sigstore/sigstore v1.8.10 // indirect github.com/sigstore/timestamp-authority v1.2.2 // indirect github.com/sirupsen/logrus v1.9.3 github.com/skeema/knownhosts v1.2.2 // indirect @@ -481,7 +481,7 @@ require ( github.com/spf13/cast v1.7.0 // indirect github.com/spiffe/go-spiffe/v2 v2.3.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/sylabs/sif/v2 v2.17.1 // indirect + github.com/sylabs/sif/v2 v2.19.2 // indirect github.com/sylabs/squashfs v1.0.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect @@ -519,7 +519,6 @@ require ( go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.step.sm/crypto v0.51.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect @@ -529,14 +528,14 @@ require ( golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.6.0 // indirect + golang.org/x/time v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/api v0.196.0 // indirect - google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.66.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/api v0.200.0 // indirect + google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 // indirect @@ -546,19 +545,19 @@ require ( gorm.io/gorm v1.25.9 // indirect k8s.io/apiextensions-apiserver v0.31.1 // indirect k8s.io/apiserver v0.31.1 // indirect - k8s.io/cli-runtime v0.31.1 // indirect - k8s.io/component-helpers v0.31.1 // indirect + k8s.io/cli-runtime v0.31.2 // indirect + k8s.io/component-helpers v0.31.2 // indirect k8s.io/kube-openapi v0.0.0-20240816214639-573285566f34 // indirect - k8s.io/metrics v0.31.1 // indirect + k8s.io/metrics v0.31.2 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect modernc.org/libc v1.55.3 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect modernc.org/sqlite v1.33.1 // indirect oras.land/oras-go v1.2.5 // indirect - sigs.k8s.io/controller-runtime v0.19.0 // indirect + sigs.k8s.io/controller-runtime v0.19.1 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/kustomize/v5 v5.4.2 // indirect + sigs.k8s.io/kustomize/kustomize/v5 v5.5.0 // indirect sigs.k8s.io/release-utils v0.8.4 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) diff --git a/go.sum b/go.sum index f1f84685d0..74eff1214d 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjby cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/auth v0.9.3 h1:VOEUIAADkkLtyfr3BLa3R8Ed/j6w1jTBmARx+wb5w5U= -cloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk= +cloud.google.com/go/auth v0.9.8 h1:+CSJ0Gw9iVeSENVCKJoLHhdUykDgXSc4Qn+gu2BRtR8= +cloud.google.com/go/auth v0.9.8/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= @@ -81,8 +81,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= +cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= @@ -121,16 +121,16 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.2.0 h1:kZKMKVNk/IsSSc/udOb83K0hL/Yh/Gcqpz+oAkoIFN8= -cloud.google.com/go/iam v1.2.0/go.mod h1:zITGuWgsLZxd8OwAlX+eMFgZDXzBm7icj1PVTYG766Q= -cloud.google.com/go/kms v1.19.0 h1:x0OVJDl6UH1BSX4THKlMfdcFWoE4ruh90ZHuilZekrU= -cloud.google.com/go/kms v1.19.0/go.mod h1:e4imokuPJUc17Trz2s6lEXFDt8bgDmvpVynH39bdrHM= +cloud.google.com/go/iam v1.2.1 h1:QFct02HRb7H12J/3utj0qf5tobFh9V4vR6h9eX5EBRU= +cloud.google.com/go/iam v1.2.1/go.mod h1:3VUIJDPpwT6p/amXRC5GY8fCCh70lxPygguVtI0Z4/g= +cloud.google.com/go/kms v1.20.0 h1:uKUvjGqbBlI96xGE669hcVnEMw1Px/Mvfa62dhM5UrY= +cloud.google.com/go/kms v1.20.0/go.mod h1:/dMbFF1tLLFnQV44AoI2GlotbjowyUfgVwezxW291fM= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.6.0 h1:mM1ZmaNsQsnb+5n1DNPeL0KwQd9jQRqSqSDEkBZr+aI= -cloud.google.com/go/longrunning v0.6.0/go.mod h1:uHzSZqW89h7/pasCWNYdUpwGz3PcVWhrWupreVPYLts= +cloud.google.com/go/longrunning v0.6.1 h1:lOLTFxYpr8hcRtcwWir5ITh1PAKUD/sG2lKrTSYjyMc= +cloud.google.com/go/longrunning v0.6.1/go.mod h1:nHISoOZpBcmlwbJmiVk5oDRz0qG/ZxPynEGs1iZ79s0= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= @@ -221,10 +221,12 @@ github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.14.0 github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.14.0/go.mod h1:tlqp9mUGbsP+0z3Q+c0Q5MgSdq/OMwQhm5bffR3Q3ss= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.15.0 h1:eXzkOEXbSTOa7cJ7EqeCVi/OFi/ppDrUtQuttCWy74c= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.15.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.1.0 h1:DRiANoJTiW6obBQe3SqZizkuV1PEgfiiGivmVocDy64= @@ -256,6 +258,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -311,8 +315,8 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE= github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY= -github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY= -github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4= +github.com/adrg/xdg v0.5.1 h1:Im8iDbEFARltY09yOJlSGu4Asjk2vF85+3Dyru8uJ0U= +github.com/adrg/xdg v0.5.1/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY= github.com/agnivade/levenshtein v1.2.0/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= @@ -389,12 +393,12 @@ github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/grype v0.77.0 h1:HoTdZ67INrEpEiSKL713zY+j77HxoEAcsMPIZDZ4yP4= github.com/anchore/grype v0.77.0/go.mod h1:k6QLcebOqPm+90y8mMesOJM6A6DYQllOic6Tmz507sc= -github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA= -github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.4-0.20241005180410-efa76446cc1c h1:JXezMk8fF5ns4AgRGW49SGfoRgDjJHsDmcpNw272jkU= -github.com/anchore/stereoscope v0.0.4-0.20241005180410-efa76446cc1c/go.mod h1:GMupz2FoBhy5RTTmawU06c2pZxgVTceahLWiwJef2uI= -github.com/anchore/syft v1.14.0 h1:BeMmc3a9d/63O+nPM8QfV1Olh3r+pYf95JOqbfN4gQg= -github.com/anchore/syft v1.14.0/go.mod h1:8bN2W/Tr4Mmm42h2XB9LPiPOps+NzCFIaQOKLBGb2b8= +github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f h1:dAQPIrQ3a5PBqZeZ+B9NGZsGmodk4NO9OjDIsQmQyQM= +github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI= +github.com/anchore/stereoscope v0.0.5 h1:PILlvsQS3+dT5rNsDudRhi91jukR65y2itG1lQOLn0s= +github.com/anchore/stereoscope v0.0.5/go.mod h1:jwK34VB049/iRE1DyWUv4ZWraOaFQ+FpurgvkWMGQzQ= +github.com/anchore/syft v1.14.2 h1:y/1QIsSUaVDzbT1Q29BkKAAyNivt+2wgWzpCxI0b5yc= +github.com/anchore/syft v1.14.2/go.mod h1:tyGQPeUSS9498A10nUF1kEVIObsvsnmrWt6hP25EjXE= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= @@ -428,41 +432,41 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.30.5 h1:mWSRTwQAb0aLE17dSzztCVJWI9+cRMgqebndjwDyK0g= -github.com/aws/aws-sdk-go-v2 v1.30.5/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/config v1.27.33 h1:Nof9o/MsmH4oa0s2q9a0k7tMz5x/Yj5k06lDODWz3BU= -github.com/aws/aws-sdk-go-v2/config v1.27.33/go.mod h1:kEqdYzRb8dd8Sy2pOdEbExTTF5v7ozEXX0McgPE7xks= -github.com/aws/aws-sdk-go-v2/credentials v1.17.32 h1:7Cxhp/BnT2RcGy4VisJ9miUPecY+lyE9I8JvcZofn9I= -github.com/aws/aws-sdk-go-v2/credentials v1.17.32/go.mod h1:P5/QMF3/DCHbXGEGkdbilXHsyTBX5D3HSwcrSc9p20I= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 h1:pfQ2sqNpMVK6xz2RbqLEL0GH87JOwSxPV2rzm8Zsb74= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13/go.mod h1:NG7RXPUlqfsCLLFfi0+IpKN4sCB9D9fw/qTaSB+xRoU= +github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= +github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2/config v1.27.43 h1:p33fDDihFC390dhhuv8nOmX419wjOSDQRb+USt20RrU= +github.com/aws/aws-sdk-go-v2/config v1.27.43/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc= +github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 h1:TMH3f/SCAWdNtXXVPPu5D6wrr4G5hI1rAxbcocKfC7Q= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17/go.mod h1:1ZRXLdTpzdJb9fwTMXiLipENRxkGMTn1sfKexGllQCw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 h1:pI7Bzt0BJtYA0N/JEC6B8fJ4RBrEMi1LBrkMdFYNSnQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17/go.mod h1:Dh5zzJYMtxfIjYW+/evjQ8uj2OyR/ve2KROHGHlSFqE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 h1:Mqr/V5gvrhA2gvgnF42Zh5iMiQNcOYthFYwCyrnuWlc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17/go.mod h1:aLJpZlCmjE+V+KtN1q1uyZkfnUWpQGpbsn89XPKyzfU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 h1:y6LX9GUoEA3mO0qpFl1ZQHj1rFyPWVphlzebiSt2tKE= github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2/go.mod h1:Q0LcmaN/Qr8+4aSBrdrXXePqoX0eOuYpJLbYpilmWnA= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 h1:PpbXaecV3sLAS6rjQiaKw4/jyq3Z8gNzmoJupHAoBp0= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2/go.mod h1:fUHpGXr4DrXkEDpGAjClPsviWf+Bszeb0daKE0blxv8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 h1:rfprUlsdzgl7ZL2KlXiUAoJnI/VxfHCvDFr2QDFj6u4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19/go.mod h1:SCWkEdRq8/7EK60NcvvQ6NXKuTcchAD4ROAsC37VEZE= -github.com/aws/aws-sdk-go-v2/service/kms v1.35.7 h1:v0D1LeMkA/X+JHAZWERrr+sUGOt8KrCZKnJA6KszkcE= -github.com/aws/aws-sdk-go-v2/service/kms v1.35.7/go.mod h1:K9lwD0Rsx9+NSaJKsdAdlDK4b2G4KKOEve9PzHxPoMI= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 h1:pIaGg+08llrP7Q5aiz9ICWbY8cqhTkyy+0SHvfzQpTc= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.7/go.mod h1:eEygMHnTKH/3kNp9Jr1n3PdejuSNcgwLe1dWgQtO0VQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 h1:/Cfdu0XV3mONYKaOt1Gr0k1KvQzkzPyiKUdlWJqy+J4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7/go.mod h1:bCbAxKDqNvkHxRaIMnyVPXPo+OaPRwvmgzMxbz1VKSA= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 h1:NKTa1eqZYw8tiHSRGpP0VtTdub/8KNk8sDkNPFaOKDE= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.7/go.mod h1:NXi1dIAGteSaRLqYgarlhP/Ij0cFT+qmCwiJqWh/U5o= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.2 h1:tfBABi5R6aSZlhgTWHxL+opYUDOnIGoNcJLwVYv0jLM= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.2/go.mod h1:dZYFcQwuoh+cLOlFnZItijZptmyDhRIkOKWFO1CfzV8= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 h1:bSYXVyUzoTHoKalBmwaZxs97HU9DWWI3ehHSAMa7xOk= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.2/go.mod h1:skMqY7JElusiOUjMJMOv1jJsP7YUg7DrhgqZZWuzu1U= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 h1:AhmO1fHINP9vFYUE0LHzCWg/LfUWUF+zFPEcY9QXb7o= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2/go.mod h1:o8aQygT2+MVP0NaV6kbdE1YnnIM8RRVQzoeUH45GOdI= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 h1:CiS7i0+FUe+/YY1GvIBLLrR/XNGZ4CtM1Ll0XavNuVo= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.2/go.mod h1:HtaiBI8CjYoNVde8arShXb94UbQQi9L4EMr6D+xGBwo= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= -github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= +github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 h1:SoFYaT9UyGkR0+nogNyD/Lj+bsixB+SNuAS4ABlEs6M= github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8/go.mod h1:2JF49jcDOrLStIXN/j/K1EKRq8a8R2qRnlZA6/o/c7c= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -484,8 +488,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmatcuk/doublestar/v2 v2.0.4 h1:6I6oUiT/sU27eE2OFcWqBhL1SwjyvQuOssxT4a1yidI= github.com/bmatcuk/doublestar/v2 v2.0.4/go.mod h1:QMmcs3H2AUQICWhfzLXz+IYln8lRQmTZRptLie8RgRw= -github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= -github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q= +github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= @@ -509,8 +513,6 @@ github.com/buildkite/roko v1.2.0/go.mod h1:23R9e6nHxgedznkwwfmqZ6+0VJZJZ2Sg/uVcp github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= -github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= -github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -572,14 +574,14 @@ github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHq github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd v1.7.21 h1:USGXRK1eOC/SX0L195YgxTHb0a00anxajOzgfN0qrCA= -github.com/containerd/containerd v1.7.21/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g= +github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ= +github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw= github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA= github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= +github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4= +github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -621,8 +623,6 @@ github.com/defenseunicorns/gojsonschema v0.0.0-20231116163348-e00f069122d6 h1:gw github.com/defenseunicorns/gojsonschema v0.0.0-20231116163348-e00f069122d6/go.mod h1:StKLYMmPj1R5yIs6CK49EkcW1TvUYuw5Vri+LRk7Dy8= github.com/defenseunicorns/pkg/helpers/v2 v2.0.1 h1:j08rz9vhyD9Bs+yKiyQMY2tSSejXRMxTqEObZ5M1Wbk= github.com/defenseunicorns/pkg/helpers/v2 v2.0.1/go.mod h1:u1PAqOICZyiGIVA2v28g55bQH1GiAt0Bc4U9/rnWQvQ= -github.com/defenseunicorns/pkg/kubernetes v0.3.0 h1:f4VSIaUdvn87/dhiZvRbUfHhcHa8bKia6aU0WcvPbYg= -github.com/defenseunicorns/pkg/kubernetes v0.3.0/go.mod h1:FsuKQGpPZOnZWifBse7v787+avtIu2lte5LTsaojDkY= github.com/defenseunicorns/pkg/oci v1.0.2 h1:JRdFbKnJQiGVsMUWmcmm0ZS8aBmmAORXLGSAGkIGhBQ= github.com/defenseunicorns/pkg/oci v1.0.2/go.mod h1:z11UFenAd4HQRucaEp0uhoccor/6zbQiXEQq+Z7vtI0= github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da h1:ZOjWpVsFZ06eIhnh4mkaceTiVoktdU67+M7KDHJ268M= @@ -657,8 +657,8 @@ github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfG github.com/distribution/distribution/v3 v3.0.0-beta.1/go.mod h1:O9O8uamhHzWWQVTjuQpyYUVm/ShPHPUDgvQMpHGVBDs= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.2.1+incompatible h1:U5BPtiD0viUzjGAjV1p0MGB8eVA3L3cbIrnyWmSJI70= -github.com/docker/cli v27.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= +github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= @@ -724,8 +724,8 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= @@ -756,8 +756,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= -github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= +github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= +github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -781,8 +781,8 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= @@ -835,8 +835,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U= -github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc= @@ -857,8 +857,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= -github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= +github.com/goccy/go-yaml v1.13.0 h1:0Wtp0FZLd7Sm8gERmR9S6Iczzb3vItJj7NaHmFg8pTs= +github.com/goccy/go-yaml v1.13.0/go.mod h1:IjYwxUiJDoqpx2RmbdjMUceGHZwYLon3sfOGl5Hi9lc= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -869,6 +869,8 @@ github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-cz/devslog v0.0.11 h1:v4Yb9o0ZpuZ/D8ZrtVw1f9q5XrjnkxwHF1XmWwO8IHg= +github.com/golang-cz/devslog v0.0.11/go.mod h1:bSe5bm0A7Nyfqtijf1OMNgVJHlWEuVSXnkuASiE1vV8= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= @@ -876,8 +878,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -1000,8 +1002,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.3.3 h1:QRje2j5GZimBzlbhGA2V2QlGNgL8G6e+wGo/+/2bWI0= -github.com/googleapis/enterprise-certificate-proxy v0.3.3/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= +github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= +github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -1097,8 +1099,8 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU= -github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk= +github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA= +github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= @@ -1127,8 +1129,8 @@ github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10C github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jedib0t/go-pretty/v6 v6.6.0 h1:wmZVuAcEkZRT+Aq1xXpE8IGat4vE5WXOMmBpbQqERXw= -github.com/jedib0t/go-pretty/v6 v6.6.0/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= +github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc= +github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc= @@ -1168,6 +1170,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -1418,6 +1422,8 @@ github.com/petergtz/pegomock v2.9.0+incompatible h1:BKfb5XfkJfehe5T+O1xD4Zm26Sb9 github.com/petergtz/pegomock v2.9.0+incompatible/go.mod h1:nuBLWZpVyv/fLo56qTwt/AUau7jgouO1h7bEvZCq82o= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/phsym/console-slog v0.3.1 h1:Fuzcrjr40xTc004S9Kni8XfNsk+qrptQmyR+wZw9/7A= +github.com/phsym/console-slog v0.3.1/go.mod h1:oJskjp/X6e6c0mGpfP8ELkfKUsrkDifYRAqJQgmdDS0= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= @@ -1445,8 +1451,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1484,8 +1490,8 @@ github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJu github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= -github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= -github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -1529,8 +1535,8 @@ github.com/sassoftware/relic/v7 v7.6.2/go.mod h1:kjmP0IBVkJZ6gXeAu35/KCEfca//+PK github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ= github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= -github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= +github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY= +github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc= github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA= github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= @@ -1554,18 +1560,18 @@ github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWw github.com/sigstore/protobuf-specs v0.3.2/go.mod h1:RZ0uOdJR4OB3tLQeAyWoJFbNCBFrPQdcokntde4zRBA= github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8= github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc= -github.com/sigstore/sigstore v1.8.9 h1:NiUZIVWywgYuVTxXmRoTT4O4QAGiTEKup4N1wdxFadk= -github.com/sigstore/sigstore v1.8.9/go.mod h1:d9ZAbNDs8JJfxJrYmulaTazU3Pwr8uLL9+mii4BNR3w= +github.com/sigstore/sigstore v1.8.10 h1:r4t+TYzJlG9JdFxMy+um9GZhZ2N1hBTyTex0AHEZxFs= +github.com/sigstore/sigstore v1.8.10/go.mod h1:BekjqxS5ZtHNJC4u3Q3Stvfx2eyisbW/lUZzmPU2u4A= github.com/sigstore/sigstore-go v0.6.1 h1:tGkkv1oDIER+QYU5MrjqlttQOVDWfSkmYwMqkJhB/cg= github.com/sigstore/sigstore-go v0.6.1/go.mod h1:Xe5GHmUeACRFbomUWzVkf/xYCn8xVifb9DgqJrV2dIw= -github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9 h1:tgpdvjyoEgYFeTBFe4MHvBKsG+J4E7NVtstChIExVT8= -github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9/go.mod h1:wCz6cAZKL/wFumDHX9l8VkVITS2GntrOfs2j/kwH4wo= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.9 h1:eXFm3cte0hvxxYsvGpCMd7aBusEgKJdlUw1Fb5AZQpw= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.9/go.mod h1:RYy9GKnFKKwqbg3Uc6rUyhQdichSVkFlfxnY6f7cAWc= -github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9 h1:liWcl12dfFeQXU0JemQVgdVQx02Fls9UPdrFzVrCWhs= -github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9/go.mod h1:Ckx62auqPQvNJWRBAboY+/kHs77gy6L33b6UtB/FB5U= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.9 h1:E+bvFTS6uM//iSAeneNj5pubzntQmio/yAKFzmRzzD0= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.9/go.mod h1:0RKVuZXIZAFhT0frfx+GzyrtlesiRK3ceF55nIgkZI4= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10 h1:e5GfVngPjGap/N3ODefayt7vKIPS1/v3hWLZ9+4MrN4= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10/go.mod h1:HOr3AdFPKdND2FNl/sUD5ZifPl1OMJvrbf9xIaaWcus= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.10 h1:9tZEpfIL/ewAG9G87AHe3aVoy8Ujos2F1qLfCckX6jQ= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.10/go.mod h1:VnIAcitund62R45ezK/dtUeEhuRtB3LsAgJ8m0H34zc= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10 h1:Xre51HdjIIaVo5ox5zyL+6h0tkrx7Ke9Neh7fLmmZK0= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10/go.mod h1:VNfdklQDbyGJog8S7apdxiEfmYmCkKyxrsCL9xprkTY= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.10 h1:HjfjL3x3dP2kaGqQHVog974cTcKfzFaGjfZyLQ9KXrg= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.10/go.mod h1:jaeEjkTW1p3gUyPjz9lTcT4TydCs208FoyAwIs6bIT4= github.com/sigstore/timestamp-authority v1.2.2 h1:X4qyutnCQqJ0apMewFyx+3t7Tws00JQ/JonBiu3QvLE= github.com/sigstore/timestamp-authority v1.2.2/go.mod h1:nEah4Eq4wpliDjlY342rXclGSO7Kb9hoRrl9tqLW13A= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1630,8 +1636,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/sylabs/sif/v2 v2.17.1 h1:p6Sl0LWyShXBj2SBsS1dMOMIMrZHe8pwBnBrYt6uo4M= -github.com/sylabs/sif/v2 v2.17.1/go.mod h1:XUGB6AQUXGkms3qPOPdevctT3lBLRLWZNWHVnt5HMKE= +github.com/sylabs/sif/v2 v2.19.2 h1:KKcUKnbnT69rN1WWHRYoAVKFpqnXpNJ36kmQLpp86Uc= +github.com/sylabs/sif/v2 v2.19.2/go.mod h1:nhX6D/CJntHDWspNLXLe+yct0cd5lm8HJ7VIW6hgKrw= github.com/sylabs/squashfs v1.0.0 h1:xAyMS21ogglkuR5HaY55PCfqY3H32ma9GkasTYo28Zg= github.com/sylabs/squashfs v1.0.0/go.mod h1:rhWzvgefq1X+R+LZdts10hfMsTg3g74OfGunW8tvg/4= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= @@ -1781,8 +1787,6 @@ go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+M go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.step.sm/crypto v0.51.2 h1:5EiCGIMg7IvQTGmJrwRosbXeprtT80OhoS/PJarg60o= go.step.sm/crypto v0.51.2/go.mod h1:QK7czLjN2k+uqVp5CHXxJbhc70kVRSP+0CQF3zsR5M0= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -2084,7 +2088,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -2117,8 +2120,8 @@ golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -2240,8 +2243,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.196.0 h1:k/RafYqebaIJBO3+SMnfEGtFVlvp5vSgqTUF54UN/zg= -google.golang.org/api v0.196.0/go.mod h1:g9IL21uGkYgvQ5BZg6BAtoGJQIm8r6EgaAbpNey5wBE= +google.golang.org/api v0.200.0 h1:0ytfNWn101is6e9VBoct2wrGDjOi5vn7jw5KtaQgDrU= +google.golang.org/api v0.200.0/go.mod h1:Tc5u9kcbjO7A8SwGlYj4IiVifJU01UqXtEgDMYmBmV8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2354,12 +2357,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 h1:BulPr26Jqjnd4eYDVe+YvyR7Yc2vJGkO5/0UxD0/jZU= -google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4= -google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= -google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 h1:nFS3IivktIU5Mk6KQa+v6RKkHUpdQpphqGNLxqNnbEk= +google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:tEzYTYZxbmVNOu0OAFH9HzdJtLn6h4Aj89zzlBCdHms= +google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f h1:jTm13A2itBi3La6yTGqn8bVSrc3ZZ1r8ENHlIXBfnRA= +google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f/go.mod h1:CLGoBuH1VHxAUXVPP8FfPwPEVJB6lz3URE5mY2SuayE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -2396,8 +2399,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= -google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2414,8 +2417,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2466,30 +2469,30 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU= -k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI= +k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= +k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40= k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ= -k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= -k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= +k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c= k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM= -k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk= -k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U= -k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0= -k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg= -k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8= -k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w= -k8s.io/component-helpers v0.31.1 h1:5hZUf3747atdgtR3gPntrG35rC2CkK7rYq2KUraz6Os= -k8s.io/component-helpers v0.31.1/go.mod h1:ye0Gi8KzFNTfpIuzvVDtxJQMP/0Owkukf1vGf22Hl6U= +k8s.io/cli-runtime v0.31.2 h1:7FQt4C4Xnqx8V1GJqymInK0FFsoC+fAZtbLqgXYVOLQ= +k8s.io/cli-runtime v0.31.2/go.mod h1:XROyicf+G7rQ6FQJMbeDV9jqxzkWXTYD6Uxd15noe0Q= +k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= +k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= +k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA= +k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ= +k8s.io/component-helpers v0.31.2 h1:V2yjoNeyg8WfvwrJwzfYz+RUwjlbcAIaDaHEStBbaZM= +k8s.io/component-helpers v0.31.2/go.mod h1:cNz+1ck38R0qWrjcw/rhQgGP6+Gwgw8ngr2ziDNmSXM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240816214639-573285566f34 h1:/amS69DLm09mtbFtN3+LyygSFohnYGMseF8iv+2zulg= k8s.io/kube-openapi v0.0.0-20240816214639-573285566f34/go.mod h1:G0W3eI9gG219NHRq3h5uQaRBl4pj4ZpwzRP5ti8y770= -k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24= -k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM= -k8s.io/metrics v0.31.1 h1:h4I4dakgh/zKflWYAOQhwf0EXaqy8LxAIyE/GBvxqRc= -k8s.io/metrics v0.31.1/go.mod h1:JuH1S9tJiH9q1VCY0yzSCawi7kzNLsDzlWDJN4xR+iA= +k8s.io/kubectl v0.31.2 h1:gTxbvRkMBwvTSAlobiTVqsH6S8Aa1aGyBcu5xYLsn8M= +k8s.io/kubectl v0.31.2/go.mod h1:EyASYVU6PY+032RrTh5ahtSOMgoDRIux9V1JLKtG5xM= +k8s.io/metrics v0.31.2 h1:sQhujR9m3HN/Nu/0fTfTscjnswQl0qkQAodEdGBS0N4= +k8s.io/metrics v0.31.2/go.mod h1:QqqyReApEWO1UEgXOSXiHCQod6yTxYctbAAQBWZkboU= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= @@ -2527,16 +2530,16 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/cli-utils v0.37.2 h1:GOfKw5RV2HDQZDJlru5KkfLO1tbxqMoyn1IYUxqBpNg= sigs.k8s.io/cli-utils v0.37.2/go.mod h1:V+IZZr4UoGj7gMJXklWBg6t5xbdThFBcpj4MrZuCYco= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/controller-runtime v0.19.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk= +sigs.k8s.io/controller-runtime v0.19.1/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.17.3 h1:6GCuHSsxq7fN5yhF2XrC+AAr8gxQwhexgHflOAD/JJU= -sigs.k8s.io/kustomize/api v0.17.3/go.mod h1:TuDH4mdx7jTfK61SQ/j1QZM/QWR+5rmEiNjvYlhzFhc= -sigs.k8s.io/kustomize/kustomize/v5 v5.4.2 h1:9Zl5Gqg3XMdBEvkR54pVLCBj7FVO7W+VPNDDEzD6AyE= -sigs.k8s.io/kustomize/kustomize/v5 v5.4.2/go.mod h1:5ypfJVYlPb2MKKeoGknVLxvHemDlQT+szI4+KOhnD6k= -sigs.k8s.io/kustomize/kyaml v0.17.2 h1:+AzvoJUY0kq4QAhH/ydPHHMRLijtUKiyVyh7fOSshr0= -sigs.k8s.io/kustomize/kyaml v0.17.2/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= +sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= +sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U= +sigs.k8s.io/kustomize/kustomize/v5 v5.5.0 h1:o1mtt6vpxsxDYaZKrw3BnEtc+pAjLz7UffnIvHNbvW0= +sigs.k8s.io/kustomize/kustomize/v5 v5.5.0/go.mod h1:AeFCmgCrXzmvjWWaeZCyBp6XzG1Y0w1svYus8GhJEOE= +sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E= +sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= sigs.k8s.io/release-utils v0.8.4 h1:4QVr3UgbyY/d9p74LBhg0njSVQofUsAZqYOzVZBhdBw= sigs.k8s.io/release-utils v0.8.4/go.mod h1:m1bHfscTemQp+z+pLCZnkXih9n0+WukIUU70n6nFnU0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/hack/examples-checksums/zarf-package-component-actions-amd64.txt b/hack/examples-checksums/zarf-package-component-actions-amd64.txt new file mode 100644 index 0000000000..24913a26dd --- /dev/null +++ b/hack/examples-checksums/zarf-package-component-actions-amd64.txt @@ -0,0 +1,3 @@ +cfd67a2aeebf13c632207183e1d5cd57146a28aa22b5ddf8896c6ce593c627c2 components/on-deploy-with-wait-action.tar +d26e18c92ff9f93b296fad6be153f02d4a746f0ec44dbcf4c526f1e121ffe4ec components/on-remove.tar +fbfcd7215652819a3b03084d2a12ca7594d8c610ac6e2ebed2f229a0019a52e2 components/on-deploy-with-template-use-of-variable.tar diff --git a/hack/examples-checksums/zarf-package-component-choice-amd64.txt b/hack/examples-checksums/zarf-package-component-choice-amd64.txt new file mode 100644 index 0000000000..ecce58903a --- /dev/null +++ b/hack/examples-checksums/zarf-package-component-choice-amd64.txt @@ -0,0 +1,2 @@ +fa862d90928e52ccc9faa69b5eae73bb97fa5acb76407ba6a177eb338f7d692d components/first-choice.tar +fb99083f2881d87f556c1a7a163876aeaaf1e6094526ff50b2775fc85f8858a3 components/second-choice.tar diff --git a/hack/examples-checksums/zarf-package-dos-games-amd64-1.1.0.txt b/hack/examples-checksums/zarf-package-dos-games-amd64-1.1.0.txt new file mode 100644 index 0000000000..e0a3ce3493 --- /dev/null +++ b/hack/examples-checksums/zarf-package-dos-games-amd64-1.1.0.txt @@ -0,0 +1,8 @@ +0a44b759e219d9d6f3c7cbbf40c57ede71a1f9bf54da65767c4137be74727662 images/blobs/sha256/0a44b759e219d9d6f3c7cbbf40c57ede71a1f9bf54da65767c4137be74727662 +4752b809555b8767401dfd39638f256c2373763a1f2cc421012301bb48481e6d images/blobs/sha256/4752b809555b8767401dfd39638f256c2373763a1f2cc421012301bb48481e6d +49f63464352d7b53ceea3b60b9cc764c1a810b28217ee9f13ab7f974bb3ed968 components/baseline.tar +4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 images/blobs/sha256/4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 +b66dbb27a73334db6ac9c030475837bd7f4472d835c72b2360534b203edce6cb images/oci-layout +c7ee390ce7fc9b525429312617f5fbff5fe195544c1d95b44b72330bff15a615 images/index.json +cc1421ef2ded4a559feaefe8dc266488d60675fcc995db7e51f0b0a6d893e010 images/blobs/sha256/cc1421ef2ded4a559feaefe8dc266488d60675fcc995db7e51f0b0a6d893e010 +e6886dc0b01f09d19480a3270fd9e7c4b261346cee9490b881b36edf21c7e722 images/blobs/sha256/e6886dc0b01f09d19480a3270fd9e7c4b261346cee9490b881b36edf21c7e722 diff --git a/hack/examples-checksums/zarf-package-manifests-amd64-0.0.1.txt b/hack/examples-checksums/zarf-package-manifests-amd64-0.0.1.txt new file mode 100644 index 0000000000..3553f82efa --- /dev/null +++ b/hack/examples-checksums/zarf-package-manifests-amd64-0.0.1.txt @@ -0,0 +1,27 @@ +0f23e58bd0b7c74311703e20c21c690a6847e62240ed456f8821f4c067d3659b images/blobs/sha256/0f23e58bd0b7c74311703e20c21c690a6847e62240ed456f8821f4c067d3659b +12cba3a8e34081029e840e7ac5454c080835cbc5a7adc1620482e939283a3a49 images/blobs/sha256/12cba3a8e34081029e840e7ac5454c080835cbc5a7adc1620482e939283a3a49 +27833a3ba0a545deda33bb01eaf95a14d05d43bf30bce9267d92d17f069fe897 images/blobs/sha256/27833a3ba0a545deda33bb01eaf95a14d05d43bf30bce9267d92d17f069fe897 +27e17b7ec145d38d0be7b5837639a1206f2f3902f7831a6060d0b897f144decd images/index.json +295c7be079025306c4f1d65997fcf7adb411c88f139ad1d34b537164aa060369 images/blobs/sha256/295c7be079025306c4f1d65997fcf7adb411c88f139ad1d34b537164aa060369 +3a96ca29c7fb133e78765557b2bf29a257467f679c43e4153ad05bcde8a1ce3d images/blobs/sha256/3a96ca29c7fb133e78765557b2bf29a257467f679c43e4153ad05bcde8a1ce3d +45ef08258efc940f6336384ae1f35224b5bdf89a3b7abbb5effcbb6c5d62cabe components/nginx-remote.tar +489db2792d7fc3ed75b6970b2e0e73f782bd5c0ed2462ddd683ae92cce04cdb6 images/blobs/sha256/489db2792d7fc3ed75b6970b2e0e73f782bd5c0ed2462ddd683ae92cce04cdb6 +4db1b89c0bd13344176ddce2d093b9da2ae58336823ffed2009a7ea4b62d2a95 images/blobs/sha256/4db1b89c0bd13344176ddce2d093b9da2ae58336823ffed2009a7ea4b62d2a95 +4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 images/blobs/sha256/4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 +706446e9c6667c0880d5da3f39c09a6c7d2114f5a5d6b74a2fafd24ae30d2078 images/blobs/sha256/706446e9c6667c0880d5da3f39c09a6c7d2114f5a5d6b74a2fafd24ae30d2078 +8ca774778e858d3f97d9ec1bec1de879ac5e10096856dc22ed325a3ad944f78a images/blobs/sha256/8ca774778e858d3f97d9ec1bec1de879ac5e10096856dc22ed325a3ad944f78a +92974acd1b7d5aec7654a2df3a310f97c56b7449fc5d042ba8442dbace9a0da6 images/blobs/sha256/92974acd1b7d5aec7654a2df3a310f97c56b7449fc5d042ba8442dbace9a0da6 +9926d2e1a82b13f28b6b9c720bb6947b34c8eabc943de113a3fbc8fabee82d94 images/blobs/sha256/9926d2e1a82b13f28b6b9c720bb6947b34c8eabc943de113a3fbc8fabee82d94 +9b61d3667e8d8d1d8f14ebb413c1ac3fe62373fd69af6aafb281b7a8733f50aa images/blobs/sha256/9b61d3667e8d8d1d8f14ebb413c1ac3fe62373fd69af6aafb281b7a8733f50aa +ae8092b154d705e09bc77523083da3e93200a476ae3aa2b7a5e1747b1cbb8fef images/blobs/sha256/ae8092b154d705e09bc77523083da3e93200a476ae3aa2b7a5e1747b1cbb8fef +b4cd0df67c961ba7f49c86c2e1e6e89d2fd1b8c40ad6fe59508db060dfac51fe images/blobs/sha256/b4cd0df67c961ba7f49c86c2e1e6e89d2fd1b8c40ad6fe59508db060dfac51fe +b66dbb27a73334db6ac9c030475837bd7f4472d835c72b2360534b203edce6cb images/oci-layout +b9c1296647242c2c9c7ffe8cc3a1b9ecde558e8748969ad6a64428ab5922769a images/blobs/sha256/b9c1296647242c2c9c7ffe8cc3a1b9ecde558e8748969ad6a64428ab5922769a +c398742ba22c44f9bbc08dcbbdf0c978b20928fde49dceacded095bc09a46b84 images/blobs/sha256/c398742ba22c44f9bbc08dcbbdf0c978b20928fde49dceacded095bc09a46b84 +c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc7316833c images/blobs/sha256/c926b61bad3b94ae7351bafd0c184c159ebf0643b085f7ef1d47ecdc7316833c +cadc8652ff5abccc918746eb742e7b9165a48428b2c8cc6a48eb6ce782ce5405 images/blobs/sha256/cadc8652ff5abccc918746eb742e7b9165a48428b2c8cc6a48eb6ce782ce5405 +d37d27b92cce4fb1383d5fbe32540382ea3d9662c7be3555f5a0f6a044099e1b images/blobs/sha256/d37d27b92cce4fb1383d5fbe32540382ea3d9662c7be3555f5a0f6a044099e1b +d8173b5b3d825c1c19acf91cb66599f453187705ca9cdb4608d7be5482768cba images/blobs/sha256/d8173b5b3d825c1c19acf91cb66599f453187705ca9cdb4608d7be5482768cba +d95fa8da986254bcd64c1251b695fe91875383dac1ed1780480fdf70f02cea3b images/blobs/sha256/d95fa8da986254bcd64c1251b695fe91875383dac1ed1780480fdf70f02cea3b +f55cf5db16c790710ce2cd7b3d4fa00db89bdeea9d516aa83a596e910de103b2 components/podinfo-kustomize.tar +f59dcac0742ce66d707aed956c25cd0fc20d162ecaca308637197eac1cef13fc components/httpd-local.tar diff --git a/hack/examples-checksums/zarf-package-variables-amd64.txt b/hack/examples-checksums/zarf-package-variables-amd64.txt new file mode 100644 index 0000000000..a0fdb11006 --- /dev/null +++ b/hack/examples-checksums/zarf-package-variables-amd64.txt @@ -0,0 +1,12 @@ +1ff0f94a80076ab49af75159e23f062a30a75d333a8e9c021bf39669230afcfe images/blobs/sha256/1ff0f94a80076ab49af75159e23f062a30a75d333a8e9c021bf39669230afcfe +291f5d3c8c1742164379dfd09b17eeec4f70bcb165773d65d450dec5ef94d907 images/index.json +4b2a24be75c4766f2d20892ddb84841e3773d0e26249ee57eed530da19c07bb2 components/variables-with-nginx.tar +557c9ede65655e5a70e4a32f1651638ea3bfb0802edd982810884602f700ba25 images/blobs/sha256/557c9ede65655e5a70e4a32f1651638ea3bfb0802edd982810884602f700ba25 +84181e80d10e844350789d3324e848cf728df4f3d0f6c978789dd489f493934a images/blobs/sha256/84181e80d10e844350789d3324e848cf728df4f3d0f6c978789dd489f493934a +a8a737eacb28af35791c2a444d8095ca3d493ba31eca78cd57a6fe3cced79154 components/variables-with-terraform.tar +ac232364af842735579e922641ae2f67d5b8ea97df33a207c5ea05f60c63a92d images/blobs/sha256/ac232364af842735579e922641ae2f67d5b8ea97df33a207c5ea05f60c63a92d +b66dbb27a73334db6ac9c030475837bd7f4472d835c72b2360534b203edce6cb images/oci-layout +d4ceccbfc2696101c94fbf2149036e4ff815e4723e518721ff85105ce5aa8afc images/blobs/sha256/d4ceccbfc2696101c94fbf2149036e4ff815e4723e518721ff85105ce5aa8afc +d776269cad101c9f8e33e2baa0a05993ed0786604d86ea525f62d5d7ae7b9540 images/blobs/sha256/d776269cad101c9f8e33e2baa0a05993ed0786604d86ea525f62d5d7ae7b9540 +e9427fcfa8642f8ddf5106f742a75eca0dbac676cf8145598623d04fa45dd74e images/blobs/sha256/e9427fcfa8642f8ddf5106f742a75eca0dbac676cf8145598623d04fa45dd74e +f1f26f5702560b7e591bef5c4d840f76a232bf13fd5aefc4e22077a1ae4440c7 images/blobs/sha256/f1f26f5702560b7e591bef5c4d840f76a232bf13fd5aefc4e22077a1ae4440c7 diff --git a/hack/examples-checksums/zarf-package-yolo-amd64.txt b/hack/examples-checksums/zarf-package-yolo-amd64.txt new file mode 100644 index 0000000000..e925a4d3d9 --- /dev/null +++ b/hack/examples-checksums/zarf-package-yolo-amd64.txt @@ -0,0 +1 @@ +b31cd4195a94c235f6560274fac9efb9934c517381d16593592d02f212e1cd70 components/yolo-games.tar diff --git a/packages/distros/k3s/common/zarf.yaml b/packages/distros/k3s/common/zarf.yaml deleted file mode 100644 index 0a2b6b287e..0000000000 --- a/packages/distros/k3s/common/zarf.yaml +++ /dev/null @@ -1,55 +0,0 @@ -kind: ZarfInitConfig -metadata: - name: distro-k3s - -variables: - - name: K3S_ARGS - description: Arguments to pass to K3s - default: --disable traefik - -components: - - name: k3s - only: - localOS: linux - description: > - *** REQUIRES ROOT (not sudo) *** - Install K3s, a certified Kubernetes distribution built for IoT & Edge computing. - K3s provides the cluster need for Zarf running in Appliance Mode as well as can - host a low-resource Gitops Service if not using an existing Kubernetes platform. - actions: - onDeploy: - defaults: - maxRetries: 5 - before: - - cmd: ./zarf internal is-valid-hostname - maxRetries: 0 - description: Check if the current system has a, RFC1123 compliant hostname - # If running RHEL variant, disable firewalld - # https://rancher.com/docs/k3s/latest/en/advanced/#additional-preparation-for-red-hat-centos-enterprise-linux - # NOTE: The empty echo prevents infinite retry loops on non-RHEL systems where the exit code would be an error - - cmd: "[ -e /etc/redhat-release ] && systemctl disable firewalld --now || echo ''" - description: If running a RHEL variant, disable 'firewalld' per k3s docs - after: - # Configure K3s systemd service - - cmd: systemctl daemon-reload - description: Reload the system services - - cmd: systemctl enable k3s - description: Enable 'k3s' to run at system boot - - cmd: systemctl restart k3s - description: Start the 'k3s' system service - onRemove: - before: - - cmd: /opt/zarf/zarf-clean-k3s.sh - description: Remove 'k3s' from the system - - cmd: rm /opt/zarf/zarf-clean-k3s.sh - description: Remove the cleanup script - files: - # K3s removal script - - source: zarf-clean-k3s.sh - target: /opt/zarf/zarf-clean-k3s.sh - executable: true - # The K3s systemd service definition - - source: k3s.service - target: /etc/systemd/system/k3s.service - symlinks: - - /etc/systemd/system/multi-user.target.wants/k3s.service diff --git a/packages/distros/k3s/common/k3s.service b/packages/distros/k3s/k3s.service similarity index 100% rename from packages/distros/k3s/common/k3s.service rename to packages/distros/k3s/k3s.service diff --git a/packages/distros/k3s/common/zarf-clean-k3s.sh b/packages/distros/k3s/zarf-clean-k3s.sh similarity index 100% rename from packages/distros/k3s/common/zarf-clean-k3s.sh rename to packages/distros/k3s/zarf-clean-k3s.sh diff --git a/packages/distros/k3s/zarf.yaml b/packages/distros/k3s/zarf.yaml index 0813b1ee38..49feef0e85 100644 --- a/packages/distros/k3s/zarf.yaml +++ b/packages/distros/k3s/zarf.yaml @@ -3,16 +3,33 @@ metadata: name: distro-k3s description: Used to establish a new Zarf cluster +variables: + - name: K3S_ARGS + description: Arguments to pass to K3s + default: --disable traefik + components: # AMD-64 version of the K3s stack - name: k3s - import: - path: common - name: k3s only: + localOS: linux cluster: architecture: amd64 + description: > + *** REQUIRES ROOT (not sudo) *** + Install K3s, a certified Kubernetes distribution built for IoT & Edge computing. + K3s provides the cluster need for Zarf running in Appliance Mode as well as can + host a low-resource Gitops Service if not using an existing Kubernetes platform. files: + # K3s removal script + - source: zarf-clean-k3s.sh + target: /opt/zarf/zarf-clean-k3s.sh + executable: true + # The K3s systemd service definition + - source: k3s.service + target: /etc/systemd/system/k3s.service + symlinks: + - /etc/systemd/system/multi-user.target.wants/k3s.service # Include the actual K3s binary - source: https://github.com/k3s-io/k3s/releases/download/v1.28.4+k3s2/k3s shasum: 9014535a4cd20c788282d60398a06279983562093455b53ab76701539ce67acf @@ -29,20 +46,56 @@ components: target: /var/lib/rancher/k3s/agent/images/k3s.tar.zst actions: onDeploy: + defaults: + maxRetries: 5 before: - cmd: if [ "$(uname -m)" != "x86_64" ]; then echo "this package architecture is amd64, but the target system has a different architecture. These architectures must be the same" && exit 1; fi description: Check that the host architecture matches the package architecture maxRetries: 0 + - cmd: ./zarf internal is-valid-hostname + maxRetries: 0 + description: Check if the current system has a, RFC1123 compliant hostname + # If running RHEL variant, disable firewalld + # https://rancher.com/docs/k3s/latest/en/advanced/#additional-preparation-for-red-hat-centos-enterprise-linux + # NOTE: The empty echo prevents infinite retry loops on non-RHEL systems where the exit code would be an error + - cmd: "[ -e /etc/redhat-release ] && systemctl disable firewalld --now || echo ''" + description: If running a RHEL variant, disable 'firewalld' per k3s docs + after: + # Configure K3s systemd service + - cmd: systemctl daemon-reload + description: Reload the system services + - cmd: systemctl enable k3s + description: Enable 'k3s' to run at system boot + - cmd: systemctl restart k3s + description: Start the 'k3s' system service + onRemove: + before: + - cmd: /opt/zarf/zarf-clean-k3s.sh + description: Remove 'k3s' from the system + - cmd: rm /opt/zarf/zarf-clean-k3s.sh + description: Remove the cleanup script # ARM-64 version of the K3s stack - name: k3s - import: - path: common - name: k3s only: + localOS: linux cluster: architecture: arm64 + description: > + *** REQUIRES ROOT (not sudo) *** + Install K3s, a certified Kubernetes distribution built for IoT & Edge computing. + K3s provides the cluster need for Zarf running in Appliance Mode as well as can + host a low-resource Gitops Service if not using an existing Kubernetes platform. files: + # K3s removal script + - source: zarf-clean-k3s.sh + target: /opt/zarf/zarf-clean-k3s.sh + executable: true + # The K3s systemd service definition + - source: k3s.service + target: /etc/systemd/system/k3s.service + symlinks: + - /etc/systemd/system/multi-user.target.wants/k3s.service # Include the actual K3s binary - source: https://github.com/k3s-io/k3s/releases/download/v1.28.4+k3s2/k3s-arm64 shasum: 1ae72ca06d3302f3e86ef92e6e8f84e14a084da69564e87d6e2e75f62e72388d @@ -59,7 +112,31 @@ components: target: /var/lib/rancher/k3s/agent/images/k3s.tar.zst actions: onDeploy: + defaults: + maxRetries: 5 before: - cmd: if [ "$(uname -m)" != "aarch64" ] && [ "$(uname -m)" != "arm64" ]; then echo "this package architecture is arm64, but the target system has a different architecture. These architectures must be the same" && exit 1; fi description: Check that the host architecture matches the package architecture maxRetries: 0 + - cmd: ./zarf internal is-valid-hostname + maxRetries: 0 + description: Check if the current system has a, RFC1123 compliant hostname + # If running RHEL variant, disable firewalld + # https://rancher.com/docs/k3s/latest/en/advanced/#additional-preparation-for-red-hat-centos-enterprise-linux + # NOTE: The empty echo prevents infinite retry loops on non-RHEL systems where the exit code would be an error + - cmd: "[ -e /etc/redhat-release ] && systemctl disable firewalld --now || echo ''" + description: If running a RHEL variant, disable 'firewalld' per k3s docs + after: + # Configure K3s systemd service + - cmd: systemctl daemon-reload + description: Reload the system services + - cmd: systemctl enable k3s + description: Enable 'k3s' to run at system boot + - cmd: systemctl restart k3s + description: Start the 'k3s' system service + onRemove: + before: + - cmd: /opt/zarf/zarf-clean-k3s.sh + description: Remove 'k3s' from the system + - cmd: rm /opt/zarf/zarf-clean-k3s.sh + description: Remove the cleanup script diff --git a/packages/gitea/zarf.yaml b/packages/gitea/zarf.yaml index 2f59bebdba..6a51afe161 100644 --- a/packages/gitea/zarf.yaml +++ b/packages/gitea/zarf.yaml @@ -71,12 +71,6 @@ components: - name: GIT_SERVER_CREATE_PVC mute: true after: - - wait: - cluster: - kind: pod - namespace: zarf - name: app=gitea - condition: Ready - cmd: ./zarf internal create-read-only-gitea-user --no-progress maxRetries: 3 maxTotalSeconds: 60 diff --git a/packages/zarf-agent/zarf.yaml b/packages/zarf-agent/zarf.yaml index 65ee63170f..1e1dac492f 100644 --- a/packages/zarf-agent/zarf.yaml +++ b/packages/zarf-agent/zarf.yaml @@ -40,11 +40,3 @@ components: windows: pwsh dir: ../.. description: Build the local agent image (if 'AGENT_IMAGE_TAG' was specified as 'local') - onDeploy: - after: - - wait: - cluster: - kind: pod - namespace: zarf - name: app=agent-hook - condition: Ready diff --git a/packages/zarf-registry/chart/templates/deployment.yaml b/packages/zarf-registry/chart/templates/deployment.yaml index e0e878eb82..f4263ca731 100644 --- a/packages/zarf-registry/chart/templates/deployment.yaml +++ b/packages/zarf-registry/chart/templates/deployment.yaml @@ -33,8 +33,11 @@ spec: {{- end }} priorityClassName: system-node-critical securityContext: - fsGroup: 1000 runAsUser: 1000 + fsGroup: 2000 + runAsGroup: 2000 + seccompProfile: + type: "RuntimeDefault" containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" @@ -53,6 +56,12 @@ spec: httpGet: path: / port: 5000 + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: ["ALL"] resources: {{ toYaml .Values.resources | indent 12 }} env: diff --git a/packages/zarf-registry/zarf.yaml b/packages/zarf-registry/zarf.yaml index 190eeba4c0..2a5b60dbed 100644 --- a/packages/zarf-registry/zarf.yaml +++ b/packages/zarf-registry/zarf.yaml @@ -171,12 +171,3 @@ components: images: # This image (or images) must match that used for injection (see zarf-config.toml) - "###ZARF_PKG_TMPL_REGISTRY_IMAGE_DOMAIN######ZARF_PKG_TMPL_REGISTRY_IMAGE###:###ZARF_PKG_TMPL_REGISTRY_IMAGE_TAG###" - actions: - onDeploy: - after: - - wait: - cluster: - kind: deployment - namespace: zarf - name: app=docker-registry - condition: Available diff --git a/site/src/content/docs/commands/zarf_tools_sbom.md b/site/src/content/docs/commands/zarf_tools_sbom.md index 139d55bdc6..544b727f47 100644 --- a/site/src/content/docs/commands/zarf_tools_sbom.md +++ b/site/src/content/docs/commands/zarf_tools_sbom.md @@ -25,7 +25,7 @@ zarf tools sbom [flags] -c, --config string syft configuration file --enrich stringArray enable package data enrichment from local and online sources (options: all, golang, java, javascript) --exclude stringArray exclude paths from being scanned using a glob expression - --file string file to write the default report output to (default is STDOUT) (DEPRECATED: use: output) + --file string file to write the default report output to (default is STDOUT) (DEPRECATED: use: --output FORMAT=PATH) --from stringArray specify the source behavior to use (e.g. docker, registry, oci-dir, ...) -h, --help help for sbom -o, --output stringArray report output format (= to output to a file), formats=[cyclonedx-json cyclonedx-xml github-json spdx-json spdx-tag-value syft-json syft-table syft-text template] (default [syft-table]) diff --git a/site/src/content/docs/commands/zarf_tools_sbom_convert.md b/site/src/content/docs/commands/zarf_tools_sbom_convert.md index dc08f90913..e239863e6c 100644 --- a/site/src/content/docs/commands/zarf_tools_sbom_convert.md +++ b/site/src/content/docs/commands/zarf_tools_sbom_convert.md @@ -21,7 +21,7 @@ zarf tools sbom convert [SOURCE-SBOM] -o [FORMAT] [flags] ### Options ``` - --file string file to write the default report output to (default is STDOUT) (DEPRECATED: use: output) + --file string file to write the default report output to (default is STDOUT) (DEPRECATED: use: --output FORMAT=PATH) -h, --help help for convert -o, --output stringArray report output format (= to output to a file), formats=[cyclonedx-json cyclonedx-xml github-json spdx-json spdx-tag-value syft-json syft-table syft-text template] (default [syft-table]) -t, --template string specify the path to a Go template file diff --git a/site/src/content/docs/commands/zarf_tools_sbom_scan.md b/site/src/content/docs/commands/zarf_tools_sbom_scan.md index 4eb9303c2e..e2098828ad 100644 --- a/site/src/content/docs/commands/zarf_tools_sbom_scan.md +++ b/site/src/content/docs/commands/zarf_tools_sbom_scan.md @@ -24,7 +24,7 @@ zarf tools sbom scan [SOURCE] [flags] --base-path string base directory for scanning, no links will be followed above this directory, and all paths will be reported relative to this directory --enrich stringArray enable package data enrichment from local and online sources (options: all, golang, java, javascript) --exclude stringArray exclude paths from being scanned using a glob expression - --file string file to write the default report output to (default is STDOUT) (DEPRECATED: use: output) + --file string file to write the default report output to (default is STDOUT) (DEPRECATED: use: --output FORMAT=PATH) --from stringArray specify the source behavior to use (e.g. docker, registry, oci-dir, ...) -h, --help help for scan -o, --output stringArray report output format (= to output to a file), formats=[cyclonedx-json cyclonedx-xml github-json spdx-json spdx-tag-value syft-json syft-table syft-text template] (default [syft-table]) diff --git a/site/src/content/docs/ref/init-package.mdx b/site/src/content/docs/ref/init-package.mdx index db35cd2330..a155549e9a 100644 --- a/site/src/content/docs/ref/init-package.mdx +++ b/site/src/content/docs/ref/init-package.mdx @@ -32,8 +32,8 @@ View all init options w/ [`zarf init --help`](/commands/zarf_init/). An 'init' package requires a series of specially named, and configured components to ensure the cluster is correctly initialized. These components are: -- [`zarf-injector`](#zarf-injector) -- [`zarf-seed-registry`](#zarf-seed-registry) +- [`zarf-injector`](#zarf-injector-and-zarf-seed-registry) +- [`zarf-seed-registry`](#zarf-injector-and-zarf-seed-registry) - [`zarf-registry`](#zarf-registry) - [`zarf-agent`](#zarf-agent) diff --git a/src/cmd/cmd.go b/src/cmd/cmd.go new file mode 100644 index 0000000000..169c0747dc --- /dev/null +++ b/src/cmd/cmd.go @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package cmd contains the CLI commands for Zarf. +package cmd + +// setBaseDirectory sets the base directory. This is a directory with a zarf.yaml. +func setBaseDirectory(args []string) string { + if len(args) > 0 { + return args[0] + } + return "." +} diff --git a/src/cmd/common/setup.go b/src/cmd/common/setup.go deleted file mode 100644 index ac47d0c95d..0000000000 --- a/src/cmd/common/setup.go +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2021-Present The Zarf Authors - -// Package common handles command configuration across all commands -package common - -import ( - "errors" - "fmt" - "io" - "os" - "time" - - "github.com/pterm/pterm" - - "github.com/zarf-dev/zarf/src/pkg/message" -) - -// SetupCLI sets up the CLI logging -func SetupCLI(logLevel string, skipLogFile, noColor bool) error { - if noColor { - message.DisableColor() - } - - printViperConfigUsed() - - if logLevel != "" { - match := map[string]message.LogLevel{ - "warn": message.WarnLevel, - "info": message.InfoLevel, - "debug": message.DebugLevel, - "trace": message.TraceLevel, - } - lvl, ok := match[logLevel] - if !ok { - return errors.New("invalid log level, valid options are warn, info, debug, and trace") - } - message.SetLogLevel(lvl) - message.Debug("Log level set to " + logLevel) - } - - // Disable progress bars for CI envs - if os.Getenv("CI") == "true" { - message.Debug("CI environment detected, disabling progress bars") - message.NoProgress = true - } - - if !skipLogFile { - ts := time.Now().Format("2006-01-02-15-04-05") - f, err := os.CreateTemp("", fmt.Sprintf("zarf-%s-*.log", ts)) - if err != nil { - return fmt.Errorf("could not create a log file in a the temporary directory: %w", err) - } - logFile, err := message.UseLogFile(f) - if err != nil { - return fmt.Errorf("could not save a log file to the temporary directory: %w", err) - } - pterm.SetDefaultOutput(io.MultiWriter(os.Stderr, logFile)) - message.Notef("Saving log file to %s", f.Name()) - } - return nil -} diff --git a/src/cmd/common/utils.go b/src/cmd/common/utils.go deleted file mode 100644 index 1da7e456ee..0000000000 --- a/src/cmd/common/utils.go +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2021-Present The Zarf Authors - -// Package common handles command configuration across all commands -package common - -// SetBaseDirectory sets the base directory. This is a directory with a zarf.yaml. -func SetBaseDirectory(args []string) string { - if len(args) > 0 { - return args[0] - } - return "." -} diff --git a/src/cmd/common/viper.go b/src/cmd/common/viper.go index fa4f548582..cef9456562 100644 --- a/src/cmd/common/viper.go +++ b/src/cmd/common/viper.go @@ -5,14 +5,15 @@ package common import ( + "context" "errors" "os" "strings" + "github.com/zarf-dev/zarf/src/pkg/logger" + "github.com/spf13/viper" "github.com/zarf-dev/zarf/src/config" - "github.com/zarf-dev/zarf/src/config/lang" - "github.com/zarf-dev/zarf/src/pkg/message" ) // Constants for use when loading configurations from viper config files @@ -20,17 +21,21 @@ const ( // Root config keys - VLogLevel = "log_level" VArchitecture = "architecture" - VNoLogFile = "no_log_file" - VNoProgress = "no_progress" - VNoColor = "no_color" VZarfCache = "zarf_cache" VTmpDir = "tmp_dir" VInsecure = "insecure" VPlainHTTP = "plain_http" VInsecureSkipTLSVerify = "insecure_skip_tls_verify" + // Root config, Logging + + VLogLevel = "log_level" + VLogFormat = "log_format" + VNoLogFile = "no_log_file" + VNoProgress = "no_progress" + VNoColor = "no_color" + // Init config keys VInitComponents = "init.components" @@ -162,7 +167,10 @@ func isVersionCmd() bool { return len(args) > 1 && (args[1] == "version" || args[1] == "v") } -func printViperConfigUsed() { +// PrintViperConfigUsed informs users when Zarf has detected a config file. +func PrintViperConfigUsed(ctx context.Context) { + l := logger.From(ctx) + // Only print config info if viper is initialized. vInitialized := v != nil if !vInitialized { @@ -173,11 +181,11 @@ func printViperConfigUsed() { return } if vConfigError != nil { - message.WarnErrf(vConfigError, lang.CmdViperErrLoadingConfigFile, vConfigError.Error()) + l.Error("unable to load config file", "error", vConfigError) return } if cfgFile := v.ConfigFileUsed(); cfgFile != "" { - message.Notef(lang.CmdViperInfoUsingConfigFile, cfgFile) + l.Info("using config file", "location", cfgFile) } } diff --git a/src/cmd/destroy.go b/src/cmd/destroy.go index 6951efd96b..eeca2ce3f3 100644 --- a/src/cmd/destroy.go +++ b/src/cmd/destroy.go @@ -16,6 +16,7 @@ import ( "github.com/zarf-dev/zarf/src/config/lang" "github.com/zarf-dev/zarf/src/internal/packager/helm" "github.com/zarf-dev/zarf/src/pkg/cluster" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/utils/exec" @@ -33,7 +34,9 @@ var destroyCmd = &cobra.Command{ // TODO(mkcp): refactor and de-nest this function. RunE: func(cmd *cobra.Command, _ []string) error { ctx := cmd.Context() - timeoutCtx, cancel := context.WithTimeout(cmd.Context(), cluster.DefaultTimeout) + l := logger.From(ctx) + + timeoutCtx, cancel := context.WithTimeout(ctx, cluster.DefaultTimeout) defer cancel() c, err := cluster.NewClusterWithWait(timeoutCtx) if err != nil { @@ -46,6 +49,7 @@ var destroyCmd = &cobra.Command{ state, err := c.LoadZarfState(ctx) if err != nil { message.WarnErr(err, err.Error()) + l.Warn(err.Error()) } // If Zarf deployed the cluster, burn it all down @@ -68,6 +72,7 @@ var destroyCmd = &cobra.Command{ err := exec.CmdWithPrint(script) if errors.Is(err, os.ErrPermission) { message.Warnf(lang.CmdDestroyErrScriptPermissionDenied, script) + l.Warn("received 'permission denied' when trying to execute script. Please double-check you have the correct kube-context.", "script", script) // Don't remove scripts we can't execute so the user can try to manually run continue @@ -79,11 +84,12 @@ var destroyCmd = &cobra.Command{ err = os.Remove(script) if err != nil { message.WarnErr(err, fmt.Sprintf("Unable to remove script. script=%s", script)) + l.Warn("unable to remove script", "script", script, "error", err.Error()) } } } else { // Perform chart uninstallation - helm.Destroy(removeComponents) + helm.Destroy(ctx, removeComponents) // If Zarf didn't deploy the cluster, only delete the ZarfNamespace if err := c.DeleteZarfNamespace(ctx); err != nil { diff --git a/src/cmd/dev.go b/src/cmd/dev.go index 34e0f76776..7540c2b365 100644 --- a/src/cmd/dev.go +++ b/src/cmd/dev.go @@ -32,6 +32,8 @@ import ( var extractPath string +var defaultRegistry = fmt.Sprintf("%s:%d", helpers.IPV4Localhost, types.ZarfInClusterContainerRegistryNodePort) + var devCmd = &cobra.Command{ Use: "dev", Aliases: []string{"prepare", "prep"}, @@ -44,7 +46,7 @@ var devDeployCmd = &cobra.Command{ Short: lang.CmdDevDeployShort, Long: lang.CmdDevDeployLong, RunE: func(cmd *cobra.Command, args []string) error { - pkgConfig.CreateOpts.BaseDir = common.SetBaseDirectory(args) + pkgConfig.CreateOpts.BaseDir = setBaseDirectory(args) v := common.GetViper() pkgConfig.CreateOpts.SetVariables = helpers.TransformAndMergeMap( @@ -234,7 +236,7 @@ var devFindImagesCmd = &cobra.Command{ Short: lang.CmdDevFindImagesShort, Long: lang.CmdDevFindImagesLong, RunE: func(cmd *cobra.Command, args []string) error { - pkgConfig.CreateOpts.BaseDir = common.SetBaseDirectory(args) + pkgConfig.CreateOpts.BaseDir = setBaseDirectory(args) v := common.GetViper() @@ -289,7 +291,7 @@ var devLintCmd = &cobra.Command{ Long: lang.CmdDevLintLong, RunE: func(cmd *cobra.Command, args []string) error { config.CommonOptions.Confirm = true - pkgConfig.CreateOpts.BaseDir = common.SetBaseDirectory(args) + pkgConfig.CreateOpts.BaseDir = setBaseDirectory(args) v := common.GetViper() pkgConfig.CreateOpts.SetVariables = helpers.TransformAndMergeMap( v.GetStringMapString(common.VPkgCreateSet), pkgConfig.CreateOpts.SetVariables, strings.ToUpper) @@ -349,8 +351,7 @@ func init() { // skip searching cosign artifacts in find images devFindImagesCmd.Flags().BoolVar(&pkgConfig.FindImagesOpts.SkipCosign, "skip-cosign", false, lang.CmdDevFlagFindImagesSkipCosign) - defaultRegistry := fmt.Sprintf("%s:%d", helpers.IPV4Localhost, types.ZarfInClusterContainerRegistryNodePort) - devFindImagesCmd.Flags().StringVar(&pkgConfig.FindImagesOpts.RegistryURL, "registry-url", defaultRegistry, lang.CmdDevFlagFindImagesRegistry) + devFindImagesCmd.Flags().StringVar(&pkgConfig.FindImagesOpts.RegistryURL, "registry-url", defaultRegistry, lang.CmdDevFlagRegistry) devLintCmd.Flags().StringToStringVar(&pkgConfig.CreateOpts.SetVariables, "set", v.GetStringMapString(common.VPkgCreateSet), lang.CmdPackageCreateFlagSet) devLintCmd.Flags().StringVarP(&pkgConfig.CreateOpts.Flavor, "flavor", "f", v.GetString(common.VPkgCreateFlavor), lang.CmdPackageCreateFlagFlavor) @@ -364,6 +365,12 @@ func bindDevDeployFlags(v *viper.Viper) { devDeployFlags.StringToStringVar(&pkgConfig.CreateOpts.RegistryOverrides, "registry-override", v.GetStringMapString(common.VPkgCreateRegistryOverride), lang.CmdPackageCreateFlagRegistryOverride) devDeployFlags.StringVarP(&pkgConfig.CreateOpts.Flavor, "flavor", "f", v.GetString(common.VPkgCreateFlavor), lang.CmdPackageCreateFlagFlavor) + devDeployFlags.StringVar(&pkgConfig.DeployOpts.RegistryURL, "registry-url", defaultRegistry, lang.CmdDevFlagRegistry) + err := devDeployFlags.MarkHidden("registry-url") + if err != nil { + message.Debug("Unable to mark dev-deploy flag as hidden", "error", err) + } + devDeployFlags.StringToStringVar(&pkgConfig.PkgOpts.SetVariables, "deploy-set", v.GetStringMapString(common.VPkgDeploySet), lang.CmdPackageDeployFlagSet) // Always require adopt-existing-resources flag (no viper) diff --git a/src/cmd/initialize.go b/src/cmd/initialize.go index 01470e817d..70e73c1223 100644 --- a/src/cmd/initialize.go +++ b/src/cmd/initialize.go @@ -8,7 +8,6 @@ import ( "context" "errors" "fmt" - "os" "path" "path/filepath" "strings" @@ -37,9 +36,6 @@ var initCmd = &cobra.Command{ Long: lang.CmdInitLong, Example: lang.CmdInitExample, RunE: func(cmd *cobra.Command, _ []string) error { - zarfLogo := message.GetLogo() - _, _ = fmt.Fprintln(os.Stderr, zarfLogo) - if err := validateInitFlags(); err != nil { return fmt.Errorf("invalid command flags were provided: %w", err) } diff --git a/src/cmd/package.go b/src/cmd/package.go index 30b80c612a..c0d441a0f0 100644 --- a/src/cmd/package.go +++ b/src/cmd/package.go @@ -14,6 +14,8 @@ import ( "runtime" "strings" + "github.com/zarf-dev/zarf/src/pkg/logger" + "github.com/AlecAivazis/survey/v2" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/spf13/cobra" @@ -47,11 +49,14 @@ var packageCreateCmd = &cobra.Command{ Short: lang.CmdPackageCreateShort, Long: lang.CmdPackageCreateLong, RunE: func(cmd *cobra.Command, args []string) error { - pkgConfig.CreateOpts.BaseDir = common.SetBaseDirectory(args) + l := logger.From(cmd.Context()) + pkgConfig.CreateOpts.BaseDir = setBaseDirectory(args) var isCleanPathRegex = regexp.MustCompile(`^[a-zA-Z0-9\_\-\/\.\~\\:]+$`) if !isCleanPathRegex.MatchString(config.CommonOptions.CachePath) { + // TODO(mkcp): Remove message on logger release message.Warnf(lang.CmdPackageCreateCleanPathErr, config.ZarfDefaultCachePath) + l.Warn("invalid characters in Zarf cache path, using default", "cfg", config.ZarfDefaultCachePath, "default", config.ZarfDefaultCachePath) config.CommonOptions.CachePath = config.ZarfDefaultCachePath } @@ -59,13 +64,17 @@ var packageCreateCmd = &cobra.Command{ pkgConfig.CreateOpts.SetVariables = helpers.TransformAndMergeMap( v.GetStringMapString(common.VPkgCreateSet), pkgConfig.CreateOpts.SetVariables, strings.ToUpper) - pkgClient, err := packager.New(&pkgConfig) + pkgClient, err := packager.New(&pkgConfig, + packager.WithContext(cmd.Context()), + ) if err != nil { return err } defer pkgClient.ClearTempPaths() err = pkgClient.Create(cmd.Context()) + + // NOTE(mkcp): LintErrors are rendered with a table var lintErr *lint.LintError if errors.As(err, &lintErr) { common.PrintFindings(lintErr) @@ -192,6 +201,7 @@ var packageInspectCmd = &cobra.Command{ } }, RunE: func(cmd *cobra.Command, args []string) error { + // NOTE(mkcp): Gets user input with message src, err := choosePackage(args) if err != nil { return err @@ -225,6 +235,9 @@ var packageInspectCmd = &cobra.Command{ if err != nil { return fmt.Errorf("failed to inspect package: %w", err) } + // HACK(mkcp): This init call ensures we still can still print Yaml when message is disabled. Remove when we + // release structured logged and don't have to disable message globally in pre-run. + message.InitializePTerm(logger.DestinationDefault) err = utils.ColorPrintYAML(output, nil, false) if err != nil { return err @@ -266,7 +279,11 @@ var packageListCmd = &cobra.Command{ }) } + // NOTE(mkcp): Renders table with message. header := []string{"Package", "Version", "Components"} + // HACK(mkcp): Similar to `package inspect`, we do want to use message here but we have to make sure our feature + // flagging doesn't disable this. Nothing happens after this so it's safe, but still very hacky. + message.InitializePTerm(logger.DestinationDefault) message.Table(header, packageData) // Print out any unmarshalling errors diff --git a/src/cmd/root.go b/src/cmd/root.go index bf695e3760..63513c7104 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -6,10 +6,17 @@ package cmd import ( "context" + "errors" "fmt" + "io" + "log/slog" "os" "slices" "strings" + "time" + + "github.com/zarf-dev/zarf/src/cmd/say" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/pterm/pterm" "github.com/spf13/cobra" @@ -18,7 +25,6 @@ import ( "github.com/zarf-dev/zarf/src/cmd/tools" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/config/lang" - "github.com/zarf-dev/zarf/src/pkg/layout" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/types" ) @@ -28,6 +34,8 @@ var ( pkgConfig = types.PackagerConfig{} // LogLevelCLI holds the log level as input from a command LogLevelCLI string + // LogFormat holds the log format as input from a command + LogFormat string // SkipLogFile is a flag to skip logging to a file SkipLogFile bool // NoColor is a flag to disable colors in output @@ -35,79 +43,108 @@ var ( ) var rootCmd = &cobra.Command{ - Use: "zarf COMMAND", - PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { - // If --insecure was provided, set --insecure-skip-tls-verify and --plain-http to match - if config.CommonOptions.Insecure { - config.CommonOptions.InsecureSkipTLSVerify = true - config.CommonOptions.PlainHTTP = true - } + Use: "zarf COMMAND", + Short: lang.RootCmdShort, + Long: lang.RootCmdLong, + Args: cobra.MaximumNArgs(1), + SilenceUsage: true, + // TODO(mkcp): Do we actually want to silence errors here? + SilenceErrors: true, + PersistentPreRunE: preRun, + Run: run, +} - // Skip for vendor only commands - if common.CheckVendorOnlyFromPath(cmd) { - return nil - } +func preRun(cmd *cobra.Command, _ []string) error { + // If --insecure was provided, set --insecure-skip-tls-verify and --plain-http to match + if config.CommonOptions.Insecure { + config.CommonOptions.InsecureSkipTLSVerify = true + config.CommonOptions.PlainHTTP = true + } - skipLogFile := SkipLogFile + // Skip for vendor only commands + if common.CheckVendorOnlyFromPath(cmd) { + return nil + } - // Dont write tool commands to file. - comps := strings.Split(cmd.CommandPath(), " ") - if len(comps) > 1 && comps[1] == "tools" { - skipLogFile = true - } - if len(comps) > 1 && comps[1] == "version" { - skipLogFile = true - } + // Setup message + skipLogFile := SkipLogFile - // Dont write help command to file. - if cmd.Parent() == nil { - skipLogFile = true - } + // Don't write tool commands to file. + comps := strings.Split(cmd.CommandPath(), " ") + if len(comps) > 1 && comps[1] == "tools" { + skipLogFile = true + } + if len(comps) > 1 && comps[1] == "version" { + skipLogFile = true + } - err := common.SetupCLI(LogLevelCLI, skipLogFile, NoColor) - if err != nil { - return err - } - return nil - }, - Short: lang.RootCmdShort, - Long: lang.RootCmdLong, - Args: cobra.MaximumNArgs(1), - SilenceUsage: true, - SilenceErrors: true, - Run: func(cmd *cobra.Command, args []string) { - zarfLogo := message.GetLogo() - _, _ = fmt.Fprintln(os.Stderr, zarfLogo) - err := cmd.Help() - if err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - } + // Dont write help command to file. + if cmd.Parent() == nil { + skipLogFile = true + } - if len(args) > 0 { - if strings.Contains(args[0], config.ZarfPackagePrefix) || strings.Contains(args[0], "zarf-init") { - message.Warnf(lang.RootCmdDeprecatedDeploy, args[0]) - } - if args[0] == layout.ZarfYAML { - message.Warn(lang.RootCmdDeprecatedCreate) - } - } - }, + // Configure logger and add it to cmd context. + l, err := setupLogger(LogLevelCLI, LogFormat) + if err != nil { + return err + } + ctx := logger.WithContext(cmd.Context(), l) + cmd.SetContext(ctx) + + // Configure the global message instance. + var disableMessage bool + if LogFormat != "" { + disableMessage = true + ctx := logger.WithLoggingEnabled(ctx, true) + cmd.SetContext(ctx) + } + err = setupMessage(messageCfg{ + level: LogLevelCLI, + skipLogFile: skipLogFile, + noColor: NoColor, + featureDisabled: disableMessage, + }) + if err != nil { + return err + } + + // Print out config location + common.PrintViperConfigUsed(cmd.Context()) + return nil +} + +func run(cmd *cobra.Command, _ []string) { + err := cmd.Help() + if err != nil { + _, _ = fmt.Fprintln(os.Stderr, err) + } } // Execute is the entrypoint for the CLI. func Execute(ctx context.Context) { + // Add `zarf say` + rootCmd.AddCommand(say.Command()) + cmd, err := rootCmd.ExecuteContextC(ctx) if err == nil { return } + + // Check if we need to use the default err printer defaultPrintCmds := []string{"helm", "yq", "kubectl"} comps := strings.Split(cmd.CommandPath(), " ") if len(comps) > 1 && comps[1] == "tools" && slices.Contains(defaultPrintCmds, comps[2]) { cmd.PrintErrln(cmd.ErrPrefix(), err.Error()) - } else { - errParagraph := message.Paragraph(err.Error()) - pterm.Error.Println(errParagraph) + os.Exit(1) } + + // TODO(mkcp): Remove message on logger release + errParagraph := message.Paragraph(err.Error()) + pterm.Error.Println(errParagraph) + + // NOTE(mkcp): The default logger is set with user flags downstream in rootCmd's preRun func, so we don't have + // access to it on Execute's ctx. + logger.Default().Error(err.Error()) os.Exit(1) } @@ -122,15 +159,114 @@ func init() { v := common.InitViper() + // Logs rootCmd.PersistentFlags().StringVarP(&LogLevelCLI, "log-level", "l", v.GetString(common.VLogLevel), lang.RootCmdFlagLogLevel) - rootCmd.PersistentFlags().StringVarP(&config.CLIArch, "architecture", "a", v.GetString(common.VArchitecture), lang.RootCmdFlagArch) + rootCmd.PersistentFlags().StringVar(&LogFormat, "log-format", v.GetString(common.VLogFormat), "Select a logging format. Defaults to 'text'. Valid options are: 'text', 'json'") rootCmd.PersistentFlags().BoolVar(&SkipLogFile, "no-log-file", v.GetBool(common.VNoLogFile), lang.RootCmdFlagSkipLogFile) rootCmd.PersistentFlags().BoolVar(&message.NoProgress, "no-progress", v.GetBool(common.VNoProgress), lang.RootCmdFlagNoProgress) rootCmd.PersistentFlags().BoolVar(&NoColor, "no-color", v.GetBool(common.VNoColor), lang.RootCmdFlagNoColor) + + rootCmd.PersistentFlags().StringVarP(&config.CLIArch, "architecture", "a", v.GetString(common.VArchitecture), lang.RootCmdFlagArch) rootCmd.PersistentFlags().StringVar(&config.CommonOptions.CachePath, "zarf-cache", v.GetString(common.VZarfCache), lang.RootCmdFlagCachePath) rootCmd.PersistentFlags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", v.GetString(common.VTmpDir), lang.RootCmdFlagTempDir) + + // Security rootCmd.PersistentFlags().BoolVar(&config.CommonOptions.Insecure, "insecure", v.GetBool(common.VInsecure), lang.RootCmdFlagInsecure) rootCmd.PersistentFlags().MarkDeprecated("insecure", "please use --plain-http, --insecure-skip-tls-verify, or --skip-signature-validation instead.") rootCmd.PersistentFlags().BoolVar(&config.CommonOptions.PlainHTTP, "plain-http", v.GetBool(common.VPlainHTTP), lang.RootCmdFlagPlainHTTP) rootCmd.PersistentFlags().BoolVar(&config.CommonOptions.InsecureSkipTLSVerify, "insecure-skip-tls-verify", v.GetBool(common.VInsecureSkipTLSVerify), lang.RootCmdFlagInsecureSkipTLSVerify) + + // HACK(mkcp): This is a workaround for us testing that help output matches to the byte. Undo this and update tests + // before release. + rootCmd.PersistentFlags().MarkHidden("log-format") +} + +// setup Logger handles creating a logger and setting it as the global default. +func setupLogger(level, format string) (*slog.Logger, error) { + // If we didn't get a level from config, fallback to "info" + if level == "" { + level = "info" + } + sLevel, err := logger.ParseLevel(level) + if err != nil { + return nil, err + } + cfg := logger.Config{ + Level: sLevel, + Format: logger.Format(format), + Destination: logger.DestinationDefault, + } + l, err := logger.New(cfg) + if err != nil { + return nil, err + } + logger.SetDefault(l) + l.Debug("logger successfully initialized", "cfg", cfg) + return l, nil +} + +type messageCfg struct { + level string + skipLogFile bool + noColor bool + // featureDisabled is a feature flag that disables it + featureDisabled bool +} + +// setupMessage configures message while we migrate over to logger. +func setupMessage(cfg messageCfg) error { + // HACK(mkcp): Discard message logs if feature is disabled. message calls InitializePTerm once in its init() fn so + // this ends up being a messy solution. + if cfg.featureDisabled { + // Discard all* PTerm messages. *see below + message.InitializePTerm(io.Discard) + // Disable all progress bars and spinners + message.NoProgress = true + // Ensures no user input is needed while we maintain backwards compatibility with message + config.CommonOptions.Confirm = true + return nil + } + + if cfg.noColor { + message.DisableColor() + } + + level := cfg.level + if cfg.level != "" { + match := map[string]message.LogLevel{ + // NOTE(mkcp): Add error for forwards compatibility with logger + "error": message.WarnLevel, + "warn": message.WarnLevel, + "info": message.InfoLevel, + "debug": message.DebugLevel, + "trace": message.TraceLevel, + } + lvl, ok := match[level] + if !ok { + return errors.New("invalid log level, valid options are warn, info, debug, error, and trace") + } + message.SetLogLevel(lvl) + message.Debug("Log level set to " + level) + } + + // Disable progress bars for CI envs + if os.Getenv("CI") == "true" { + message.Debug("CI environment detected, disabling progress bars") + message.NoProgress = true + } + + if !cfg.skipLogFile { + ts := time.Now().Format("2006-01-02-15-04-05") + f, err := os.CreateTemp("", fmt.Sprintf("zarf-%s-*.log", ts)) + if err != nil { + return fmt.Errorf("could not create a log file in a the temporary directory: %w", err) + } + logFile, err := message.UseLogFile(f) + if err != nil { + return fmt.Errorf("could not save a log file to the temporary directory: %w", err) + } + pterm.SetDefaultOutput(io.MultiWriter(os.Stderr, logFile)) + message.Notef("Saving log file to %s", f.Name()) + } + return nil } diff --git a/src/cmd/say/say.go b/src/cmd/say/say.go new file mode 100644 index 0000000000..94daed409f --- /dev/null +++ b/src/cmd/say/say.go @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package say prints out the adorable creature we all know and love. +package say + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +// Command prints out the Zarf logo. +func Command() *cobra.Command { + return &cobra.Command{ + Use: "say", + Short: "Print Zarf logo", + Long: "Print out the adorable Zarf logo", + // HACK(mkcp): Hidden is a workaround until we update `test-docs-and-schema` for the new command and flags. + Hidden: true, + RunE: func(_ *cobra.Command, _ []string) error { + _, err := fmt.Fprintln(os.Stderr, logo()) + return err + }, + } +} + +func logo() string { + return ` +         *,                                                                               +         *(((&&&&&/*.                                                                     +          *(((((%&&&&&&&*,                                                                +           *(((((((&&&&&&&&&*              ,,*****,.                      **%&&&&&((((((  +            *(((((((((&&&&&&&@*    **@@@@@@&&&&&&&&&&@@@@@**         */&&&&&&((((((((((   +              *((((((///(&&&&&&@@@@&&&&@@@@@@@@@&&&&&&&&&&&&&&@/* *%&&&&&&/////((((((*    +                *(((///////&&&&&&&&&&&&&@@@@@@@@@&&&&&&&&&&&&&&&&&(%&&&/**///////(/*      +       */&&&&&&&&&&&&&&&&*/***&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/*******///*          +   *&%&&&&&&&&&&&&&&&&&&&&&&&***&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&****/&&&&&&&&&&&&(/* + */((((((((((((((///////******%%&&&&&&&&//&@@*&&&&&&&&&&&&&&&&&&&#%&&&&*/####(/////((((/. +     */((((((((((///////******%%%%%%%%%(##@@@//%&%%%%%%%&%&%%&&/(@@(/&&(***///////(((*    +          ***(((((/////********%%%%%%%/&%***/((%%%%%%%%%%%%%%%%(#&@*%/%%***/////**        +            *&&%%%%%%//*******%%%%%%%%@@****%%/%%%%%%%%%%%%%%%%%%***@@%%**(%%%&&*         +          *&&%%%%%(////******/(%%%%%%%@@@**@@&%%%%%%%%%%%%%%%%%(@@*%@@%%*****////%&*      +        *&%%%%%#////////***/////%%%%%%*@@@@@/%%%%%%%%%%%%%%%%%%%%@@@@%%*****///////((*    +       *%%%%((((///////*    *////(%%%%%%##%%%%%%%%%%%(%%%%*%%%%%%%%%%%*                   +      *(((((((/***            */////#%%%%%%%%%%#%%%%%%%%%%%%%%%%%%%%#*                    +                   %%(           ,*///((%%%%%%%%(**/#%%%##**/%%%%%*                       +                 %%%&&&&           *///*/(((((########//######**                          +                 %&&&&&*          *#######(((((((//////((((*                              +                                  ###%##############(((#####*                             +                   %@&&          *&#(%######*#########(#####/                             +                   /&&* ..       ,&#(/%####(*#########/#####/             #%@%&&&         +             **         &&     ./%##((*&####/(#######(#####*(*            %&&&&&&         +           *@%%@*             *&#####((((####*(#####(*###(*(##*              ,  %@&       +          *@%%%%*            *%######((((*%####/*((*%####/*(###*  *                       +         *@%%%%%%*      *##* **#(###((((///#*#*(((((/#**#((*(##**#,*/##*,    %@&&         +         *@%%%*%%%*  ****,*##/*#*##(((((((/(((((((((/(((*(((((###########*,  #&&#         +         *@%%%*(%%%/*   **######(#((..((((((((((((((((((*  ,*(#####(((((*,                +         *@%%%#(*%%%%*   ,**/####(* */(((((((((((((((((*     ,**,                         +          *@%%%*(/(%%%%/*     ******(((((((((((*(((((*                                    +           *@%%%#(((*/%%%%%%##%%*((((((((((((**((((*                                      +            *@%%%%*(((((((((((((((((((((((*/%*((*.             (&&&(                      +             ,*%%%%%%*((((((((((((((((**%%%**,                (&                          +                *%%%%%%%%%(/*****(#%%%%%**                      &%                        +                   ,**%%%%%%%%%%%%%***                                                    +                                                                                          +             ,((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((,           +                         .....(((((((/////////////////((((((((.....                       +                                                                                          +            ///////////////      ///////      *****************  ***************,         +                    ////.       ///  ////     *///          ***  ****                     +                 ////,         ///    ////    *///////////////.  /////**/******           +              /////          //////////////   *///      *///     ///*                     +           ./////////////// ////         ///  *///        ////   ///*                     +                                                                                          + +` +} diff --git a/src/cmd/tools/zarf.go b/src/cmd/tools/zarf.go index df516f9506..1bf56fd574 100644 --- a/src/cmd/tools/zarf.go +++ b/src/cmd/tools/zarf.go @@ -173,7 +173,7 @@ var updateCredsCmd = &cobra.Command{ } // Update Zarf 'init' component Helm releases if present - h := helm.NewClusterOnly(&types.PackagerConfig{}, template.GetZarfVariableConfig(), newState, c) + h := helm.NewClusterOnly(&types.PackagerConfig{}, template.GetZarfVariableConfig(cmd.Context()), newState, c) if slices.Contains(args, message.RegistryKey) && newState.RegistryInfo.IsInternal() { err = h.UpdateZarfRegistryValues(ctx) diff --git a/src/config/lang/english.go b/src/config/lang/english.go index c78e57a443..38717db929 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -354,7 +354,7 @@ $ zarf package pull oci://ghcr.io/defenseunicorns/packages/dos-games:1.0.0 -a sk CmdDevFlagRepoChartPath = `If git repos hold helm charts, often found with gitops tools, specify the chart path, e.g. "/" or "/chart"` CmdDevFlagGitAccount = "User or organization name for the git account that the repos are created under." CmdDevFlagKubeVersion = "Override the default helm template KubeVersion when performing a package chart template" - CmdDevFlagFindImagesRegistry = "Override the ###ZARF_REGISTRY### value" + CmdDevFlagRegistry = "Override the ###ZARF_REGISTRY### value" CmdDevFlagFindImagesWhy = "Prints the source manifest for the specified image" CmdDevFlagFindImagesSkipCosign = "Skip searching for cosign artifacts related to discovered images" @@ -589,10 +589,6 @@ $ zarf tools update-creds artifact --artifact-push-username={USERNAME} --artifac // tools version CmdToolsVersionShort = "Print the version" - - // cmd viper setup - CmdViperErrLoadingConfigFile = "failed to load config file: %s" - CmdViperInfoUsingConfigFile = "Using config file %s" ) // Zarf Agent messages diff --git a/src/injector/src/main.rs b/src/injector/src/main.rs index e1b9cc3dc5..c1312eb398 100644 --- a/src/injector/src/main.rs +++ b/src/injector/src/main.rs @@ -51,7 +51,7 @@ fn collect_binary_data(paths: &Vec) -> io::Result> { println!("Processing {}", path.display()); let new_content = get_file(path); buffer - .write(&new_content.unwrap()) + .write_all(&new_content.unwrap()) .expect("Could not add the file contents to the merged file buffer"); } @@ -143,14 +143,14 @@ async fn handler(Path(path): Path) -> Response { let name = caps.get(1).unwrap().as_str().to_string(); let reference = caps.get(2).unwrap().as_str().to_string(); handle_get_manifest(name, reference).await - } else if blob.is_match(&path) { + } else if blob.is_match(path) { let caps = blob.captures(path).unwrap(); let tag = caps.get(1).unwrap().as_str().to_string(); handle_get_digest(tag).await } else { Response::builder() .status(StatusCode::NOT_FOUND) - .body(format!("Not Found")) + .body("Not Found".to_string()) .unwrap() .into_response() } @@ -185,7 +185,7 @@ async fn handle_get_manifest(name: String, reference: String) -> Response { if sha_manifest.is_empty() { Response::builder() .status(StatusCode::NOT_FOUND) - .body(format!("Not Found")) + .body("Not Found".to_string()) .unwrap() .into_response() } else { diff --git a/src/internal/healthchecks/healthchecks.go b/src/internal/healthchecks/healthchecks.go index 7957953378..447ddb81cf 100644 --- a/src/internal/healthchecks/healthchecks.go +++ b/src/internal/healthchecks/healthchecks.go @@ -6,15 +6,21 @@ package healthchecks import ( "context" + "errors" + "fmt" - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" "github.com/zarf-dev/zarf/src/api/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator" + "sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector" + "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event" + "sigs.k8s.io/cli-utils/pkg/kstatus/status" "sigs.k8s.io/cli-utils/pkg/kstatus/watcher" "sigs.k8s.io/cli-utils/pkg/object" ) -// Run waits for a list of objects to be reconciled +// Run waits for a list of Zarf healthchecks to reach a ready state. func Run(ctx context.Context, watcher watcher.StatusWatcher, healthChecks []v1alpha1.NamespacedObjectKindReference) error { objs := []object.ObjMetadata{} for _, hc := range healthChecks { @@ -32,9 +38,99 @@ func Run(ctx context.Context, watcher watcher.StatusWatcher, healthChecks []v1al } objs = append(objs, obj) } - err := pkgkubernetes.WaitForReady(ctx, watcher, objs) + err := WaitForReady(ctx, watcher, objs) if err != nil { return err } return nil } + +// WaitForReadyRuntime waits for all of the objects to reach a ready state. +func WaitForReadyRuntime(ctx context.Context, sw watcher.StatusWatcher, robjs []runtime.Object) error { + objs := []object.ObjMetadata{} + for _, robj := range robjs { + obj, err := object.RuntimeToObjMeta(robj) + if err != nil { + return err + } + objs = append(objs, obj) + } + return WaitForReady(ctx, sw, objs) +} + +// WaitForReady waits for all of the objects to reach a ready state. +func WaitForReady(ctx context.Context, sw watcher.StatusWatcher, objs []object.ObjMetadata) error { + cancelCtx, cancel := context.WithCancel(ctx) + defer cancel() + + eventCh := sw.Watch(cancelCtx, objs, watcher.Options{}) + statusCollector := collector.NewResourceStatusCollector(objs) + done := statusCollector.ListenWithObserver(eventCh, collector.ObserverFunc( + func(statusCollector *collector.ResourceStatusCollector, _ event.Event) { + rss := []*event.ResourceStatus{} + for _, rs := range statusCollector.ResourceStatuses { + if rs == nil { + continue + } + rss = append(rss, rs) + } + desired := status.CurrentStatus + if aggregator.AggregateStatus(rss, desired) == desired { + cancel() + return + } + }), + ) + <-done + + if statusCollector.Error != nil { + return statusCollector.Error + } + + // Only check parent context error, otherwise we would error when desired status is achieved. + if ctx.Err() != nil { + errs := []error{} + for _, id := range objs { + rs := statusCollector.ResourceStatuses[id] + switch rs.Status { + case status.CurrentStatus: + case status.NotFoundStatus: + errs = append(errs, fmt.Errorf("%s: %s not found", rs.Identifier.Name, rs.Identifier.GroupKind.Kind)) + default: + errs = append(errs, fmt.Errorf("%s: %s not ready", rs.Identifier.Name, rs.Identifier.GroupKind.Kind)) + } + } + errs = append(errs, ctx.Err()) + return errors.Join(errs...) + } + + return nil +} + +// ImmediateWatcher should only be used for testing and returns the set status immediately. +type ImmediateWatcher struct { + status status.Status +} + +// NewImmediateWatcher returns a ImmediateWatcher. +func NewImmediateWatcher(status status.Status) *ImmediateWatcher { + return &ImmediateWatcher{ + status: status, + } +} + +// Watch watches the given objects and immediately returns the configured status. +func (w *ImmediateWatcher) Watch(_ context.Context, objs object.ObjMetadataSet, _ watcher.Options) <-chan event.Event { + eventCh := make(chan event.Event, len(objs)) + for _, obj := range objs { + eventCh <- event.Event{ + Type: event.ResourceUpdateEvent, + Resource: &event.ResourceStatus{ + Identifier: obj, + Status: w.status, + }, + } + } + close(eventCh) + return eventCh +} diff --git a/src/internal/healthchecks/healthchecks_test.go b/src/internal/healthchecks/healthchecks_test.go index 9761f7ba84..d52d0d2ff9 100644 --- a/src/internal/healthchecks/healthchecks_test.go +++ b/src/internal/healthchecks/healthchecks_test.go @@ -6,6 +6,7 @@ package healthchecks import ( "context" + "errors" "testing" "time" @@ -45,19 +46,19 @@ metadata: func TestRunHealthChecks(t *testing.T) { t.Parallel() tests := []struct { - name string - podYaml string - expectErr error + name string + podYamls []string + expectErrs []error }{ { - name: "Pod is running", - podYaml: podCurrentYaml, - expectErr: nil, + name: "Pod is ready", + podYamls: []string{podCurrentYaml}, + expectErrs: nil, }, { - name: "Pod is never ready", - podYaml: podYaml, - expectErr: context.DeadlineExceeded, + name: "One pod is never ready", + podYamls: []string{podYaml, podCurrentYaml}, + expectErrs: []error{errors.New("in-progress-pod: Pod not ready"), context.DeadlineExceeded}, }, } @@ -70,24 +71,27 @@ func TestRunHealthChecks(t *testing.T) { ) ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) defer cancel() - m := make(map[string]interface{}) - err := yaml.Unmarshal([]byte(tt.podYaml), &m) - require.NoError(t, err) - pod := &unstructured.Unstructured{Object: m} statusWatcher := watcher.NewDefaultStatusWatcher(fakeClient, fakeMapper) - podGVR := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} - require.NoError(t, fakeClient.Tracker().Create(podGVR, pod, pod.GetNamespace())) - objs := []v1alpha1.NamespacedObjectKindReference{ - { + objs := []v1alpha1.NamespacedObjectKindReference{} + for _, podYaml := range tt.podYamls { + m := make(map[string]interface{}) + err := yaml.Unmarshal([]byte(podYaml), &m) + require.NoError(t, err) + pod := &unstructured.Unstructured{Object: m} + podGVR := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} + err = fakeClient.Tracker().Create(podGVR, pod, pod.GetNamespace()) + require.NoError(t, err) + objs = append(objs, v1alpha1.NamespacedObjectKindReference{ APIVersion: pod.GetAPIVersion(), Kind: pod.GetKind(), Namespace: pod.GetNamespace(), Name: pod.GetName(), - }, + }) } - err = Run(ctx, statusWatcher, objs) - if tt.expectErr != nil { - require.ErrorIs(t, err, tt.expectErr) + + err := Run(ctx, statusWatcher, objs) + if tt.expectErrs != nil { + require.EqualError(t, err, errors.Join(tt.expectErrs...).Error()) return } require.NoError(t, err) diff --git a/src/internal/packager/helm/chart.go b/src/internal/packager/helm/chart.go index 6009d5f9bc..35e1e5625c 100644 --- a/src/internal/packager/helm/chart.go +++ b/src/internal/packager/helm/chart.go @@ -9,6 +9,7 @@ import ( "context" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "time" "github.com/Masterminds/semver/v3" @@ -23,9 +24,9 @@ import ( "helm.sh/helm/v3/pkg/releaseutil" "helm.sh/helm/v3/pkg/storage/driver" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" - "github.com/zarf-dev/zarf/src/api/v1alpha1" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/internal/healthchecks" "github.com/zarf-dev/zarf/src/pkg/message" @@ -129,20 +130,14 @@ func (h *Helm) InstallOrUpgradeChart(ctx context.Context) (types.ConnectStrings, return nil, "", fmt.Errorf("unable to build the resource list: %w", err) } - healthChecks := []v1alpha1.NamespacedObjectKindReference{} + runtimeObjs := []runtime.Object{} for _, resource := range resourceList { - apiVersion, kind := resource.Object.GetObjectKind().GroupVersionKind().ToAPIVersionAndKind() - healthChecks = append(healthChecks, v1alpha1.NamespacedObjectKindReference{ - APIVersion: apiVersion, - Kind: kind, - Name: resource.Name, - Namespace: resource.Namespace, - }) + runtimeObjs = append(runtimeObjs, resource.Object) } if !h.chart.NoWait { // Ensure we don't go past the timeout by using a context initialized with the helm timeout spinner.Updatef("Running health checks") - if err := healthchecks.Run(helmCtx, h.cluster.Watcher, healthChecks); err != nil { + if err := healthchecks.WaitForReadyRuntime(helmCtx, h.cluster.Watcher, runtimeObjs); err != nil { return nil, "", err } } @@ -219,12 +214,13 @@ func (h *Helm) TemplateChart(ctx context.Context) (manifest string, chartValues } // RemoveChart removes a chart from the cluster. -func (h *Helm) RemoveChart(namespace string, name string, spinner *message.Spinner) error { +func (h *Helm) RemoveChart(ctx context.Context, namespace string, name string, spinner *message.Spinner) error { // Establish a new actionConfig for the namespace. _ = h.createActionConfig(namespace, spinner) // Perform the uninstall. response, err := h.uninstallChart(name) message.Debug(response) + logger.From(ctx).Debug("chart uninstalled", "response", response) return err } diff --git a/src/internal/packager/helm/destroy.go b/src/internal/packager/helm/destroy.go index 44c519a00a..21693aaa92 100644 --- a/src/internal/packager/helm/destroy.go +++ b/src/internal/packager/helm/destroy.go @@ -5,17 +5,23 @@ package helm import ( + "context" "regexp" + "time" "github.com/zarf-dev/zarf/src/pkg/cluster" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "helm.sh/helm/v3/pkg/action" ) // Destroy removes ZarfInitPackage charts from the cluster and optionally all Zarf-installed charts. -func Destroy(purgeAllZarfInstallations bool) { +func Destroy(ctx context.Context, purgeAllZarfInstallations bool) { + start := time.Now() + l := logger.From(ctx) spinner := message.NewProgressSpinner("Removing Zarf-installed charts") defer spinner.Stop() + l.Info("removing Zarf-installed charts") h := Helm{} @@ -24,6 +30,7 @@ func Destroy(purgeAllZarfInstallations bool) { if err != nil { // Don't fatal since this is a removal action spinner.Errorf(err, "Unable to initialize the K8s client") + l.Error("unable to initialize the K8s client", "error", err.Error()) return } @@ -42,6 +49,7 @@ func Destroy(purgeAllZarfInstallations bool) { if err != nil { // Don't fatal since this is a removal action spinner.Errorf(err, "Unable to get the list of installed charts") + l.Error("unable to get the list of installed charts", "error", err.Error()) } // Iterate over all releases @@ -53,12 +61,15 @@ func Destroy(purgeAllZarfInstallations bool) { // Filter on zarf releases if zarfPrefix.MatchString(release.Name) { spinner.Updatef("Uninstalling helm chart %s/%s", release.Namespace, release.Name) - if err = h.RemoveChart(release.Namespace, release.Name, spinner); err != nil { + l.Info("uninstalling helm chart", "namespace", release.Namespace, "name", release.Name) + if err = h.RemoveChart(ctx, release.Namespace, release.Name, spinner); err != nil { // Don't fatal since this is a removal action spinner.Errorf(err, "Unable to uninstall the chart") + l.Error("unable to uninstall the chart", "error", err.Error()) } } } spinner.Success() + l.Debug("done uninstalling charts", "duration", time.Since(start)) } diff --git a/src/internal/packager/helm/repo.go b/src/internal/packager/helm/repo.go index 249f19f0f2..7791771282 100644 --- a/src/internal/packager/helm/repo.go +++ b/src/internal/packager/helm/repo.go @@ -8,9 +8,12 @@ import ( "context" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" + "log/slog" "os" "path/filepath" "strings" + "time" "github.com/defenseunicorns/pkg/helpers/v2" "helm.sh/helm/v3/pkg/action" @@ -38,7 +41,9 @@ func (h *Helm) PackageChart(ctx context.Context, cosignKeyPath string) error { // check if the chart is a git url with a ref (if an error is returned url will be empty) isGitURL := strings.HasSuffix(url, ".git") if err != nil { + // TODO(mkcp): Remove message on logger release message.Debugf("unable to parse the url, continuing with %s", h.chart.URL) + logger.From(ctx).Debug("unable to parse the url, continuing", "url", h.chart.URL) } if isGitURL { @@ -68,6 +73,13 @@ func (h *Helm) PackageChart(ctx context.Context, cosignKeyPath string) error { // PackageChartFromLocalFiles creates a chart archive from a path to a chart on the host os. func (h *Helm) PackageChartFromLocalFiles(ctx context.Context, cosignKeyPath string) error { + l := logger.From(ctx) + l.Info("processing local helm chart", + "name", h.chart.Name, + "version", h.chart.Version, + "path", h.chart.LocalPath, + ) + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Processing helm chart %s:%s from %s", h.chart.Name, h.chart.Version, h.chart.LocalPath) defer spinner.Stop() @@ -94,7 +106,12 @@ func (h *Helm) PackageChartFromLocalFiles(ctx context.Context, cosignKeyPath str saved = filepath.Join(temp, filepath.Base(h.chart.LocalPath)) err = helpers.CreatePathAndCopy(h.chart.LocalPath, saved) } - defer os.RemoveAll(temp) + defer func(l *slog.Logger) { + err := os.RemoveAll(temp) + if err != nil { + l.Error(err.Error()) + } + }(l) if err != nil { return fmt.Errorf("unable to save the archive and create the package %s: %w", saved, err) @@ -108,11 +125,19 @@ func (h *Helm) PackageChartFromLocalFiles(ctx context.Context, cosignKeyPath str spinner.Success() + l.Debug("done processing local helm chart", + "name", h.chart.Name, + "version", h.chart.Version, + "path", h.chart.LocalPath, + ) return nil } // PackageChartFromGit is a special implementation of chart archiving that supports the https://p1.dso.mil/#/products/big-bang/ model. func (h *Helm) PackageChartFromGit(ctx context.Context, cosignKeyPath string) error { + l := logger.From(ctx) + l.Info("processing helm chart", "name", h.chart.Name) + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Processing helm chart %s", h.chart.Name) defer spinner.Stop() @@ -121,7 +146,11 @@ func (h *Helm) PackageChartFromGit(ctx context.Context, cosignKeyPath string) er if err != nil { return err } - defer os.RemoveAll(gitPath) + defer func(l *slog.Logger) { + if err := os.RemoveAll(gitPath); err != nil { + l.Error(err.Error()) + } + }(l) // Set the directory for the chart and package it h.chart.LocalPath = filepath.Join(gitPath, h.chart.GitPath) @@ -130,6 +159,14 @@ func (h *Helm) PackageChartFromGit(ctx context.Context, cosignKeyPath string) er // DownloadPublishedChart loads a specific chart version from a remote repo. func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) error { + l := logger.From(ctx) + l.Info("processing helm chart", + "name", h.chart.Name, + "version", h.chart.Version, + "repo", h.chart.URL, + ) + start := time.Now() + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Processing helm chart %s:%s from repo %s", h.chart.Name, h.chart.Version, h.chart.URL) defer spinner.Stop() @@ -146,7 +183,12 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) // Not returning the error here since the repo file is only needed if we are pulling from a repo that requires authentication if err != nil { + // TODO(mkcp): Remove message on logger release message.Debugf("Unable to load the repo file at %q: %s", pull.Settings.RepositoryConfig, err.Error()) + l.Debug("unable to load the repo file", + "path", pull.Settings.RepositoryConfig, + "error", err.Error(), + ) } var username string @@ -202,7 +244,12 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) if err = helpers.CreateDirectory(temp, helpers.ReadWriteExecuteUser); err != nil { return fmt.Errorf("unable to create helm chart temp directory: %w", err) } - defer os.RemoveAll(temp) + defer func(l *slog.Logger) { + err := os.RemoveAll(temp) + if err != nil { + l.Error(err.Error()) + } + }(l) saved, _, err := chartDownloader.DownloadTo(chartURL, pull.Version, temp) if err != nil { @@ -222,7 +269,12 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) } spinner.Success() - + l.Debug("done downloading helm chart", + "name", h.chart.Name, + "version", h.chart.Version, + "repo", h.chart.URL, + "duration", time.Since(start), + ) return nil } @@ -304,13 +356,16 @@ func (h *Helm) buildChartDependencies() error { var notFoundErr *downloader.ErrRepoNotFound if errors.As(err, ¬FoundErr) { // If we encounter a repo not found error point the user to `zarf tools helm repo add` + // TODO(mkcp): Remove message on logger release message.Warnf("%s. Please add the missing repo(s) via the following:", notFoundErr.Error()) for _, repository := range notFoundErr.Repos { + // TODO(mkcp): Remove message on logger release message.ZarfCommand(fmt.Sprintf("tools helm repo add %s", repository)) } return err } if err != nil { + // TODO(mkcp): Remove message on logger release message.ZarfCommand("tools helm dependency build --verify") message.Warnf("Unable to perform a rebuild of Helm dependencies: %s", err.Error()) return err diff --git a/src/internal/packager/helm/zarf.go b/src/internal/packager/helm/zarf.go index 03e4db2ed0..b6945a6e8c 100644 --- a/src/internal/packager/helm/zarf.go +++ b/src/internal/packager/helm/zarf.go @@ -13,11 +13,10 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/cli-utils/pkg/object" - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/zarf-dev/zarf/src/api/v1alpha1" + "github.com/zarf-dev/zarf/src/internal/healthchecks" "github.com/zarf-dev/zarf/src/internal/packager/template" "github.com/zarf-dev/zarf/src/pkg/cluster" "github.com/zarf-dev/zarf/src/pkg/message" @@ -61,7 +60,7 @@ func (h *Helm) UpdateZarfRegistryValues(ctx context.Context) error { } waitCtx, waitCancel := context.WithTimeout(ctx, 60*time.Second) defer waitCancel() - err = pkgkubernetes.WaitForReady(waitCtx, h.cluster.Watcher, objs) + err = healthchecks.WaitForReady(waitCtx, h.cluster.Watcher, objs) if err != nil { return err } @@ -157,7 +156,7 @@ func (h *Helm) UpdateZarfAgentValues(ctx context.Context) error { } waitCtx, waitCancel := context.WithTimeout(ctx, 60*time.Second) defer waitCancel() - err = pkgkubernetes.WaitForReady(waitCtx, h.cluster.Watcher, objs) + err = healthchecks.WaitForReady(waitCtx, h.cluster.Watcher, objs) if err != nil { return err } diff --git a/src/internal/packager/images/common.go b/src/internal/packager/images/common.go index 285c541edb..3d5137a995 100644 --- a/src/internal/packager/images/common.go +++ b/src/internal/packager/images/common.go @@ -13,7 +13,6 @@ import ( "github.com/google/go-containerregistry/pkg/crane" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/zarf-dev/zarf/src/config" - "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/transform" "github.com/zarf-dev/zarf/src/types" ) @@ -98,18 +97,18 @@ func WithPushAuth(ri types.RegistryInfo) crane.Option { return WithBasicAuth(ri.PushUsername, ri.PushPassword) } -func createPushOpts(cfg PushConfig, pb *message.ProgressBar) []crane.Option { +func createPushOpts(cfg PushConfig) []crane.Option { opts := CommonOpts(cfg.Arch) opts = append(opts, WithPushAuth(cfg.RegInfo)) - transport := http.DefaultTransport.(*http.Transport).Clone() - transport.TLSClientConfig.InsecureSkipVerify = config.CommonOptions.InsecureSkipTLSVerify + defaultTransport := http.DefaultTransport.(*http.Transport).Clone() + defaultTransport.TLSClientConfig.InsecureSkipVerify = config.CommonOptions.InsecureSkipTLSVerify // TODO (@WSTARR) This is set to match the TLSHandshakeTimeout to potentially mitigate effects of https://github.com/zarf-dev/zarf/issues/1444 - transport.ResponseHeaderTimeout = 10 * time.Second + defaultTransport.ResponseHeaderTimeout = 10 * time.Second - transportWithProgressBar := helpers.NewTransport(transport, pb) + transport := helpers.NewTransport(defaultTransport, nil) - opts = append(opts, crane.WithTransport(transportWithProgressBar)) + opts = append(opts, crane.WithTransport(transport)) return opts } diff --git a/src/internal/packager/images/pull.go b/src/internal/packager/images/pull.go index a11b6097d7..7d5baf8464 100644 --- a/src/internal/packager/images/pull.go +++ b/src/internal/packager/images/pull.go @@ -9,6 +9,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "io/fs" "maps" "os" @@ -16,6 +17,7 @@ import ( "strings" "sync" "sync/atomic" + "time" "github.com/avast/retry-go/v4" "github.com/defenseunicorns/pkg/helpers/v2" @@ -60,9 +62,12 @@ func checkForIndex(refInfo transform.Image, desc *remote.Descriptor) error { return nil } -// Pull pulls all of the images from the given config. +// Pull pulls all images from the given config. func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, error) { + l := logger.From(ctx) var longer string + pullStart := time.Now() + imageCount := len(cfg.ImageList) // Give some additional user feedback on larger image sets if imageCount > 15 { @@ -80,8 +85,12 @@ func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, er return nil, err } + // Give some additional user feedback on larger image sets + imageFetchStart := time.Now() + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Fetching info for %d images. %s", imageCount, longer) defer spinner.Stop() + l.Info("fetching info for images", "count", imageCount, "destination", cfg.DestinationDirectory) logs.Warn.SetOutput(&message.DebugWriter{}) logs.Progress.SetOutput(&message.DebugWriter{}) @@ -97,11 +106,14 @@ func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, er var counter, totalBytes atomic.Int64 + // Spawn a goroutine for each for _, refInfo := range cfg.ImageList { refInfo := refInfo eg.Go(func() error { idx := counter.Add(1) + // TODO(mkcp): Remove message on logger release spinner.Updatef("Fetching image info (%d of %d)", idx, imageCount) + l.Debug("fetching image info", "name", refInfo.Name) ref := refInfo.Reference for k, v := range cfg.RegistryOverrides { @@ -130,7 +142,9 @@ func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, er return fmt.Errorf("rate limited by registry: %w", err) } + // TODO(mkcp): Remove message on logger release message.Warnf("Falling back to local 'docker', failed to find the manifest on a remote: %s", err.Error()) + l.Warn("Falling back to local 'docker', failed to find the manifest on a remote", "error", err.Error()) // Attempt to connect to the local docker daemon. cli, err := client.NewClientWithOpts(client.FromEnv) @@ -217,40 +231,55 @@ func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, er }) } + // Wait until we're done fetching images if err := eg.Wait(); err != nil { return nil, err } + // TODO(mkcp): Remove message on logger release spinner.Successf("Fetched info for %d images", imageCount) + l.Debug("done fetching info for images", "count", len(cfg.ImageList), "duration", time.Since(imageFetchStart)) doneSaving := make(chan error) updateText := fmt.Sprintf("Pulling %d images", imageCount) + // TODO(mkcp): Remove progress bar on logger release go utils.RenderProgressBarForLocalDirWrite(cfg.DestinationDirectory, totalBytes.Load(), doneSaving, updateText, updateText) + l.Info("pulling images", "count", len(cfg.ImageList)) toPull := maps.Clone(fetched) err = retry.Do(func() error { saved, err := SaveConcurrent(ctx, cranePath, toPull) + // Done save, remove from download list. for k := range saved { delete(toPull, k) } return err - }, retry.Context(ctx), retry.Attempts(2)) + }, + retry.Context(ctx), + retry.Attempts(2), + ) if err != nil { + // TODO(mkcp): Remove message on logger release message.Warnf("Failed to save images in parallel, falling back to sequential save: %s", err.Error()) + l.Warn("failed to save images in parallel, falling back to sequential save", "error", err.Error()) err = retry.Do(func() error { saved, err := SaveSequential(ctx, cranePath, toPull) for k := range saved { delete(toPull, k) } return err - }, retry.Context(ctx), retry.Attempts(2)) + }, + retry.Context(ctx), + retry.Attempts(2), + ) if err != nil { return nil, err } } // Send a signal to the progress bar that we're done and wait for the thread to finish + // TODO(mkcp): Remove progress bar on logger release doneSaving <- nil <-doneSaving @@ -279,6 +308,8 @@ func Pull(ctx context.Context, cfg PullConfig) (map[transform.Image]v1.Image, er return nil, err } + l.Debug("done pulling images", "count", len(cfg.ImageList), "duration", time.Since(pullStart)) + return fetched, nil } @@ -326,24 +357,39 @@ func CleanupInProgressLayers(ctx context.Context, img v1.Image) error { // SaveSequential saves images sequentially. func SaveSequential(ctx context.Context, cl clayout.Path, m map[transform.Image]v1.Image) (map[transform.Image]v1.Image, error) { + l := logger.From(ctx) saved := map[transform.Image]v1.Image{} for info, img := range m { annotations := map[string]string{ ocispec.AnnotationBaseImageName: info.Reference, } + wStart := time.Now() + size, err := img.Size() + if err != nil { + return saved, err + } + l.Info("saving image", "ref", info.Reference, "size", size, "method", "sequential") if err := cl.AppendImage(img, clayout.WithAnnotations(annotations)); err != nil { if err := CleanupInProgressLayers(ctx, img); err != nil { message.WarnErr(err, "failed to clean up in-progress layers, please run `zarf tools clear-cache`") + l.Error("failed to clean up in-progress layers. please run `zarf tools clear-cache`") } return saved, err } saved[info] = img + l.Debug("done saving image", + "ref", info.Reference, + "size", size, + "method", "sequential", + "duration", time.Since(wStart), + ) } return saved, nil } // SaveConcurrent saves images in a concurrent, bounded manner. func SaveConcurrent(ctx context.Context, cl clayout.Path, m map[transform.Image]v1.Image) (map[transform.Image]v1.Image, error) { + l := logger.From(ctx) saved := map[transform.Image]v1.Image{} var mu sync.Mutex @@ -363,12 +409,25 @@ func SaveConcurrent(ctx context.Context, cl clayout.Path, m map[transform.Image] return err } + size, err := img.Size() + if err != nil { + return err + } + wStart := time.Now() + l.Info("saving image", "ref", info.Reference, "size", size, "method", "concurrent") if err := cl.WriteImage(img); err != nil { if err := CleanupInProgressLayers(ectx, img); err != nil { message.WarnErr(err, "failed to clean up in-progress layers, please run `zarf tools clear-cache`") + l.Error("failed to clean up in-progress layers. please run `zarf tools clear-cache`") } return err } + l.Debug("done saving image", + "ref", info.Reference, + "size", size, + "method", "concurrent", + "duration", time.Since(wStart), + ) mu.Lock() defer mu.Unlock() diff --git a/src/internal/packager/images/push.go b/src/internal/packager/images/push.go index f8cbf90c4e..e04c628023 100644 --- a/src/internal/packager/images/push.go +++ b/src/internal/packager/images/push.go @@ -6,11 +6,9 @@ package images import ( "context" - "fmt" "time" "github.com/avast/retry-go/v4" - "github.com/defenseunicorns/pkg/helpers/v2" "github.com/google/go-containerregistry/pkg/crane" "github.com/google/go-containerregistry/pkg/logs" v1 "github.com/google/go-containerregistry/pkg/v1" @@ -27,7 +25,6 @@ func Push(ctx context.Context, cfg PushConfig) error { logs.Progress.SetOutput(&message.DebugWriter{}) toPush := map[transform.Image]v1.Image{} - var totalSize int64 // Build an image list from the references for _, refInfo := range cfg.ImageList { img, err := utils.LoadOCIImage(cfg.SourceDirectory, refInfo) @@ -35,16 +32,6 @@ func Push(ctx context.Context, cfg PushConfig) error { return err } toPush[refInfo] = img - imgSize, err := calcImgSize(img) - if err != nil { - return err - } - totalSize += imgSize - } - - // If this is not a no checksum image push we will be pushing two images (the second will go faster as it checks the same layers) - if !cfg.NoChecksum { - totalSize = totalSize * 2 } var ( @@ -52,7 +39,6 @@ func Push(ctx context.Context, cfg PushConfig) error { tunnel *cluster.Tunnel registryURL = cfg.RegInfo.Address ) - err = retry.Do(func() error { c, _ := cluster.NewCluster() if c != nil { @@ -64,16 +50,12 @@ func Push(ctx context.Context, cfg PushConfig) error { defer tunnel.Close() } } - - progress := message.NewProgressBar(totalSize, fmt.Sprintf("Pushing %d images", len(toPush))) - defer progress.Close() - pushOptions := createPushOpts(cfg, progress) + pushOptions := createPushOpts(cfg) pushImage := func(img v1.Image, name string) error { if tunnel != nil { return tunnel.Wrap(func() error { return crane.Push(img, name, pushOptions...) }) } - return crane.Push(img, name, pushOptions...) } @@ -84,14 +66,7 @@ func Push(ctx context.Context, cfg PushConfig) error { } }() for refInfo, img := range toPush { - refTruncated := helpers.Truncate(refInfo.Reference, 55, true) - progress.Updatef(fmt.Sprintf("Pushing %s", refTruncated)) - - size, err := calcImgSize(img) - if err != nil { - return err - } - + message.Infof("Pushing %s", refInfo.Reference) // If this is not a no checksum image push it for use with the Zarf agent if !cfg.NoChecksum { offlineNameCRC, err := transform.ImageTransformHost(registryURL, refInfo.Reference) @@ -102,8 +77,6 @@ func Push(ctx context.Context, cfg PushConfig) error { if err = pushImage(img, offlineNameCRC); err != nil { return err } - - totalSize -= size } // To allow for other non-zarf workloads to easily see the images upload a non-checksum version @@ -113,16 +86,12 @@ func Push(ctx context.Context, cfg PushConfig) error { return err } - message.Debugf("push %s -> %s)", refInfo.Reference, offlineName) - if err = pushImage(img, offlineName); err != nil { return err } pushed = append(pushed, refInfo) - totalSize -= size } - progress.Successf("Pushed %d images", len(cfg.ImageList)) return nil }, retry.Context(ctx), retry.Attempts(uint(cfg.Retries)), retry.Delay(500*time.Millisecond)) if err != nil { @@ -131,25 +100,3 @@ func Push(ctx context.Context, cfg PushConfig) error { return nil } - -func calcImgSize(img v1.Image) (int64, error) { - size, err := img.Size() - if err != nil { - return size, err - } - - layers, err := img.Layers() - if err != nil { - return size, err - } - - for _, layer := range layers { - ls, err := layer.Size() - if err != nil { - return size, err - } - size += ls - } - - return size, nil -} diff --git a/src/internal/packager/sbom/catalog.go b/src/internal/packager/sbom/catalog.go index 65c32c039b..8d96f66628 100755 --- a/src/internal/packager/sbom/catalog.go +++ b/src/internal/packager/sbom/catalog.go @@ -12,6 +12,9 @@ import ( "path/filepath" "regexp" + "github.com/zarf-dev/zarf/src/pkg/logger" + "github.com/zarf-dev/zarf/src/pkg/message" + "github.com/anchore/stereoscope/pkg/file" "github.com/anchore/stereoscope/pkg/image" "github.com/anchore/syft/syft" @@ -30,7 +33,6 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/pkg/layout" - "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/transform" "github.com/zarf-dev/zarf/src/pkg/utils" ) @@ -52,6 +54,7 @@ var componentPrefix = "zarf-component-" // Catalog catalogs the given components and images to create an SBOM. func Catalog(ctx context.Context, componentSBOMs map[string]*layout.ComponentSBOM, imageList []transform.Image, paths *layout.PackagePaths) error { + l := logger.From(ctx) imageCount := len(imageList) componentCount := len(componentSBOMs) cachePath, err := config.GetAbsCachePath() @@ -59,6 +62,7 @@ func Catalog(ctx context.Context, componentSBOMs map[string]*layout.ComponentSBO return err } builder := Builder{ + // TODO(mkcp): Remove message on logger release spinner: message.NewProgressSpinner("Creating SBOMs for %d images and %d components with files.", imageCount, componentCount), cachePath: cachePath, imagesPath: paths.Images.Base, @@ -72,32 +76,39 @@ func Catalog(ctx context.Context, componentSBOMs map[string]*layout.ComponentSBO // Generate a list of images and files for the sbom viewer json, err := builder.generateJSONList(componentSBOMs, imageList) if err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to generate the SBOM image list") - return err + return fmt.Errorf("unable to generate the SBOM image list: %w", err) } builder.jsonList = json // Generate SBOM for each image currImage := 1 + l.Info("creating SBOMs for images", "count", imageCount) for _, refInfo := range imageList { + // TODO(mkcp): Remove message on logger release builder.spinner.Updatef("Creating image SBOMs (%d of %d): %s", currImage, imageCount, refInfo.Reference) + l.Info("creating image SBOMs", "reference", refInfo.Reference) // Get the image that we are creating an SBOM for img, err := utils.LoadOCIImage(paths.Images.Base, refInfo) if err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to load the image to generate an SBOM") - return err + return fmt.Errorf("unable to load the image to generate an SBOM: %w", err) } jsonData, err := builder.createImageSBOM(ctx, img, refInfo.Reference) if err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to create SBOM for image %s", refInfo.Reference) - return err + return fmt.Errorf("unable to create SBOM for image=%s: %w", refInfo.Reference, err) } if err = builder.createSBOMViewerAsset(refInfo.Reference, jsonData); err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to create SBOM viewer for image %s", refInfo.Reference) - return err + return fmt.Errorf("unable to create SBOM viewer for image=%s: %w", refInfo.Reference, err) } currImage++ @@ -106,23 +117,30 @@ func Catalog(ctx context.Context, componentSBOMs map[string]*layout.ComponentSBO currComponent := 1 // Generate SBOM for each component + l.Info("creating SBOMs for components", "count", componentCount) for component := range componentSBOMs { + // TODO(mkcp): Remove message on logger release builder.spinner.Updatef("Creating component file SBOMs (%d of %d): %s", currComponent, componentCount, component) + l.Info("creating component file SBOMs", "component", component) if componentSBOMs[component] == nil { + // TODO(mkcp): Remove message on logger release message.Debugf("Component %s has invalid SBOM, skipping", component) + l.Debug("component has invalid SBOM, skipping", "component", component) continue } jsonData, err := builder.createFileSBOM(ctx, *componentSBOMs[component], component) if err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to create SBOM for component %s", component) - return err + return fmt.Errorf("unable to create SBOM for component=%s: %w", component, err) } if err = builder.createSBOMViewerAsset(fmt.Sprintf("%s%s", componentPrefix, component), jsonData); err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to create SBOM viewer for component %s", component) - return err + return fmt.Errorf("unable to create SBOM for component=%s: %w", component, err) } currComponent++ @@ -131,18 +149,22 @@ func Catalog(ctx context.Context, componentSBOMs map[string]*layout.ComponentSBO // Include the compare tool if there are any image SBOMs OR component SBOMs if len(componentSBOMs) > 0 || len(imageList) > 0 { if err := builder.createSBOMCompareAsset(); err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to create SBOM compare tool") - return err + return fmt.Errorf("unable to create SBOM compare tool: %w", err) } } if err := paths.SBOMs.Archive(); err != nil { + // TODO(mkcp): Remove message on logger release builder.spinner.Errorf(err, "Unable to archive SBOMs") - return err + return fmt.Errorf("unable to archive SBOMs: %w", err) } + // TODO(mkcp): Remove message on logger release builder.spinner.Success() + l.Debug("done building catalog") return nil } diff --git a/src/internal/packager/sbom/tools.go b/src/internal/packager/sbom/tools.go index 972b709906..ae95ac7486 100644 --- a/src/internal/packager/sbom/tools.go +++ b/src/internal/packager/sbom/tools.go @@ -5,7 +5,9 @@ package sbom import ( + "context" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "path/filepath" "github.com/AlecAivazis/survey/v2" @@ -14,7 +16,8 @@ import ( ) // ViewSBOMFiles opens a browser to view the SBOM files and pauses for user input. -func ViewSBOMFiles(directory string) error { +func ViewSBOMFiles(ctx context.Context, directory string) error { + l := logger.From(ctx) sbomViewFiles, err := filepath.Glob(filepath.Join(directory, "sbom-viewer-*")) if err != nil { return err @@ -22,12 +25,14 @@ func ViewSBOMFiles(directory string) error { if len(sbomViewFiles) == 0 { message.Note("There were no images with software bill-of-materials (SBOM) included.") + l.Info("there were no images with software bill-of-materials (SBOM) included.") return nil } link := sbomViewFiles[0] msg := fmt.Sprintf("This package has %d images with software bill-of-materials (SBOM) included. If your browser did not open automatically you can copy and paste this file location into your browser address bar to view them: %s\n\n", len(sbomViewFiles), link) message.Note(msg) + l.Info("this package has images with software bill-of-materials (SBOM) included. If your browser did not open automatically you can copy and paste this file location into your browser address bar to view them", "SBOMCount", len(sbomViewFiles), "link", link) if err := exec.LaunchURL(link); err != nil { return err } diff --git a/src/internal/packager/template/template.go b/src/internal/packager/template/template.go index 872754ce4d..a77d09de93 100644 --- a/src/internal/packager/template/template.go +++ b/src/internal/packager/template/template.go @@ -5,6 +5,7 @@ package template import ( + "context" "encoding/base64" "fmt" "log/slog" @@ -16,6 +17,7 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/pkg/interactive" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/utils" "github.com/zarf-dev/zarf/src/pkg/variables" @@ -26,7 +28,7 @@ const ( ) // GetZarfVariableConfig gets a variable configuration specific to Zarf -func GetZarfVariableConfig() *variables.VariableConfig { +func GetZarfVariableConfig(ctx context.Context) *variables.VariableConfig { prompt := func(variable v1alpha1.InteractiveVariable) (value string, err error) { if config.CommonOptions.Confirm { return variable.Default, nil @@ -34,10 +36,10 @@ func GetZarfVariableConfig() *variables.VariableConfig { return interactive.PromptVariable(variable) } - return variables.New( - "zarf", - prompt, - slog.New(message.ZarfHandler{})) + if logger.Enabled(ctx) { + return variables.New("zarf", prompt, logger.From(ctx)) + } + return variables.New("zarf", prompt, slog.New(message.ZarfHandler{})) } // GetZarfTemplates returns the template keys and values to be used for templating. diff --git a/src/internal/packager2/inspect.go b/src/internal/packager2/inspect.go index 0e4c1e0321..ca03d51f4c 100644 --- a/src/internal/packager2/inspect.go +++ b/src/internal/packager2/inspect.go @@ -54,7 +54,7 @@ func InspectList(ctx context.Context, opt ZarfInspectOptions) ([]string, error) if err != nil { return nil, err } - // Only list images if we have have components + // Only list images if we have components if len(pkg.Components) > 0 { for _, component := range pkg.Components { imageList = append(imageList, component.Images...) @@ -104,7 +104,7 @@ func handleSBOMOptions(ctx context.Context, opt ZarfInspectOptions) error { return err } if opt.ViewSBOM { - err := sbom.ViewSBOMFiles(sbomPath) + err := sbom.ViewSBOMFiles(ctx, sbomPath) if err != nil { return err } diff --git a/src/internal/packager2/mirror.go b/src/internal/packager2/mirror.go index 8532a8c4e6..2f6599911a 100644 --- a/src/internal/packager2/mirror.go +++ b/src/internal/packager2/mirror.go @@ -15,7 +15,6 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/crane" - "github.com/google/go-containerregistry/pkg/logs" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/zarf-dev/zarf/src/config" @@ -24,6 +23,7 @@ import ( "github.com/zarf-dev/zarf/src/internal/gitea" "github.com/zarf-dev/zarf/src/internal/packager2/layout" "github.com/zarf-dev/zarf/src/pkg/cluster" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/filters" "github.com/zarf-dev/zarf/src/pkg/transform" @@ -56,8 +56,7 @@ func Mirror(ctx context.Context, opt MirrorOptions) error { } func pushImagesToRegistry(ctx context.Context, c *cluster.Cluster, pkgLayout *layout.PackageLayout, filter filters.ComponentFilterStrategy, regInfo types.RegistryInfo, noImgChecksum bool, retries int) error { - logs.Warn.SetOutput(&message.DebugWriter{}) - logs.Progress.SetOutput(&message.DebugWriter{}) + l := logger.From(ctx) components, err := filter.Apply(pkgLayout.Pkg) if err != nil { @@ -85,15 +84,15 @@ func pushImagesToRegistry(ctx context.Context, c *cluster.Cluster, pkgLayout *la return nil } - transport := http.DefaultTransport.(*http.Transport).Clone() - transport.TLSClientConfig.InsecureSkipVerify = config.CommonOptions.InsecureSkipTLSVerify + defaultTransport := http.DefaultTransport.(*http.Transport).Clone() + defaultTransport.TLSClientConfig.InsecureSkipVerify = config.CommonOptions.InsecureSkipTLSVerify // TODO (@WSTARR) This is set to match the TLSHandshakeTimeout to potentially mitigate effects of https://github.com/zarf-dev/zarf/issues/1444 - transport.ResponseHeaderTimeout = 10 * time.Second - transportWithProgressBar := helpers.NewTransport(transport, nil) + defaultTransport.ResponseHeaderTimeout = 10 * time.Second + transport := helpers.NewTransport(defaultTransport, nil) pushOptions := []crane.Option{ crane.WithPlatform(&v1.Platform{OS: "linux", Architecture: pkgLayout.Pkg.Build.Architecture}), - crane.WithTransport(transportWithProgressBar), + crane.WithTransport(transport), crane.WithAuth(authn.FromConfig(authn.AuthConfig{ Username: regInfo.PushUsername, Password: regInfo.PushPassword, @@ -124,6 +123,7 @@ func pushImagesToRegistry(ctx context.Context, c *cluster.Cluster, pkgLayout *la names = append(names, offlineName) for _, name := range names { message.Infof("Pushing image %s", name) + l.Info("pushing image", "name", name) err = crane.Push(img, name, pushOptions...) if err != nil { return err @@ -168,6 +168,7 @@ func pushImagesToRegistry(ctx context.Context, c *cluster.Cluster, pkgLayout *la } func pushReposToRepository(ctx context.Context, c *cluster.Cluster, pkgLayout *layout.PackageLayout, filter filters.ComponentFilterStrategy, gitInfo types.GitServerInfo, retries int) error { + l := logger.From(ctx) components, err := filter.Apply(pkgLayout.Pkg) if err != nil { return err @@ -190,6 +191,7 @@ func pushReposToRepository(ctx context.Context, c *cluster.Cluster, pkgLayout *l err = retry.Do(func() error { if !dns.IsServiceURL(gitInfo.Address) { message.Infof("Pushing repository %s to server %s", repoURL, gitInfo.Address) + l.Info("pushing repository to server", "repo", repoURL, "server", gitInfo.Address) err = repository.Push(ctx, gitInfo.Address, gitInfo.PushUsername, gitInfo.PushPassword) if err != nil { return err @@ -219,6 +221,7 @@ func pushReposToRepository(ctx context.Context, c *cluster.Cluster, pkgLayout *l } return tunnel.Wrap(func() error { message.Infof("Pushing repository %s to server %s", repoURL, tunnel.HTTPEndpoint()) + l.Info("pushing repository to server", "repo", repoURL, "server", tunnel.HTTPEndpoint()) err = repository.Push(ctx, tunnel.HTTPEndpoint(), gitInfo.PushUsername, gitInfo.PushPassword) if err != nil { return err diff --git a/src/internal/packager2/remove.go b/src/internal/packager2/remove.go index e20382da2d..2d1365b1f8 100644 --- a/src/internal/packager2/remove.go +++ b/src/internal/packager2/remove.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "slices" "helm.sh/helm/v3/pkg/action" @@ -33,6 +34,7 @@ type RemoveOptions struct { // Remove removes a package that was already deployed onto a cluster, uninstalling all installed helm charts. func Remove(ctx context.Context, opt RemoveOptions) error { + l := logger.From(ctx) pkg, err := packageFromSourceOrCluster(ctx, opt.Cluster, opt.Source, opt.SkipSignatureValidation, opt.PublicKeyPath) if err != nil { return err @@ -109,6 +111,7 @@ func Remove(ctx context.Context, opt RemoveOptions) error { } if errors.Is(err, driver.ErrReleaseNotFound) { message.Warnf("Helm release for helm chart '%s' in the namespace '%s' was not found. Was it already removed?", chart.ChartName, chart.Namespace) + l.Warn("helm release was not found. was it already removed?", "name", chart.ChartName, "namespace", chart.Namespace) } // Pop the removed helm chart from the installed charts slice. @@ -119,6 +122,7 @@ func Remove(ctx context.Context, opt RemoveOptions) error { if err != nil { // We warn and ignore errors because we may have removed the cluster that this package was inside of message.Warnf("Unable to update the secret for package %s, this may be normal if the cluster was removed: %s", depPkg.Name, err.Error()) + l.Warn("unable to update secret for package, this may be normal if the cluster was removed", "pkgName", depPkg.Name, "error", err.Error()) } } } @@ -139,6 +143,7 @@ func Remove(ctx context.Context, opt RemoveOptions) error { if err != nil { // We warn and ignore errors because we may have removed the cluster that this package was inside of message.Warnf("Unable to update the secret for package %s, this may be normal if the cluster was removed: %s", depPkg.Name, err.Error()) + l.Warn("unable to update secret package, this may be normal if the cluster was removed", "pkgName", depPkg.Name, "error", err.Error()) } } return nil @@ -157,6 +162,7 @@ func Remove(ctx context.Context, opt RemoveOptions) error { err := opt.Cluster.DeleteDeployedPackage(ctx, depPkg.Name) if err != nil { message.Warnf("Unable to delete the secret for package %s, this may be normal if the cluster was removed: %s", depPkg.Name, err.Error()) + l.Warn("unable to delete secret for package, this may be normal if the cluster was removed", "pkgName", depPkg.Name, "error", err.Error()) } } diff --git a/src/pkg/cluster/cluster.go b/src/pkg/cluster/cluster.go index 5db77e0c9c..4686deed76 100644 --- a/src/pkg/cluster/cluster.go +++ b/src/pkg/cluster/cluster.go @@ -17,9 +17,12 @@ import ( "sigs.k8s.io/cli-utils/pkg/kstatus/watcher" "github.com/avast/retry-go/v4" - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" ) const ( @@ -38,8 +41,11 @@ type Cluster struct { // NewClusterWithWait creates a new Cluster instance and waits for the given timeout for the cluster to be ready. func NewClusterWithWait(ctx context.Context) (*Cluster, error) { + start := time.Now() + l := logger.From(ctx) spinner := message.NewProgressSpinner("Waiting for cluster connection") defer spinner.Stop() + l.Info("waiting for cluster connection") c, err := NewCluster() if err != nil { @@ -69,6 +75,7 @@ func NewClusterWithWait(ctx context.Context) (*Cluster, error) { } spinner.Success() + l.Debug("done waiting for cluster, connected", "duration", time.Since(start)) return c, nil } @@ -76,11 +83,11 @@ func NewClusterWithWait(ctx context.Context) (*Cluster, error) { // NewCluster creates a new Cluster instance and validates connection to the cluster by fetching the Kubernetes version. func NewCluster() (*Cluster, error) { clusterErr := errors.New("unable to connect to the cluster") - clientset, config, err := pkgkubernetes.ClientAndConfig() + clientset, config, err := ClientAndConfig() if err != nil { return nil, errors.Join(clusterErr, err) } - watcher, err := pkgkubernetes.WatcherForConfig(config) + watcher, err := WatcherForConfig(config) if err != nil { return nil, errors.Join(clusterErr, err) } @@ -96,3 +103,36 @@ func NewCluster() (*Cluster, error) { } return c, nil } + +// ClientAndConfig returns a Kubernetes client and the rest config used to configure the client. +func ClientAndConfig() (kubernetes.Interface, *rest.Config, error) { + loader := clientcmd.NewDefaultClientConfigLoadingRules() + clientCfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loader, nil) + cfg, err := clientCfg.ClientConfig() + if err != nil { + return nil, nil, err + } + clientset, err := kubernetes.NewForConfig(cfg) + if err != nil { + return nil, nil, err + } + return clientset, cfg, nil +} + +// WatcherForConfig returns a status watcher for the give Kubernetes configuration. +func WatcherForConfig(cfg *rest.Config) (watcher.StatusWatcher, error) { + dynamicClient, err := dynamic.NewForConfig(cfg) + if err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(cfg) + if err != nil { + return nil, err + } + restMapper, err := apiutil.NewDynamicRESTMapper(cfg, httpClient) + if err != nil { + return nil, err + } + sw := watcher.NewDefaultStatusWatcher(dynamicClient, restMapper) + return sw, nil +} diff --git a/src/pkg/cluster/injector.go b/src/pkg/cluster/injector.go index 48552ac5e1..8586934710 100644 --- a/src/pkg/cluster/injector.go +++ b/src/pkg/cluster/injector.go @@ -24,9 +24,9 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "github.com/defenseunicorns/pkg/helpers/v2" - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" "github.com/zarf-dev/zarf/src/config" + "github.com/zarf-dev/zarf/src/internal/healthchecks" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/transform" "github.com/zarf-dev/zarf/src/pkg/utils" @@ -117,7 +117,7 @@ func (c *Cluster) StartInjection(ctx context.Context, tmpDir, imagesDir string, waitCtx, waitCancel := context.WithTimeout(ctx, 60*time.Second) defer waitCancel() - err = pkgkubernetes.WaitForReadyRuntime(waitCtx, c.Watcher, []runtime.Object{pod}) + err = healthchecks.WaitForReadyRuntime(waitCtx, c.Watcher, []runtime.Object{pod}) if err != nil { return err } @@ -319,6 +319,9 @@ func hasBlockingTaints(taints []corev1.Taint) bool { func buildInjectionPod(nodeName, image string, payloadCmNames []string, shasum string, resReq corev1.ResourceRequirements) *corev1.Pod { executeMode := int32(0777) + userID := int64(1000) + groupID := int64(2000) + fsGroupID := int64(2000) pod := &corev1.Pod{ TypeMeta: metav1.TypeMeta{ @@ -337,6 +340,12 @@ func buildInjectionPod(nodeName, image string, payloadCmNames []string, shasum s NodeName: nodeName, // Do not try to restart the pod as it will be deleted/re-created instead. RestartPolicy: corev1.RestartPolicyNever, + SecurityContext: &corev1.PodSecurityContext{ + RunAsUser: &userID, + RunAsGroup: &groupID, + FSGroup: &fsGroupID, + SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault}, + }, Containers: []corev1.Container{ { Name: "injector", @@ -366,6 +375,14 @@ func buildInjectionPod(nodeName, image string, payloadCmNames []string, shasum s }, }, }, + SecurityContext: &corev1.SecurityContext{ + ReadOnlyRootFilesystem: helpers.BoolPtr(true), + AllowPrivilegeEscalation: helpers.BoolPtr(false), + RunAsNonRoot: helpers.BoolPtr(true), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + }, Resources: resReq, }, }, diff --git a/src/pkg/cluster/injector_test.go b/src/pkg/cluster/injector_test.go index 67dff422f2..e5acdf3227 100644 --- a/src/pkg/cluster/injector_test.go +++ b/src/pkg/cluster/injector_test.go @@ -15,6 +15,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/layout" "github.com/google/go-containerregistry/pkg/v1/random" "github.com/stretchr/testify/require" + "github.com/zarf-dev/zarf/src/internal/healthchecks" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,8 +23,6 @@ import ( "k8s.io/client-go/kubernetes/fake" k8stesting "k8s.io/client-go/testing" "sigs.k8s.io/cli-utils/pkg/kstatus/status" - - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" ) func TestInjector(t *testing.T) { @@ -31,7 +30,7 @@ func TestInjector(t *testing.T) { cs := fake.NewSimpleClientset() c := &Cluster{ Clientset: cs, - Watcher: pkgkubernetes.NewImmediateWatcher(status.CurrentStatus), + Watcher: healthchecks.NewImmediateWatcher(status.CurrentStatus), } cs.PrependReactor("delete-collection", "configmaps", func(action k8stesting.Action) (bool, runtime.Object, error) { delAction, ok := action.(k8stesting.DeleteCollectionActionImpl) diff --git a/src/pkg/cluster/namespace.go b/src/pkg/cluster/namespace.go index 99d50a5f5e..24525dc6b1 100644 --- a/src/pkg/cluster/namespace.go +++ b/src/pkg/cluster/namespace.go @@ -14,13 +14,17 @@ import ( kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" ) // DeleteZarfNamespace deletes the Zarf namespace from the connected cluster. func (c *Cluster) DeleteZarfNamespace(ctx context.Context) error { + start := time.Now() + l := logger.From(ctx) spinner := message.NewProgressSpinner("Deleting the zarf namespace from this cluster") defer spinner.Stop() + l.Info("deleting the zarf namespace from this cluster") err := c.Clientset.CoreV1().Namespaces().Delete(ctx, ZarfNamespaceName, metav1.DeleteOptions{}) if kerrors.IsNotFound(err) { @@ -42,6 +46,8 @@ func (c *Cluster) DeleteZarfNamespace(ctx context.Context) error { if err != nil { return err } + + l.Debug("done deleting the zarf namespace from this cluster", "duration", time.Since(start)) return nil } diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index f2279b0221..a6274356a0 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -20,6 +20,7 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/config/lang" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/pki" "github.com/zarf-dev/zarf/src/types" @@ -205,7 +206,7 @@ func (c *Cluster) LoadZarfState(ctx context.Context) (*types.ZarfState, error) { if err != nil { return nil, fmt.Errorf("%w: %w", stateErr, err) } - c.debugPrintZarfState(state) + c.debugPrintZarfState(ctx, state) return state, nil } @@ -230,10 +231,11 @@ func (c *Cluster) sanitizeZarfState(state *types.ZarfState) *types.ZarfState { return state } -func (c *Cluster) debugPrintZarfState(state *types.ZarfState) { +func (c *Cluster) debugPrintZarfState(ctx context.Context, state *types.ZarfState) { if state == nil { return } + // this is a shallow copy, nested pointers WILL NOT be copied oldState := *state sanitized := c.sanitizeZarfState(&oldState) @@ -242,11 +244,13 @@ func (c *Cluster) debugPrintZarfState(state *types.ZarfState) { return } message.Debugf("ZarfState - %s", string(b)) + + logger.From(ctx).Debug("cluster.debugPrintZarfState", "state", sanitized) } // SaveZarfState takes a given state and persists it to the Zarf/zarf-state secret. func (c *Cluster) SaveZarfState(ctx context.Context, state *types.ZarfState) error { - c.debugPrintZarfState(state) + c.debugPrintZarfState(ctx, state) data, err := json.Marshal(&state) if err != nil { diff --git a/src/pkg/cluster/testdata/expected-injection-pod.json b/src/pkg/cluster/testdata/expected-injection-pod.json index 30f2e5b1f1..297a5e28bc 100644 --- a/src/pkg/cluster/testdata/expected-injection-pod.json +++ b/src/pkg/cluster/testdata/expected-injection-pod.json @@ -1 +1 @@ -{"kind":"Pod","apiVersion":"v1","metadata":{"name":"injector","namespace":"zarf","creationTimestamp":null,"labels":{"app":"zarf-injector","zarf.dev/agent":"ignore"}},"spec":{"volumes":[{"name":"init","configMap":{"name":"rust-binary","defaultMode":511}},{"name":"seed","emptyDir":{}},{"name":"foo","configMap":{"name":"foo"}},{"name":"bar","configMap":{"name":"bar"}}],"containers":[{"name":"injector","image":"docker.io/library/ubuntu:latest","command":["/zarf-init/zarf-injector","shasum"],"workingDir":"/zarf-init","resources":{"limits":{"cpu":"1","memory":"256Mi"},"requests":{"cpu":"500m","memory":"64Mi"}},"volumeMounts":[{"name":"init","mountPath":"/zarf-init/zarf-injector","subPath":"zarf-injector"},{"name":"seed","mountPath":"/zarf-seed"},{"name":"foo","mountPath":"/zarf-init/foo","subPath":"foo"},{"name":"bar","mountPath":"/zarf-init/bar","subPath":"bar"}],"readinessProbe":{"httpGet":{"path":"/v2/","port":5000},"periodSeconds":2,"successThreshold":1,"failureThreshold":10},"imagePullPolicy":"IfNotPresent"}],"restartPolicy":"Never","nodeName":"injection-node"},"status":{}} +{"kind":"Pod","apiVersion":"v1","metadata":{"name":"injector","namespace":"zarf","creationTimestamp":null,"labels":{"app":"zarf-injector","zarf.dev/agent":"ignore"}},"spec":{"volumes":[{"name":"init","configMap":{"name":"rust-binary","defaultMode":511}},{"name":"seed","emptyDir":{}},{"name":"foo","configMap":{"name":"foo"}},{"name":"bar","configMap":{"name":"bar"}}],"containers":[{"name":"injector","image":"docker.io/library/ubuntu:latest","command":["/zarf-init/zarf-injector","shasum"],"workingDir":"/zarf-init","resources":{"limits":{"cpu":"1","memory":"256Mi"},"requests":{"cpu":"500m","memory":"64Mi"}},"volumeMounts":[{"name":"init","mountPath":"/zarf-init/zarf-injector","subPath":"zarf-injector"},{"name":"seed","mountPath":"/zarf-seed"},{"name":"foo","mountPath":"/zarf-init/foo","subPath":"foo"},{"name":"bar","mountPath":"/zarf-init/bar","subPath":"bar"}],"readinessProbe":{"httpGet":{"path":"/v2/","port":5000},"periodSeconds":2,"successThreshold":1,"failureThreshold":10},"imagePullPolicy":"IfNotPresent","securityContext":{"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"readOnlyRootFilesystem":true,"allowPrivilegeEscalation":false}}],"restartPolicy":"Never","nodeName":"injection-node","securityContext":{"runAsUser":1000,"runAsGroup":2000,"fsGroup":2000,"seccompProfile":{"type":"RuntimeDefault"}}},"status":{}} diff --git a/src/pkg/cluster/tunnel.go b/src/pkg/cluster/tunnel.go index 9798fd3272..16e300b7da 100644 --- a/src/pkg/cluster/tunnel.go +++ b/src/pkg/cluster/tunnel.go @@ -23,6 +23,7 @@ import ( "github.com/avast/retry-go/v4" "github.com/defenseunicorns/pkg/helpers/v2" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/types" ) @@ -221,6 +222,10 @@ func (c *Cluster) checkForZarfConnectLabel(ctx context.Context, name string) (Tu zt.urlSuffix = svc.Annotations[ZarfConnectAnnotationURL] message.Debugf("tunnel connection match: %s/%s on port %d", svc.Namespace, svc.Name, zt.RemotePort) + logger.From(ctx).Debug("tunnel connection match", + "namespace", svc.Namespace, + "name", svc.Name, + "remotePort", zt.RemotePort) } else { return zt, fmt.Errorf("no matching services found for %s", name) } @@ -393,6 +398,7 @@ func (tunnel *Tunnel) Close() { // establish opens a tunnel to a kubernetes resource, as specified by the provided tunnel struct. func (tunnel *Tunnel) establish(ctx context.Context) (string, error) { var err error + l := logger.From(ctx) // Track this locally as we may need to retry if the tunnel fails. localPort := tunnel.localPort @@ -405,11 +411,13 @@ func (tunnel *Tunnel) establish(ctx context.Context) (string, error) { // is available for selection again. if localPort == 0 { message.Debugf("Requested local port is 0. Selecting an open port on host system") + l.Debug("requested local port is 0. Selecting an open port on host system") localPort, err = helpers.GetAvailablePort() if err != nil { return "", fmt.Errorf("unable to find an available port: %w", err) } message.Debugf("Selected port %d", localPort) + l.Debug("selected port", "port", localPort) globalMutex.Lock() defer globalMutex.Unlock() } @@ -422,6 +430,13 @@ func (tunnel *Tunnel) establish(ctx context.Context) (string, error) { tunnel.namespace, ) message.Debugf(msg) + l.Debug("opening tunnel", + "localPort", localPort, + "remotePort", tunnel.remotePort, + "resourceType", tunnel.resourceType, + "resourceName", tunnel.resourceName, + "namespace", tunnel.namespace, + ) // Find the pod to port forward to podName, err := tunnel.getAttachablePodForResource(ctx) @@ -429,6 +444,7 @@ func (tunnel *Tunnel) establish(ctx context.Context) (string, error) { return "", fmt.Errorf("unable to find pod attached to given resource: %w", err) } message.Debugf("Selected pod %s to open port forward to", podName) + l.Debug("selected pod to open port forward to", "name", podName) // Build url to the port forward endpoint. // Example: http://localhost:8080/api/v1/namespaces/helm/pods/tiller-deploy-9itlq/portforward. @@ -442,6 +458,7 @@ func (tunnel *Tunnel) establish(ctx context.Context) (string, error) { URL() message.Debugf("Using URL %s to create portforward", portForwardCreateURL) + l.Debug("using URL to create portforward", "url", portForwardCreateURL) // Construct the spdy client required by the client-go portforward library. transport, upgrader, err := spdy.RoundTripperFor(tunnel.restConfig) @@ -477,6 +494,7 @@ func (tunnel *Tunnel) establish(ctx context.Context) (string, error) { tunnel.errChan = errChan message.Debugf("Creating port forwarding tunnel at %s", url) + l.Debug("creating port forwarding tunnel", "url", url) return url, nil } } diff --git a/src/pkg/cluster/zarf.go b/src/pkg/cluster/zarf.go index 3f12381e38..906a7bc166 100644 --- a/src/pkg/cluster/zarf.go +++ b/src/pkg/cluster/zarf.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "strings" + "time" autoscalingV2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" @@ -19,6 +20,7 @@ import ( "github.com/zarf-dev/zarf/src/api/v1alpha1" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/internal/gitea" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/types" ) @@ -133,41 +135,51 @@ func (c *Cluster) DeleteDeployedPackage(ctx context.Context, packageName string) // StripZarfLabelsAndSecretsFromNamespaces removes metadata and secrets from existing namespaces no longer manged by Zarf. func (c *Cluster) StripZarfLabelsAndSecretsFromNamespaces(ctx context.Context) { + start := time.Now() + l := logger.From(ctx) spinner := message.NewProgressSpinner("Removing zarf metadata & secrets from existing namespaces not managed by Zarf") defer spinner.Stop() + l.Info("removing zarf metadata & secrets from existing namespaces not managed by Zarf") deleteOptions := metav1.DeleteOptions{} listOptions := metav1.ListOptions{ LabelSelector: ZarfManagedByLabel + "=zarf", } + // TODO(mkcp): Remove unnecessary nesting w/ else namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) if err != nil { spinner.Errorf(err, "Unable to get k8s namespaces") + l.Error("unable to get k8s namespaces", "error", err) } else { for _, namespace := range namespaceList.Items { if _, ok := namespace.Labels[AgentLabel]; ok { spinner.Updatef("Removing Zarf Agent label for namespace %s", namespace.Name) + l.Info("removing Zarf Agent label", "namespace", namespace.Name) delete(namespace.Labels, AgentLabel) namespaceCopy := namespace _, err := c.Clientset.CoreV1().Namespaces().Update(ctx, &namespaceCopy, metav1.UpdateOptions{}) if err != nil { // This is not a hard failure, but we should log it spinner.Errorf(err, "Unable to update the namespace labels for %s", namespace.Name) + l.Warn("unable to update the namespace labels", "namespace", namespace.Name, "error", err) } } spinner.Updatef("Removing Zarf secrets for namespace %s", namespace.Name) + l.Info("removing Zarf secrets", "namespace", namespace.Name) err := c.Clientset.CoreV1(). Secrets(namespace.Name). DeleteCollection(ctx, deleteOptions, listOptions) if err != nil { spinner.Errorf(err, "Unable to delete secrets from namespace %s", namespace.Name) + l.Error("unable to delete secrets", "namespace", namespace.Name, "error", err) } } } spinner.Success() + l.Debug("done stripping zarf labels and secrets from namespaces", "duration", time.Since(start)) } // RecordPackageDeployment saves metadata about a package that has been deployed to the cluster. diff --git a/src/pkg/layout/component.go b/src/pkg/layout/component.go index 9a3735b54b..3e524852fe 100644 --- a/src/pkg/layout/component.go +++ b/src/pkg/layout/component.go @@ -5,6 +5,7 @@ package layout import ( + "context" "fmt" "io/fs" "os" @@ -13,6 +14,7 @@ import ( "github.com/defenseunicorns/pkg/helpers/v2" "github.com/mholt/archiver/v3" "github.com/zarf-dev/zarf/src/api/v1alpha1" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" ) @@ -39,7 +41,8 @@ type Components struct { var ErrNotLoaded = fmt.Errorf("not loaded") // Archive archives a component. -func (c *Components) Archive(component v1alpha1.ZarfComponent, cleanupTemp bool) error { +func (c *Components) Archive(ctx context.Context, component v1alpha1.ZarfComponent, cleanupTemp bool) error { + l := logger.From(ctx) name := component.Name if _, ok := c.Dirs[name]; !ok { return &fs.PathError{ @@ -61,7 +64,9 @@ func (c *Components) Archive(component v1alpha1.ZarfComponent, cleanupTemp bool) } if size > 0 { tb := fmt.Sprintf("%s.tar", base) + // TODO(mkcp): Remove message on logger release message.Debugf("Archiving %q", name) + l.Debug("archiving component", "name", name) if err := helpers.CreateReproducibleTarballFromDir(base, name, tb); err != nil { return err } @@ -70,7 +75,9 @@ func (c *Components) Archive(component v1alpha1.ZarfComponent, cleanupTemp bool) } c.Tarballs[name] = tb } else { + // TODO(mkcp): Remove message on logger release message.Debugf("Component %q is empty, skipping archiving", name) + l.Debug("component is empty, skipping archiving", "name", name) } delete(c.Dirs, name) diff --git a/src/pkg/layout/package.go b/src/pkg/layout/package.go index 7824d34ba9..2141de586f 100644 --- a/src/pkg/layout/package.go +++ b/src/pkg/layout/package.go @@ -5,6 +5,7 @@ package layout import ( + "context" "errors" "fmt" "os" @@ -19,6 +20,7 @@ import ( ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/zarf-dev/zarf/src/api/v1alpha1" "github.com/zarf-dev/zarf/src/pkg/interactive" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/deprecated" "github.com/zarf-dev/zarf/src/pkg/utils" @@ -225,22 +227,29 @@ func (pp *PackagePaths) GenerateChecksums() (string, error) { } // ArchivePackage creates an archive for a Zarf package. -func (pp *PackagePaths) ArchivePackage(destinationTarball string, maxPackageSizeMB int) error { +func (pp *PackagePaths) ArchivePackage(ctx context.Context, destinationTarball string, maxPackageSizeMB int) error { + l := logger.From(ctx) + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Writing %s to %s", pp.Base, destinationTarball) defer spinner.Stop() + l.Info("archiving zarf package", "base", pp.Base, "destination", destinationTarball) // Make the archive archiveSrc := []string{pp.Base + string(os.PathSeparator)} if err := archiver.Archive(archiveSrc, destinationTarball); err != nil { return fmt.Errorf("unable to create package: %w", err) } + // TODO(mkcp): Remove message on logger release spinner.Updatef("Wrote %s to %s", pp.Base, destinationTarball) + l.Debug("ArchivePackage wrote", "base", pp.Base, "destination", destinationTarball) fi, err := os.Stat(destinationTarball) if err != nil { return fmt.Errorf("unable to read the package archive: %w", err) } + // TODO(mkcp): Remove message on logger release spinner.Successf("Package saved to %q", destinationTarball) + l.Debug("package saved", "destination", destinationTarball) // Convert Megabytes to bytes. chunkSize := maxPackageSizeMB * 1000 * 1000 @@ -251,6 +260,7 @@ func (pp *PackagePaths) ArchivePackage(destinationTarball string, maxPackageSize return fmt.Errorf("unable to split the package archive into multiple files: must be less than 1,000 files") } message.Notef("Package is larger than %dMB, splitting into multiple files", maxPackageSizeMB) + l.Info("package is larger than max, splitting into multiple files", "maxPackageSize", maxPackageSizeMB) err := splitFile(destinationTarball, chunkSize) if err != nil { return fmt.Errorf("unable to split the package archive into multiple files: %w", err) diff --git a/src/pkg/logger/logger.go b/src/pkg/logger/logger.go new file mode 100644 index 0000000000..bd17269772 --- /dev/null +++ b/src/pkg/logger/logger.go @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package logger implements a log/slog based logger in Zarf. +package logger + +import ( + "context" + "fmt" + "io" + "log/slog" + "os" + "strings" + "sync/atomic" + + "github.com/phsym/console-slog" + + "github.com/golang-cz/devslog" +) + +var defaultLogger atomic.Pointer[slog.Logger] + +// init sets a logger with default config when the package is initialized. +func init() { + l, _ := New(ConfigDefault()) //nolint:errcheck + SetDefault(l) +} + +// Level declares each supported log level. These are 1:1 what log/slog supports by default. Info is the default level. +type Level int + +// Store names for Levels +var ( + Debug = Level(slog.LevelDebug) // -4 + Info = Level(slog.LevelInfo) // 0 + Warn = Level(slog.LevelWarn) // 4 + Error = Level(slog.LevelError) // 8 +) + +// validLevels is a set that provides an ergonomic way to check if a level is a member of the set. +var validLevels = map[Level]bool{ + Debug: true, + Info: true, + Warn: true, + Error: true, +} + +// strLevels maps a string to its Level. +var strLevels = map[string]Level{ + // NOTE(mkcp): Map trace to debug for backwards compatibility. + "trace": Debug, + "debug": Debug, + "info": Info, + "warn": Warn, + "error": Error, +} + +// ParseLevel takes a string representation of a Level, ensure it exists, and then converts it into a Level. +func ParseLevel(s string) (Level, error) { + k := strings.ToLower(s) + l, ok := strLevels[k] + if !ok { + return 0, fmt.Errorf("invalid log level: %s", k) + } + return l, nil +} + +// Format declares the kind of logging handler to use. +// NOTE(mkcp): An empty Format defaults to "none" while logger is being worked on, but this is intended to use "text" +// on release. +type Format string + +// ToLower takes a Format string and converts it to lowercase for case-agnostic validation. Users shouldn't have to care +// about "json" vs. "JSON" for example - they should both work. +func (f Format) ToLower() Format { + return Format(strings.ToLower(string(f))) +} + +var ( + // FormatText uses the standard slog TextHandler + FormatText Format = "text" + // FormatJSON uses the standard slog JSONHandler + FormatJSON Format = "json" + // FormatConsole uses console-slog to provide prettier colorful messages + FormatConsole Format = "console" + // FormatDev uses a verbose and prettyprinting devslog handler + FormatDev Format = "dev" + // FormatNone sends log writes to DestinationNone / io.Discard + FormatNone Format = "none" +) + +// Destination declares an io.Writer to send logs to. +type Destination io.Writer + +var ( + // DestinationDefault points to Stderr + DestinationDefault Destination = os.Stderr + // DestinationNone discards logs as they are received + DestinationNone Destination = io.Discard +) + +// Config is configuration for a logger. +type Config struct { + // Level sets the log level. An empty value corresponds to Info aka 0. + Level + Format + Destination +} + +// ConfigDefault returns a Config with defaults like Text formatting at Info level writing to Stderr. +func ConfigDefault() Config { + return Config{ + Level: Info, + Format: FormatText, + Destination: DestinationDefault, // Stderr + } +} + +// New takes a Config and returns a validated logger. +func New(cfg Config) (*slog.Logger, error) { + var handler slog.Handler + opts := slog.HandlerOptions{} + + // Use default destination if none + if cfg.Destination == nil { + cfg.Destination = DestinationDefault + } + + // Check that we have a valid log level. + if !validLevels[cfg.Level] { + return nil, fmt.Errorf("unsupported log level: %d", cfg.Level) + } + opts.Level = slog.Level(cfg.Level) + + switch cfg.Format.ToLower() { + case FormatText: + handler = slog.NewTextHandler(cfg.Destination, &opts) + case FormatJSON: + handler = slog.NewJSONHandler(cfg.Destination, &opts) + case FormatConsole: + handler = console.NewHandler(cfg.Destination, &console.HandlerOptions{ + Level: slog.Level(cfg.Level), + }) + case FormatDev: + opts.AddSource = true + handler = devslog.NewHandler(DestinationDefault, &devslog.Options{ + HandlerOptions: &opts, + NewLineAfterLog: true, + }) + // Use discard handler if no format provided + case "", FormatNone: + handler = slog.NewTextHandler(DestinationNone, &slog.HandlerOptions{}) + // Format not found, let's error out + default: + return nil, fmt.Errorf("unsupported log format: %s", cfg.Format) + } + + log := slog.New(handler) + return log, nil +} + +// ctxKey provides a location to store a logger in a context. +type ctxKey struct{} + +// defaultCtxKey provides a default key if one is not passed into From. +var defaultCtxKey = ctxKey{} + +// WithContext takes a context.Context and a *slog.Logger, storing it on the key +func WithContext(ctx context.Context, logger *slog.Logger) context.Context { + return context.WithValue(ctx, defaultCtxKey, logger) +} + +// TODO (@austinabro321) once we switch over to the new logger completely the enabled key & logic should be deleted +type ctxKeyEnabled struct{} + +var defaultCtxKeyEnabled = ctxKeyEnabled{} + +// WithLoggingEnabled allows stores a value to determine whether or not slog logging is enabled +func WithLoggingEnabled(ctx context.Context, enabled bool) context.Context { + return context.WithValue(ctx, defaultCtxKeyEnabled, enabled) +} + +// Enabled returns true if slog logging is enabled +func Enabled(ctx context.Context) bool { + if ctx == nil { + return false + } + enabled := ctx.Value(defaultCtxKeyEnabled) + switch v := enabled.(type) { + case bool: + return v + default: + return false + } +} + +// From takes a context and reads out a *slog.Logger. If From does not find a value it will return a discarding logger +// similar to log-format "none". +func From(ctx context.Context) *slog.Logger { + // Check that we have a ctx + if ctx == nil { + return newEmpty() + } + // Grab value from key + log := ctx.Value(defaultCtxKey) + if log == nil { + return newEmpty() + } + + // Ensure our value is a *slog.Logger before we cast. + switch l := log.(type) { + case *slog.Logger: + return l + default: + // Not reached + panic(fmt.Sprintf("unexpected value type on context key: %T", log)) + } +} + +// newDiscard returns a logger without any settings that goes to io.Discard +func newEmpty() *slog.Logger { + h := slog.NewTextHandler(DestinationNone, &slog.HandlerOptions{}) + return slog.New(h) +} + +// Default retrieves a logger from the package default. This is intended as a fallback when a logger cannot easily be +// passed in as a dependency, like when developing a new function. Use it like you would use context.TODO(). +func Default() *slog.Logger { + return defaultLogger.Load() +} + +// SetDefault takes a logger and atomically stores it as the package default. This is intended to be called when the +// application starts to override the default config with application-specific config. See Default() for more usage +// details. +func SetDefault(l *slog.Logger) { + defaultLogger.Store(l) +} diff --git a/src/pkg/logger/logger_test.go b/src/pkg/logger/logger_test.go new file mode 100644 index 0000000000..74695ca063 --- /dev/null +++ b/src/pkg/logger/logger_test.go @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2021-Present The Zarf Authors + +// Package logger implements a log/slog based logger in Zarf. +package logger + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_New(t *testing.T) { + t.Parallel() + + tt := []struct { + name string + cfg Config + }{ + { + name: "Empty level, format, and destination are ok", + cfg: Config{}, + }, + { + name: "Default config is ok", + cfg: ConfigDefault(), + }, + { + name: "Debug logs are ok", + cfg: Config{ + Level: Debug, + }, + }, + { + name: "Info logs are ok", + cfg: Config{ + Level: Info, + }, + }, + { + name: "Warn logs are ok", + cfg: Config{ + Level: Warn, + }, + }, + { + name: "Error logs are ok", + cfg: Config{ + Level: Error, + }, + }, + { + name: "Text format is supported", + cfg: Config{ + Format: FormatText, + }, + }, + { + name: "JSON format is supported", + cfg: Config{ + Format: FormatJSON, + }, + }, + { + name: "FormatNone is supported to disable logs", + cfg: Config{ + Format: FormatNone, + }, + }, + { + name: "DestinationNone is supported to disable logs", + cfg: Config{ + Destination: DestinationNone, + }, + }, + { + name: "users can send logs to any io.Writer", + cfg: Config{ + Destination: os.Stdout, + }, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + res, err := New(tc.cfg) + require.NoError(t, err) + require.NotNil(t, res) + }) + } +} + +func Test_NewErrors(t *testing.T) { + t.Parallel() + + tt := []struct { + name string + cfg Config + }{ + { + name: "unsupported log level errors", + cfg: Config{ + Level: 3, + }, + }, + { + name: "wildly unsupported log level errors", + cfg: Config{ + Level: 42389412389213489, + }, + }, + { + name: "unsupported format errors", + cfg: Config{ + Format: "foobar", + }, + }, + { + name: "wildly unsupported format errors", + cfg: Config{ + Format: "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$ lorem ipsum dolor sit amet 243897 )*&($#", + }, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + res, err := New(tc.cfg) + require.Error(t, err) + require.Nil(t, res) + }) + } +} + +func Test_ParseLevel(t *testing.T) { + t.Parallel() + + tt := []struct { + name string + s string + expect Level + }{ + { + name: "can parse debug", + s: "debug", + expect: Debug, + }, + { + name: "can parse info", + s: "Info", + expect: Info, + }, + { + name: "can parse warn", + s: "warn", + expect: Warn, + }, + { + name: "can parse error", + s: "error", + expect: Error, + }, + { + name: "can handle uppercase", + s: "ERROR", + expect: Error, + }, + { + name: "can handle inconsistent uppercase", + s: "errOR", + expect: Error, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + res, err := ParseLevel(tc.s) + require.NoError(t, err) + require.Equal(t, tc.expect, res) + }) + } +} + +func Test_ParseLevelErrors(t *testing.T) { + t.Parallel() + + tt := []struct { + name string + s string + }{ + { + name: "errors out on unknown level", + s: "SUPER-DEBUG-10x-supremE", + }, + { + name: "is precise about character variations", + s: "érrør", + }, + { + name: "does not partial match level", + s: "error-info", + }, + { + name: "does not partial match level 2", + s: "info-error", + }, + { + name: "does not partial match level 3", + s: "info2", + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + _, err := ParseLevel(tc.s) + require.Error(t, err) + }) + } +} + +func TestContext(t *testing.T) { + t.Parallel() + + t.Run("can load a logger from the default key", func(t *testing.T) { + ctx := WithContext(context.Background(), Default()) + res := From(ctx) + require.NotNil(t, res) + }) + t.Run("can add a flag to the context to determine if enabled", func(t *testing.T) { + ctx := WithLoggingEnabled(context.Background(), true) + require.True(t, Enabled(ctx)) + }) +} diff --git a/src/pkg/packager/actions/actions.go b/src/pkg/packager/actions/actions.go index dbef82b613..e688e0b6ce 100644 --- a/src/pkg/packager/actions/actions.go +++ b/src/pkg/packager/actions/actions.go @@ -7,6 +7,7 @@ package actions import ( "context" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "regexp" "runtime" "strings" @@ -23,8 +24,9 @@ import ( // Run runs all provided actions. func Run(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefaults, actions []v1alpha1.ZarfComponentAction, variableConfig *variables.VariableConfig) error { + // TODO(mkcp): Remove interactive on logger release if variableConfig == nil { - variableConfig = template.GetZarfVariableConfig() + variableConfig = template.GetZarfVariableConfig(ctx) } for _, a := range actions { @@ -37,13 +39,12 @@ func Run(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefaults, a // Run commands that a component has provided. func runAction(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefaults, action v1alpha1.ZarfComponentAction, variableConfig *variables.VariableConfig) error { - var ( - cmdEscaped string - out string - err error - - cmd = action.Cmd - ) + var cmdEscaped string + var out string + var err error + cmd := action.Cmd + l := logger.From(ctx) + start := time.Now() // If the action is a wait, convert it to a command. if action.Wait != nil { @@ -79,14 +80,17 @@ func runAction(ctx context.Context, defaultCfg v1alpha1.ZarfComponentActionDefau cmdEscaped = helpers.Truncate(cmd, 60, false) } + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Running \"%s\"", cmdEscaped) // Persist the spinner output so it doesn't get overwritten by the command output. spinner.EnablePreserveWrites() + l.Info("running command", "cmd", cmdEscaped) actionDefaults := actionGetCfg(ctx, defaultCfg, action, variableConfig.GetAllTemplates()) if cmd, err = actionCmdMutation(ctx, cmd, actionDefaults.Shell); err != nil { spinner.Errorf(err, "Error mutating command: %s", cmdEscaped) + l.Error("error mutating command", "cmd", cmdEscaped, "err", err.Error()) } duration := time.Duration(actionDefaults.MaxTotalSeconds) * time.Second @@ -116,10 +120,13 @@ retryCmd: // If the action has a wait, change the spinner message to reflect that on success. if action.Wait != nil { spinner.Successf("Wait for \"%s\" succeeded", cmdEscaped) - } else { - spinner.Successf("Completed \"%s\"", cmdEscaped) + l.Debug("wait for action succeeded", "cmd", cmdEscaped, "duration", time.Since(start)) + return nil } + spinner.Successf("Completed \"%s\"", cmdEscaped) + l.Debug("completed action", "cmd", cmdEscaped, "duration", time.Since(start)) + // If the command ran successfully, continue to the next action. return nil } @@ -127,6 +134,7 @@ retryCmd: // If no timeout is set, run the command and return or continue retrying. if actionDefaults.MaxTotalSeconds < 1 { spinner.Updatef("Waiting for \"%s\" (no timeout)", cmdEscaped) + l.Info("waiting for action (no timeout)", "cmd", cmdEscaped) //TODO (schristoff): Make it so tryCmd can take a normal ctx if err := tryCmd(context.Background()); err != nil { continue retryCmd @@ -137,6 +145,7 @@ retryCmd: // Run the command on repeat until success or timeout. spinner.Updatef("Waiting for \"%s\" (timeout: %ds)", cmdEscaped, actionDefaults.MaxTotalSeconds) + l.Info("waiting for action", "cmd", cmdEscaped, "timeout", actionDefaults.MaxTotalSeconds) select { // On timeout break the loop to abort. case <-timeout: @@ -205,7 +214,7 @@ func convertWaitToCmd(_ context.Context, wait v1alpha1.ZarfComponentActionWait, } // Perform some basic string mutations to make commands more useful. -func actionCmdMutation(_ context.Context, cmd string, shellPref v1alpha1.Shell) (string, error) { +func actionCmdMutation(ctx context.Context, cmd string, shellPref v1alpha1.Shell) (string, error) { zarfCommand, err := utils.GetFinalExecutableCommand() if err != nil { return cmd, err @@ -227,7 +236,9 @@ func actionCmdMutation(_ context.Context, cmd string, shellPref v1alpha1.Shell) get, err := helpers.MatchRegex(envVarRegex, cmd) if err == nil { newCmd := strings.ReplaceAll(cmd, get("envIndicator"), fmt.Sprintf("$Env:%s", get("varName"))) + // TODO(mkcp): Remove message on logger release message.Debugf("Converted command \"%s\" to \"%s\" t", cmd, newCmd) + logger.From(ctx).Debug("converted command", "cmd", cmd, "newCmd", newCmd) cmd = newCmd } } @@ -276,9 +287,12 @@ func actionGetCfg(_ context.Context, cfg v1alpha1.ZarfComponentActionDefaults, a } func actionRun(ctx context.Context, cfg v1alpha1.ZarfComponentActionDefaults, cmd string, shellPref v1alpha1.Shell, spinner *message.Spinner) (string, error) { + l := logger.From(ctx) shell, shellArgs := exec.GetOSShell(shellPref) + // TODO(mkcp): Remove message on logger release message.Debugf("Running command in %s: %s", shell, cmd) + l.Debug("running command", "shell", shell, "cmd", cmd) execCfg := exec.Config{ Env: cfg.Env, @@ -293,7 +307,9 @@ func actionRun(ctx context.Context, cfg v1alpha1.ZarfComponentActionDefaults, cm out, errOut, err := exec.CmdWithContext(ctx, execCfg, shell, append(shellArgs, cmd)...) // Dump final complete output (respect mute to prevent sensitive values from hitting the logs). if !cfg.Mute { + // TODO(mkcp): Remove message on logger release message.Debug(cmd, out, errOut) + l.Debug("action complete", "cmd", cmd, "out", out, "errOut", errOut) } return out, err diff --git a/src/pkg/packager/common.go b/src/pkg/packager/common.go index 1325a70b46..442335cec0 100644 --- a/src/pkg/packager/common.go +++ b/src/pkg/packager/common.go @@ -8,6 +8,7 @@ import ( "context" "errors" "fmt" + "github.com/zarf-dev/zarf/src/pkg/logger" "os" "slices" "strings" @@ -30,6 +31,7 @@ import ( // Packager is the main struct for managing packages. type Packager struct { + ctx context.Context cfg *types.PackagerConfig variableConfig *variables.VariableConfig state *types.ZarfState @@ -65,36 +67,43 @@ func WithTemp(base string) Modifier { } } +// WithContext sets the packager's context +func WithContext(ctx context.Context) Modifier { + return func(p *Packager) { + p.ctx = ctx + } +} + /* New creates a new package instance with the provided config. Note: This function creates a tmp directory that should be cleaned up with p.ClearTempPaths(). */ func New(cfg *types.PackagerConfig, mods ...Modifier) (*Packager, error) { + var err error if cfg == nil { return nil, fmt.Errorf("no config provided") } - var ( - err error - pkgr = &Packager{ - cfg: cfg, - } - ) + pkgr := &Packager{cfg: cfg} + for _, mod := range mods { + mod(pkgr) + } - pkgr.variableConfig = template.GetZarfVariableConfig() + l := logger.From(pkgr.ctx) + pkgr.variableConfig = template.GetZarfVariableConfig(pkgr.ctx) + cacheDir := config.CommonOptions.CachePath + tmpDir := config.CommonOptions.TempDirectory if config.CommonOptions.TempDirectory != "" { // If the cache directory is within the temp directory, warn the user - if strings.HasPrefix(config.CommonOptions.CachePath, config.CommonOptions.TempDirectory) { + if strings.HasPrefix(cacheDir, tmpDir) { + // TODO(mkcp): Remove message on logger release message.Warnf("The cache directory (%q) is within the temp directory (%q) and will be removed when the temp directory is cleaned up", config.CommonOptions.CachePath, config.CommonOptions.TempDirectory) + l.Warn("the cache directory is within the temp directory and will be removed when the temp directory is cleaned up", "cacheDir", cacheDir, "tmpDir", tmpDir) } } - for _, mod := range mods { - mod(pkgr) - } - // Fill the source if it wasn't provided - note source can be nil if the package is being created if pkgr.source == nil && pkgr.cfg.CreateOpts.BaseDir == "" { pkgr.source, err = sources.New(&pkgr.cfg.PkgOpts) @@ -109,7 +118,9 @@ func New(cfg *types.PackagerConfig, mods ...Modifier) (*Packager, error) { if err != nil { return nil, fmt.Errorf("unable to create package temp paths: %w", err) } + // TODO(mkcp): Remove message on logger release message.Debug("Using temporary directory:", dir) + l.Debug("using temporary directory", "tmpDir", dir) pkgr.layout = layout.New(dir) } @@ -118,9 +129,20 @@ func New(cfg *types.PackagerConfig, mods ...Modifier) (*Packager, error) { // ClearTempPaths removes the temp directory and any files within it. func (p *Packager) ClearTempPaths() { - // Remove the temp directory, but don't throw an error if it fails - _ = os.RemoveAll(p.layout.Base) - _ = os.RemoveAll(layout.SBOMDir) + // Remove the temp directory + l := logger.From(p.ctx) + l.Debug("clearing temp paths", + "basePath", p.layout.Base, + "SBOMDir", layout.SBOMDir, + ) + err := os.RemoveAll(p.layout.Base) + if err != nil { + l.Error(err.Error(), "basePath", p.layout.Base) + } + err2 := os.RemoveAll(layout.SBOMDir) + if err2 != nil { + l.Error(err2.Error(), "SBOMDir", layout.SBOMDir) + } } // GetVariableConfig returns the variable configuration for the packager. diff --git a/src/pkg/packager/create.go b/src/pkg/packager/create.go index 517726eba4..125dd002d3 100755 --- a/src/pkg/packager/create.go +++ b/src/pkg/packager/create.go @@ -8,51 +8,84 @@ import ( "context" "fmt" "os" + "time" - "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/pkg/layout" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/creator" + + "github.com/defenseunicorns/pkg/helpers/v2" ) // Create generates a Zarf package tarball for a given PackageConfig and optional base directory. func (p *Packager) Create(ctx context.Context) error { + l := logger.From(ctx) + l.Info("starting package create") + cStart := time.Now() + + // Begin setup cwd, err := os.Getwd() if err != nil { return err } + cfg := p.cfg - if err := os.Chdir(p.cfg.CreateOpts.BaseDir); err != nil { - return fmt.Errorf("unable to access directory %q: %w", p.cfg.CreateOpts.BaseDir, err) + // Set basedir + createOpts := cfg.CreateOpts + baseDir := createOpts.BaseDir + if err := os.Chdir(baseDir); err != nil { + return fmt.Errorf("unable to access directory %q: %w", baseDir, err) } - + // TODO(mkcp): Remove message on logger release message.Note(fmt.Sprintf("Using build directory %s", p.cfg.CreateOpts.BaseDir)) + l.Info("using build directory", "baseDir", baseDir) - pc := creator.NewPackageCreator(p.cfg.CreateOpts, cwd) - - if err := helpers.CreatePathAndCopy(layout.ZarfYAML, p.layout.ZarfYAML); err != nil { + // Setup package creator + lo := p.layout + pc := creator.NewPackageCreator(createOpts, cwd) + if err := helpers.CreatePathAndCopy(layout.ZarfYAML, lo.ZarfYAML); err != nil { return err } - pkg, warnings, err := pc.LoadPackageDefinition(ctx, p.layout) + // Load package def + pkg, warnings, err := pc.LoadPackageDefinition(p.ctx, lo) if err != nil { return err } + // Store on packager config p.cfg.Pkg = pkg + for _, warning := range warnings { + l.Warn(warning) + } + l.Info("package loaded", + "kind", pkg.Kind, + "name", pkg.Metadata.Name, + "description", pkg.Metadata.Description, + ) + // TODO(mkcp): Remove interactive on logger release if !p.confirmAction(config.ZarfCreateStage, warnings, nil) { return fmt.Errorf("package creation canceled") } - if err := pc.Assemble(ctx, p.layout, p.cfg.Pkg.Components, p.cfg.Pkg.Metadata.Architecture); err != nil { + aStart := time.Now() + l.Debug("starting package assembly", "kind", pkg.Kind) + if err := pc.Assemble(ctx, p.layout, pkg.Components, pkg.Metadata.Architecture); err != nil { return err } + l.Debug("done assembling package", "kind", pkg.Kind, "duration", time.Since(aStart)) // cd back for output if err := os.Chdir(cwd); err != nil { return err } - return pc.Output(ctx, p.layout, &p.cfg.Pkg) + if err = pc.Output(ctx, p.layout, &pkg); err != nil { + return err + } + + l.Debug("done creating package", "kind", pkg.Kind, "duration", time.Since(cStart)) + return nil } diff --git a/src/pkg/packager/creator/normal.go b/src/pkg/packager/creator/normal.go index 099fda5e2b..d13d05e595 100644 --- a/src/pkg/packager/creator/normal.go +++ b/src/pkg/packager/creator/normal.go @@ -27,6 +27,7 @@ import ( "github.com/zarf-dev/zarf/src/internal/packager/kustomize" "github.com/zarf-dev/zarf/src/internal/packager/sbom" "github.com/zarf-dev/zarf/src/pkg/layout" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/actions" "github.com/zarf-dev/zarf/src/pkg/packager/filters" @@ -62,6 +63,10 @@ func NewPackageCreator(createOpts types.ZarfCreateOptions, cwd string) *PackageC // LoadPackageDefinition loads and configures a zarf.yaml file during package create. func (pc *PackageCreator) LoadPackageDefinition(ctx context.Context, src *layout.PackagePaths) (pkg v1alpha1.ZarfPackage, warnings []string, err error) { + l := logger.From(ctx) + start := time.Now() + l.Debug("start loading package definiton", "src", src.ZarfYAML) + pkg, warnings, err = src.ReadZarfYAML() if err != nil { return v1alpha1.ZarfPackage{}, nil, err @@ -116,12 +121,14 @@ func (pc *PackageCreator) LoadPackageDefinition(ctx context.Context, src *layout return v1alpha1.ZarfPackage{}, nil, err } + l.Debug("done loading package definition", "src", src.ZarfYAML, "duration", time.Since(start)) return pkg, warnings, nil } -// Assemble assembles all of the package assets into Zarf's tmp directory layout. +// Assemble copies all package assets into Zarf's tmp directory layout. func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths, components []v1alpha1.ZarfComponent, arch string) error { var imageList []transform.Image + l := logger.From(ctx) skipSBOMFlagUsed := pc.createOpts.SkipSBOM componentSBOMs := map[string]*layout.ComponentSBOM{} @@ -131,7 +138,9 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths onFailure := func() { if err := actions.Run(ctx, onCreate.Defaults, onCreate.OnFailure, nil); err != nil { + // TODO(mkcp): Remove message on logger release message.Debugf("unable to run component failure action: %s", err.Error()) + l.Debug("unable to run component failure action", "error", err.Error()) } } @@ -140,6 +149,7 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths return fmt.Errorf("unable to add component %q: %w", component.Name, err) } + // TODO(mkcp): Migrate to logger if err := actions.Run(ctx, onCreate.Defaults, onCreate.OnSuccess, nil); err != nil { onFailure() return fmt.Errorf("unable to run component success action: %w", err) @@ -173,8 +183,8 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths // Images are handled separately from other component assets. if len(imageList) > 0 { + // TODO(mkcp): Remove message on logger release message.HeaderInfof("📦 PACKAGE IMAGES") - dst.AddImages() cachePath, err := config.GetAbsCachePath() @@ -206,16 +216,25 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths sbomImageList = append(sbomImageList, info) } } + + // Sort images index to make build reproducible. + err = utils.SortImagesIndex(dst.Images.Base) + if err != nil { + return err + } } // Ignore SBOM creation if the flag is set. if skipSBOMFlagUsed { + // TODO(mkcp): Remove message on logger release message.Debug("Skipping image SBOM processing per --skip-sbom flag") - } else { - dst.AddSBOMs() - if err := sbom.Catalog(ctx, componentSBOMs, sbomImageList, dst); err != nil { - return fmt.Errorf("unable to create an SBOM catalog for the package: %w", err) - } + l.Debug("skipping image SBOM processing per --skip-sbom flag") + return nil + } + + dst.AddSBOMs() + if err := sbom.Catalog(ctx, componentSBOMs, sbomImageList, dst); err != nil { + return fmt.Errorf("unable to create an SBOM catalog for the package: %w", err) } return nil @@ -234,11 +253,15 @@ func (pc *PackageCreator) Assemble(ctx context.Context, dst *layout.PackagePaths // - writes the Zarf package as a tarball to a local directory, // or an OCI registry based on the --output flag func (pc *PackageCreator) Output(ctx context.Context, dst *layout.PackagePaths, pkg *v1alpha1.ZarfPackage) (err error) { + l := logger.From(ctx) + start := time.Now() + l.Debug("starting package output", "kind", pkg.Kind) + // Process the component directories into compressed tarballs // NOTE: This is purposefully being done after the SBOM cataloging for _, component := range pkg.Components { // Make the component a tar archive - if err := dst.Components.Archive(component, true); err != nil { + if err := dst.Components.Archive(ctx, component, true); err != nil { return fmt.Errorf("unable to archive component: %s", err.Error()) } } @@ -269,6 +292,7 @@ func (pc *PackageCreator) Output(ctx context.Context, dst *layout.PackagePaths, if err != nil { return err } + // TODO(mkcp): Port zoci.NewRemote to new logger remote, err := zoci.NewRemote(ref, oci.PlatformForArch(config.GetArch())) if err != nil { return err @@ -285,6 +309,7 @@ func (pc *PackageCreator) Output(ctx context.Context, dst *layout.PackagePaths, if config.CommonOptions.InsecureSkipTLSVerify { flags = append(flags, "--insecure-skip-tls-verify") } + // TODO(mkcp): Remove message on logger release message.Title("To inspect/deploy/pull:", "") message.ZarfCommand("package inspect %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), strings.Join(flags, " ")) message.ZarfCommand("package deploy %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), strings.Join(flags, " ")) @@ -295,10 +320,13 @@ func (pc *PackageCreator) Output(ctx context.Context, dst *layout.PackagePaths, tarballPath := filepath.Join(pc.createOpts.Output, packageName) // Try to remove the package if it already exists. - _ = os.Remove(tarballPath) + err = os.Remove(tarballPath) + if err != nil { + logger.From(ctx).Error(err.Error()) + } // Create the package tarball. - if err := dst.ArchivePackage(tarballPath, pc.createOpts.MaxPackageSizeMB); err != nil { + if err := dst.ArchivePackage(ctx, tarballPath, pc.createOpts.MaxPackageSizeMB); err != nil { return fmt.Errorf("unable to archive package: %w", err) } } @@ -321,17 +349,24 @@ func (pc *PackageCreator) Output(ctx context.Context, dst *layout.PackagePaths, } if pc.createOpts.ViewSBOM { - err := sbom.ViewSBOMFiles(sbomDir) + err := sbom.ViewSBOMFiles(ctx, sbomDir) if err != nil { return err } } } + l.Debug("done package output", "kind", pkg.Kind, "duration", time.Since(start)) return nil } +// TODO(mkcp): Refactor addComponent to better segment component handling logic by its type. There's also elaborate +// if/elses that can be de-nested. func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.ZarfComponent, dst *layout.PackagePaths) error { + l := logger.From(ctx) + // TODO(mkcp): Remove message on logger release message.HeaderInfof("📦 %s COMPONENT", strings.ToUpper(component.Name)) + l.Info("adding component", "name", component.Name) + start := time.Now() componentPaths, err := dst.Components.Create(component) if err != nil { @@ -416,18 +451,26 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z } } - if len(component.DataInjections) > 0 { + // Run data injections + injectionsCount := len(component.DataInjections) + if injectionsCount > 0 { + injectStart := time.Now() + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Loading data injections") defer spinner.Stop() + l.Info("data injections found, running", "injections", injectionsCount) for dataIdx, data := range component.DataInjections { - spinner.Updatef("Copying data injection %s for %s", data.Target.Path, data.Target.Selector) + target := data.Target + spinner.Updatef("Copying data injection %s for %s", target.Path, target.Selector) + l.Info("copying data injection", "path", target.Path, "selector", target.Selector) - rel := filepath.Join(layout.DataInjectionsDir, strconv.Itoa(dataIdx), filepath.Base(data.Target.Path)) + rel := filepath.Join(layout.DataInjectionsDir, strconv.Itoa(dataIdx), filepath.Base(target.Path)) dst := filepath.Join(componentPaths.Base, rel) if helpers.IsURL(data.Source) { - if err := utils.DownloadToFile(ctx, data.Source, dst, component.DeprecatedCosignKeyPath); err != nil { + err := utils.DownloadToFile(ctx, data.Source, dst, component.DeprecatedCosignKeyPath) + if err != nil { return fmt.Errorf(lang.ErrDownloading, data.Source, err.Error()) } } else { @@ -437,9 +480,12 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z } } spinner.Success() + l.Debug("done loading data injections", "duration", time.Since(injectStart)) } + // Process k8s manifests if len(component.Manifests) > 0 { + manifestStart := time.Now() // Get the proper count of total manifests to add. manifestCount := 0 @@ -448,8 +494,10 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z manifestCount += len(manifest.Kustomizations) } + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Loading %d K8s manifests", manifestCount) defer spinner.Stop() + l.Info("processing k8s manifests", "component", component.Name, "manifests", manifestCount) // Iterate over all manifests. for _, manifest := range component.Manifests { @@ -458,7 +506,9 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z dst := filepath.Join(componentPaths.Base, rel) // Copy manifests without any processing. + // TODO(mkcp): Remove message on logger release spinner.Updatef("Copying manifest %s", path) + l.Info("copying manifest", "path", path) if helpers.IsURL(path) { if err := utils.DownloadToFile(ctx, path, dst, component.DeprecatedCosignKeyPath); err != nil { return fmt.Errorf(lang.ErrDownloading, path, err.Error()) @@ -472,7 +522,9 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z for kustomizeIdx, path := range manifest.Kustomizations { // Generate manifests from kustomizations and place in the package. + // TODO(mkcp): Remove message on logger release spinner.Updatef("Building kustomization for %s", path) + l.Info("building kustomization", "path", path) kname := fmt.Sprintf("kustomization-%s-%d.yaml", manifest.Name, kustomizeIdx) rel := filepath.Join(layout.ManifestsDir, kname) @@ -484,12 +536,19 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z } } spinner.Success() + l.Debug("done processing k8s manifests", + "component", component.Name, + "duration", time.Since(manifestStart)) } // Load all specified git repos. - if len(component.Repos) > 0 { + reposCount := len(component.Repos) + if reposCount > 0 { + reposStart := time.Now() + // TODO(mkcp): Remove message on logger release spinner := message.NewProgressSpinner("Loading %d git repos", len(component.Repos)) defer spinner.Stop() + l.Info("loading git repos", "component", component.Name, "repos", reposCount) for _, url := range component.Repos { // Pull all the references if there is no `@` in the string. @@ -499,12 +558,14 @@ func (pc *PackageCreator) addComponent(ctx context.Context, component v1alpha1.Z } } spinner.Success() + l.Debug("done loading git repos", "component", component.Name, "duration", time.Since(reposStart)) } if err := actions.Run(ctx, onCreate.Defaults, onCreate.After, nil); err != nil { return fmt.Errorf("unable to run component after action: %w", err) } + l.Debug("done adding component", "name", component.Name, "duration", time.Since(start)) return nil } diff --git a/src/pkg/packager/creator/skeleton.go b/src/pkg/packager/creator/skeleton.go index 8d1acbdf34..9792230f0b 100644 --- a/src/pkg/packager/creator/skeleton.go +++ b/src/pkg/packager/creator/skeleton.go @@ -96,9 +96,9 @@ func (sc *SkeletonCreator) Assemble(_ context.Context, dst *layout.PackagePaths, // - writes the loaded zarf.yaml to disk // // - signs the package -func (sc *SkeletonCreator) Output(_ context.Context, dst *layout.PackagePaths, pkg *v1alpha1.ZarfPackage) (err error) { +func (sc *SkeletonCreator) Output(ctx context.Context, dst *layout.PackagePaths, pkg *v1alpha1.ZarfPackage) (err error) { for _, component := range pkg.Components { - if err := dst.Components.Archive(component, false); err != nil { + if err := dst.Components.Archive(ctx, component, false); err != nil { return err } } diff --git a/src/pkg/packager/dev.go b/src/pkg/packager/dev.go index de7af6f4af..1985edb655 100644 --- a/src/pkg/packager/dev.go +++ b/src/pkg/packager/dev.go @@ -16,6 +16,7 @@ import ( "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/creator" "github.com/zarf-dev/zarf/src/pkg/packager/filters" + "github.com/zarf-dev/zarf/src/types" ) // DevDeploy creates + deploys a package in one shot @@ -76,6 +77,24 @@ func (p *Packager) DevDeploy(ctx context.Context) error { if !p.cfg.CreateOpts.NoYOLO { p.cfg.Pkg.Metadata.YOLO = true + + // Set default builtin values so they exist in case any helm charts rely on them + registryInfo := types.RegistryInfo{Address: p.cfg.DeployOpts.RegistryURL} + if err := registryInfo.FillInEmptyValues(); err != nil { + return err + } + gitServer := types.GitServerInfo{} + if err = gitServer.FillInEmptyValues(); err != nil { + return err + } + artifactServer := types.ArtifactServerInfo{} + artifactServer.FillInEmptyValues() + + p.state = &types.ZarfState{ + RegistryInfo: registryInfo, + GitServer: gitServer, + ArtifactServer: artifactServer, + } } else { p.hpaModified = false // Reset registry HPA scale down whether an error occurs or not diff --git a/src/pkg/packager/inspect.go b/src/pkg/packager/inspect.go index 03dee54883..01c6ca4135 100644 --- a/src/pkg/packager/inspect.go +++ b/src/pkg/packager/inspect.go @@ -51,7 +51,7 @@ func (p *Packager) Inspect(ctx context.Context) error { } if p.cfg.InspectOpts.ViewSBOM { - err := sbom.ViewSBOMFiles(sbomDir) + err := sbom.ViewSBOMFiles(ctx, sbomDir) if err != nil { return err } diff --git a/src/pkg/packager/remove.go b/src/pkg/packager/remove.go index 322db5570f..b1149e343d 100644 --- a/src/pkg/packager/remove.go +++ b/src/pkg/packager/remove.go @@ -185,7 +185,7 @@ func (p *Packager) removeComponent(ctx context.Context, deployedPackage *types.D spinner.Updatef("Uninstalling chart '%s' from the '%s' component", chart.ChartName, deployedComponent.Name) helmCfg := helm.NewClusterOnly(p.cfg, p.variableConfig, p.state, p.cluster) - if err := helmCfg.RemoveChart(chart.Namespace, chart.ChartName, spinner); err != nil { + if err := helmCfg.RemoveChart(ctx, chart.Namespace, chart.ChartName, spinner); err != nil { if !errors.Is(err, driver.ErrReleaseNotFound) { onFailure() return deployedPackage, fmt.Errorf("unable to uninstall the helm chart %s in the namespace %s: %w", diff --git a/src/pkg/utils/image.go b/src/pkg/utils/image.go index 3756a759e1..cd62128159 100644 --- a/src/pkg/utils/image.go +++ b/src/pkg/utils/image.go @@ -9,6 +9,8 @@ import ( "fmt" "os" "path/filepath" + "slices" + "strings" "github.com/defenseunicorns/pkg/helpers/v2" v1 "github.com/google/go-containerregistry/pkg/v1" @@ -102,3 +104,25 @@ func OnlyHasImageLayers(img v1.Image) (bool, error) { } return true, nil } + +// SortImagesIndex sorts the index.json by digest. +func SortImagesIndex(ociPath string) error { + indexPath := filepath.Join(ociPath, "index.json") + b, err := os.ReadFile(indexPath) + if err != nil { + return err + } + var index ocispec.Index + err = json.Unmarshal(b, &index) + if err != nil { + return err + } + slices.SortFunc(index.Manifests, func(a, b ocispec.Descriptor) int { + return strings.Compare(string(a.Digest), string(b.Digest)) + }) + b, err = json.Marshal(index) + if err != nil { + return err + } + return os.WriteFile(indexPath, b, helpers.ReadWriteUser) +} diff --git a/src/pkg/utils/network.go b/src/pkg/utils/network.go index 17aa9a6ac3..fa70237dde 100644 --- a/src/pkg/utils/network.go +++ b/src/pkg/utils/network.go @@ -14,9 +14,11 @@ import ( "os" "path/filepath" "strings" + "time" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/config/lang" + "github.com/zarf-dev/zarf/src/pkg/logger" "github.com/zarf-dev/zarf/src/pkg/message" ) @@ -75,7 +77,7 @@ func DownloadToFile(ctx context.Context, src, dst, cosignKeyPath string) (err er return fmt.Errorf("unable to download file with sget: %s: %w", src, err) } } else { - err = httpGetFile(src, file) + err = httpGetFile(ctx, src, file) if err != nil { return err } @@ -95,7 +97,11 @@ func DownloadToFile(ctx context.Context, src, dst, cosignKeyPath string) (err er return nil } -func httpGetFile(url string, destinationFile *os.File) (err error) { +func httpGetFile(ctx context.Context, url string, destinationFile *os.File) (err error) { + l := logger.From(ctx) + l.Info("download start", "url", url) + start := time.Now() + // Get the data resp, err := http.Get(url) if err != nil { @@ -111,16 +117,17 @@ func httpGetFile(url string, destinationFile *os.File) (err error) { return fmt.Errorf("bad HTTP status: %s", resp.Status) } - // Writer the body to file + // Setup progress bar + // TODO(mkcp): Remove message on logger release title := fmt.Sprintf("Downloading %s", filepath.Base(url)) progressBar := message.NewProgressBar(resp.ContentLength, title) - - if _, err = io.Copy(destinationFile, io.TeeReader(resp.Body, progressBar)); err != nil { + reader := io.TeeReader(resp.Body, progressBar) + // Copy response body to file + if _, err = io.Copy(destinationFile, reader); err != nil { progressBar.Failf("Unable to save the file %s: %s", destinationFile.Name(), err.Error()) - return err + return fmt.Errorf("unable to save the file %s: %w", destinationFile.Name(), err) } - - title = fmt.Sprintf("Downloaded %s", url) - progressBar.Successf("%s", title) + progressBar.Successf("Downloaded %s", url) + l.Debug("download successful", "url", url, "size", resp.ContentLength, "duration", time.Since(start)) return nil } diff --git a/src/test/common.go b/src/test/common.go index 4201fea6b9..b103c4da03 100644 --- a/src/test/common.go +++ b/src/test/common.go @@ -55,6 +55,11 @@ func GetCLIName() string { // Zarf executes a Zarf command. func (e2e *ZarfE2ETest) Zarf(t *testing.T, args ...string) (_ string, _ string, err error) { + return e2e.ZarfInDir(t, "", args...) +} + +// ZarfInDir executes a Zarf command in specific directory. +func (e2e *ZarfE2ETest) ZarfInDir(t *testing.T, dir string, args ...string) (_ string, _ string, err error) { if !slices.Contains(args, "--tmpdir") && !slices.Contains(args, "tools") { tmpdir, err := os.MkdirTemp("", "zarf-") if err != nil { @@ -83,7 +88,9 @@ func (e2e *ZarfE2ETest) Zarf(t *testing.T, args ...string) (_ string, _ string, err = errors.Join(err, errRemove) }(cacheDir) } - return exec.CmdWithTesting(t, exec.PrintCfg(), e2e.ZarfBinPath, args...) + cfg := exec.PrintCfg() + cfg.Dir = dir + return exec.CmdWithTesting(t, cfg, e2e.ZarfBinPath, args...) } // Kubectl executes `zarf tools kubectl ...` diff --git a/src/test/e2e/03_deprecations_test.go b/src/test/e2e/03_deprecations_test.go index 27fcc4a59a..a20684c2ad 100644 --- a/src/test/e2e/03_deprecations_test.go +++ b/src/test/e2e/03_deprecations_test.go @@ -5,98 +5,91 @@ package test import ( + "context" "fmt" + "path/filepath" "testing" + goyaml "github.com/goccy/go-yaml" + "github.com/otiai10/copy" "github.com/stretchr/testify/require" + + layout2 "github.com/zarf-dev/zarf/src/internal/packager2/layout" ) -// TestDeprecatedComponentScripts verifies that deprecated component scripts are still able to be executed (after being internally -// migrated into zarf actions). +// TestDeprecatedComponentScripts verifies that deprecated component scripts are still able to be executed after being internally migrated into zarf actions. func TestDeprecatedComponentScripts(t *testing.T) { - t.Log("E2E: Testing deprecated component scripts") + t.Parallel() - // Note these files will be created in the package directory, not CWD - testPackageDirPath := "src/test/packages/03-deprecated-component-scripts" - prepareArtifact := fmt.Sprintf("%s/test-deprecated-prepare-hook.txt", testPackageDirPath) deployArtifacts := []string{ "test-deprecated-deploy-before-hook.txt", "test-deprecated-deploy-after-hook.txt", } - allArtifacts := append(deployArtifacts, prepareArtifact) - e2e.CleanFiles(t, allArtifacts...) - defer e2e.CleanFiles(t, allArtifacts...) - - // 1. Try creating the package to test the create scripts - testPackagePath := fmt.Sprintf("%s/zarf-package-deprecated-component-scripts-%s.tar.zst", testPackageDirPath, e2e.Arch) - outputFlag := fmt.Sprintf("-o=%s", testPackageDirPath) - stdOut, stdErr, err := e2e.Zarf(t, "package", "create", testPackageDirPath, outputFlag, "--confirm") - defer e2e.CleanFiles(t, testPackagePath) - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "Component '1-test-deprecated-prepare-scripts' is using scripts") - require.Contains(t, stdErr, "Component '2-test-deprecated-deploy-scripts' is using scripts") - require.Contains(t, stdErr, "Component '3-test-deprecated-timeout-scripts' is using scripts") - - // Test for package create prepare artifact - require.FileExists(t, prepareArtifact) - - // Test to ensure the deploy scripts are not executed + + packagePath := t.TempDir() + err := copy.Copy("src/test/packages/03-deprecated-component-scripts", packagePath) + require.NoError(t, err) + + workingDirPath := t.TempDir() + tarName := fmt.Sprintf("zarf-package-deprecated-component-scripts-%s.tar.zst", e2e.Arch) + + // Try creating the package to test the create scripts + _, _, err = e2e.ZarfInDir(t, workingDirPath, "package", "create", packagePath, "--confirm") + require.NoError(t, err) + + require.FileExists(t, filepath.Join(packagePath, "test-deprecated-prepare-hook.txt")) for _, artifact := range deployArtifacts { - require.NoFileExists(t, artifact) + require.NoFileExists(t, filepath.Join(workingDirPath, artifact)) } - // 2. Deploy the simple script that should pass - stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", testPackagePath, "--confirm", "--components=2-test-deprecated-deploy-scripts") - require.NoError(t, err, stdOut, stdErr) + // Deploy the simple script that should pass + _, _, err = e2e.ZarfInDir(t, workingDirPath, "package", "deploy", tarName, "--confirm", "--components=2-test-deprecated-deploy-scripts") + require.NoError(t, err) - // Check that the deploy artifacts were created for _, artifact := range deployArtifacts { - require.FileExists(t, artifact) + require.FileExists(t, filepath.Join(workingDirPath, artifact)) } - // 3. Deploy the simple script that should fail the timeout - stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", testPackagePath, "--confirm", "--components=3-test-deprecated-timeout-scripts") - require.Error(t, err, stdOut, stdErr) + // Deploy the simple script that should fail the timeout + _, _, err = e2e.ZarfInDir(t, workingDirPath, "package", "deploy", tarName, "--confirm", "--components=3-test-deprecated-timeout-scripts") + require.Error(t, err) } // TestDeprecatedSetAndPackageVariables verifies that deprecated setVariables and PKG_VARs still able to be set. func TestDeprecatedSetAndPackageVariables(t *testing.T) { - t.Log("E2E: Testing deprecated set variables") + t.Parallel() // Note prepare script files will be created in the package directory, not CWD testPackageDirPath := "src/test/packages/03-deprecated-set-variable" - prepareArtifact := fmt.Sprintf("%s/test-deprecated-prepare-hook.txt", testPackageDirPath) - deployArtifacts := []string{ - "test-deprecated-deploy-before-hook.txt", - "test-deprecated-deploy-after-hook.txt", - } - allArtifacts := append(deployArtifacts, prepareArtifact) - e2e.CleanFiles(t, allArtifacts...) - defer e2e.CleanFiles(t, allArtifacts...) - // 2. Try creating the package to test the create scripts - testPackagePath := fmt.Sprintf("%s/zarf-package-deprecated-set-variable-%s.tar.zst", testPackageDirPath, e2e.Arch) - outputFlag := fmt.Sprintf("-o=%s", testPackageDirPath) + outPath := t.TempDir() + tarPath := filepath.Join(outPath, fmt.Sprintf("zarf-package-deprecated-set-variable-%s.tar.zst", e2e.Arch)) // Check that the command still errors out - stdOut, stdErr, err := e2e.Zarf(t, "package", "create", testPackageDirPath, outputFlag, "--confirm") - require.Error(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "template \"ECHO\" must be '--set'") - - // Check that the command displays a warning on create - stdOut, stdErr, err = e2e.Zarf(t, "package", "create", testPackageDirPath, outputFlag, "--confirm", "--set", "ECHO=Zarf-The-Axolotl") - defer e2e.CleanFiles(t, testPackagePath) - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "Component '1-test-deprecated-set-variable' is using setVariable") - require.Contains(t, stdErr, "deprecated syntax ###ZARF_PKG_VAR_ECHO###") - - // 1. Deploy the setVariable action that should pass and output the variable - stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", testPackagePath, "--confirm", "--components=1-test-deprecated-set-variable") - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "Hello from Hello Kitteh") - - // 2. Deploy the setVariable action that should pass and output the variable - stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", testPackagePath, "--confirm", "--components=2-test-deprecated-pkg-var") - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "Zarf-The-Axolotl") + _, _, err := e2e.Zarf(t, "package", "create", testPackageDirPath, "-o", outPath, "--confirm") + require.Error(t, err) + + // // Check that the command displays a warning on create + _, _, err = e2e.Zarf(t, "package", "create", testPackageDirPath, "-o", outPath, "--confirm", "--set", "ECHO=Zarf-The-Axolotl") + require.NoError(t, err) + + pkgLayout, err := layout2.LoadFromTar(context.Background(), tarPath, layout2.PackageLayoutOptions{}) + require.NoError(t, err) + b, err := goyaml.Marshal(pkgLayout.Pkg.Components) + require.NoError(t, err) + expectedYaml := `- name: 1-test-deprecated-set-variable + actions: + onDeploy: + before: + - cmd: echo "Hello Kitteh" + setVariables: + - name: HELLO_KITTEH + - cmd: echo "Hello from ${ZARF_VAR_HELLO_KITTEH}" +- name: 2-test-deprecated-pkg-var + actions: + onDeploy: + before: + - cmd: echo "Zarf-The-Axolotl" +` + require.Equal(t, expectedYaml, string(b)) } diff --git a/src/test/e2e/04_create_templating_test.go b/src/test/e2e/04_create_templating_test.go index fb03553553..af1aa83bf4 100644 --- a/src/test/e2e/04_create_templating_test.go +++ b/src/test/e2e/04_create_templating_test.go @@ -5,53 +5,42 @@ package test import ( + "context" "fmt" "os" "path/filepath" "testing" "github.com/stretchr/testify/require" + + "github.com/zarf-dev/zarf/src/api/v1alpha1" + layout2 "github.com/zarf-dev/zarf/src/internal/packager2/layout" ) func TestCreateTemplating(t *testing.T) { t.Log("E2E: Create Templating") - // run `zarf package create` with a specified image cache location - tmpdir := t.TempDir() - decompressPath := filepath.Join(tmpdir, ".package-decompressed") - sbomPath := filepath.Join(tmpdir, ".sbom-location") - - pkgName := fmt.Sprintf("zarf-package-templating-%s.tar.zst", e2e.Arch) + sbomPath := t.TempDir() + outPath := t.TempDir() + templatingPath := filepath.Join(outPath, fmt.Sprintf("zarf-package-templating-%s.tar.zst", e2e.Arch)) + fileFoldersPath := filepath.Join(outPath, fmt.Sprintf("zarf-package-file-folders-templating-sbom-%s.tar.zst", e2e.Arch)) // Test that not specifying a package variable results in an error - _, _, err := e2e.Zarf(t, "package", "create", "src/test/packages/04-templating", "--confirm") + _, _, err := e2e.Zarf(t, "package", "create", "src/test/packages/04-templating", "-o", outPath, "--confirm") require.Error(t, err) // Test a simple package variable example with `--set` (will fail to pull an image if this is not set correctly) - stdOut, stdErr, err := e2e.Zarf(t, "package", "create", "src/test/packages/04-templating", "--set", "PODINFO_VERSION=6.4.0", "--confirm") - require.NoError(t, err, stdOut, stdErr) - - stdOut, stdErr, err = e2e.Zarf(t, "t", "archiver", "decompress", pkgName, decompressPath, "--unarchive-all") - require.NoError(t, err, stdOut, stdErr) + _, _, err = e2e.Zarf(t, "package", "create", "src/test/packages/04-templating", "-o", outPath, "--set", "PODINFO_VERSION=6.4.0", "--confirm") + require.NoError(t, err) - // Check that the constant in the zarf.yaml is replaced correctly - builtConfig, err := os.ReadFile(decompressPath + "/zarf.yaml") + pkgLayout, err := layout2.LoadFromTar(context.Background(), templatingPath, layout2.PackageLayoutOptions{}) require.NoError(t, err) - require.Contains(t, string(builtConfig), "name: PODINFO_VERSION\n value: 6.4.0") + expectedConstant := v1alpha1.Constant{Name: "PODINFO_VERSION", Value: "6.4.0", Pattern: "^[\\w\\-\\.]+$"} + require.Contains(t, pkgLayout.Pkg.Constants, expectedConstant) // Test that files and file folders template and handle SBOMs correctly - stdOut, stdErr, err = e2e.Zarf(t, "package", "create", "src/test/packages/04-file-folders-templating-sbom/", "--sbom-out", sbomPath, "--confirm") - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "Creating SBOMs for 0 images and 2 components with files.") - - fileFoldersPkgName := fmt.Sprintf("zarf-package-file-folders-templating-sbom-%s.tar.zst", e2e.Arch) - - // Deploy the package and look for the variables in the output - stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", fileFoldersPkgName, "--set", "DOGGO=doggy", "--set", "KITTEH=meowza", "--set", "PANDA=pandemonium", "--confirm") - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "A doggy barks!") - require.Contains(t, stdErr, " - meowza") - require.Contains(t, stdErr, "# Total pandemonium") + _, _, err = e2e.Zarf(t, "package", "create", "src/test/packages/04-file-folders-templating-sbom/", "-o", outPath, "--sbom-out", sbomPath, "--confirm") + require.NoError(t, err) // Ensure that the `requirements.txt` files are discovered correctly require.FileExists(t, filepath.Join(sbomPath, "file-folders-templating-sbom", "compare.html")) @@ -65,5 +54,20 @@ func TestCreateTemplating(t *testing.T) { require.NoError(t, err) require.Contains(t, string(filesJSON), "pandas") - e2e.CleanFiles(t, pkgName, fileFoldersPkgName) + // Deploy the package and look for the variables in the output + workingPath := t.TempDir() + _, _, err = e2e.ZarfInDir(t, workingPath, "package", "deploy", fileFoldersPath, "--set", "DOGGO=doggy", "--set", "KITTEH=meowza", "--set", "PANDA=pandemonium", "--confirm") + require.NoError(t, err) + + b, err := os.ReadFile(filepath.Join(workingPath, "temp", "requirements.txt")) + require.NoError(t, err) + require.Equal(t, "# Total pandemonium\npandas==1.5.0\n", string(b)) + + b, err = os.ReadFile(filepath.Join(workingPath, "temp", "include-files", "simple.txt")) + require.NoError(t, err) + require.Equal(t, "A doggy barks!\n", string(b)) + + b, err = os.ReadFile(filepath.Join(workingPath, "temp", "include-files", "something.yaml")) + require.NoError(t, err) + require.Equal(t, "something:\n - a\n - meowza\n - meows\n", string(b)) } diff --git a/src/test/e2e/06_create_sbom_test.go b/src/test/e2e/06_create_sbom_test.go index 0254c56e25..9426a21d4c 100644 --- a/src/test/e2e/06_create_sbom_test.go +++ b/src/test/e2e/06_create_sbom_test.go @@ -5,6 +5,7 @@ package test import ( + "context" "fmt" "os" "path/filepath" @@ -12,61 +13,63 @@ import ( "testing" "github.com/stretchr/testify/require" + + layout2 "github.com/zarf-dev/zarf/src/internal/packager2/layout" ) func TestCreateSBOM(t *testing.T) { - tmpdir := t.TempDir() - sbomPath := filepath.Join(tmpdir, ".sbom-location") + t.Parallel() - pkgName := fmt.Sprintf("zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch) + outSbomPath := filepath.Join(t.TempDir(), ".sbom-location") + buildPath := t.TempDir() + tarPath := filepath.Join(buildPath, fmt.Sprintf("zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch)) - stdOut, stdErr, err := e2e.Zarf(t, "package", "create", "examples/dos-games", "--sbom-out", sbomPath, "--confirm") - require.NoError(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "Creating SBOMs for 1 images and 0 components with files.") - // Test that the game package generates the SBOMs we expect (images only) - require.FileExists(t, filepath.Join(sbomPath, "dos-games", "sbom-viewer-ghcr.io_zarf-dev_doom-game_0.0.1.html")) - require.FileExists(t, filepath.Join(sbomPath, "dos-games", "compare.html")) - require.FileExists(t, filepath.Join(sbomPath, "dos-games", "ghcr.io_zarf-dev_doom-game_0.0.1.json")) + expectedFiles := []string{ + "sbom-viewer-ghcr.io_zarf-dev_doom-game_0.0.1.html", + "compare.html", + "ghcr.io_zarf-dev_doom-game_0.0.1.json", + } - // Clean the SBOM path so it is force to be recreated - e2e.CleanFiles(t, sbomPath) + _, _, err := e2e.Zarf(t, "package", "create", "examples/dos-games", "-o", buildPath, "--sbom-out", outSbomPath, "--confirm") + require.NoError(t, err) - stdOut, stdErr, err = e2e.Zarf(t, "package", "inspect", pkgName, "--sbom-out", sbomPath) - require.NoError(t, err, stdOut, stdErr) - // Test that the game package generates the SBOMs we expect (images only) - _, err = os.ReadFile(filepath.Join(sbomPath, "dos-games", "sbom-viewer-ghcr.io_zarf-dev_doom-game_0.0.1.html")) + pkgLayout, err := layout2.LoadFromTar(context.Background(), tarPath, layout2.PackageLayoutOptions{}) require.NoError(t, err) - _, err = os.ReadFile(filepath.Join(sbomPath, "dos-games", "compare.html")) + getSbomPath, err := pkgLayout.GetSBOM(t.TempDir()) require.NoError(t, err) - _, err = os.ReadFile(filepath.Join(sbomPath, "dos-games", "ghcr.io_zarf-dev_doom-game_0.0.1.json")) + for _, expectedFile := range expectedFiles { + require.FileExists(t, filepath.Join(getSbomPath, expectedFile)) + require.FileExists(t, filepath.Join(outSbomPath, "dos-games", expectedFile)) + } + + // Clean the SBOM path so it is force to be recreated + err = os.RemoveAll(outSbomPath) require.NoError(t, err) - stdOut, _, err = e2e.Zarf(t, "package", "inspect", pkgName, "--list-images") + _, _, err = e2e.Zarf(t, "package", "inspect", tarPath, "--sbom-out", outSbomPath) + require.NoError(t, err) + + for _, expectedFile := range expectedFiles { + require.FileExists(t, filepath.Join(outSbomPath, "dos-games", expectedFile)) + } + + stdOut, _, err := e2e.Zarf(t, "package", "inspect", tarPath, "--list-images") require.NoError(t, err) require.Equal(t, "- ghcr.io/zarf-dev/doom-game:0.0.1\n", stdOut) // Pull the current zarf binary version to find the corresponding init package - version, stdErr, err := e2e.Zarf(t, "version") - require.NoError(t, err, version, stdErr) + version, _, err := e2e.Zarf(t, "version") + require.NoError(t, err) initName := fmt.Sprintf("build/zarf-init-%s-%s.tar.zst", e2e.Arch, strings.TrimSpace(version)) - - stdOut, stdErr, err = e2e.Zarf(t, "package", "inspect", initName, "--sbom-out", sbomPath) - require.NoError(t, err, stdOut, stdErr) - // Test that we preserve the filepath - _, err = os.ReadFile(filepath.Join(sbomPath, "dos-games", "sbom-viewer-ghcr.io_zarf-dev_doom-game_0.0.1.html")) - require.NoError(t, err) - // Test that the init package generates the SBOMs we expect (images + component files) - _, err = os.ReadFile(filepath.Join(sbomPath, "init", "sbom-viewer-docker.io_gitea_gitea_1.21.5-rootless.html")) - require.NoError(t, err) - _, err = os.ReadFile(filepath.Join(sbomPath, "init", "docker.io_gitea_gitea_1.21.5-rootless.json")) - require.NoError(t, err) - _, err = os.ReadFile(filepath.Join(sbomPath, "init", "sbom-viewer-zarf-component-k3s.html")) - require.NoError(t, err) - _, err = os.ReadFile(filepath.Join(sbomPath, "init", "zarf-component-k3s.json")) - require.NoError(t, err) - _, err = os.ReadFile(filepath.Join(sbomPath, "init", "compare.html")) + _, _, err = e2e.Zarf(t, "package", "inspect", initName, "--sbom-out", outSbomPath) require.NoError(t, err) - e2e.CleanFiles(t, pkgName) + // Test that we preserve the filepath + require.FileExists(t, filepath.Join(outSbomPath, "dos-games", "sbom-viewer-ghcr.io_zarf-dev_doom-game_0.0.1.html")) + require.FileExists(t, filepath.Join(outSbomPath, "init", "sbom-viewer-docker.io_gitea_gitea_1.21.5-rootless.html")) + require.FileExists(t, filepath.Join(outSbomPath, "init", "docker.io_gitea_gitea_1.21.5-rootless.json")) + require.FileExists(t, filepath.Join(outSbomPath, "init", "sbom-viewer-zarf-component-k3s.html")) + require.FileExists(t, filepath.Join(outSbomPath, "init", "zarf-component-k3s.json")) + require.FileExists(t, filepath.Join(outSbomPath, "init", "compare.html")) } diff --git a/src/test/e2e/10_component_flavor_test.go b/src/test/e2e/10_component_flavor_test.go index a1f748bd22..5bf12ed335 100644 --- a/src/test/e2e/10_component_flavor_test.go +++ b/src/test/e2e/10_component_flavor_test.go @@ -5,120 +5,76 @@ package test import ( + "context" "fmt" - "os" "path/filepath" "testing" "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" -) - -type FlavorSuite struct { - suite.Suite - *require.Assertions -} -var ( - flavorExample = filepath.Join("examples", "package-flavors") - flavorTest = filepath.Join("src", "test", "packages", "10-package-flavors") - flavorExamplePath string - flavorTestAMDPath = filepath.Join("build", "zarf-package-test-package-flavors-amd64.tar.zst") - flavorTestARMPath = filepath.Join("build", "zarf-package-test-package-flavors-arm64.tar.zst") + layout2 "github.com/zarf-dev/zarf/src/internal/packager2/layout" ) -func (suite *FlavorSuite) SetupSuite() { - suite.Assertions = require.New(suite.T()) - - // Setup the example package path after e2e has been initialized - flavorExamplePath = filepath.Join("build", fmt.Sprintf("zarf-package-package-flavors-%s-1.0.0.tar.zst", e2e.Arch)) -} - -func (suite *FlavorSuite) TearDownSuite() { - err := os.RemoveAll(flavorExamplePath) - suite.NoError(err) - err = os.RemoveAll(flavorTestAMDPath) - suite.NoError(err) - err = os.RemoveAll(flavorTestARMPath) - suite.NoError(err) -} - -func (suite *FlavorSuite) Test_0_FlavorExample() { - suite.T().Log("E2E: Package Flavor Example") - - _, stdErr, err := e2e.Zarf(suite.T(), "package", "create", flavorExample, "-o", "build", "--flavor", "oracle-cookie-crunch", "--no-color", "--confirm") - suite.NoError(err) - - // Ensure that the oracle image is included - suite.Contains(stdErr, `oraclelinux:9-slim`) - - // Ensure that the common pod was included - suite.Contains(stdErr, `description: The pod that runs the specified flavor of Enterprise Linux`) - - // Ensure that the other flavors are not included - suite.NotContains(stdErr, `rockylinux:9-minimal`) - suite.NotContains(stdErr, `almalinux:9-minimal`) - suite.NotContains(stdErr, `opensuse/leap:15`) -} - -func (suite *FlavorSuite) Test_1_FlavorArchFiltering() { - suite.T().Log("E2E: Package Flavor + Arch Filtering") - - _, stdErr, err := e2e.Zarf(suite.T(), "package", "create", flavorTest, "-o", "build", "--flavor", "vanilla", "-a", "amd64", "--no-color", "--confirm") - suite.NoError(err) - - // Ensure that the initial filter was applied - suite.Contains(stdErr, ` -- name: combined - description: vanilla-amd`) - - // Ensure that the import filter was applied - suite.Contains(stdErr, ` -- name: via-import - description: vanilla-amd`) - - // Ensure that the other flavors / architectures are not included - suite.NotContains(stdErr, `vanilla-arm`) - suite.NotContains(stdErr, `chocolate-amd`) - suite.NotContains(stdErr, `chocolate-arm`) - - _, stdErr, err = e2e.Zarf(suite.T(), "package", "create", flavorTest, "-o", "build", "--flavor", "chocolate", "-a", "amd64", "--no-color", "--confirm") - suite.NoError(err) - - // Ensure that the initial filter was applied - suite.Contains(stdErr, ` -- name: combined - description: chocolate-amd`) - - // Ensure that the import filter was applied - suite.Contains(stdErr, ` -- name: via-import - description: chocolate-amd`) - - // Ensure that the other flavors / architectures are not included - suite.NotContains(stdErr, `vanilla-arm`) - suite.NotContains(stdErr, `vanilla-amd`) - suite.NotContains(stdErr, `chocolate-arm`) - - _, stdErr, err = e2e.Zarf(suite.T(), "package", "create", flavorTest, "-o", "build", "--flavor", "chocolate", "-a", "arm64", "--no-color", "--confirm") - suite.NoError(err) - - // Ensure that the initial filter was applied - suite.Contains(stdErr, ` -- name: combined - description: chocolate-arm`) - - // Ensure that the import filter was applied - suite.Contains(stdErr, ` -- name: via-import - description: chocolate-arm`) - - // Ensure that the other flavors / architectures are not included - suite.NotContains(stdErr, `vanilla-arm`) - suite.NotContains(stdErr, `vanilla-amd`) - suite.NotContains(stdErr, `chocolate-amd`) +func TestFlavorExample(t *testing.T) { + t.Parallel() + + tmpDir := t.TempDir() + flavorExample := filepath.Join("examples", "package-flavors") + _, _, err := e2e.Zarf(t, "package", "create", flavorExample, "-o", tmpDir, "--flavor", "oracle-cookie-crunch", "--no-color", "--confirm") + require.NoError(t, err) + + tarPath := filepath.Join(tmpDir, fmt.Sprintf("zarf-package-package-flavors-%s-1.0.0.tar.zst", e2e.Arch)) + pkgLayout, err := layout2.LoadFromTar(context.Background(), tarPath, layout2.PackageLayoutOptions{}) + require.NoError(t, err) + pkgLayout.Pkg.Metadata.Description = "The pod that runs the specified flavor of Enterprise Linux" + imgs := []string{} + for _, comp := range pkgLayout.Pkg.Components { + imgs = append(imgs, comp.Images...) + } + require.ElementsMatch(t, imgs, []string{"oraclelinux:9-slim"}) } -func TestFlavorSuite(t *testing.T) { - suite.Run(t, new(FlavorSuite)) +func TestFlavorArchFiltering(t *testing.T) { + t.Parallel() + + tests := []struct { + arch string + flavor string + expectedIDs []string + }{ + { + arch: "amd64", + flavor: "vanilla", + expectedIDs: []string{"combined-vanilla-amd", "via-import-vanilla-amd"}, + }, + { + arch: "amd64", + flavor: "chocolate", + expectedIDs: []string{"combined-chocolate-amd", "via-import-chocolate-amd"}, + }, + { + arch: "arm64", + flavor: "chocolate", + expectedIDs: []string{"combined-chocolate-arm", "via-import-chocolate-arm"}, + }, + } + for _, tt := range tests { + t.Run(tt.arch+"-"+tt.flavor, func(t *testing.T) { + t.Parallel() + + tmpDir := t.TempDir() + flavorTest := filepath.Join("src", "test", "packages", "10-package-flavors") + _, _, err := e2e.Zarf(t, "package", "create", flavorTest, "-o", tmpDir, "--flavor", tt.flavor, "-a", tt.arch, "--no-color", "--confirm") + require.NoError(t, err) + + tarPath := filepath.Join(tmpDir, fmt.Sprintf("zarf-package-test-package-flavors-%s.tar.zst", tt.arch)) + pkgLayout, err := layout2.LoadFromTar(context.Background(), tarPath, layout2.PackageLayoutOptions{}) + require.NoError(t, err) + compIDs := []string{} + for _, comp := range pkgLayout.Pkg.Components { + compIDs = append(compIDs, comp.Name+"-"+comp.Description) + } + require.ElementsMatch(t, compIDs, tt.expectedIDs) + }) + } } diff --git a/src/test/e2e/99_yolo_test.go b/src/test/e2e/99_yolo_test.go index 03281df1a7..b9203ed000 100644 --- a/src/test/e2e/99_yolo_test.go +++ b/src/test/e2e/99_yolo_test.go @@ -53,9 +53,17 @@ func TestDevDeploy(t *testing.T) { return } + // Generic test of dev deploy stdOut, stdErr, err := e2e.Zarf(t, "dev", "deploy", "examples/dos-games") require.NoError(t, err, stdOut, stdErr) - stdOut, stdErr, err = e2e.Zarf(t, "package", "remove", "dos-games", "--confirm") + stdOut, stdErr, err = e2e.Zarf(t, "tools", "kubectl", "delete", "namespace", "dos-games") + require.NoError(t, err, stdOut, stdErr) + + // Special test of hidden registry-url flag + stdOut, stdErr, err = e2e.Zarf(t, "dev", "deploy", "src/test/packages/99-registry-url", "--registry-url", "ghcr.io") + require.NoError(t, err, stdOut, stdErr) + + stdOut, stdErr, err = e2e.Zarf(t, "tools", "kubectl", "delete", "namespace", "registry-url") require.NoError(t, err, stdOut, stdErr) } diff --git a/src/test/e2e/main_test.go b/src/test/e2e/main_test.go index 9fe02d40df..0f6d81df32 100644 --- a/src/test/e2e/main_test.go +++ b/src/test/e2e/main_test.go @@ -35,7 +35,11 @@ func TestMain(m *testing.M) { } e2e.Arch = config.GetArch() - e2e.ZarfBinPath = filepath.Join("build", test.GetCLIName()) + zarfBinPath, err := filepath.Abs(filepath.Join("build", test.GetCLIName())) + if err != nil { + log.Fatal(err) + } + e2e.ZarfBinPath = zarfBinPath e2e.ApplianceMode = os.Getenv(applianceModeEnvVar) == "true" e2e.ApplianceModeKeep = os.Getenv(applianceModeKeepEnvVar) == "true" diff --git a/src/test/external/ext_in_cluster_test.go b/src/test/external/ext_in_cluster_test.go index 81102c0b14..1b4f668d8c 100644 --- a/src/test/external/ext_in_cluster_test.go +++ b/src/test/external/ext_in_cluster_test.go @@ -14,9 +14,9 @@ import ( "testing" "time" - pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/zarf-dev/zarf/src/internal/healthchecks" "github.com/zarf-dev/zarf/src/pkg/cluster" "github.com/zarf-dev/zarf/src/pkg/utils/exec" "github.com/zarf-dev/zarf/src/test/testutil" @@ -88,7 +88,7 @@ func (suite *ExtInClusterTestSuite) SetupSuite() { } waitCtx, waitCancel := context.WithTimeout(context.Background(), 60*time.Second) defer waitCancel() - err = pkgkubernetes.WaitForReady(waitCtx, c.Watcher, objs) + err = healthchecks.WaitForReady(waitCtx, c.Watcher, objs) suite.NoError(err) } @@ -199,7 +199,7 @@ func (suite *ExtInClusterTestSuite) Test_1_Deploy() { } waitCtx, waitCancel := context.WithTimeout(context.Background(), 60*time.Second) defer waitCancel() - err = pkgkubernetes.WaitForReady(waitCtx, c.Watcher, objs) + err = healthchecks.WaitForReady(waitCtx, c.Watcher, objs) suite.NoError(err) _, _, err = exec.CmdWithTesting(suite.T(), exec.PrintCfg(), zarfBinPath, "destroy", "--confirm") diff --git a/src/test/packages/04-file-folders-templating-sbom/zarf.yaml b/src/test/packages/04-file-folders-templating-sbom/zarf.yaml index 5aa4cb4ddf..fc440a1411 100644 --- a/src/test/packages/04-file-folders-templating-sbom/zarf.yaml +++ b/src/test/packages/04-file-folders-templating-sbom/zarf.yaml @@ -18,7 +18,6 @@ components: after: - cmd: cat temp/include-files/simple.txt - cmd: cat temp/include-files/something.yaml - - cmd: rm -r temp - name: files required: true files: @@ -28,4 +27,3 @@ components: onDeploy: after: - cmd: cat temp/requirements.txt - - cmd: rm -r temp diff --git a/src/test/packages/99-registry-url/registry-url.yaml b/src/test/packages/99-registry-url/registry-url.yaml new file mode 100644 index 0000000000..1332cf9fde --- /dev/null +++ b/src/test/packages/99-registry-url/registry-url.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: registry-url +spec: + containers: + - name: podinfo + image: "###ZARF_REGISTRY###/stefanprodan/podinfo:6.4.0" diff --git a/src/test/packages/99-registry-url/zarf.yaml b/src/test/packages/99-registry-url/zarf.yaml new file mode 100644 index 0000000000..1e4aebc4dc --- /dev/null +++ b/src/test/packages/99-registry-url/zarf.yaml @@ -0,0 +1,16 @@ +kind: ZarfPackageConfig +metadata: + name: registry-url + description: Deploys a simple pod with the special ZARF_REGISTRY value + +components: + - name: registry-url + required: true + manifests: + - name: registry-url + namespace: registry-url + noWait: true + files: + - registry-url.yaml + images: + - ghcr.io/stefanprodan/podinfo:6.4.0 diff --git a/src/types/packager.go b/src/types/packager.go index fb3f68bfd5..840d05242a 100644 --- a/src/types/packager.go +++ b/src/types/packager.go @@ -4,10 +4,18 @@ // Package types contains all the types used by Zarf. package types -import "github.com/zarf-dev/zarf/src/api/v1alpha1" +import ( + "context" + + "github.com/zarf-dev/zarf/src/api/v1alpha1" +) // PackagerConfig is the main struct that the packager uses to hold high-level options. type PackagerConfig struct { + // Context provides deadlines, cancellations, and values throughout the API. + // NOTE(mkcp): Storing ctx on structs is not recommended, but this is intended as a temporary workaround. + Context context.Context + // CreateOpts tracks the user-defined options used to create the package CreateOpts ZarfCreateOptions diff --git a/src/types/runtime.go b/src/types/runtime.go index 03ad9375fd..aad1bd000c 100644 --- a/src/types/runtime.go +++ b/src/types/runtime.go @@ -78,6 +78,8 @@ type ZarfDeployOptions struct { Timeout time.Duration // [Library Only] A map of component names to chart names containing Helm Chart values to override values on deploy ValuesOverridesMap map[string]map[string]map[string]interface{} + // [Dev Deploy Only] Manual override for ###ZARF_REGISTRY### + RegistryURL string } // ZarfMirrorOptions tracks the user-defined preferences during a package mirror.