diff --git a/.github/workflows/build-snap.yaml b/.github/workflows/build-snap.yaml new file mode 100644 index 000000000..5df087f3f --- /dev/null +++ b/.github/workflows/build-snap.yaml @@ -0,0 +1,51 @@ +name: Build k8s-snap + +on: + workflow_call: + inputs: + flavor: + description: k8s-snap flavor (e.g. moonray or strict) + type: string + outputs: + snap-artifact: + description: Name of the uploaded snap artifact + value: ${{ jobs.build-snap.outputs.snap-artifact }} + +jobs: + build-snap: + name: Build snap + runs-on: ubuntu-20.04 + outputs: + snap-artifact: ${{ steps.build.outputs.snap-artifact }} + steps: + - name: Checking out repo + uses: actions/checkout@v4 + - name: Apply patches + if: ${{ inputs.flavor }} != "" + run: | + ./build-scripts/patches/${{ inputs.flavor }}/apply + - name: Install lxd + uses: ./.github/workflows/install-lxd.yaml + - name: Install snapcraft + run: | + sudo snap install snapcraft --classic + - name: Build snap + id: build + env: + flavor: ${{ inputs.flavor }} + run: | + if [[ -n "$flavor" ]]; then + out_snap=k8s-$flavor.snap + else + out_snap=k8s.snap + fi + + sg lxd -c 'snapcraft --use-lxd' + mv k8s_*.snap $out_snap + + echo "snap-artifact=$out_snap" >> "$GITHUB_OUTPUT" + - name: Uploading snap + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.build.outputs.snap-artifact }} + path: ${{ steps.build.outputs.snap-artifact }} diff --git a/.github/workflows/cron-jobs.yaml b/.github/workflows/cron-jobs.yaml index 6fcc85631..a8e49f615 100644 --- a/.github/workflows/cron-jobs.yaml +++ b/.github/workflows/cron-jobs.yaml @@ -81,46 +81,7 @@ jobs: - { branch: release-1.30, channel: 1.30-classic/edge } - { branch: release-1.31, channel: 1.31-classic/edge } - steps: - - name: Checking out repo - uses: actions/checkout@v4 - with: - ref: ${{matrix.branch}} - - name: Setup Trivy vulnerability scanner - run: | - mkdir -p sarifs - VER=$(curl --silent -qI https://github.com/aquasecurity/trivy/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); - wget https://github.com/aquasecurity/trivy/releases/download/${VER}/trivy_${VER#v}_Linux-64bit.tar.gz - tar -zxvf ./trivy_${VER#v}_Linux-64bit.tar.gz - - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - ignore-unfixed: true - format: "sarif" - output: "trivy-k8s-repo-scan--results.sarif" - severity: "MEDIUM,HIGH,CRITICAL" - env: - TRIVY_DB_REPOSITORY: "public.ecr.aws/aquasecurity/trivy-db" - - name: Gather Trivy repo scan results - run: | - cp trivy-k8s-repo-scan--results.sarif ./sarifs/ - - name: Run Trivy vulnerability scanner on the snap - run: | - snap download k8s --channel ${{ matrix.channel }} - mv ./k8s*.snap ./k8s.snap - unsquashfs k8s.snap - for var in $(env | grep -o '^TRIVY_[^=]*'); do - unset "$var" - done - ./trivy --db-repository public.ecr.aws/aquasecurity/trivy-db rootfs ./squashfs-root/ --format sarif > sarifs/snap.sarif - - name: Get HEAD sha - run: | - SHA="$(git rev-parse HEAD)" - echo "head_sha=$SHA" >> "$GITHUB_ENV" - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: "sarifs" - sha: ${{ env.head_sha }} - ref: refs/heads/${{matrix.branch}} + uses: ./.github/workflows/security-scan.yaml + with: + channel: ${{ matrix.channel }} + checkout-ref: ${{ $matrix.branch }} diff --git a/.github/workflows/download-k8s-snap.yaml b/.github/workflows/download-k8s-snap.yaml new file mode 100644 index 000000000..05a46235c --- /dev/null +++ b/.github/workflows/download-k8s-snap.yaml @@ -0,0 +1,47 @@ +name: Download k8s-snap + +inputs: + # Download k8s-snap using either a GH action artifact or a snap channel. + artifact: + description: The name of a GH action artifact. + type: string + channel: + description: k8s snap channel. + type: string + output-file: + description: The *.snap destination path. + type: string + required: true + +runs: + using: "composite" + steps: + - name: Exit if no input provided + if: ${{ inputs.artifact }} == '' && ${{ inputs.channel }} == '' + run: | + echo "No k8s-snap artifact or channel specified..." + exit 1 + - name: Exit if multiple inputs provided + if: ${{ inputs.artifact }} != '' && ${{ inputs.channel }} != '' + run: | + echo "Received snap artifact AND snap channel." + exit 1 + - name: Create destination dir. + run: mkdir -p $(dirname ${{ inputs.output-file }}) + + - name: Download snap artifact + if: ${{ inputs.artifact }} != '' + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.artifact }} + path: ${{ github.workspace }} + - name: Move snap artifact. + if: ${{ inputs.artifact }} != '' + run: mv ${{ github.workspace }}/${{ inputs.artifact }} ${{ inputs.output-file }} + + - name: Download snap channel + if: ${{ inputs.artifact }} != '' + run: | + cd $(dirname ${{ inputs.output-file }}) + snap download k8s --channel=${{ inputs.channel }} --basename k8s + mv k8s.snap ${{ inputs.output-file }} diff --git a/.github/workflows/get-e2e-test-tags.yaml b/.github/workflows/get-e2e-test-tags.yaml new file mode 100644 index 000000000..a0d24de86 --- /dev/null +++ b/.github/workflows/get-e2e-test-tags.yaml @@ -0,0 +1,36 @@ +name: Get e2e test tags + +on: + workflow_call: + outputs: + test-tags: + description: The filter tags to use when running e2e tests + value: ${{ jobs.get-tags.outputs.test-tags }} + +jobs: + get-tags: + name: Build snap + runs-on: ubuntu-latest + outputs: + test-tags: ${{ steps.get-tags.outputs.snap-artifact }} + steps: + - name: Checking out repo + uses: actions/checkout@v4 + + - name: Build snap + id: get-tags + run: | + tags="pull_request" + if ${{ github.event_name == 'pull_request' }}; then + # Run all tests if there are test changes. In case of a PR, we'll + # get a merge commit that includes all changes. + if git diff HEAD HEAD~1 --name-only | grep "tests/"; then + tags="up_to_weekly" + fi + # Run all tests on backports. + if echo ${{ github.base_ref }} | grep "release-"; then + tags="up_to_weekly" + fi + fi + + echo "test-tags=$tags" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/install-lxd.yaml b/.github/workflows/install-lxd.yaml new file mode 100644 index 000000000..14d9fbfd3 --- /dev/null +++ b/.github/workflows/install-lxd.yaml @@ -0,0 +1,17 @@ +name: Install lxd + +runs: + using: "composite" + steps: + - name: Install lxd snap + run: | + sudo snap refresh lxd --channel 5.21/stable + - name: Initialize lxd + run: + sudo lxd init --auto + sudo usermod --append --groups lxd $USER + sg lxd -c 'lxc version' + - name: Apply Docker iptables workaround + run: + sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT + sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT diff --git a/.github/workflows/integration-informing.yaml b/.github/workflows/integration-informing.yaml index d569a7c66..dba4d4e01 100644 --- a/.github/workflows/integration-informing.yaml +++ b/.github/workflows/integration-informing.yaml @@ -16,89 +16,32 @@ permissions: contents: read jobs: - build: + build-snap: name: Build ${{ matrix.patch }} - runs-on: ubuntu-20.04 + uses: ./.github/workflows/build-snap.yaml + id: build-snap strategy: matrix: patch: ["moonray"] fail-fast: false - steps: - - name: Checking out repo - uses: actions/checkout@v4 - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - - name: Install snapcraft - run: | - sudo snap install snapcraft --classic - - name: Apply ${{ matrix.patch }} patch - run: | - ./build-scripts/patches/${{ matrix.patch }}/apply - - name: Build snap - run: | - sg lxd -c 'snapcraft --use-lxd' - mv k8s_*.snap k8s-${{ matrix.patch }}.snap - - name: Uploading snap - uses: actions/upload-artifact@v4 - with: - name: k8s-${{ matrix.patch }}.snap - path: k8s-${{ matrix.patch }}.snap + with: + flavor: ${{ matrix.patch }} + + get-e2e-test-tags: + name: "Get e2e test tags" + uses: ./.github/workflows/get-e2e-test-tags.yaml test-integration: - needs: [ build ] - name: Test ${{ matrix.patch }} ${{ matrix.os }} + name: Test ${{ matrix.os }} strategy: + fail-fast: false matrix: os: ["ubuntu:20.04"] patch: ["moonray"] - fail-fast: false - runs-on: ["self-hosted", "Linux", "AMD64", "jammy", "large"] - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Install tox - run: pip install tox - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Download snap - uses: actions/download-artifact@v4 - with: - name: k8s-${{ matrix.patch }}.snap - path: ${{ github.workspace }}/build - - name: Apply ${{ matrix.patch }} patch - run: | - ./build-scripts/patches/${{ matrix.patch }}/apply - - name: Run end to end tests - env: - TEST_SNAP: ${{ github.workspace }}/build/k8s-${{ matrix.patch }}.snap - TEST_SUBSTRATE: lxd - TEST_LXD_IMAGE: ${{ matrix.os }} - TEST_FLAVOR: ${{ matrix.patch }} - TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports - run: | - cd tests/integration && sg lxd -c 'tox -e integration -- --tags pull_request' - - name: Prepare inspection reports - if: failure() - run: | - tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports - echo "artifact_name=inspection-reports-${{ matrix.os }}-${{ matrix.patch }}" | sed 's/:/-/g' >> $GITHUB_ENV - - name: Upload inspection report artifact - if: failure() - uses: actions/upload-artifact@v4 - with: - name: ${{ env.artifact_name }} - path: ${{ github.workspace }}/inspection-reports.tar.gz + needs: build + uses: ./.github/workflows/run-e2e-tests.yaml + with: + arch: amd64 + os: ${{ matrix.os }} + test-tags: ${{ jobs.get-e2e-test-tags.outputs.test-tags}} + artifact: k8s-${{ matrix.patch }}.snap diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 13857352e..a93d694a4 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -19,31 +19,10 @@ permissions: contents: read jobs: - build: - name: Build - runs-on: ubuntu-20.04 - - steps: - - name: Checking out repo - uses: actions/checkout@v4 - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - - name: Install snapcraft - run: | - sudo snap install snapcraft --classic - - name: Build snap - run: | - sg lxd -c 'snapcraft --use-lxd' - mv k8s_*.snap k8s.snap - - name: Uploading snap - uses: actions/upload-artifact@v4 - with: - name: k8s.snap - path: k8s.snap + build-snap: + name: Build k8s-snap + uses: ./.github/workflows/build-snap.yaml + id: build-snap test-branches: name: Test Branch Management @@ -63,125 +42,27 @@ jobs: run: | tox -c tests/branch_management -e test + get-e2e-test-tags: + name: "Get e2e test tags" + uses: ./.github/workflows/get-e2e-test-tags.yaml + test-integration: name: Test ${{ matrix.os }} strategy: fail-fast: false matrix: os: ["ubuntu:20.04", "ubuntu:22.04", "ubuntu:24.04"] - runs-on: ["self-hosted", "Linux", "AMD64", "jammy", "large"] needs: build - - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Install tox - run: pip install tox - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Download snap - uses: actions/download-artifact@v4 - with: - name: k8s.snap - path: ${{ github.workspace }}/build - - name: Run end to end tests - env: - TEST_SNAP: ${{ github.workspace }}/build/k8s.snap - TEST_SUBSTRATE: lxd - TEST_LXD_IMAGE: ${{ matrix.os }} - TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports - # Test the latest (up to) 6 releases for the flavour - # TODO(ben): upgrade nightly to run all flavours - TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic" - # Upgrading from 1.30 is not supported. - TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31" - TEST_MIRROR_LIST: '[{"name": "ghcr.io", "port": 5000, "remote": "https://ghcr.io", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}, {"name": "docker.io", "port": 5001, "remote": "https://registry-1.docker.io", "username": "", "password": ""}, {"name": "rocks.canonical.com", "port": 5002, "remote": "https://rocks.canonical.com/cdk"}]' - run: | - tags="pull_request" - # Run all tests if there are test changes. In case of a PR, we'll - # get a merge commit that includes all changes. - if git diff HEAD HEAD~1 --name-only | grep "tests/"; then - tags="up_to_weekly" - fi - # Run all tests on backports. - if echo ${{ github.base_ref }} | grep "release-"; then - tags="up_to_weekly" - fi - cd tests/integration && sg lxd -c "tox -e integration -- --tags $tags" - - name: Prepare inspection reports - if: failure() - run: | - tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports - echo "artifact_name=inspection-reports-${{ matrix.os }}" | sed 's/:/-/g' >> $GITHUB_ENV - - name: Upload inspection report artifact - if: failure() - uses: actions/upload-artifact@v4 - with: - name: ${{ env.artifact_name }} - path: ${{ github.workspace }}/inspection-reports.tar.gz + uses: ./.github/workflows/run-e2e-tests.yaml + with: + arch: amd64 + os: ${{ matrix.os }} + test-tags: ${{ jobs.get-e2e-test-tags.outputs.test-tags}} + artifact: ${{ jobs.build-snap.outputs.snap-artifact}} security-scan: - permissions: - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/upload-sarif to upload SARIF results name: Security scan - runs-on: ubuntu-20.04 needs: build - steps: - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - # We run into rate limiting issues if we don't authenticate - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Checking out repo - uses: actions/checkout@v4 - - name: Fetch snap - uses: actions/download-artifact@v4 - with: - name: k8s.snap - path: build - - name: Setup Trivy vulnerability scanner - run: | - mkdir -p manual-trivy/sarifs - pushd manual-trivy - VER=$(curl --silent -qI https://github.com/aquasecurity/trivy/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); - wget https://github.com/aquasecurity/trivy/releases/download/${VER}/trivy_${VER#v}_Linux-64bit.tar.gz - tar -zxvf ./trivy_${VER#v}_Linux-64bit.tar.gz - popd - - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - ignore-unfixed: true - format: "sarif" - output: "trivy-k8s-repo-scan--results.sarif" - severity: "MEDIUM,HIGH,CRITICAL" - env: - TRIVY_DB_REPOSITORY: "public.ecr.aws/aquasecurity/trivy-db" - - name: Gather Trivy repo scan results - run: | - cp trivy-k8s-repo-scan--results.sarif ./manual-trivy/sarifs/ - - name: Run Trivy vulnerability scanner on the snap - run: | - for var in $(env | grep -o '^TRIVY_[^=]*'); do - unset "$var" - done - cp build/k8s.snap . - unsquashfs k8s.snap - ./manual-trivy/trivy --db-repository public.ecr.aws/aquasecurity/trivy-db rootfs ./squashfs-root/ --format sarif > ./manual-trivy/sarifs/snap.sarif - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: "./manual-trivy/sarifs" + uses: ./.github/workflows/security-scan.yaml + with: + artifact: ${{ jobs.build-snap.outputs.snap-artifact}} diff --git a/.github/workflows/nightly-test.yaml b/.github/workflows/nightly-test.yaml index 98089d932..25785e6cb 100644 --- a/.github/workflows/nightly-test.yaml +++ b/.github/workflows/nightly-test.yaml @@ -16,56 +16,9 @@ jobs: arch: ["amd64", "arm64"] release: ["latest/edge"] fail-fast: false # TODO: remove once arm64 works - - runs-on: ${{ matrix.arch == 'arm64' && 'self-hosted-linux-arm64-jammy-large' || 'self-hosted-linux-amd64-jammy-large' }} - - steps: - - name: Checking out repo - uses: actions/checkout@v4 - - name: Install lxd and tox - run: | - sudo apt update - sudo apt install -y tox - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Create build directory - run: mkdir -p build - - name: Install ${{ matrix.release }} k8s snap - run: | - cd build - snap download k8s --channel=${{ matrix.release }} --basename k8s - - name: Run end to end tests # tox path needs to be specified for arm64 - env: - TEST_SNAP: ${{ github.workspace }}/build/k8s.snap - TEST_SUBSTRATE: lxd - TEST_LXD_IMAGE: ${{ matrix.os }} - TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports - # Test the latest (up to) 6 releases for the flavour - # TODO(ben): upgrade nightly to run all flavours - TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic" - # Upgrading from 1.30 is not supported. - TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31" - TEST_STRICT_INTERFACE_CHANNELS: "recent 6 strict" - TEST_MIRROR_LIST: '[{"name": "ghcr.io", "port": 5000, "remote": "https://ghcr.io", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}, {"name": "docker.io", "port": 5001, "remote": "https://registry-1.docker.io", "username": "", "password": ""}, {"name": "rocks.canonical.com", "port": 5002, "remote": "https://rocks.canonical.com/cdk"}]' - run: | - export PATH="/home/runner/.local/bin:$PATH" - cd tests/integration && sg lxd -c 'tox -vve integration -- --tags up_to_nightly ' - - name: Prepare inspection reports - if: failure() - run: | - tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports - echo "artifact_name=inspection-reports-${{ matrix.os }}-${{ matrix.arch }}" | sed 's/:/-/g' >> $GITHUB_ENV - - name: Upload inspection report artifact - if: failure() - uses: actions/upload-artifact@v4 - with: - name: ${{ env.artifact_name }} - path: ${{ github.workspace }}/inspection-reports.tar.gz - - name: Tmate debugging session - if: ${{ failure() && github.event_name == 'pull_request' }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 10 + uses: ./.github/workflows/run-e2e-tests.yaml + with: + arch: ${{ matrix.arch }} + os: ${{ matrix.os }} + release: latest/edge + test-tags: up_to_weekly diff --git a/.github/workflows/run-e2e-tests.yaml b/.github/workflows/run-e2e-tests.yaml new file mode 100644 index 000000000..953f9d6cf --- /dev/null +++ b/.github/workflows/run-e2e-tests.yaml @@ -0,0 +1,72 @@ +name: Run k8s-snap e2e tests + +on: + workflow_call: + inputs: + arch: + description: Job runner architecture (amd64 or arm64) + default: amd64 + type: string + os: + description: LXD image to use when running e2e tests + default: ubuntu:24.04 + type: string + # Download k8s-snap using either a GH action artifact or a snap channel. + artifact: + description: The name of a GH action artifact. + type: string + channel: + description: k8s snap channel. + type: string + test-tags: + description: Test filter tags (e.g. pull_request, up_to_weekly) + default: pull_request + type: string + +jobs: + test-integration: + name: Integration Test ${{ inputs.os }} ${{ inputs.arch }} ${{ inputs.artifact }} + runs-on: ${{ inputs.arch == 'arm64' && 'self-hosted-linux-arm64-jammy-large' || 'self-hosted-linux-amd64-jammy-large' }} + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Download k8s-snap + id: download-snap + uses: ./.github/workflows/download-k8s-snap.yaml + with: + channel: ${{ inputs.channel }} + artifact: ${{ inputs.artifact }} + - name: Install lxd + uses: ./.github/workflows/install-lxd.yaml + - name: Install tox + run: pip install tox + - name: Run e2e tests + env: + TEST_SNAP: ${{ steps.download-snap.outputs.snap-artifact }} + TEST_SUBSTRATE: lxd + TEST_LXD_IMAGE: ${{ inputs.os }} + TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports + # Test the latest (up to) 6 releases for the flavour + # TODO(ben): upgrade nightly to run all flavours + TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic" + # Upgrading from 1.30 is not supported. + TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31" + TEST_STRICT_INTERFACE_CHANNELS: "recent 6 strict" + TEST_MIRROR_LIST: '[{"name": "ghcr.io", "port": 5000, "remote": "https://ghcr.io", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}, {"name": "docker.io", "port": 5001, "remote": "https://registry-1.docker.io", "username": "", "password": ""}, {"name": "rocks.canonical.com", "port": 5002, "remote": "https://rocks.canonical.com/cdk"}]' + run: | + cd tests/integration && sg lxd -c "tox -e integration -- --tags ${{ inputs.test-tags }}" + - name: Prepare inspection reports + if: failure() + run: | + tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports + echo "artifact_name=inspection-reports-${{ inputs.os }}" | sed 's/:/-/g' >> $GITHUB_ENV + - name: Upload inspection report artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ${{ env.artifact_name }} + path: ${{ github.workspace }}/inspection-reports.tar.gz diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/security-scan.yaml new file mode 100644 index 000000000..099026073 --- /dev/null +++ b/.github/workflows/security-scan.yaml @@ -0,0 +1,77 @@ +name: Security scan + +permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + +on: + workflow_call: + inputs: + # Download k8s-snap using either a GH action artifact or a snap channel. + artifact: + description: The name of a GH action artifact. + type: string + channel: + description: k8s snap channel. + type: string + checkout-ref: + description: k8s-snap git checkout ref, optional. + type: string + +jobs: + get-tags: + name: Security scan + runs-on: ubuntu-20.04 + outputs: + test-tags: ${{ steps.get-tags.outputs.snap-artifact }} + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + # We run into rate limiting issues if we don't authenticate + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Checking out repo + uses: actions/checkout@v4 + with: + ref: ${{ inputs.checkout-ref }} + - name: Download k8s-snap + id: download-snap + uses: ./.github/workflows/download-k8s-snap.yaml + with: + channel: ${{ inputs.channel }} + artifact: ${{ inputs.artifact }} + - name: Setup Trivy vulnerability scanner + run: | + mkdir -p manual-trivy/sarifs + pushd manual-trivy + VER=$(curl --silent -qI https://github.com/aquasecurity/trivy/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); + wget https://github.com/aquasecurity/trivy/releases/download/${VER}/trivy_${VER#v}_Linux-64bit.tar.gz + tar -zxvf ./trivy_${VER#v}_Linux-64bit.tar.gz + popd + - name: Run Trivy vulnerability scanner in repo mode + uses: aquasecurity/trivy-action@master + with: + scan-type: "fs" + ignore-unfixed: true + format: "sarif" + output: "trivy-k8s-repo-scan--results.sarif" + severity: "MEDIUM,HIGH,CRITICAL" + env: + TRIVY_DB_REPOSITORY: "public.ecr.aws/aquasecurity/trivy-db" + - name: Gather Trivy repo scan results + run: | + cp trivy-k8s-repo-scan--results.sarif ./manual-trivy/sarifs/ + - name: Run Trivy vulnerability scanner on the snap + run: | + for var in $(env | grep -o '^TRIVY_[^=]*'); do + unset "$var" + done + cp ${{ steps.download-snap.outputs.snap-artifact }} . + unsquashfs `basename ${{ steps.download-snap.outputs.snap-artifact }}` + ./manual-trivy/trivy --db-repository public.ecr.aws/aquasecurity/trivy-db rootfs ./squashfs-root/ --format sarif > ./manual-trivy/sarifs/snap.sarif + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: "./manual-trivy/sarifs"