diff --git a/.github/actions/setup_crane/action.yaml b/.github/actions/setup_crane/action.yaml deleted file mode 100644 index 04b216e4d..000000000 --- a/.github/actions/setup_crane/action.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Setup crane -description: "Install crane (go-containerregistry)." -runs: - using: composite - steps: - - name: Install - shell: bash - env: - VERSION: "0.12.1" - OS: ${{ runner.os == 'Linux' && 'Linux' || 'Darwin' }} - ARCH: ${{ runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM64' && 'arm64' }} - run: | - echo "::group::Install crane" - curl -sL "https://github.com/google/go-containerregistry/releases/download/v${VERSION}/go-containerregistry_${OS}_${ARCH}.tar.gz" > go-containerregistry.tar.gz - tar -xzf go-containerregistry.tar.gz - sudo mv krane gcrane crane /usr/local/bin/ - echo "::endgroup::" diff --git a/.github/actions/setup_mkosi/action.yaml b/.github/actions/setup_mkosi/action.yaml index 055289a6e..d7ab102e3 100644 --- a/.github/actions/setup_mkosi/action.yaml +++ b/.github/actions/setup_mkosi/action.yaml @@ -12,9 +12,11 @@ runs: run: | echo "::group::Dependencies" echo "deb-src http://archive.ubuntu.com/ubuntu/ $(lsb_release -cs) main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list + sudo add-apt-repository ppa:michel-slm/kernel-utils sudo apt-get update sudo apt-get install --assume-yes --no-install-recommends \ dnf \ + makepkg \ systemd-container \ qemu-system-x86 \ ovmf \ diff --git a/.github/workflows/build-micro-service-manual.yml b/.github/workflows/build-micro-service-manual.yml index dab5e130c..90e2a5b55 100644 --- a/.github/workflows/build-micro-service-manual.yml +++ b/.github/workflows/build-micro-service-manual.yml @@ -23,37 +23,6 @@ on: description: "Version of the image to build" required: true default: "0.0.0" - ref: - type: string - description: "Git ref to checkout" - required: false - release: - type: boolean - description: "Is this a release build?" - required: false - default: false - workflow_call: - inputs: - microService: - description: "Name of the micro-service image to build" - type: string - required: true - imageTag: - type: string - description: "Container image tag" - required: true - version: - type: string - description: "Version of the image to build" - required: true - ref: - type: string - description: "Git ref to checkout" - required: false - release: - type: boolean - description: "Is this a release build?" - required: true jobs: build-micro-service: @@ -66,7 +35,7 @@ jobs: id: checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Setup Go environment uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 @@ -101,6 +70,6 @@ jobs: dockerfile: ${{ env.microServiceDockerfile }} pushTag: ${{ inputs.imageTag }} githubToken: ${{ secrets.GITHUB_TOKEN }} - cosignPublicKey: ${{ inputs.release && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} - cosignPrivateKey: ${{ inputs.release && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} - cosignPassword: ${{ inputs.release && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} + cosignPublicKey: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} + cosignPrivateKey: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} + cosignPassword: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} diff --git a/.github/workflows/build-operator-manual.yml b/.github/workflows/build-operator-manual.yml index 2b63c5b94..a7bd00c58 100644 --- a/.github/workflows/build-operator-manual.yml +++ b/.github/workflows/build-operator-manual.yml @@ -6,29 +6,6 @@ on: imageTag: description: "Container image tag." required: false - ref: - type: string - description: "Git ref to checkout" - required: false - release: - type: boolean - description: "Is this a release build?" - required: false - default: false - workflow_call: - inputs: - imageTag: - type: string - description: "Container image tag" - required: true - ref: - type: string - description: "Git ref to checkout" - required: false - release: - type: boolean - description: "Is this a release build?" - required: true jobs: build-operator-manual: @@ -41,7 +18,7 @@ jobs: id: checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Setup Go environment uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 @@ -55,6 +32,6 @@ jobs: sourceDir: operators/constellation-node-operator githubToken: ${{ secrets.GITHUB_TOKEN }} pushTag: ${{ inputs.imageTag }} - cosignPublicKey: ${{ inputs.release && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} - cosignPrivateKey: ${{ inputs.release && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} - cosignPassword: ${{ inputs.release && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} + cosignPublicKey: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} + cosignPrivateKey: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} + cosignPassword: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} diff --git a/.github/workflows/build-os-image.yml b/.github/workflows/build-os-image.yml index 2d8b1d834..4314bdd33 100644 --- a/.github/workflows/build-os-image.yml +++ b/.github/workflows/build-os-image.yml @@ -20,29 +20,6 @@ on: - "debug" # TODO: implement console access enabled image # - "console" - ref: - type: string - description: "Git ref to checkout" - required: false - workflow_call: - inputs: - imageVersion: - description: "Semantic version including patch e.g. v.. (only used for releases)" - required: false - type: string - isRelease: - description: 'Is this a release? (sets "ref" to special value "-")' - type: boolean - required: false - default: false - stream: - description: "Image stream / type. (Use 'stable' for releases, 'nightly' for regular non-release images and 'debug' for debug builds)" - type: string - required: true - ref: - type: string - description: "Git ref to checkout" - required: false jobs: build-dependencies: @@ -59,7 +36,7 @@ jobs: - name: Checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Build bootstrapper if: inputs.stream != 'debug' @@ -118,7 +95,7 @@ jobs: - name: Checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Determine version id: version @@ -232,7 +209,7 @@ jobs: - name: Checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Download build dependencies uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 @@ -344,7 +321,7 @@ jobs: - name: Checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Download OS image artifact uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 @@ -531,7 +508,7 @@ jobs: - name: Checkout repository uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Login to AWS uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # tag=v1.7.0 diff --git a/.github/workflows/e2e-mini.yml b/.github/workflows/e2e-mini.yml index 61a0022e1..ac61e6f38 100644 --- a/.github/workflows/e2e-mini.yml +++ b/.github/workflows/e2e-mini.yml @@ -2,17 +2,6 @@ name: e2e test qemu (MiniConstellation) on: workflow_dispatch: - inputs: - ref: - type: string - description: "Git ref to checkout" - required: false - workflow_call: - inputs: - ref: - type: string - description: "Git ref to checkout" - required: true permissions: id-token: write @@ -26,8 +15,6 @@ jobs: - name: Checkout id: checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - with: - ref: ${{ inputs.ref || github.head_ref }} - name: Azure login OIDC uses: azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7 diff --git a/.github/workflows/e2e-test-manual-macos.yml b/.github/workflows/e2e-test-manual-macos.yml index 3785927f1..c37b18750 100644 --- a/.github/workflows/e2e-test-manual-macos.yml +++ b/.github/workflows/e2e-test-manual-macos.yml @@ -55,53 +55,6 @@ on: type: string default: "default" required: false - git-ref: - description: "Git ref to checkout." - type: string - default: "head" - required: false - workflow_call: - inputs: - workerNodesCount: - description: "Number of worker nodes to spawn." - type: number - required: true - controlNodesCount: - description: "Number of control-plane nodes to spawn." - type: number - required: true - cloudProvider: - description: "Which cloud provider to use." - type: string - required: true - test: - description: "The test to run." - type: string - required: true - kubernetesVersion: - description: "Kubernetes version to create the cluster from." - type: string - required: true - keepMeasurements: - description: "Keep measurements embedded in the CLI." - type: boolean - required: true - osImage: - description: "Full name of OS image (CSP independent image version UID). Leave empty for latest debug image on main." - type: string - required: true - isDebugImage: - description: "Is OS image a debug image?" - type: boolean - required: true - machineType: - description: "Override VM machine type. Leave as 'default' or empty to use the default VM type for the selected cloud provider." - type: string - required: true - git-ref: - description: "Git ref to checkout." - type: string - required: true env: ARM_CLIENT_ID: ${{ secrets.AZURE_E2E_CLIENT_ID }} @@ -113,7 +66,7 @@ jobs: build-bootstrapper-linux: name: "Build bootstrapper (debug image)" runs-on: ubuntu-22.04 - if: ${{ inputs.isDebugImage == 'true' }} + if: ${{ github.event.inputs.isDebugImage == 'true' }} steps: - name: Setup Go environment uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 @@ -122,17 +75,11 @@ jobs: go-version: "1.19.4" - name: Check out repository - if: inputs.git-ref == 'head' && github.event.steps.check-bootstrapper-cache.cache-hit != 'true' + if: ${{ github.event.steps.check-bootstrapper-cache.cache-hit != 'true'}} uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - - name: Checkout ref - if: inputs.git-ref != 'head' && github.event.steps.check-bootstrapper-cache.cache-hit != 'true' - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - with: - ref: ${{ inputs.git-ref }} - - name: Build bootstrapper if: ${{ github.event.steps.check-bootstrapper-cache.cache-hit != 'true'}} uses: ./.github/actions/build_bootstrapper @@ -191,32 +138,25 @@ jobs: shell: bash run: brew install coreutils kubectl bash - - name: Checkout head - if: inputs.git-ref == 'head' + - name: Check out repository uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - - name: Checkout ref - if: inputs.git-ref != 'head' - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 - with: - ref: ${{ inputs.git-ref }} - - name: Setup Go environment uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: go-version: "1.19.4" - name: Login to Azure - if: ${{ inputs.cloudProvider == 'azure' }} + if: ${{ github.event.inputs.cloudProvider == 'azure' }} uses: ./.github/actions/login_azure with: azure_credentials: ${{ secrets.AZURE_E2E_CREDENTIALS }} - name: Create Azure resource group id: az_resource_group_gen - if: ${{ inputs.cloudProvider == 'azure' }} + if: ${{ github.event.inputs.cloudProvider == 'azure' }} shell: bash run: | uuid=$(uuidgen) @@ -225,23 +165,23 @@ jobs: echo "res_group_name=$name" >> "$GITHUB_OUTPUT" - name: Set up gcloud CLI - if: ${{ inputs.cloudProvider == 'gcp' }} + if: ${{ github.event.inputs.cloudProvider == 'gcp' }} uses: google-github-actions/setup-gcloud@d51b5346f85640ec2aa2fa057354d2b82c2fcbce # v1.0.1 - name: Run manual E2E test id: e2e_test uses: ./.github/actions/e2e_test with: - workerNodesCount: ${{ inputs.workerNodesCount }} - controlNodesCount: ${{ inputs.controlNodesCount }} - cloudProvider: ${{ inputs.cloudProvider }} - machineType: ${{ inputs.machineType }} + workerNodesCount: ${{ github.event.inputs.workerNodesCount }} + controlNodesCount: ${{ github.event.inputs.controlNodesCount }} + cloudProvider: ${{ github.event.inputs.cloudProvider }} + machineType: ${{ github.event.inputs.machineType }} gcpProject: ${{ secrets.GCP_E2E_PROJECT }} gcp_service_account_json: ${{ secrets.GCP_SERVICE_ACCOUNT }} gcpClusterServiceAccountKey: ${{ secrets.GCP_CLUSTER_SERVICE_ACCOUNT }} - test: ${{ inputs.test }} - kubernetesVersion: ${{ inputs.kubernetesVersion }} - keepMeasurements: ${{ inputs.keepMeasurements }} + test: ${{ github.event.inputs.test }} + kubernetesVersion: ${{ github.event.inputs.kubernetesVersion }} + keepMeasurements: ${{ github.event.inputs.keepMeasurements }} azureSubscription: ${{ secrets.AZURE_E2E_SUBSCRIPTION_ID }} azureTenant: ${{ secrets.AZURE_E2E_TENANT_ID }} azureClientID: ${{ secrets.AZURE_E2E_CLIENT_ID }} @@ -249,7 +189,7 @@ jobs: azureUserAssignedIdentity: ${{ secrets.AZURE_E2E_USER_ASSIGNED_IDENTITY }} azureResourceGroup: ${{ steps.az_resource_group_gen.outputs.res_group_name }} osImage: ${{ needs.find-latest-image.outputs.image }} - isDebugImage: ${{ inputs.isDebugImage }} + isDebugImage: ${{ github.event.inputs.isDebugImage }} - name: Always terminate cluster if: always() @@ -262,7 +202,7 @@ jobs: if: ${{ failure() && github.ref == 'refs/heads/main' }} run: | brew install gettext && brew link --force gettext - export TEAMS_JOB_NAME="${{ inputs.cloudProvider }} (macOS, manual)" + export TEAMS_JOB_NAME="${{ github.event.inputs.cloudProvider }} (macOS, manual)" export TEAMS_RUN_ID=${{ github.run_id }} envsubst < teams-payload.json > to-be-send.json curl \ @@ -273,7 +213,7 @@ jobs: working-directory: .github/actions/e2e_test - name: Always destroy Azure resource group - if: ${{ always() && inputs.cloudProvider == 'azure' }} + if: ${{ always() && github.event.inputs.cloudProvider == 'azure' }} shell: bash run: | az group delete \ diff --git a/.github/workflows/e2e-test-manual.yml b/.github/workflows/e2e-test-manual.yml index d118ed556..aa2278be2 100644 --- a/.github/workflows/e2e-test-manual.yml +++ b/.github/workflows/e2e-test-manual.yml @@ -61,48 +61,6 @@ on: type: string default: "head" required: false - workflow_call: - inputs: - workerNodesCount: - description: "Number of worker nodes to spawn." - type: number - required: true - controlNodesCount: - description: "Number of control-plane nodes to spawn." - type: number - required: true - cloudProvider: - description: "Which cloud provider to use." - type: string - required: true - test: - description: "The test to run." - type: string - required: true - kubernetesVersion: - description: "Kubernetes version to create the cluster from." - type: string - required: true - keepMeasurements: - description: "Keep measurements embedded in the CLI." - type: boolean - required: true - osImage: - description: "Full name of OS image (CSP independent image version UID). Leave empty for latest debug image on main." - type: string - required: true - isDebugImage: - description: "Is OS image a debug image?" - type: boolean - required: true - machineType: - description: "Override VM machine type. Leave as 'default' or empty to use the default VM type for the selected cloud provider." - type: string - required: true - git-ref: - description: "Git ref to checkout." - type: string - required: true env: ARM_CLIENT_ID: ${{ secrets.AZURE_E2E_CLIENT_ID }} @@ -132,18 +90,11 @@ jobs: exit 0 fi - - name: Checkout head - if: inputs.git-ref == 'head' + - name: Checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - - name: Checkout ref - if: inputs.git-ref != 'head' - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 - with: - ref: ${{ inputs.git-ref }} - - name: Find latest image id: find-latest-image if: steps.check-input.outputs.image == '' @@ -176,14 +127,14 @@ jobs: go-version: "1.19.4" - name: Login to Azure - if: ${{ inputs.cloudProvider == 'azure' }} + if: ${{ github.event.inputs.cloudProvider == 'azure' }} uses: ./.github/actions/login_azure with: azure_credentials: ${{ secrets.AZURE_E2E_CREDENTIALS }} - name: Create Azure resource group id: az_resource_group_gen - if: ${{ inputs.cloudProvider == 'azure' }} + if: ${{ github.event.inputs.cloudProvider == 'azure' }} shell: bash run: | uuid=$(cat /proc/sys/kernel/random/uuid) @@ -195,16 +146,16 @@ jobs: id: e2e_test uses: ./.github/actions/e2e_test with: - workerNodesCount: ${{ inputs.workerNodesCount }} - controlNodesCount: ${{ inputs.controlNodesCount }} - cloudProvider: ${{ inputs.cloudProvider }} - machineType: ${{ inputs.machineType }} + workerNodesCount: ${{ github.event.inputs.workerNodesCount }} + controlNodesCount: ${{ github.event.inputs.controlNodesCount }} + cloudProvider: ${{ github.event.inputs.cloudProvider }} + machineType: ${{ github.event.inputs.machineType }} gcpProject: ${{ secrets.GCP_E2E_PROJECT }} gcp_service_account_json: ${{ secrets.GCP_SERVICE_ACCOUNT }} gcpClusterServiceAccountKey: ${{ secrets.GCP_CLUSTER_SERVICE_ACCOUNT }} - test: ${{ inputs.test }} - kubernetesVersion: ${{ inputs.kubernetesVersion }} - keepMeasurements: ${{ inputs.keepMeasurements }} + test: ${{ github.event.inputs.test }} + kubernetesVersion: ${{ github.event.inputs.kubernetesVersion }} + keepMeasurements: ${{ github.event.inputs.keepMeasurements }} azureSubscription: ${{ secrets.AZURE_E2E_SUBSCRIPTION_ID }} azureTenant: ${{ secrets.AZURE_E2E_TENANT_ID }} azureClientID: ${{ secrets.AZURE_E2E_CLIENT_ID }} @@ -212,7 +163,7 @@ jobs: azureUserAssignedIdentity: ${{ secrets.AZURE_E2E_USER_ASSIGNED_IDENTITY }} azureResourceGroup: ${{ steps.az_resource_group_gen.outputs.res_group_name }} osImage: ${{ needs.find-latest-image.outputs.image }} - isDebugImage: ${{ inputs.isDebugImage }} + isDebugImage: ${{ github.event.inputs.isDebugImage }} - name: Always terminate cluster if: always() @@ -225,7 +176,7 @@ jobs: if: ${{ failure() && github.ref == 'refs/heads/main' }} run: | sudo apt-get install gettext-base -y - export TEAMS_JOB_NAME="${{ inputs.cloudProvider }} (manual)" + export TEAMS_JOB_NAME="${{ github.event.inputs.cloudProvider }} (manual)" export TEAMS_RUN_ID=${{ github.run_id }} envsubst < teams-payload.json > to-be-send.json curl \ @@ -236,7 +187,7 @@ jobs: working-directory: .github/actions/e2e_test - name: Always destroy Azure resource group - if: ${{ always() && inputs.cloudProvider == 'azure' }} + if: ${{ always() && github.event.inputs.cloudProvider == 'azure' }} shell: bash run: | az group delete \ diff --git a/.github/workflows/generate-measurements.yml b/.github/workflows/generate-measurements.yml index 5ef02a98f..fa0db97ce 100644 --- a/.github/workflows/generate-measurements.yml +++ b/.github/workflows/generate-measurements.yml @@ -15,36 +15,6 @@ on: description: "Sign and upload the measurements?" type: boolean required: true - isRelease: - description: "Is this a release?" - type: boolean - default: false - required: false - ref: - type: string - description: "Git ref to checkout" - required: false - workflow_call: - inputs: - osImage: - description: "Full name of OS image (CSP independent image version UID)." - type: string - required: true - isDebugImage: - description: "Is OS image a debug image?" - type: boolean - required: true - signMeasurements: - description: "Sign and upload the measurements?" - type: boolean - required: true - isRelease: - description: "Is this a release?" - type: boolean - ref: - type: string - description: "Git ref to checkout" - required: false jobs: calculate-measurements-on-csp: @@ -53,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - provider: ["aws", "azure", "gcp", "qemu"] + provider: ["aws", "azure", "gcp"] permissions: id-token: write contents: read @@ -70,13 +40,13 @@ jobs: - name: Check out repository uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Extract ref, stream and version id: extract uses: ./.github/actions/shortname with: - shortname: ${{ inputs.osImage }} + shortname: ${{ github.event.inputs.osImage }} - name: Check if image definition from build pipeline exists run: | @@ -112,7 +82,6 @@ jobs: echo "res_group_name=$name" >> "$GITHUB_OUTPUT" - name: Create Cluster in E2E Test environment - if: matrix.provider != 'qemu' id: create_cluster uses: ./.github/actions/e2e_test with: @@ -128,17 +97,16 @@ jobs: azureClientSecret: ${{ secrets.AZURE_E2E_CLIENT_SECRET }} azureUserAssignedIdentity: ${{ secrets.AZURE_E2E_USER_ASSIGNED_IDENTITY }} azureResourceGroup: ${{ steps.az_resource_group_gen.outputs.res_group_name }} - osImage: ${{ inputs.osImage }} - isDebugImage: ${{ inputs.isDebugImage }} + osImage: ${{ github.event.inputs.osImage }} + isDebugImage: ${{ github.event.inputs.isDebugImage }} test: "nop" - name: Fetch PCRs from running cluster - if: matrix.provider != 'qemu' run: | KUBECONFIG="${PWD}/constellation-admin.conf" kubectl rollout status ds/verification-service -n kube-system --timeout=3m CONSTELL_IP=$(jq -r ".ip" constellation-id.json) mkdir -p "${{ github.workspace }}/generated-measurements" - pcr-reader -constell-ip "${CONSTELL_IP}" -format json -metadata -csp "${{ matrix.provider }}" -image "${{ inputs.osImage }}" > "${{ github.workspace }}/generated-measurements/measurements.json" + pcr-reader -constell-ip "${CONSTELL_IP}" -format json -metadata -csp "${{ matrix.provider }}" -image "${{ github.event.inputs.osImage }}" > "${{ github.workspace }}/generated-measurements/measurements.json" echo "All PCRs of current boot:" cat "${{ github.workspace }}/generated-measurements/measurements.json" case ${CSP} in @@ -191,33 +159,6 @@ jobs: env: CSP: ${{ matrix.provider }} - - name: Set PCRs for QEMU - if: matrix.provider == 'qemu' - env: - ref: ${{ steps.extract.outputs.ref }} - stream: ${{ steps.extract.outputs.stream }} - version: ${{ steps.extract.outputs.version }} - run: | - path="constellation/v1/ref/${ref}/stream/${stream}/${version}/image/csp/${{ matrix.provider }}/measurements.image.json" - mkdir -p "${{ github.workspace }}/generated-measurements" - wget -O ${{ github.workspace }}/generated-measurements/measurements.image.json "https://cdn.confidential.cloud/${path}" - jq '.measurements' < ${{ github.workspace }}/generated-measurements/measurements.image.json | jq '{"measurements": .}' > ${{ github.workspace }}/generated-measurements/measurements.json - cat "${{ github.workspace }}/generated-measurements/measurements.json" - yq ' - .csp = "QEMU" | - .image = "${{ steps.extract.outputs.version }}" | - .measurements.4.warnOnly = false | - .measurements.8.warnOnly = false | - .measurements.9.warnOnly = false | - .measurements.11.warnOnly = false | - .measurements.12.warnOnly = false | - .measurements.13.warnOnly = false | - .measurements.15.warnOnly = false | - .measurements.15.expected = "0000000000000000000000000000000000000000000000000000000000000000"' \ - -I 0 -o json -i "${{ github.workspace }}/generated-measurements/measurements.json" - mv "${{ github.workspace }}/generated-measurements/measurements.json" "${{ github.workspace }}/generated-measurements/measurements-${{ matrix.provider }}.json" - shell: bash - - name: Upload measurements as artifact uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 with: @@ -225,7 +166,7 @@ jobs: path: "${{ github.workspace }}/generated-measurements" - name: Always terminate cluster - if: always() && matrix.provider != 'qemu' + if: always() continue-on-error: true uses: ./.github/actions/constellation_destroy with: @@ -249,12 +190,12 @@ jobs: strategy: fail-fast: false matrix: - provider: ["aws", "azure", "gcp", "qemu"] + provider: ["aws", "azure", "gcp"] steps: - name: Check out repository uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Setup Go environment uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 @@ -299,7 +240,7 @@ jobs: strategy: fail-fast: false matrix: - provider: ["aws", "azure", "gcp", "qemu"] + provider: ["aws", "azure", "gcp"] permissions: id-token: write contents: read @@ -323,9 +264,9 @@ jobs: - name: Sign measurements shell: bash env: - COSIGN_PUBLIC_KEY: ${{ inputs.isRelease && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} - COSIGN_PRIVATE_KEY: ${{ inputs.isRelease && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} - COSIGN_PASSWORD: ${{ inputs.isRelease && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} + COSIGN_PUBLIC_KEY: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PUBLIC_KEY || secrets.COSIGN_DEV_PUBLIC_KEY }} + COSIGN_PRIVATE_KEY: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PRIVATE_KEY || secrets.COSIGN_DEV_PRIVATE_KEY }} + COSIGN_PASSWORD: ${{ startsWith(github.ref, 'refs/heads/release/v') && secrets.COSIGN_PASSWORD || secrets.COSIGN_DEV_PASSWORD }} run: | echo "${COSIGN_PUBLIC_KEY}" > cosign.pub # Enabling experimental mode also publishes signature to Rekor @@ -353,7 +294,7 @@ jobs: strategy: fail-fast: false matrix: - provider: ["aws", "azure", "gcp", "qemu"] + provider: ["aws", "azure", "gcp"] permissions: id-token: write contents: read diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index ec4c77577..ab415d1c7 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -2,17 +2,6 @@ name: Build CLI and prepare release on: workflow_dispatch: - inputs: - ref: - type: string - description: "Git ref to checkout" - required: false - workflow_call: - inputs: - ref: - type: string - description: "Git ref to checkout" - required: true jobs: build-cli: @@ -27,7 +16,7 @@ jobs: id: checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Setup Go environment uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: @@ -96,7 +85,7 @@ jobs: id: checkout uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: - ref: ${{ inputs.ref || github.head_ref }} + ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }} - name: Download syft & grype run: | SYFT_VERSION=0.62.1 @@ -247,7 +236,6 @@ jobs: uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 with: draft: true - generate_release_notes: true files: | constellation-* cosign.pub diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 09cd850ef..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,360 +0,0 @@ -name: Release - -on: - workflow_dispatch: - inputs: - version: - description: "Version to release (e.g. v1.2.3)" - required: true - kind: - description: "Release kind" - type: choice - options: [minor, patch] - required: true - default: "minor" - -jobs: - verify-inputs: - name: Verify inputs - runs-on: ubuntu-22.04 - env: - FULL_VERSION: ${{ inputs.version }} - outputs: - WITHOUT_V: ${{ steps.version-info.outputs.WITHOUT_V }} - PART_MAJOR: ${{ steps.version-info.outputs.PART_MAJOR }} - PART_MINOR: ${{ steps.version-info.outputs.PART_MINOR }} - PART_PATCH: ${{ steps.version-info.outputs.PART_PATCH }} - MAJOR: ${{ steps.version-info.outputs.MAJOR }} - MAJOR_MINOR: ${{ steps.version-info.outputs.MAJOR_MINOR }} - MAJOR_MINOR_PATCH: ${{ steps.version-info.outputs.MAJOR_MINOR_PATCH }} - RELEASE_BRANCH: ${{ steps.version-info.outputs.RELEASE_BRANCH }} - steps: - - name: Verify version - run: | - if [[ ! "${FULL_VERSION}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Version must be in the form of vX.Y.Z" - exit 1 - fi - - name: Extract version info - id: version-info - run: | - WITHOUT_V=${FULL_VERSION#v} - PART_MAJOR=${WITHOUT_V%%.*} - PART_MINOR=${WITHOUT_V#*.} - PART_MINOR=${PART_MINOR%%.*} - PART_PATCH=${WITHOUT_V##*.} - { - echo "WITHOUT_V=${WITHOUT_V}" - echo "PART_MAJOR=${PART_MAJOR}" - echo "PART_MINOR=${PART_MINOR}" - echo "PART_PATCH=${PART_PATCH}" - echo "MAJOR=${PART_MAJOR}" - echo "MAJOR_MINOR=${PART_MAJOR}.${PART_MINOR}" - echo "MAJOR_MINOR_PATCH=${PART_MAJOR}.${PART_MINOR}.${PART_PATCH}" - echo "RELEASE_BRANCH=release/v${PART_MAJOR}.${PART_MINOR}" - } >> "$GITHUB_OUTPUT" - - docs: - name: Create docs release - runs-on: ubuntu-22.04 - if: inputs.kind == 'minor' - needs: verify-inputs - env: - VERSION: ${{ inputs.version }} - MAJOR_MINOR: ${{ needs.verify-inputs.outputs.MAJOR_MINOR }} - BRANCH: docs/${{ needs.verify-inputs.outputs.MAJOR_MINOR }} - steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - with: - ref: ${{ github.head_ref }} - - name: Create docs branch - run: | - git fetch - git pull - git checkout "${BRANCH}" || git checkout -B "${BRANCH}" - - name: Create docs release - working-directory: docs - run: | - npm install - npm run docusaurus docs:version "${MAJOR_MINOR}" - - name: Commit - run: | - git config --global user.name "release[bot]" - git config --global user.email "release[bot]@users.noreply.github.com" - git add docs - git commit -m "Generate docs for ${VERSION}" - git push --set-upstream origin "${BRANCH}" - - name: Create docs pull request - uses: repo-sync/pull-request@65785d95a5a466e46a9d0708933a3bd51bbf9dde # tag=v2.6.2 - with: - source_branch: ${{env.BRANCH}} - destination_branch: "main" - pr_title: "Update docs for ${VERSION}" - pr_body: | - :robot: *This is an automated PR.* :robot: - github_token: ${{ secrets.GITHUB_TOKEN }} - - prepare-release-branch: - name: Prepare release branch - if: inputs.kind == 'minor' - runs-on: ubuntu-22.04 - needs: verify-inputs - env: - BRANCH: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - with: - ref: ${{ github.head_ref }} - - name: Create release branch - run: | - git fetch - git pull - git checkout "${BRANCH}" || git checkout -B "${BRANCH}" - git push origin "${BRANCH}" - - micro-services: - name: Build micro services - needs: [verify-inputs, prepare-release-branch] - uses: ./.github/workflows/build-micro-service-manual.yml - secrets: inherit - strategy: - matrix: - service: - [join-service, kmsserver, verification-service, qemu-metadata-api] - with: - microService: ${{ matrix.service }} - imageTag: ${{ inputs.version }} - version: ${{ needs.verify-inputs.outputs.WITHOUT_V }} - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - release: true - - constellation-node-operator: - name: Build Constellation node-operator - needs: [verify-inputs, prepare-release-branch] - secrets: inherit - uses: ./.github/workflows/build-operator-manual.yml - with: - imageTag: ${{ inputs.version }} - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - release: true - - update-versions: - name: Update container image versions - needs: [verify-inputs, micro-services, constellation-node-operator] - runs-on: ubuntu-22.04 - env: - VERSION: ${{ inputs.version }} - WITHOUT_V: ${{ needs.verify-inputs.outputs.WITHOUT_V }} - steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - with: - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - - name: Install crane - uses: ./.github/actions/setup_crane - - - name: Update enterprise image version - run: | - sed -i "s/defaultImage = \"v[0-9]\+\.[0-9]\+\.[0-9]\+\"/defaultImage = \"${VERSION}\"/" internal/config/images_enterprise.go - git add internal/config/images_enterprise.go - - - name: Update CMakeLists.txt - run: | - sed -i "s/project(constellation LANGUAGES C VERSION [0-9]\+\.[0-9]\+\.[0-9]\+)/project(constellation LANGUAGES C VERSION ${WITHOUT_V})/" CMakeLists.txt - git add CMakeLists.txt - - - name: Update Helm Charts - run: | - yq eval -i ".version = \"${WITHOUT_V}\"" cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml - for service in kms join-service ccm cnm autoscaler verification-service konnectivity gcp-guest-agent; do - yq eval -i "(.dependencies[] | select(.name == \"${service}\")).version = \"${WITHOUT_V}\"" cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml - yq eval -i ".version = \"${WITHOUT_V}\"" "cli/internal/helm/charts/edgeless/constellation-services/charts/${service}/Chart.yaml" - git add "cli/internal/helm/charts/edgeless/constellation-services/charts/${service}/Chart.yaml" - done - git add cli/internal/helm/charts/edgeless/constellation-services/Chart.yaml - yq eval -i ".version = \"${WITHOUT_V}\"" cli/internal/helm/charts/edgeless/operators/Chart.yaml - for service in node-maintenance-operator constellation-operator; do - yq eval -i "(.dependencies[] | select(.name == \"${service}\")).version = \"${WITHOUT_V}\"" cli/internal/helm/charts/edgeless/operators/Chart.yaml - yq eval -i ".version = \"${WITHOUT_V}\"" "cli/internal/helm/charts/edgeless/operators/charts/${service}/Chart.yaml" - git add "cli/internal/helm/charts/edgeless/operators/charts/${service}/Chart.yaml" - done - git add cli/internal/helm/charts/edgeless/operators/Chart.yaml - - - name: Update micro service versions - run: | - for service in node-operator join-service kmsserver verification-service qemu-metadata-api; do - name=ghcr.io/edgelesssys/constellation/${service} - digest=$(crane digest "${name}:${VERSION}") - sed -i "s#\"${name}:v[0-9]\+\.[0-9]\+\.[0-9]\+@sha256:[0-9a-f]\+\"#\"${name}:${VERSION}@${digest}\"#" internal/versions/versions.go - done - git add internal/versions/versions.go - - - name: Commit - run: | - git config --global user.name "release[bot]" - git config --global user.email "release[bot]@users.noreply.github.com" - git commit -m "Update version to ${VERSION}" - git push - - os-image: - name: Build OS image - needs: [verify-inputs, update-versions] - uses: ./.github/workflows/build-os-image.yml - secrets: inherit - with: - imageVersion: ${{ inputs.version }} - isRelease: true - stream: "stable" - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - generate-measurements: - name: Generate OS image measurements - needs: [verify-inputs, os-image] - uses: ./.github/workflows/generate-measurements.yml - secrets: inherit - with: - osImage: ${{ inputs.version }} - isDebugImage: false - signMeasurements: true - isRelease: true - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - update-hardcoded-measurements: - name: Update hardcoded measurements (in the CLI) - needs: [verify-inputs, generate-measurements] - runs-on: ubuntu-22.04 - env: - VERSION: ${{ inputs.version }} - WITHOUT_V: ${{ needs.verify-inputs.outputs.WITHOUT_V }} - steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - with: - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - - name: Setup Go environment - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 - with: - go-version: "1.19.4" - cache: true - - - name: Build generateMeasurements tool - working-directory: internal/attestation/measurements - run: go build -o generateMeasurements -tags=enterprise generateMeasurements.go - - - name: Update hardcoded measurements - working-directory: internal/attestation/measurements - run: | - ./generateMeasurements - git add measurements_enterprise.go - - - name: Commit - run: | - git config --global user.name "release[bot]" - git config --global user.email "release[bot]@users.noreply.github.com" - git commit -m "Hardcode measurements for ${VERSION}" - git push - - e2e-tests: - name: Run E2E tests - needs: [verify-inputs, update-hardcoded-measurements] - secrets: inherit - strategy: - matrix: - csp: [aws, azure, gcp] - uses: ./.github/workflows/e2e-test-manual.yml - with: - workerNodesCount: 2 - controlNodesCount: 3 - cloudProvider: ${{ matrix.csp }} - test: "sonobuoy full" - kubernetesVersion: "1.25" - keepMeasurements: true - osImage: ${{ inputs.version }} - isDebugImage: false - machineType: "default" - git-ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - e2e-tests-macos: - name: Run E2E tests (macOS) - needs: [verify-inputs, update-hardcoded-measurements] - secrets: inherit - strategy: - matrix: - csp: [aws, azure, gcp] - uses: ./.github/workflows/e2e-test-manual-macos.yml - with: - workerNodesCount: 2 - controlNodesCount: 3 - cloudProvider: ${{ matrix.csp }} - test: "sonobuoy full" - kubernetesVersion: "1.25" - keepMeasurements: true - osImage: ${{ inputs.version }} - isDebugImage: false - machineType: "default" - git-ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - e2e-mini: - name: Run E2E tests for mini Constellation - needs: [verify-inputs, update-hardcoded-measurements] - uses: ./.github/workflows/e2e-mini.yml - secrets: inherit - with: - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - tag-release: - name: Tag release - needs: [verify-inputs, e2e-tests, e2e-tests-macos, e2e-mini] - runs-on: ubuntu-22.04 - env: - VERSION: ${{ inputs.version }} - steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - with: - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - - name: Tag release - run: | - git config --global user.name "release[bot]" - git config --global user.email "release[bot]@users.noreply.github.com" - git tag -a "${VERSION}" -m "Release ${VERSION}" - git push origin "refs/tags/${VERSION}" - - draft-release-cli: - name: Draft release (CLI) - needs: [verify-inputs, tag-release] - uses: ./.github/workflows/release-cli.yml - with: - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - pr-get-changes-back-into-main: - name: PR to Merge changes from release branch into main - if: inputs.kind == 'minor' - runs-on: ubuntu-22.04 - needs: [verify-inputs, tag-release] - env: - VERSION: ${{ inputs.version }} - NEW_BRANCH: feat/release/${{ inputs.version }}/changes-to-main - steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3.1.0 - with: - ref: ${{ needs.verify-inputs.outputs.RELEASE_BRANCH }} - - - name: Create branch with changes - run: | - git config --global user.name "release[bot]" - git config --global user.email "release[bot]@users.noreply.github.com" - git fetch - git checkout -b "${NEW_BRANCH}" - git rebase origin/main - git push --set-upstream origin "${NEW_BRANCH}" - - - name: Create docs pull request - uses: repo-sync/pull-request@65785d95a5a466e46a9d0708933a3bd51bbf9dde # tag=v2.6.2 - with: - source_branch: ${{ env.NEW_BRANCH }} - destination_branch: "main" - pr_title: "Bring back changes from release branch ${VERSION}" - pr_body: | - :robot: *This is an automated PR.* :robot: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/image/measured-boot/pcr-stable.json b/image/measured-boot/pcr-stable.json index 5530ceabc..a135153cd 100755 --- a/image/measured-boot/pcr-stable.json +++ b/image/measured-boot/pcr-stable.json @@ -1,16 +1,8 @@ { "measurements": { - "8": { - "expected": "0000000000000000000000000000000000000000000000000000000000000000" - }, - "11": { - "expected": "0000000000000000000000000000000000000000000000000000000000000000" - }, - "13": { - "expected": "0000000000000000000000000000000000000000000000000000000000000000" - }, - "15": { - "expected": "0000000000000000000000000000000000000000000000000000000000000000" - } + "8": "0000000000000000000000000000000000000000000000000000000000000000", + "11": "0000000000000000000000000000000000000000000000000000000000000000", + "13": "0000000000000000000000000000000000000000000000000000000000000000", + "15": "0000000000000000000000000000000000000000000000000000000000000000" } } diff --git a/image/measured-boot/precalculate_pcr_12.sh b/image/measured-boot/precalculate_pcr_12.sh index 6f0d02b68..d39372942 100755 --- a/image/measured-boot/precalculate_pcr_12.sh +++ b/image/measured-boot/precalculate_pcr_12.sh @@ -35,9 +35,7 @@ write_output() { cat > "${out}" << EOF { "measurements": { - "12": { - "expected": "${expected_pcr_12}" - } + "12": "${expected_pcr_12}" }, "cmdline": "${cmdline}", "cmdline-sha256": "${cmdline_hash}" diff --git a/image/measured-boot/precalculate_pcr_4.sh b/image/measured-boot/precalculate_pcr_4.sh index c2e04535c..b5afa7a2d 100755 --- a/image/measured-boot/precalculate_pcr_4.sh +++ b/image/measured-boot/precalculate_pcr_4.sh @@ -23,9 +23,7 @@ write_output() { cat > "${out}" << EOF { "measurements": { - "4": { - "expected": "${expected_pcr_4}" - } + "4": "${expected_pcr_4}" }, "efistages": [ { diff --git a/image/measured-boot/precalculate_pcr_9.sh b/image/measured-boot/precalculate_pcr_9.sh index c0ad8a869..19dcf6cf1 100755 --- a/image/measured-boot/precalculate_pcr_9.sh +++ b/image/measured-boot/precalculate_pcr_9.sh @@ -28,9 +28,7 @@ write_output() { cat > "${out}" << EOF { "measurements": { - "9": { - "expected": "${expected_pcr_9}" - } + "9": "${expected_pcr_9}" }, "initrd-sha256": "${initrd_hash}" } diff --git a/internal/attestation/measurements/generateMeasurements.go b/internal/attestation/measurements/generateMeasurements.go deleted file mode 100644 index fa7a435d5..000000000 --- a/internal/attestation/measurements/generateMeasurements.go +++ /dev/null @@ -1,258 +0,0 @@ -//go:build ignore - -/* -Copyright (c) Edgeless Systems GmbH -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package main - -import ( - "bytes" - "context" - "encoding/base64" - "fmt" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "log" - "net/http" - "net/url" - "os" - "path" - "sort" - "strconv" - "strings" - - "github.com/edgelesssys/constellation/v2/internal/attestation/measurements" - "github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider" - "github.com/edgelesssys/constellation/v2/internal/config" - "github.com/edgelesssys/constellation/v2/internal/constants" - "github.com/edgelesssys/constellation/v2/internal/shortname" - "github.com/edgelesssys/constellation/v2/internal/sigstore" - "golang.org/x/tools/go/ast/astutil" -) - -const byteArrayCompositeLitWidth = 235 - -func mustGetMeasurements(ctx context.Context, verifier rekorVerifier, cosignPublicKey []byte, client *http.Client, provider cloudprovider.Provider, image string) measurements.M { - measurementsURL, err := measurementURL(provider, image, "measurements.json") - if err != nil { - panic(err) - } - signatureURL, err := measurementURL(provider, image, "measurements.json.sig") - if err != nil { - panic(err) - } - - log.Println("Fetching measurements from", measurementsURL, "and signature from", signatureURL) - var fetchedMeasurements measurements.M - hash, err := fetchedMeasurements.FetchAndVerify( - ctx, client, - measurementsURL, - signatureURL, - cosignPublicKey, - measurements.WithMetadata{ - CSP: provider, - Image: image, - }, - ) - if err != nil { - panic(err) - } - if err := verifyWithRekor(ctx, verifier, hash); err != nil { - panic(err) - } - return fetchedMeasurements -} - -func measurementURL(provider cloudprovider.Provider, image, file string) (*url.URL, error) { - ref, stream, version, err := shortname.ToParts(image) - if err != nil { - return nil, fmt.Errorf("parsing image name: %w", err) - } - url, err := url.Parse(constants.CDNRepositoryURL) - if err != nil { - return nil, fmt.Errorf("parsing image version repository URL: %w", err) - } - url.Path = path.Join(constants.CDNAPIPrefix, "ref", ref, "stream", stream, version, "image", "csp", strings.ToLower(provider.String()), file) - return url, nil -} - -func verifyWithRekor(ctx context.Context, verifier rekorVerifier, hash string) error { - uuids, err := verifier.SearchByHash(ctx, hash) - if err != nil { - return fmt.Errorf("searching Rekor for hash: %w", err) - } - - if len(uuids) == 0 { - return fmt.Errorf("no matching entries in Rekor") - } - - // We expect the first entry in Rekor to be our original entry. - // SHA256 should ensure there is no entry with the same hash. - // Any subsequent hashes are treated as potential attacks and are ignored. - // Attacks on Rekor will be monitored from other backend services. - artifactUUID := uuids[0] - - return verifier.VerifyEntry( - ctx, artifactUUID, - base64.StdEncoding.EncodeToString([]byte(constants.CosignPublicKey)), - ) -} - -func byteArrayCompositeLit(hex [32]byte, pos token.Pos) *ast.CompositeLit { - var elts []ast.Expr - curPos := pos + 16 // 16 = len("[32]byte{") + padding - for i, b := range hex { - elts = append(elts, &ast.BasicLit{ - ValuePos: curPos, - Kind: token.INT, - Value: fmt.Sprintf("0x%02x", b), - }) - if (i+1)%8 == 0 { - curPos += 11 // line break - } else { - curPos += 6 // 6 = len("0x00, ") - } - } - return &ast.CompositeLit{ - Type: &ast.ArrayType{ - Lbrack: pos, - Len: ast.NewIdent("32"), - Elt: ast.NewIdent("byte"), - }, - Lbrace: pos + 8, // 8 = len("[32]byte") - Elts: elts, - Rbrace: pos + 223, // 223 = len("[32]byte{0x00, 0x01, ...}") - 1 - } -} - -func measurementsEntryKeyValueExpr(pcr uint32, measuremnt measurements.Measurement, pos token.Pos) (*ast.KeyValueExpr, token.Pos) { - key := fmt.Sprintf("%d", pcr) - keyLen := len(key) - colon := pos + token.Pos(keyLen) - valuePos := token.Pos(colon + 2) - expectedKeyPos := token.Pos(valuePos + 5) - expectedColon := token.Pos(expectedKeyPos + 8) - expectedValuePos := token.Pos(expectedColon + 2) - warnOnlyKeyPos := token.Pos(expectedColon + 1 + byteArrayCompositeLitWidth) - warnOnlyColon := token.Pos(warnOnlyKeyPos + 9) - warnOnlyValuePos := token.Pos(warnOnlyColon + 2) - var rbrace token.Pos - if measuremnt.WarnOnly { - rbrace = token.Pos(warnOnlyValuePos + 9) // 9 = len("true") + padding - } else { - rbrace = token.Pos(warnOnlyValuePos + 10) // 10 = len("false") + padding - } - - return &ast.KeyValueExpr{ - Key: &ast.BasicLit{ - ValuePos: pos, - Kind: token.INT, - Value: key, - }, - Colon: colon, - Value: &ast.CompositeLit{ - // Type: ast.NewIdent("Measurement"), - Lbrace: valuePos, - Elts: []ast.Expr{ - &ast.KeyValueExpr{ - Key: &ast.Ident{NamePos: expectedKeyPos, Name: "Expected"}, - Colon: expectedColon, - Value: byteArrayCompositeLit(measuremnt.Expected, expectedValuePos), - }, - &ast.KeyValueExpr{ - Key: &ast.Ident{NamePos: warnOnlyKeyPos, Name: "WarnOnly"}, - Colon: warnOnlyColon, - Value: &ast.Ident{NamePos: warnOnlyValuePos, Name: strconv.FormatBool(measuremnt.WarnOnly)}, - }, - }, - Rbrace: rbrace, - }, - }, rbrace + 1 -} - -func measurementsCompositeLiteral(measurements measurements.M, pos token.Pos) *ast.CompositeLit { - lbrace := pos + 1 - var elts []ast.Expr - pcrs := make([]uint32, 0, len(measurements)) - for pcr := range measurements { - pcrs = append(pcrs, pcr) - } - sort.Slice(pcrs, func(i, j int) bool { return pcrs[i] < pcrs[j] }) - entryPos := lbrace + 5 - for _, pcr := range pcrs { - kvExpr, newEntryPos := measurementsEntryKeyValueExpr(pcr, measurements[pcr], entryPos) - elts = append(elts, kvExpr) - entryPos = newEntryPos + 4 // 4 = padding and newline - } - return &ast.CompositeLit{ - Lbrace: lbrace, - Type: &ast.Ident{ - NamePos: pos, - Name: "M", - }, - Elts: elts, - Rbrace: entryPos - 1, - } -} - -func main() { - defaultConf := config.Default() - log.Printf("Generating measurements for %s\n", defaultConf.Image) - - const filePath = "./measurements_enterprise.go" - - ctx := context.Background() - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments) - if err != nil { - log.Fatal(err) - } - rekor, err := sigstore.NewRekor() - if err != nil { - log.Fatal(err) - } - newFile := astutil.Apply(file, func(cursor *astutil.Cursor) bool { - n := cursor.Node() - - if clause, ok := n.(*ast.CaseClause); ok && len(clause.List) > 0 && len(clause.Body) > 0 { - sel, ok := clause.List[0].(*ast.SelectorExpr) - if !ok { - return true - } - returnStmt, ok := clause.Body[0].(*ast.ReturnStmt) - if !ok || len(returnStmt.Results) == 0 { - return true - } - - provider := cloudprovider.FromString(sel.Sel.Name) - if provider == cloudprovider.Unknown { - return true - } - log.Println("Found", provider) - measuremnts := mustGetMeasurements(ctx, rekor, []byte(constants.CosignPublicKey), http.DefaultClient, provider, defaultConf.Image) - returnStmt.Results[0] = measurementsCompositeLiteral(measuremnts, returnStmt.Return+7) - } - return true - }, nil, - ) - - var buf bytes.Buffer - printConfig := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8} - - if err = printConfig.Fprint(&buf, fset, newFile); err != nil { - log.Fatalf("error formatting file %s: %s", filePath, err) - } - if err := os.WriteFile(filePath, buf.Bytes(), 0o644); err != nil { - log.Fatalf("error writing file %s: %s", filePath, err) - } - log.Println("Successfully generated hashes.") -} - -type rekorVerifier interface { - SearchByHash(context.Context, string) ([]string, error) - VerifyEntry(context.Context, string, string) error -}