diff --git a/.github/actions/test/integration/build/action.yml b/.github/actions/test/integration/build/action.yml index adcf018c..447de18c 100644 --- a/.github/actions/test/integration/build/action.yml +++ b/.github/actions/test/integration/build/action.yml @@ -11,7 +11,7 @@ runs: - name: Set ENV shell: bash env: - REPO: ghcr.io/gardenlinux/gardenlinux-ccloud + REPO: ghcr.io/gardenlinux/gardenlinux-sci TAG: ${{ inputs.image_tag }} ESP_SIZE: 2 # GiB DISK_SIZE: 8 # GiB @@ -99,12 +99,21 @@ runs: chmod 600 /opt/ssh_host_ed25519_key SSH_KEY=$(cat /opt/ssh_host_ed25519_key.pub) echo "SSH_KEY=$SSH_KEY" >> $GITHUB_ENV - sed -i "s|SSH_KEY_GOES_HERE|$SSH_KEY|g" ./.github/actions/test/integration/build/dev-user-butane.yaml + cp ./.github/actions/test/integration/build/dev-user-butane.yaml ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + yq '.storage.files += load("./.github/actions/test/integration/build/root-hints.yaml")' ./.github/actions/test/integration/build/dev-user-butane.yaml > ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml + + sed -i "s|SSH_KEY_GOES_HERE|$SSH_KEY|g" ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + sed -i "s|SSH_KEY_GOES_HERE|$SSH_KEY|g" ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml + PASSWORD=$(openssl passwd "password") echo "PASSWORD=$PASSWORD" >> $GITHUB_ENV - sed -i "s|PASSWORD_GOES_HERE|$PASSWORD|g" ./.github/actions/test/integration/build/dev-user-butane.yaml - sed -i "s|TAG_GOES_HERE|${{ inputs.image_tag }}|g" ./.github/actions/test/integration/build/dev-user-butane.yaml - butane --pretty --strict ./.github/actions/test/integration/build/dev-user-butane.yaml > "/opt/${TAG}.ign" + sed -i "s|PASSWORD_GOES_HERE|$PASSWORD|g" ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + sed -i "s|PASSWORD_GOES_HERE|$PASSWORD|g" ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml + sed -i "s|TAG_GOES_HERE|${{ inputs.image_tag }}|g" ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml + sed -i "s|TAG_GOES_HERE|${{ inputs.image_tag }}|g" ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml + + butane --pretty --strict ./.github/actions/test/integration/build/dev-user-butane-hv1.yaml > "/opt/${TAG}-hv1.ign" + butane --pretty --strict ./.github/actions/test/integration/build/dev-user-butane-hv2.yaml > "/opt/${TAG}-hv2.ign" - name: Download ubuntu cloud image shell: bash @@ -126,7 +135,7 @@ runs: # - name: Upload artifacts # uses: actions/upload-artifact@v4 # with: - # name: gardenlinux-ccloud-${{ inputs.image_tag }} + # name: gardenlinux-sci-${{ inputs.image_tag }} # path: /opt/${{ inputs.image_tag }}.* # retention-days: 1 # overwrite: true diff --git a/.github/actions/test/integration/build/dev-user-butane.yaml b/.github/actions/test/integration/build/dev-user-butane.yaml index b8486454..ac08d4a1 100644 --- a/.github/actions/test/integration/build/dev-user-butane.yaml +++ b/.github/actions/test/integration/build/dev-user-butane.yaml @@ -1,5 +1,5 @@ variant: fcos -version: 1.3.0 +version: 1.7.0 passwd: users: - name: root @@ -37,12 +37,6 @@ storage: # custom 192.168.122.2 hv1 192.168.122.3 hv2 - - path: /opt/persist/root-hints.yaml - mode: 0644 - contents: - inline: | - hints: - - size: lt 500G # turn off hugepages, not required for this test # also SIGNIFICANTLY reduces test runtime - path: /opt/persist/hugepages.env @@ -55,7 +49,7 @@ storage: contents: inline: | # pull the image from GHCR instead of keppel - OCI_REPO=ghcr.io/gardenlinux/gardenlinux-ccloud + OCI_REPO=ghcr.io/gardenlinux/gardenlinux-sci # point to a custom tag to download for the persist step OCI_TAG=TAG_GOES_HERE # Enable unlimited core dumps for all systemd services @@ -85,3 +79,10 @@ storage: kernel.core_pattern=|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h kernel.core_pipe_limit=16 fs.suid_dumpable=2 +# Disable libvirt sockets not required for CI tests +systemd: + units: + - name: libvirtd-tls.socket + mask: true + - name: libvirtd-tcp.socket + mask: true diff --git a/.github/actions/test/integration/build/root-hints.yaml b/.github/actions/test/integration/build/root-hints.yaml new file mode 100644 index 00000000..59159664 --- /dev/null +++ b/.github/actions/test/integration/build/root-hints.yaml @@ -0,0 +1,6 @@ +- path: /opt/persist/root-hints.yaml + mode: 0644 + contents: + inline: | + hints: + - size: lt 500G diff --git a/.github/actions/test/integration/dependencies/action.yml b/.github/actions/test/integration/dependencies/action.yml index e1923df9..65fb700c 100644 --- a/.github/actions/test/integration/dependencies/action.yml +++ b/.github/actions/test/integration/dependencies/action.yml @@ -34,7 +34,7 @@ runs: - name: butane shell: bash run: | - BUTANE_VERSION="0.24.0" + BUTANE_VERSION="0.27.0" curl -LO "https://github.com/coreos/butane/releases/download/v${BUTANE_VERSION}/butane-x86_64-unknown-linux-gnu" chmod +x "butane-x86_64-unknown-linux-gnu" sudo mv "butane-x86_64-unknown-linux-gnu" /usr/local/bin/butane diff --git a/.github/actions/test/integration/setup/action.yml b/.github/actions/test/integration/setup/action.yml index 915b282b..1b8b1bea 100644 --- a/.github/actions/test/integration/setup/action.yml +++ b/.github/actions/test/integration/setup/action.yml @@ -15,7 +15,8 @@ runs: - name: Copy ignition file shell: bash run: | - sudo cp "/opt/${TAG}.ign" /var/lib/libvirt/images/hv.ign + sudo cp "/opt/${TAG}-hv1.ign" /var/lib/libvirt/images/HV1.ign + sudo cp "/opt/${TAG}-hv2.ign" /var/lib/libvirt/images/HV2.ign - name: Create HyperVisor 1 shell: bash diff --git a/.github/actions/test/integration/setup/hv.xml b/.github/actions/test/integration/setup/hv.xml index 90ab559f..c8f6f0d8 100644 --- a/.github/actions/test/integration/setup/hv.xml +++ b/.github/actions/test/integration/setup/hv.xml @@ -15,7 +15,7 @@ - + @@ -32,6 +32,6 @@ - + diff --git a/.github/actions/test/integration/test/qemu/vm.xml b/.github/actions/test/integration/test/qemu/vm.xml index 3626dc12..1fe453b8 100644 --- a/.github/actions/test/integration/test/qemu/vm.xml +++ b/.github/actions/test/integration/test/qemu/vm.xml @@ -15,12 +15,12 @@ - + - + - + diff --git a/.github/scripts/compute-image-tag.sh b/.github/scripts/compute-image-tag.sh new file mode 100755 index 00000000..d0c9c389 --- /dev/null +++ b/.github/scripts/compute-image-tag.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Computes the OCI image tag for Garden Linux ccloud images +# +# This script centralizes the image tag format computation to ensure consistency +# across all workflows (nightly, dev, upload_oci). +# +# Usage: +# ./compute-image-tag.sh [flavor] +# +# Arguments: +# version - The version for the tag (e.g., "1877.10.1", "pr-123") +# flavor - The image flavor (e.g., "metal-sci-usi-amd64"). Defaults to "metal-sci-usi-amd64". +# +# Environment: +# GITHUB_SHA - Git commit SHA (required, set automatically by GitHub Actions) +# +# Output: +# Prints the computed image tag to stdout +# +# Tag format: +# {version}-{flavor}-{dashed_version}-{commit_sha_short} +# +# Examples: +# ./compute-image-tag.sh "1877.10.1" +# # Output: 1877.10.1-metal-sci-usi-amd64-1877-10-1-abcd1234 +# +# ./compute-image-tag.sh "pr-123" "metal-capi-amd64" +# # Output: pr-123-metal-capi-amd64-pr-123-abcd1234 + +set -euo pipefail + +VERSION="${1:?Error: VERSION argument required}" +FLAVOR="${2:-metal-sci-usi-amd64}" + +if [ -z "${GITHUB_SHA:-}" ]; then + echo "Error: GITHUB_SHA environment variable is required" >&2 + exit 1 +fi + +COMMIT_SHA="${GITHUB_SHA::8}" +DASHED_VERSION="${VERSION//./-}" + +IMAGE_TAG="${VERSION}-${FLAVOR}-${DASHED_VERSION}-${COMMIT_SHA}" + +echo "$IMAGE_TAG" diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 6dc97a4b..9fff5f5b 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -3,6 +3,7 @@ on: push: branches: - main + - rel-1877-dev paths-ignore: - "**/README.md" - "docs/**" @@ -11,6 +12,13 @@ on: paths-ignore: - "**/README.md" - "docs/**" + +# Cancel any in-progress PR workflow runs when PR is closed +# Used to ensure cleanup runs after any PR build are uploaded (or aborts before the upload) +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event.action == 'closed' }} + jobs: set_version: if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} @@ -19,30 +27,25 @@ jobs: VERSION: ${{ steps.version.outputs.VERSION }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: submodules: recursive - name: use VERSION file to support dev build on rel-branch id: version run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "VERSION=today" >> $GITHUB_OUTPUT - else - echo "VERSION=$(cat VERSION)" >> $GITHUB_OUTPUT - fi + echo "VERSION=$(cat VERSION)" >> $GITHUB_OUTPUT build: needs: [set_version] if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} - uses: gardenlinux/gardenlinux/.github/workflows/build.yml@40e7dfa820cb8bd5e0317779f818d31464c18c63 + uses: gardenlinux/gardenlinux/.github/workflows/build.yml@409e9b640087ade203321a8d63bd1651f4677205 with: version: ${{ needs.set_version.outputs.VERSION }} # to set target to "release" or "nightly" we need proper KMS secrets # have a look at gardenlinux/.github/workflows/github.mjs target: dev fail_fast: true - platform_test_build: false # secrets: # aws_region: ${{ secrets.AWS_REGION }} # aws_kms_role: ${{ secrets.KMS_SIGNING_IAM_ROLE }} @@ -55,16 +58,18 @@ jobs: runs-on: ubuntu-latest outputs: UPLOAD_VERSION: ${{ steps.meta.outputs.upload_version }} - COMMIT_SHA: ${{ steps.meta.outputs.sha }} + image_tag: ${{ steps.meta.outputs.image_tag }} steps: - - name: Derive image version + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Compute image metadata id: meta run: | PR_NUMBER=${{ github.event.pull_request.number }} UPLOAD_VERSION="pr-${PR_NUMBER}" echo "upload_version=${UPLOAD_VERSION}" >> $GITHUB_OUTPUT - SHA="${GITHUB_SHA::8}" - echo "sha=${SHA}" >> $GITHUB_OUTPUT + IMAGE_TAG=$(.github/scripts/compute-image-tag.sh "${UPLOAD_VERSION}") + echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT upload: name: Upload PR image to OCI @@ -83,7 +88,7 @@ jobs: if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.action != 'closed' }} uses: ./.github/workflows/test.yml with: - image_tag: "${{ needs.meta.outputs.UPLOAD_VERSION }}-metal-sci-usi-amd64-${{ needs.meta.outputs.UPLOAD_VERSION }}-${{ needs.meta.outputs.COMMIT_SHA }}" + image_tag: ${{ needs.meta.outputs.image_tag }} cleanup_images: name: Cleanup PR images @@ -104,7 +109,7 @@ jobs: response=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-ccloud/versions?per_page=$page_size&page=$page") + "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-sci/versions?per_page=$page_size&page=$page") page_ids=$(echo "$response" | jq -r --arg prefix "${UPLOAD_VERSION}" ' .[] | select(.metadata.container.tags[]? | test("^" + $prefix + "(-.*)?$")) | .id @@ -133,7 +138,7 @@ jobs: -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-ccloud/versions/$version_id") + "https://api.github.com/orgs/gardenlinux/packages/container/gardenlinux-sci/versions/$version_id") if [ "$http_code" != "204" ]; then echo "Failed to delete version $version_id (HTTP $http_code)" fi diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 546d6f74..c6480aa6 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -14,29 +14,49 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: submodules: recursive build: needs: [checkout] - uses: gardenlinux/gardenlinux/.github/workflows/build.yml@40e7dfa820cb8bd5e0317779f818d31464c18c63 + uses: gardenlinux/gardenlinux/.github/workflows/build.yml@409e9b640087ade203321a8d63bd1651f4677205 with: version: ${{ inputs.version || 'now' }} # to set target to "release" or "nightly" we need proper KMS secrets - # have a look at gardenlinux/.github/workflows/github.mjs + # have a look at gardenlinux/.github/workflows/github.mjs target: dev fail_fast: true - platform_test_build: false + #platform_test_build: false # secrets: # aws_region: ${{ secrets.AWS_REGION }} # aws_kms_role: ${{ secrets.KMS_SIGNING_IAM_ROLE }} # aws_oidc_session: ${{ secrets.AWS_OIDC_SESSION }} # secureboot_db_kms_arn: ${{ secrets.SECUREBOOT_DB_KMS_ARN }} + meta: + name: Compute image metadata + needs: [build] + runs-on: ubuntu-latest + outputs: + image_tag: ${{ steps.meta.outputs.image_tag }} + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Compute image tag + id: meta + run: | + IMAGE_TAG=$(.github/scripts/compute-image-tag.sh "${{ needs.build.outputs.version }}") + echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT upload_oci: name: Run glcli to publish to OCI needs: [build] # use custom upload_oci.yml as we do not sign the images - # uses: gardenlinux/gardenlinux/.github/workflows/upload_oci.yml@40e7dfa820cb8bd5e0317779f818d31464c18c63 + # uses: gardenlinux/gardenlinux/.github/workflows/upload_oci.yml@409e9b640087ade203321a8d63bd1651f4677205 uses: ./.github/workflows/upload_oci.yml with: version: ${{ needs.build.outputs.version }} + test: + name: Test nightly image + needs: [meta, upload_oci] + uses: ./.github/workflows/test.yml + with: + image_tag: ${{ needs.meta.outputs.image_tag }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ea9abc1f..87ecf16f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,19 +1,11 @@ name: test hypervisor capabilities on: - push: - branches: - - feat/ci-test-cloud-hypervisor - workflow_run: - workflows: - - nightly - types: - - completed workflow_dispatch: inputs: image_tag: description: "Image tag to test (must be usi-sci)" type: string - default: "" + required: true workflow_call: inputs: image_tag: @@ -26,20 +18,31 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Install oras + uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2 + with: + version: 1.2.2 + - name: Validate image tag + run: | + if [ -z "${{ inputs.image_tag }}" ]; then + echo "Error: image_tag is required" + exit 1 + fi + + echo "Verifying image ${{ inputs.image_tag }} exists in GHCR..." + if ! digest=$(oras resolve ghcr.io/gardenlinux/gardenlinux-sci:${{ inputs.image_tag }} 2>&1); then + echo "Error: Image tag '${{ inputs.image_tag }}' not found in ghcr.io/gardenlinux/gardenlinux-sci" + echo "Resolve output: $digest" + exit 1 + fi + echo "Image tag present in GHCR (digest: ${digest:0:12}...)" - name: Install Dependencies uses: ./.github/actions/test/integration/dependencies - - name: Obtain newest Tag from GHCR - id: fetch_tag - if: ${{ inputs.image_tag == '' || github.event_name == 'workflow_run' || github.event_name == 'push' }} - run: | - latest_tag=$(oras repo tags ghcr.io/gardenlinux/gardenlinux-ccloud | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-metal-sci-usi-amd64-[0-9]+-[0-9]+-[0-9]-[0-9a-f]{8}$' | sort -r | head -n 1) - echo $latest_tag - echo "latest_tag=$latest_tag" >> $GITHUB_ENV - name: Build uses: ./.github/actions/test/integration/build with: - image_tag: ${{ env.latest_tag || inputs.image_tag }} + image_tag: ${{ inputs.image_tag }} - name: Setup uses: ./.github/actions/test/integration/setup - name: Test QEMU diff --git a/.github/workflows/upload_oci.yml b/.github/workflows/upload_oci.yml index 896e2495..e32154f1 100644 --- a/.github/workflows/upload_oci.yml +++ b/.github/workflows/upload_oci.yml @@ -14,7 +14,7 @@ on: jobs: generate_matrix_publish: name: Generate flavors matrix to publish - uses: gardenlinux/gardenlinux/.github/workflows/build_flavors_matrix.yml@40e7dfa820cb8bd5e0317779f818d31464c18c63 + uses: gardenlinux/gardenlinux/.github/workflows/build_flavors_matrix.yml@409e9b640087ade203321a8d63bd1651f4677205 with: flags: '${{ inputs.flavor_filter }} --no-arch --json-by-arch --build --test' upload_gl_artifacts: @@ -37,14 +37,14 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # pin@v4.1.1 with: submodules: true - - uses: oras-project/setup-oras@v1 + - uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2 - run: oras version - name: Install python-gardenlinux-lib - uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@hotfix-disabled-python-cache-in-setup-action + uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@19c1b24c01faab81a7fe24713748dd172d00904a - name: Install cosign - uses: sigstore/cosign-installer@v3.9.1 + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 with: - cosign-release: 'v2.4.1' + cosign-release: 'v3.1.3' - name: Set flavor version reference run: | git rev-parse HEAD | cut -c1-8 | tee COMMIT @@ -118,7 +118,7 @@ jobs: with: submodules: true - name: Install python-gardenlinux-lib - uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@hotfix-disabled-python-cache-in-setup-action + uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@19c1b24c01faab81a7fe24713748dd172d00904a - name: Set flavor version reference run: | git rev-parse HEAD | cut -c1-8 | tee COMMIT @@ -138,7 +138,7 @@ jobs: mkdir manifests mv oci_manifest_entry_${CNAME}.json manifests/ - gl-oci update-index \ - --container "ghcr.io/${{ github.repository }}" \ - --version ${{ inputs.upload_version || inputs.version }} \ + gl-oci push-index-from-directory \ + --index "ghcr.io/${{ github.repository }}" \ + --index-tag ${{ inputs.upload_version || inputs.version }} \ --manifest_folder manifests diff --git a/Containerfile b/Containerfile new file mode 100644 index 00000000..edd1ecce --- /dev/null +++ b/Containerfile @@ -0,0 +1,3 @@ +FROM ghcr.io/gardenlinux/builder:d6d24ba1aec66889a2acab83aedcb00e869abfcd@sha256:3dc78daebb56605baf105d2f20a6e8b94137237c1c2587b80d571fbb5c9f49ab + +RUN sed 's/version="$2"/version=\$(echo \$2 | cut -d. -f 1-2)/' -i /builder/bootstrap diff --git a/README.md b/README.md index 5d4d29bc..77b14dc7 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,7 @@ The following make targets are available: - `prepare`: Initialize and update submodules, required for first-time setup - `update [COMMIT=]`: Update Garden Linux submodule to latest (or specific) commit and sync workflow references - `clean`: Remove Garden Linux submodule and reset the environment + +

+ Bundesministerium für Wirtschaft und Energie (BMWE)-EU funding logo +

diff --git a/VERSION b/VERSION deleted file mode 120000 index e96da460..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -gardenlinux/VERSION \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..161eda4d --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1877.21.0 diff --git a/bin/flavors_parse.py b/bin/flavors_parse.py new file mode 120000 index 00000000..8c2e0e41 --- /dev/null +++ b/bin/flavors_parse.py @@ -0,0 +1 @@ +../gardenlinux/bin/flavors_parse.py \ No newline at end of file diff --git a/bin/garden-version b/bin/garden-version deleted file mode 120000 index d88969eb..00000000 --- a/bin/garden-version +++ /dev/null @@ -1 +0,0 @@ -../gardenlinux/bin/garden-version \ No newline at end of file diff --git a/bin/garden-version b/bin/garden-version new file mode 100755 index 00000000..48c2b777 --- /dev/null +++ b/bin/garden-version @@ -0,0 +1,155 @@ +#!/usr/bin/env bash + +# Contains sources from https://github.com/debuerreotype/debuerreotype + +set -Eeuo pipefail +# shellcheck disable=2128 +thisDir="$(dirname "$(readlink -f "${BASH_SOURCE}")")" +versionfile="$(readlink -f "${thisDir}/../VERSION")" +startdate="Mar 31 00:00:00 UTC 2020" +build_os="$(uname -s)" + +function check_command() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "Error: The binary '$1' could not be found. Please make sure to install it." >&2 + exit 1 + fi +} + +# Use "gdate" & sed (GNU) which must be installed by "Homebrew" +# on macOS systems to have a normalized date interface +if [ "Darwin" == "$build_os" ]; then + date_gnu="gdate" + sed_gnu="gsed" +else + date_gnu="date" + sed_gnu="sed" +fi +check_command "$date_gnu" +check_command "$sed_gnu" + +# shellcheck disable=1091 +source "${thisDir}/.constants.sh" \ + --flags 'major,minor,patch,date,datefull,epoch,git' \ + --usage '[ --major | --minor | --patch | --date | --datefull | --epoch | --git ] [|]' \ + --sample '20200427' \ + --sample '--date 27.1' \ + --help "Generates version dependent values according to the file $versionfile or to the parameter handed over. Versions can be converted adequately + +--major prints only the major version +--minor prints only the minor version +--patch prints only the patch/patch version +--date prints the date according to the version e.g. 20200427 if garden-version=27 +--datefull prints a full date deteministically usable by debootstrap +--epoch prints the seconds sinc 19700101 till garden-version +--git prints the version plus the last git-hash + +If no parameter is specified the full version . e.g. 27.5 is printed. The version is taken from $versionfile. On HEAD this should always evaluate to 'today', on branch versions this always should resolve to the next version that will be build e.g. 27.1. This implies there is no branch with a .0 in the $versionfile file. +The version calculated expresses the days since $startdate. Calculation is always UTC based." + +# shellcheck disable=2154 +eval "${dgetopt}" +typeout="default" +while true; do + flag="$1"; shift + dgetopt-case "${flag}" + case "${flag}" in + --major|--minor|--patch|--date|--datefull|--epoch|--git) + typeout="${flag}" ;; + --) break ;; + *) eusage "unknown flag '${flag}'" ;; + esac +done + +# Checks repo.gardenlinux.io for the highest available suite minor for the given major +function get_minor_from_repo { + minor=0 # running index + limit=100 # hard limit the search in case of unexpected curl results + major=$1 # major to check the latest minor for + repo_url="https://packages.gardenlinux.io/gardenlinux/dists/$major.__MINOR__/InRelease" + while [ $minor -le $limit ] + do + check_url=${repo_url//__MINOR__/$minor} + if curl -s "$check_url" | grep -q "Error"; then + ((minor--)) + echo $minor + return + fi + ((minor++)) + done +} + +function get_patch_from_repo { + # TODO: implement if we really expect that we'll ever have a nonzero micro/patch version + local major=$1 + local minor=$2 + if [ "$minor" -eq -1 ]; then + echo -1 + return + fi + echo 0 + return +} + +function trim_when_old_version { + if [ "$1" == "today" ] || [ "$1" == "experimental" ]; then + echo "$1" + return + fi + # HACK just for 1877 for SCI + # shellcheck disable=2046 + if [ $(echo "$1" | cut -d. -f1) -lt 1876 ]; then + echo "$1" | cut -d. -f1-2 + else + echo "$1" + fi +} + +input="${1:-$($sed_gnu -e "s/#.*\$//" -e "/^$/d" "${versionfile}")}"; shift || true +input=$($sed_gnu "s/^[[:space:]]*//;s/[[:space:]]*\$//" <<< "${input}") + +# no version / timestamp on versionfile +[ -z "${input}" ] && input="today" + +minor=0 +patch=0 +# shellcheck disable=2046 +if [[ "${input}" =~ ^[0-9\.]*$ && $(cut -d. -f1 <<< "${input}") -lt 10000000 ]]; +then [ $(cut -d. -sf4 <<< "${input}") ] && eusage "invalid version format ${input}. should be [..]" + + major="$(cut -d. -f1 <<< "${input}")" + # shellcheck disable=2046 + if [ $(cut -d. -sf2 <<< "${input}") ]; then + minor="$(cut -d. -f2 <<< "${input}")" + else + minor=$(get_minor_from_repo "$major") + fi + # shellcheck disable=2046 + if [ $(cut -d. -sf3 <<< "${input}") ]; then + patch="$(cut -d. -f3 <<< "${input}")" + else + patch=$(get_patch_from_repo "$major" "$minor") + fi + version="${major}.${minor}.${patch}" +else + if [[ ${input} = today ]] || [[ ${input} = experimental ]]; + then indate=$($date_gnu --date "today" +%s 2>/dev/null) + major="$(( ("${indate}" - $($date_gnu --date "${startdate}" +%s)) / (60*60*24) ))" + version=${input} + else indate=$($date_gnu --date "${input}" +%s 2>/dev/null) || eusage "invalid date ${input}" + major="$(( ("${indate}" - $($date_gnu --date "${startdate}" +%s)) / (60*60*24) ))" + version="${major}.${minor}.${patch}" + fi +fi + +# shellcheck disable=2154 +case "${typeout}" in + --major) echo "${major}" ;; + --minor) echo "${minor}" ;; + --patch) echo "${patch}" ;; + --date) $date_gnu --date "${startdate} + ${major} days" +%Y%m%d ;; + --datefull) $date_gnu --date "${startdate} + ${major} days" +%Y%m%dT%H%M%SZ ;; + --epoch) $date_gnu --date "${startdate} + ${major} days" +%s ;; + --git) echo "$(trim_when_old_version "${version}")-$(git -C "${scriptsDir}" rev-parse --short 'HEAD^{commit}')" ;; + *) trim_when_old_version "${version}" ;; +esac diff --git a/build b/build deleted file mode 120000 index 9a5480ab..00000000 --- a/build +++ /dev/null @@ -1 +0,0 @@ -gardenlinux/build \ No newline at end of file diff --git a/build b/build new file mode 100755 index 00000000..cc890cd0 --- /dev/null +++ b/build @@ -0,0 +1,128 @@ +#!/usr/bin/env bash + +set -euo pipefail +shopt -s nullglob + +exec 3>&1 +exec 1>&2 + +#container_image=ghcr.io/gardenlinux/builder:d6d24ba1aec66889a2acab83aedcb00e869abfcd +container_image=localhost/builder +container_engine=podman +target_dir=.build + +container_run_opts=( + --memory 4G + --security-opt seccomp=unconfined + --security-opt apparmor=unconfined + --security-opt label=disable + --read-only +) + +container_cmd=() + +use_kms=0 +resolve_cname=0 + +while [ $# -gt 0 ]; do + case "$1" in + --container-image) + container_image="$2" + shift 2 + ;; + --container-engine) + container_engine="$2" + shift 2 + ;; + --container-run-opts) + declare -a "container_run_opts=($2)" + shift 2 + ;; + --privileged) + container_run_opts+=(--privileged) + container_cmd=(--second-stage) + shift + ;; + --kms) + use_kms=1 + shift + ;; + --print-container-image) + printf '%s\n' "$container_image" >&3 + exit 0 + ;; + --resolve-cname) + resolve_cname=1 + shift + ;; + --target) + target_dir="$2" + shift 2 + ;; + *) + break + ;; + esac +done + +[ -d "$target_dir" ] || mkdir "$target_dir" + +container_mount_opts=( + -v "$PWD/keyring.gpg:/builder/keyring.gpg:ro" + -v "$(realpath "$target_dir"):/builder/.build" +) + +for feature in features/*; do + if [ -d "$feature" ]; then + container_mount_opts+=(-v "$(realpath -- "$feature"):/builder/$feature:ro") + fi +done + +if [ "$container_image" = localhost/builder ]; then + dir="$(dirname -- "$(realpath -- "${BASH_SOURCE[0]}")")" + "$container_engine" build -t "$container_image" "$dir" +fi + +repo="$(./get_repo)" +commit="$(./get_commit)" +timestamp="$(./get_timestamp)" +default_version="$(./get_version)" + + +if [ "$resolve_cname" = 1 ]; then + arch="$("$container_engine" run --rm "${container_run_opts[@]}" "${container_mount_opts[@]}" "$container_image" dpkg --print-architecture)" + cname="$("$container_engine" run --rm "${container_run_opts[@]}" "${container_mount_opts[@]}" "$container_image" /builder/parse_features --feature-dir /builder/features --default-arch "$arch" --default-version "$default_version" --cname "$1")" + short_commit="$(head -c 8 <<< "$commit")" + echo "$cname-$short_commit" >&3 + exit 0 +fi + +make_opts=( + REPO="$repo" + COMMIT="$commit" + TIMESTAMP="$timestamp" + DEFAULT_VERSION="$default_version" +) + +if [ "$use_kms" = 1 ]; then + for e in AWS_DEFAULT_REGION AWS_REGION AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN; do + if [ -n "${!e-}" ]; then + make_opts+=("$e=${!e}") + fi + done +fi + +# Default values which can be overriden via 'build.config' file +tempfs_size=2G + +if [[ -f "$PWD"/build.config ]]; then + . "$PWD"/build.config +fi + +make_opts+=("TEMPFS_SIZE=$tempfs_size") + +if [ -d cert ]; then + container_mount_opts+=(-v "$PWD/cert:/builder/cert:ro") +fi + +"$container_engine" run --rm "${container_run_opts[@]}" "${container_mount_opts[@]}" "$container_image" ${container_cmd[@]+"${container_cmd[@]}"} fake_xattr make --no-print-directory -C /builder "${make_opts[@]}" "$@" >&3 diff --git a/features/_iso b/features/_iso deleted file mode 120000 index d7ebec9b..00000000 --- a/features/_iso +++ /dev/null @@ -1 +0,0 @@ -../gardenlinux/features/_iso \ No newline at end of file diff --git a/features/_iso/README.md b/features/_iso/README.md new file mode 100644 index 00000000..41b572d0 --- /dev/null +++ b/features/_iso/README.md @@ -0,0 +1,21 @@ +## Feature: _iso + +## !! USE THIS FOR DEMO PURPOSES ONLY !! + +### Description + + +This feature flag creates an `.iso` artifact of Garden Linux. +The root user has a hardcoded password _gardenlinux_ + + +### Features +This feature simply creates a bootable `.iso` image as an additional artifact. + +### Meta +||| +|---|---| +|type|flag| +|artifact|None| +|included_features|None| +|excluded_features|None| diff --git a/features/_iso/exec.config b/features/_iso/exec.config new file mode 100755 index 00000000..c8536047 --- /dev/null +++ b/features/_iso/exec.config @@ -0,0 +1 @@ +echo "root:gardenlinux" | chpasswd -c YESCRYPT diff --git a/features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg b/features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg new file mode 100644 index 00000000..e438d02d --- /dev/null +++ b/features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg @@ -0,0 +1 @@ +CMDLINE_LINUX="$CMDLINE_LINUX console=ttyS0,115200" diff --git a/features/_iso/file.include/opt/install/install.sh b/features/_iso/file.include/opt/install/install.sh new file mode 100755 index 00000000..906f4831 --- /dev/null +++ b/features/_iso/file.include/opt/install/install.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -ue + +thisDir=$(readlink -f $(dirname "${BASH_SOURCE[0]}")) + +targetDisk="$1" + +pushd "$thisDir" + +# remove all HD related boot entries +for e in $(efibootmgr | awk '$NF ~ /^HD/ { print $1 }' | sed "s/Boot\([0-9A-F]*\)./\1/"); do + echo "Removing entry $e" + efibootmgr -B -b "$e" > /dev/null +done + +# prepare disk for repart +sgdisk -Z "$targetDisk" +sgdisk -o "$targetDisk" + +# actually partition and populate with data +mkdir -p /run/source +mount --bind / /run/source +systemd-repart --definitions repart/ --json=pretty --dry-run=off --copy-source=/run/source/ "$targetDisk" + +sleep 5 + +# prepare mounts for chroot env +target="/run/chroot" +mkdir "$target" +mount /dev/disk/by-label/ROOT "$target" +mount /dev/disk/by-label/ESP "$target/efi" + +# prepare extra mounts +pushd "$target" > /dev/null +mount -t proc proc proc +mount -t sysfs sys sys +mount --bind /dev dev + +# regenerate initrd and generate loader entries +chroot "$target" dracut -f /boot/initrd.img-"$(uname -r)" + +if mount --bind /sys/firmware/efi/efivars "$target/sys/firmware/efi/efivars"; then + # efi + chroot "$target" bootctl install + chroot "$target" kernel-install add "$(uname -r)" "/boot/vmlinuz-$(uname -r)" "/boot/initrd.img-$(uname -r)" +else + # legacy + chroot "${target}" sfdisk --part-attrs "${targetDisk}" 1 LegacyBIOSBootable + chroot "${target}" dd if="/usr/lib/SYSLINUX/gptmbr.bin" of="${targetDisk}" bs=440 count=1 conv=notrunc + chroot "${target}" mkdir -p /efi/syslinux + chroot "${target}" cp /usr/lib/syslinux/modules/bios/menu.c32 /efi/syslinux/ + chroot "${target}" cp /usr/lib/syslinux/modules/bios/libutil.c32 /efi/syslinux/ + chroot "${target}" syslinux --directory syslinux --install /dev/disk/by-label/ESP + mkdir /run/chroot/efi/Default + chroot "$target" kernel-install add "$(uname -r)" "/boot/vmlinuz-$(uname -r)" "/boot/initrd.img-$(uname -r)" + chroot "${target}" update-syslinux +fi + +echo "Safe to reboot" diff --git a/features/_iso/file.include/opt/install/repart/00-efi.conf b/features/_iso/file.include/opt/install/repart/00-efi.conf new file mode 100644 index 00000000..d71d8caa --- /dev/null +++ b/features/_iso/file.include/opt/install/repart/00-efi.conf @@ -0,0 +1,8 @@ +# modify only the size to fit your needs +[Partition] +Type=esp +Format=vfat +SizeMinBytes=1024M +SizeMaxBytes=1024M +Label=ESP +MountPoint=/efi diff --git a/features/_iso/file.include/opt/install/repart/10-root.conf b/features/_iso/file.include/opt/install/repart/10-root.conf new file mode 100644 index 00000000..617337f0 --- /dev/null +++ b/features/_iso/file.include/opt/install/repart/10-root.conf @@ -0,0 +1,9 @@ +# modify only the size to fit your needs, do not specify the size to use whatever space is left on disk +[Partition] +Type=root +#SizeMinBytes=2G +#SizeMaxBytes=2G +CopyFiles=/ +CopyFiles=/boot +Label=ROOT +MountPoint=/ diff --git a/features/_iso/image.iso b/features/_iso/image.iso new file mode 100755 index 00000000..2c875f5a --- /dev/null +++ b/features/_iso/image.iso @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +set -euo pipefail + +input="$(realpath -- "$1")" +output="$(realpath -- "$2")" + +dir="$(mktemp -d)" +pushd "$dir" > /dev/null + +export PATH="/builder/image.d:$PATH" + +chroot_dir="$(mktemp -d)" +mount -t tmpfs tmpfs "$chroot_dir" +tar --extract --xattrs --xattrs-include '*' --directory "$chroot_dir" < "$input" + +mount --rbind --make-rprivate /proc "$chroot_dir/proc" +mount --rbind --make-rprivate /sys "$chroot_dir/sys" +mount --rbind --make-rprivate /dev "$chroot_dir/dev" +mount --bind /usr/bin/false "${chroot_dir}/usr/bin/systemd-detect-virt" + +kernel=$(echo "${chroot_dir}"/boot/vmlinuz-* | tr " " '\n' | cut -d- -f 2- | sort -V | tail -1) +chroot "$chroot_dir" dracut -f /tmp/initrd "${kernel}" -m "bash systemd systemd-initrd kernel-modules kernel-modules-extra terminfo dracut-systemd shutdown dmsquash-live" --reproducible + +# we use ukify because dracut 059 and systemd 254 don't mix, dracut generate a broken uki +# https://github.com/dracutdevs/dracut/issues/2431 +# TODO: fix when dracut is fixed +#chroot "${chroot_dir}" dracut -f /tmp/unified ${kernel} --uefi --kernel-cmdline "console=tty0 console=ttyS0,115200 rd.live.squashimg=squashfs.img root=live:CDLABEL=GardenlinuxISO rd.live.overlay.overlayfs rd.live.dir=live rd.live.ram" -m "bash systemd systemd-initrd kernel-modules kernel-modules-extra terminfo dracut-systemd shutdown dmsquash-live" --reproducible +chroot "${chroot_dir}" /lib/systemd/ukify build --output=/tmp/unified --linux=/boot/vmlinuz-"${kernel}" --initrd=/tmp/initrd --cmdline="console=tty0 console=ttyS0,115200 rd.live.squashimg=squashfs.img root=live:CDLABEL=GardenlinuxISO rd.live.overlay.overlayfs rd.live.dir=live rd.live.ram" + +umount -l "$chroot_dir/proc" +umount -l "$chroot_dir/sys" +umount -l "$chroot_dir/dev" +umount "${chroot_dir}/usr/bin/systemd-detect-virt" + +mkdir CD_root +mkdir CD_root/{isolinux,images,kernel,boot,boot/images,boot/syslinux,live} + +mksquashfs "$chroot_dir" "CD_root/live/squashfs.img" -comp lzo +cp "${chroot_dir}/boot/"vmlinuz* "CD_root/boot/images/vmlinuz" +mv "${chroot_dir}/tmp/"initrd* "CD_root/boot/images/initrd" +mv "${chroot_dir}/tmp/unified" bootx64.efi + +#TODO: determine proper size +dd if=/dev/zero of=efiboot.img bs=512 count=131072 +mkfs.msdos -F 16 -n 'EFIBOOTISO' efiboot.img +mmd -i efiboot.img ::EFI +mmd -i efiboot.img ::EFI/BOOT +mcopy -i efiboot.img bootx64.efi ::EFI/BOOT/BOOTX64.EFI + +mv efiboot.img CD_root/isolinux/ +cp "${chroot_dir}/usr/lib/ISOLINUX/isolinux.bin" CD_root/isolinux/ +cp "${chroot_dir}/usr/lib/ISOLINUX/isohdpfx.bin" CD_root/isolinux/ +cp "${chroot_dir}/usr/lib/syslinux/modules/bios/ldlinux.c32" CD_root/isolinux + +cat << EOF > CD_root/isolinux/isolinux.cfg +PATH /boot/syslinux +DEFAULT loadconfig + +LABEL loadconfig + CONFIG /boot/syslinux/syslinux.cfg +EOF + +cat << EOF > CD_root/boot/syslinux/syslinux.cfg +MENU TITLE gardenlinux +DEFAULT GardenlinuxRam + +LABEL GardenlinuxRam +MENU LABEL Gardenlinux Live in RAM +LINUX /boot/images/vmlinuz console=tty0 console=ttyS0,115200 rd.live.squashimg=squashfs.img root=live:CDLABEL=GardenlinuxISO rd.live.overlay.overlayfs rd.live.dir=live rd.live.ram +INITRD /boot/images/initrd +EOF + +# TODO: make this reproducible +xorriso -as mkisofs \ + -volid "GardenlinuxISO" \ + -o "${output}" \ + -isohybrid-mbr "${chroot_dir}/usr/lib/ISOLINUX/isohdpfx.bin" \ + -c isolinux/boot.cat \ + -b isolinux/isolinux.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -eltorito-alt-boot \ + -e isolinux/efiboot.img \ + -no-emul-boot \ + -isohybrid-gpt-basdat \ + CD_root diff --git a/features/_iso/info.yaml b/features/_iso/info.yaml new file mode 100644 index 00000000..302d84a9 --- /dev/null +++ b/features/_iso/info.yaml @@ -0,0 +1,6 @@ +description: "iso" +type: flag +features: + exclude: + - _selinux + - sap diff --git a/features/_iso/pkg.include b/features/_iso/pkg.include new file mode 100644 index 00000000..b70528d8 --- /dev/null +++ b/features/_iso/pkg.include @@ -0,0 +1,8 @@ +dracut +dracut-core +dracut-live +binutils +isolinux +python3-pefile +systemd-ukify +gdisk diff --git a/features/_iso/test/autologin.disable b/features/_iso/test/autologin.disable new file mode 100644 index 00000000..e69de29b diff --git a/features/_iso/test/test_capabilities.py b/features/_iso/test/test_capabilities.py new file mode 100644 index 00000000..c0048aee --- /dev/null +++ b/features/_iso/test/test_capabilities.py @@ -0,0 +1 @@ +from helper.tests.capabilities import capabilities as test_capabilities diff --git a/features/_iso/test/test_packages_musthave.py b/features/_iso/test/test_packages_musthave.py new file mode 100644 index 00000000..4b2783d2 --- /dev/null +++ b/features/_iso/test/test_packages_musthave.py @@ -0,0 +1 @@ +from helper.tests.packages_musthave import packages_musthave as test_packages_musthave diff --git a/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh b/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh index 818d0f38..bc30d2c7 100755 --- a/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh +++ b/features/_pxe/file.include/usr/lib/dracut/modules.d/98gardenlinux-live/live-get-squashfs.sh @@ -27,7 +27,7 @@ if [ ! -f "${shaFile}" ]; then exit 1 fi -if ! echo "$(grep . ${shaFile}) ${squashFile}" | sha256sum --status --check; then +if ! echo "$(grep . ${shaFile}) ${squashFile}" | sha256sum --status --check -; then warn "the hash verification of the squashfs has failed - exiting" exit 1 fi diff --git a/features/_rescue/file.include/etc/systemd/system/emergency.service.d/debugprint.conf b/features/_rescue/file.include/etc/systemd/system/emergency.service.d/debugprint.conf index fd70fadb..2b7feac7 100644 --- a/features/_rescue/file.include/etc/systemd/system/emergency.service.d/debugprint.conf +++ b/features/_rescue/file.include/etc/systemd/system/emergency.service.d/debugprint.conf @@ -2,9 +2,8 @@ StandardOutput=journal+console StandardError=journal+console ExecStartPre=/bin/sh -c ' \ - systemctl --failed --no-legend --no-pager | awk "{print \$2}" | \ - xargs -r -I{} sh -c " \ - echo \"\\n=== FAILED UNIT: {} ===\\n\"; \ - journalctl -b -u {} --no-pager || true; \ - "' + for unit in $(systemctl --failed --no-legend --no-pager | awk "{print \$2}"); do \ + echo "\n=== FAILED UNIT: $unit ===\n"; \ + journalctl -b -u "$unit" --no-pager || true; \ + done' TimeoutStartSec=20s diff --git a/features/_scicommon/exec.config b/features/_scicommon/exec.config index c67667e1..d18e272c 100755 --- a/features/_scicommon/exec.config +++ b/features/_scicommon/exec.config @@ -12,19 +12,19 @@ for feature in "${FEATURES[@]}"; do done # capi versions: https://github.com/kubernetes-sigs/cri-tools/releases -CAPI_VERSION=v1.33.0 +CAPI_VERSION=v1.35.0 K8S_VERSION_REPO="${CAPI_VERSION%.*}" # key can be downloaded liek e.g. # curl -fsSL https://pkgs.k8s.io/core:/stable:/${K8S_VERSION_REPO}/deb/Release.key > pkgs-k8s-io_${K8S_VERSION_REPO}_release.key -gpg --dearmor -o "/etc/apt/keyrings/kubernetes-${K8S_VERSION_REPO}-apt-keyring.gpg" <"/builder/features/_scicommon/pkgs-k8s-io_${K8S_VERSION_REPO}_release.key" +cp "/builder/features/_scicommon/pkgs-k8s-io_${K8S_VERSION_REPO}_release.key" "/etc/apt/keyrings/kubernetes-${K8S_VERSION_REPO}-apt-keyring.asc" cat < /dev/null +dpkg -i ignition_*_amd64.deb +popd > /dev/null +rm -rf "$TEMP_DIR" diff --git a/features/_usi/file.exclude b/features/_usi/file.exclude index 9c50a71c..86e0873c 100644 --- a/features/_usi/file.exclude +++ b/features/_usi/file.exclude @@ -6,3 +6,8 @@ #/opt/{,.}* #/home/{,.}* /root/{,.}* +/etc/cron.daily/apt-compat +/etc/cron.daily/dpkg +/etc/cron.daily/quota +/etc/cron.monthly/update-pciids +/etc/cron.monthly/update-usbids diff --git a/features/_usi/file.include/etc/systemd/system-preset/00-systemd-usi.preset b/features/_usi/file.include/etc/systemd/system-preset/00-systemd-usi.preset index 56084989..55578a5e 100644 --- a/features/_usi/file.include/etc/systemd/system-preset/00-systemd-usi.preset +++ b/features/_usi/file.include/etc/systemd/system-preset/00-systemd-usi.preset @@ -2,4 +2,6 @@ disable apt-daily.timer disable dpkg-db-backup.timer disable systemd-sysupdate-reboot.timer +disable systemd-sysupdate-reboot.service disable systemd-sysupdate.timer +disable systemd-sysupdate.service diff --git a/features/_usi/file.include/etc/systemd/system/dbgimport.service b/features/_usi/file.include/etc/systemd/system/dbgimport.service new file mode 100644 index 00000000..2b84b937 --- /dev/null +++ b/features/_usi/file.include/etc/systemd/system/dbgimport.service @@ -0,0 +1,13 @@ +[Unit] +Description=Import debug container image +ConditionPathExists=|/opt/dbgimage/debug.tar +ConditionFirstBoot=yes +After=containerd.service +Requires=containerd.service + +[Service] +ExecStart=/bin/sh -c 'ctr image import --base-name "$(cat /opt/dbgimage/debug.tar.name)" /opt/dbgimage/debug.tar && rm -f /opt/dbgimage/debug.tar && rm -f /opt/dbgimage/debug.tar.name && rm -f /opt/dbgimage/image' +Type=oneshot + +[Install] +WantedBy=multi-user.target diff --git a/features/_usi/file.include/etc/systemd/system/systemd-repart.service b/features/_usi/file.include/etc/systemd/system/systemd-repart.service new file mode 120000 index 00000000..dc1dc0cd --- /dev/null +++ b/features/_usi/file.include/etc/systemd/system/systemd-repart.service @@ -0,0 +1 @@ +/dev/null \ No newline at end of file diff --git a/features/_usi/initrd.include/etc/systemd/system/systemd-repart.service b/features/_usi/initrd.include/etc/systemd/system/systemd-repart.service new file mode 120000 index 00000000..dc1dc0cd --- /dev/null +++ b/features/_usi/initrd.include/etc/systemd/system/systemd-repart.service @@ -0,0 +1 @@ +/dev/null \ No newline at end of file diff --git a/features/_usi/initrd.include/usr/bin/detect_disk b/features/_usi/initrd.include/usr/bin/detect_disk index 0a8fb937..d061a300 100755 --- a/features/_usi/initrd.include/usr/bin/detect_disk +++ b/features/_usi/initrd.include/usr/bin/detect_disk @@ -4,10 +4,6 @@ set -Eeuo pipefail ROOT_HINTS_FILE="/sysroot/opt/persist/root-hints.yaml" -if ! [[ -f $ROOT_HINTS_FILE ]]; then - echo "no root-hints.yaml provided, error" - exit 1 -fi if kname=$(/usr/bin/root-hints $ROOT_HINTS_FILE); then echo "/dev/${kname}" else diff --git a/features/_usi/initrd.include/usr/bin/persist b/features/_usi/initrd.include/usr/bin/persist index ad950446..26fcaca0 100755 --- a/features/_usi/initrd.include/usr/bin/persist +++ b/features/_usi/initrd.include/usr/bin/persist @@ -6,6 +6,11 @@ if ! disk_dev=$(/usr/bin/detect_disk); then exit 1 fi +if [[ ! -b "$disk_dev" ]]; then + echo "Device $disk_dev not found, exiting" + exit 1 +fi + # clean up the disk sgdisk -Z "$disk_dev" sgdisk -o "$disk_dev" @@ -70,14 +75,14 @@ export HOME=/root # source optional config file [ -f /sysroot/opt/persist/gl-oci.conf ] && . /sysroot/opt/persist/gl-oci.conf -OCI_REPO="${OCI_REPO:-keppel.global.cloud.sap/ccloud-ghcr-io-mirror/gardenlinux/gardenlinux-ccloud}" +OCI_REPO="${OCI_REPO:-keppel.global.cloud.sap/ccloud-ghcr-io-mirror/gardenlinux/gardenlinux-sci}" DASHED_GARDENLINUX_VERSION=${GARDENLINUX_VERSION//./-} # setup OCI_TAG, UKI_SHA and fetch UKI OCI_TAG=${OCI_TAG:-"$GARDENLINUX_VERSION-$VARIANT_ID-${DASHED_GARDENLINUX_VERSION}-$GARDENLINUX_COMMIT_ID"} OCI_TAG=${OCI_TAG//_/-} # replace underscores with dashes UKI_SHA=$(oras manifest fetch "$OCI_REPO:${OCI_TAG}" | jq -r '.layers[] | select(.mediaType=="application/io.gardenlinux.uki") | .digest') -oras blob fetch "$OCI_REPO@$UKI_SHA" -o "$esp_dir/EFI/Linux/uki.efi" +oras blob fetch "$OCI_REPO@$UKI_SHA" -o "$esp_dir/EFI/Linux/${GARDENLINUX_CNAME}.efi" if [ "$ENABLE_HUGEPAGE_SETUP" = "true" ]; then echo "hugepagesz=2MB hugepages=$hugepages" > /tmp/cmdlinef @@ -94,6 +99,20 @@ if [ "$ENABLE_HUGEPAGE_SETUP" = "true" ]; then objcopy --add-section .cmdline=/tmp/cmdlinef --change-section-vma .cmdline=$(printf 0x%x $offs) $addon "$addon_dir/hugepages.addon.efi" fi +# debug container +DBG_CONTAINER_IMPORT="/sysroot/opt/dbgimage" +DBG_CONTAINER_IMAGE_DUMP="debug.tar" +DBG_CONTAINER_FILE="/sysroot/opt/dbgimage/image" + +mkdir -p "$DBG_CONTAINER_IMPORT" +if [ -f "$DBG_CONTAINER_FILE" ]; then + oras backup --output "$DBG_CONTAINER_IMPORT/$DBG_CONTAINER_IMAGE_DUMP" "$(cat "$DBG_CONTAINER_FILE")" + cat "$DBG_CONTAINER_FILE" | awk -F':' '{print $1}' > "$DBG_CONTAINER_IMPORT/$DBG_CONTAINER_IMAGE_DUMP.name" +else + echo "no container image file provided, skipping..." +fi + + # Network config generation if [[ -x /sysroot/opt/persist/network_up.sh ]]; then chroot /sysroot /opt/persist/network_up.sh diff --git a/features/_usi/initrd.include/usr/bin/root-hints b/features/_usi/initrd.include/usr/bin/root-hints index 5186752f..360bac06 100755 --- a/features/_usi/initrd.include/usr/bin/root-hints +++ b/features/_usi/initrd.include/usr/bin/root-hints @@ -2,12 +2,17 @@ set -Eeuo pipefail +# setup error trap +trap 'err "Error occurred at line $LINENO while executing: $BASH_COMMAND"' ERR + function yqroot() { cat "$1" | chroot /sysroot /usr/bin/yq -c '.hints | .[]' } function err() { echo "$@" 1>&2 + + lsblk -bOJ | jq } function filter() { @@ -27,25 +32,94 @@ function filter() { fi if [[ $val =~ ^[0-9]+[KMGT]+$ ]]; then val=$(echo "$val" | numfmt --from=iec) - echo "and ${col^^} $op ${val}" + echo "${col^^} $op ${val}" else - echo "and ${col^^} $op \"${val}\"" + echo "${col^^} $op \"${val}\"" fi +} +function blockdevicesize() { + local kname="$1" + lsblk -bOJ | jq --arg kname "$kname" -r '.blockdevices.[] | select(.kname == $kname).size' } +udevadm settle + yamlFile="$1" +esp_disk="" +if [ -e "/dev/disk/by-label/ESP" ]; then + esp_partition=$(basename "$(readlink -f /dev/disk/by-label/ESP)") + esp_disk=$(basename "$(readlink -f "/sys/class/block/$esp_partition/..")") +fi + +# TODO: likely go rather with device uuid or alike #if dev=$(yq -e .dev "$yamlFile" 2> /dev/null); then # echo "$dev" # exit 0 #fi -flsblk="TYPE eq \"disk\"" -while IFS= read -r r; do - f=$(filter "$r") - flsblk="$flsblk $f" -done < <(yqroot "$yamlFile" ) +declare -a flsblk=() +# check if yaml file exists and is valid, if so, use it to build the filter for lsblk +if [ -f "$yamlFile" ] && yq -e . "$yamlFile" >/dev/null 2>&1; then + while IFS= read -r r; do + flsblk+=("$(filter "$r")") + done < <(yqroot "$yamlFile") +fi + +LSBLK_JSON="" + +function join { + local SEPARATOR="$1" + shift + printf "%s${SEPARATOR}" "$@" | sed --unbuffered "s/${SEPARATOR}$//" +} + +# if flsblk contains elements, we join them by 'and' and use the filter with lsblk +if [ ${#flsblk[@]} -gt 0 ]; then + flsfilter=$(join " and " "${flsblk[@]}") + echo "Using filter: $flsfilter" 1>&2 + LSBLK_JSON=$(lsblk --sort size --exclude 1,2,3,4,7,11 --filter "$flsfilter" -OJ) +else + # no hints, hence we choose the smallest disk we find. we exclude ram disk, + # floppy, ide, dynamically allocated, loopback and scsi cd-rom devices + LSBLK_JSON=$(lsblk --sort size --exclude 1,2,3,4,7,11 -OJ) +fi -#echo "$flsblk" -lsblk --filter "$flsblk" --noheadings -o kname +# from the resulting list of disks we pick the first disk that are writeable +kname=$(echo "$LSBLK_JSON" | jq -r '[.blockdevices.[]|select(.type? == "disk" and .ro? == false)][0].kname // ""') + +# check which disk to use. +# 1. if kname is empty: +# * we check if we have an esp_disk, if so we use it +# * otherwise we fail +# 2. if kname is not empty: +# * we check if we have an esp_disk, if not we use +# * kname, otherwise we check if they are the same, if not we fail, otherwise we use kname/esp_disk +if [ -z "$kname" ]; then + if [ -z "$esp_disk" ]; then + err "No suitable disk found" + exit 1 + fi + echo "Warning: No suitable disk found, falling back to ESP disk ${esp_disk}" 1>&2 + echo "$esp_disk" +else + if [ -z "$esp_disk" ]; then + # no esp_disk using kname + echo "$kname" + exit 0 + fi + + if [ "$kname" != "$esp_disk" ]; then + # check if desvice size are the same + err "Error: Found disk ${kname} does not match ESP disk ${esp_disk}." 1>&2 + kname_size=$(blockdevicesize "$kname") + esp_disk_size=$(blockdevicesize "$esp_disk") + if [ "$kname_size" != "$esp_disk_size" ]; then + err "Error: Found disk ${kname} size ${kname_size} does not match ESP disk ${esp_disk} size ${esp_disk_size}." 1>&2 + exit 1 + fi + fi + # kname == esp_disk or esp_disk has similar size to kname + echo "$esp_disk" +fi diff --git a/features/_usi/pkg.exclude b/features/_usi/pkg.exclude new file mode 100644 index 00000000..df284caa --- /dev/null +++ b/features/_usi/pkg.exclude @@ -0,0 +1 @@ +ignition diff --git a/features/_usi/pkg.include b/features/_usi/pkg.include index 7ee423c5..8f20b728 100644 --- a/features/_usi/pkg.include +++ b/features/_usi/pkg.include @@ -9,6 +9,5 @@ tpm2-tools yq gdisk binutils -oras efibootmgr systemd-ukify diff --git a/features/_usidev/exec.config b/features/_usidev/exec.config index 402f6dbf..8eee4e1c 100755 --- a/features/_usidev/exec.config +++ b/features/_usidev/exec.config @@ -1,5 +1,19 @@ #!/usr/bin/env bash -set -eufo pipefail +set -euo pipefail mkdir -p /var/usr.overlay /var/usr.overlay.workdir + +# install +mkdir /tmp/custompackages +package="https://github.com/toanju/package-gardenlinux-update/releases/download/0.9gl4%2Bbp1877/build.tar.xz.0000" + +echo "Downloading and extracting package from $package" +wget -q "$package" -O - | xz -d | tar xf - -C /tmp/custompackages + +pushd /tmp/custompackages > /dev/null +rm -f -- *dbgsym* *arm64* || true +ls -1 +dpkg -i gardenlinux-update_*_amd64.deb +popd > /dev/null +rm -rf /tmp/custompackages diff --git a/features/_usidev/pkg.exclude b/features/_usidev/pkg.exclude new file mode 100644 index 00000000..562044e0 --- /dev/null +++ b/features/_usidev/pkg.exclude @@ -0,0 +1 @@ +gardenlinux-update diff --git a/features/khost b/features/khost deleted file mode 120000 index 0b36d54a..00000000 --- a/features/khost +++ /dev/null @@ -1 +0,0 @@ -../gardenlinux/features/khost \ No newline at end of file diff --git a/features/khost/README.md b/features/khost/README.md new file mode 100644 index 00000000..7d71961c --- /dev/null +++ b/features/khost/README.md @@ -0,0 +1,19 @@ +## Feature: khost +### Description + +The khost feature adjusts Garden Linux to support running Kubernetes (vanilla) workloads. + + +### Features +The `khost` feature adjusts Garden Linux to support running Kubernetes (vanilla) workloads and installs and configures all related packages (regarding the used hardware architecture) and tools. It adjusts the `kublets`, `sysctl` and removes any swap partition. + +### Unit testing +Unit tests will ensure that the needed packages are present as well as the `kublet` is enabled within `systemd`. + +### Meta +||| +|---|---| +|type|element| +|artifact|None| +|included_features|`chost`| +|excluded_features|None| diff --git a/features/khost/exec.late b/features/khost/exec.late new file mode 100755 index 00000000..f0ea8caf --- /dev/null +++ b/features/khost/exec.late @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +K8S_VERSION=v1.34.3 +K8S_VERSION_REPO="${K8S_VERSION%.*}" + +cp /builder/features/khost/release.key /etc/apt/keyrings/kubernetes-apt-keyring.asc +echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/${K8S_VERSION_REPO}/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list +apt update -y +apt install -y --no-install-recommends "kubelet=${K8S_VERSION#v}*" "kubectl=${K8S_VERSION#v}*" "kubeadm=${K8S_VERSION#v}*" "cri-tools=${K8S_VERSION_REPO#v}*" + diff --git a/features/khost/file.exclude b/features/khost/file.exclude new file mode 100644 index 00000000..82b5c657 --- /dev/null +++ b/features/khost/file.exclude @@ -0,0 +1 @@ +/etc/init.d/apparmor diff --git a/features/khost/file.include/etc/modules-load.d/br-nf.conf b/features/khost/file.include/etc/modules-load.d/br-nf.conf new file mode 100644 index 00000000..a13fc179 --- /dev/null +++ b/features/khost/file.include/etc/modules-load.d/br-nf.conf @@ -0,0 +1 @@ +br_netfilter diff --git a/features/khost/file.include/etc/sysctl.d/20-br-nf.conf b/features/khost/file.include/etc/sysctl.d/20-br-nf.conf new file mode 100644 index 00000000..0454e18a --- /dev/null +++ b/features/khost/file.include/etc/sysctl.d/20-br-nf.conf @@ -0,0 +1,2 @@ +net.bridge.bridge-nf-call-iptables=1 +net.bridge.bridge-nf-call-ip6tables=1 diff --git a/features/khost/file.include/etc/sysctl.d/20-inotify.conf b/features/khost/file.include/etc/sysctl.d/20-inotify.conf new file mode 100644 index 00000000..8f7c9d98 --- /dev/null +++ b/features/khost/file.include/etc/sysctl.d/20-inotify.conf @@ -0,0 +1,2 @@ +fs.inotify.max_user_instances = 8192 +fs.inotify.max_user_watches = 65536 diff --git a/features/khost/file.include/etc/sysctl.d/20-ip-forward.conf b/features/khost/file.include/etc/sysctl.d/20-ip-forward.conf new file mode 100644 index 00000000..5f01c9cd --- /dev/null +++ b/features/khost/file.include/etc/sysctl.d/20-ip-forward.conf @@ -0,0 +1,3 @@ +net.ipv4.ip_forward=1 +net.ipv6.conf.all.forwarding=1 + diff --git a/features/khost/fstab.mod b/features/khost/fstab.mod new file mode 100755 index 00000000..de880d56 --- /dev/null +++ b/features/khost/fstab.mod @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# remove any swap partition +sed '/^[^[:space:]]\+[[:space:]]\+[^[:space:]]\+[[:space:]]\+swap[[:space:]]\+/d' + diff --git a/features/khost/info.yaml b/features/khost/info.yaml new file mode 100644 index 00000000..1d9d389e --- /dev/null +++ b/features/khost/info.yaml @@ -0,0 +1,5 @@ +description: 'host for kubernetes workloads (vanilla)' +type: element +features: + include: + - chost diff --git a/features/khost/pkg.include b/features/khost/pkg.include new file mode 100644 index 00000000..487a9abe --- /dev/null +++ b/features/khost/pkg.include @@ -0,0 +1,6 @@ +apparmor +conntrack +ethtool +ipvsadm +socat +gnupg diff --git a/features/khost/release.key b/features/khost/release.key new file mode 100644 index 00000000..64f4d8f8 --- /dev/null +++ b/features/khost/release.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.5 (GNU/Linux) + +mQENBGMHoXcBCADukGOEQyleViOgtkMVa7hKifP6POCTh+98xNW4TfHK/nBJN2sm +u4XaiUmtB9UuGt9jl8VxQg4hOMRf40coIwHsNwtSrc2R9v5Kgpvcv537QVIigVHH +WMNvXeoZkkoDIUljvbCEDWaEhS9R5OMYKd4AaJ+f1c8OELhEcV2dAQLLyjtnEaF/ +qmREN+3Y9+5VcRZvQHeyBxCG+hdUGE740ixgnY2gSqZ/J4YeQntQ6pMUEhT6pbaE +10q2HUierj/im0V+ZUdCh46Lk/Rdfa5ZKlqYOiA2iN1coDPIdyqKavcdfPqSraKF +Lan2KLcZcgTxP+0+HfzKefvGEnZa11civbe9ABEBAAG0PmlzdjprdWJlcm5ldGVz +IE9CUyBQcm9qZWN0IDxpc3Y6a3ViZXJuZXRlc0BidWlsZC5vcGVuc3VzZS5vcmc+ +iQE+BBMBCAAoBQJnFF34AhsDBQkIK2yBBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX +gAAKCRAjRlTamilkNtOACACDK9dQ8CH2Ji9C3Q926nVMUiXdyJK1onCBrQSEBqdR +LJaT6hGx5pzxkQGgUDpS9p7LA0u920HKLwGb7yIAWtyE5TAj2CYprGgpq98sfsGC ++U5T9IrAdya/BaTAkkP6gNhfMjNaK3bOWsvuLRlluKMNch4ify+IwLqc1JLG40bj +2HnKBGYkC3m0VtQfUuPQMImSLta/NwRHJMPo8jfGyManqMMxp35/ecP2rXMfb/l1 +WjFDY7h+6nqXay20ljMXkN23W8wFTdvC6lq45wwM5IBnKNR/TjNNYAIizZoHFWz1 +c/ecMWWWCB2S7WbY4xI3JSCOD4XIff3ie7pc68/kgPytiQIcBBMBAgAGBQJjB6F3 +AAoJEM8Lkoze1k873TQP/0t2F/jltLRQMG7VCLw7+ps5JCW5FIqu/S2i9gSdNA0E +42u+LyxjG3YxmVoVRMsxeu4kErxr8bLcA4p71W/nKeqwF9VLuXKirsBC7z2syFiL +Ndl0ARnC3ENwuMVlSCwJO0MM5NiJuLOqOGYyD1XzSfnCzkXN0JGA/bfPRS5mPfoW +0OHIRZFhqE7ED6wyWpHIKT8rXkESFwszUwW/D7o1HagX7+duLt8WkrohGbxTJ215 +YanOKSqyKd+6YGzDNUoGuMNPZJ5wTrThOkTzEFZ4HjmQ16w5xmcUISnCZd4nhsbS +qN/UyV9Vu3lnkautS15E4CcjP1RRzSkT0jka62vPtAzw+PiGryM1F7svuRaEnJD5 +GXzj9RCUaR6vtFVvqqo4fvbA99k4XXj+dFAXW0TRZ/g2QMePW9cdWielcr+vHF4Z +2EnsAmdvF7r5e2JCOU3N8OUodebU6ws4VgRVG9gptQgfMR0vciBbNDG2Xuk1WDk1 +qtscbfm5FVL36o7dkjA0x+TYCtqZIr4x3mmfAYFUqzxpfyXbSHqUJR2CoWxlyz72 +XnJ7UEo/0UbgzGzscxLPDyJHMM5Dn/Ni9FVTVKlALHnFOYYSTluoYACF1DMt7NJ3 +oyA0MELL0JQzEinixqxpZ1taOmVR/8pQVrqstqwqsp3RABaeZ80JbigUC29zJUVf +=Eplj +-----END PGP PUBLIC KEY BLOCK----- diff --git a/features/khost/test/test_packages_musthave.py b/features/khost/test/test_packages_musthave.py new file mode 100644 index 00000000..4b2783d2 --- /dev/null +++ b/features/khost/test/test_packages_musthave.py @@ -0,0 +1 @@ +from helper.tests.packages_musthave import packages_musthave as test_packages_musthave diff --git a/features/khost/test/test_systemd_unit.py b/features/khost/test/test_systemd_unit.py new file mode 100644 index 00000000..0bc474ab --- /dev/null +++ b/features/khost/test/test_systemd_unit.py @@ -0,0 +1,16 @@ +import pytest +from helper.utils import execute_remote_command +from helper.utils import validate_systemd_unit + + +@pytest.mark.parametrize( + "systemd_unit", + [ + "kubelet" + ] +) + + +def test_systemd_unit(client, systemd_unit, non_provisioner_chroot): + execute_remote_command(client, f"systemctl start {systemd_unit}") + validate_systemd_unit(client, f"{systemd_unit}") diff --git a/features/metal3/exec.config b/features/metal3/exec.config index b15043a1..4fdb8e0f 100755 --- a/features/metal3/exec.config +++ b/features/metal3/exec.config @@ -26,7 +26,7 @@ apt-mark hold ${package_name} K8S_VERSION=v1.30.7 K8S_VERSION_REPO="${K8S_VERSION%.*}" -gpg --dearmor -o "/etc/apt/keyrings/kubernetes-${K8S_VERSION_REPO}-apt-keyring.gpg" /dev/null +rm -f -- *dbgsym* *arm64* || true +ls -1 +dpkg -i cloud-hypervisor-gl*_amd64.deb edk2-cloud-hypervisor-gl*_amd64.deb libvirt-clients_*_amd64.deb libvirt-common_*_amd64.deb libvirt-daemon_*_amd64.deb libvirt-daemon-common_*_amd64.deb libvirt-daemon-config-network_*_all.deb libvirt-daemon-config-nwfilter_*_all.deb libvirt-daemon-driver-ch-gl_*_amd64.deb libvirt-daemon-driver-network_*_amd64.deb libvirt-daemon-driver-nodedev_*_amd64.deb libvirt-daemon-driver-nwfilter_*_amd64.deb libvirt-daemon-driver-qemu_*_amd64.deb libvirt-daemon-driver-secret_*_amd64.deb libvirt-daemon-driver-storage_*_amd64.deb libvirt-daemon-log_*_amd64.deb libvirt-daemon-system_*_amd64.deb libvirt0_*_amd64.deb +popd > /dev/null +rm -rf /tmp/custompackages + # UID taken from sles 15, looks like it runs as root in debian/gardenlinux adduser --uid 476 openvswitch \ --system --group --no-create-home --disabled-password --disabled-login @@ -15,11 +40,11 @@ function create() { shift ID=$1 shift - adduser --uid $ID --home /var/lib/$NAME $NAME \ + adduser --uid "$ID" --home "/var/lib/$NAME" "$NAME" \ --system --group --disabled-password --disabled-login echo "$@" for group in "$@"; do - adduser $NAME $group + adduser "$NAME" "$group" done } diff --git a/features/sci/file.include/etc/modprobe.d/kvm-amd.conf b/features/sci/file.include/etc/modprobe.d/kvm-amd.conf new file mode 100644 index 00000000..79910fc2 --- /dev/null +++ b/features/sci/file.include/etc/modprobe.d/kvm-amd.conf @@ -0,0 +1 @@ +install kvm_amd if grep -q AuthenticAMD /proc/cpuinfo; then modprobe --ignore-install kvm_amd; else echo "WARNING kvm_amd: no AMD cpu found, skipping"; exit 0; fi diff --git a/features/sci/file.include/etc/modprobe.d/kvm-intel.conf b/features/sci/file.include/etc/modprobe.d/kvm-intel.conf new file mode 100644 index 00000000..67abf1e0 --- /dev/null +++ b/features/sci/file.include/etc/modprobe.d/kvm-intel.conf @@ -0,0 +1 @@ +install kvm_intel if grep -q GenuineIntel /proc/cpuinfo; then modprobe --ignore-install kvm_intel; else echo "WARNING kvm_intel: no Intel cpu found, skipping"; exit 0; fi diff --git a/features/sci/file.include/etc/modprobe.d/nfsclient.conf b/features/sci/file.include/etc/modprobe.d/nfsclient.conf new file mode 100644 index 00000000..d1587635 --- /dev/null +++ b/features/sci/file.include/etc/modprobe.d/nfsclient.conf @@ -0,0 +1,3 @@ +# According to Netapp KVM Best Practices mount options this value should be nconnect*64 (nconnect=8) +options nfs max_session_slots=512 + diff --git a/features/sci/file.include/etc/modules-load.d/kvm.conf b/features/sci/file.include/etc/modules-load.d/kvm.conf new file mode 100644 index 00000000..01884b87 --- /dev/null +++ b/features/sci/file.include/etc/modules-load.d/kvm.conf @@ -0,0 +1,3 @@ +kvm +kvm_amd +kvm_intel diff --git a/features/sci/file.include/etc/systemd/system-preset/00-sci-libvirt.preset b/features/sci/file.include/etc/systemd/system-preset/00-sci-libvirt.preset new file mode 100644 index 00000000..a45ccf70 --- /dev/null +++ b/features/sci/file.include/etc/systemd/system-preset/00-sci-libvirt.preset @@ -0,0 +1,5 @@ +# default presets for sci image +disable virtchd-admin.socket +disable virtchd-ro.socket +disable virtchd.service +disable virtchd.socket diff --git a/features/sci/file.include/etc/systemd/system-preset/10-ipmiev.preset b/features/sci/file.include/etc/systemd/system-preset/10-ipmiev.preset new file mode 100644 index 00000000..17ed7623 --- /dev/null +++ b/features/sci/file.include/etc/systemd/system-preset/10-ipmiev.preset @@ -0,0 +1,2 @@ +# default presets for sci image +disable ipmievd.service diff --git a/features/sci/pkg.include b/features/sci/pkg.include index 71c8ba35..e05599e8 100644 --- a/features/sci/pkg.include +++ b/features/sci/pkg.include @@ -1,6 +1,5 @@ -cloud-hypervisor-gl -edk2-cloud-hypervisor-gl -libvirt-daemon-driver-ch-gl multipath-tools open-iscsi openvswitch-switch +wget +xz-utils diff --git a/features/sslfips b/features/sslfips new file mode 120000 index 00000000..94a753fc --- /dev/null +++ b/features/sslfips @@ -0,0 +1 @@ +../gardenlinux/features/sslfips \ No newline at end of file diff --git a/flavors.yaml b/flavors.yaml index 5dd93a8a..8ed403a1 100644 --- a/flavors.yaml +++ b/flavors.yaml @@ -1,7 +1,15 @@ targets: - - name: metal + - name: metal category: baremetal flavors: + - features: + - chost + - _pxe + arch: amd64 + build: true + test: true + test-platform: false + publish: false - features: - sci - _pxe @@ -41,6 +49,14 @@ targets: test: true test-platform: false publish: false + - features: + - sci + - _iso + arch: amd64 + build: true + test: true + test-platform: false + publish: false # this is needed as bare_flavors step in build.yml is currently hard wired - name: bare category: container diff --git a/gardenlinux b/gardenlinux index 40e7dfa8..409e9b64 160000 --- a/gardenlinux +++ b/gardenlinux @@ -1 +1 @@ -Subproject commit 40e7dfa820cb8bd5e0317779f818d31464c18c63 +Subproject commit 409e9b640087ade203321a8d63bd1651f4677205 diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..1ba6e4a3 --- /dev/null +++ b/renovate.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "customManagers": [ + { + "customType": "regex", + "description": "Update libvirt package version for rel-1877-dev", + "managerFilePatterns": ["/features/sci/exec\\.config$/"], + "matchStrings": [ + "LIBVIRT_VERSION=\"(?[^%]+)%2Bbp1877\"" + ], + "depNameTemplate": "gardenlinux/package-libvirt", + "datasourceTemplate": "github-releases", + "extractVersionTemplate": "^(?.+)\\+bp1877$", + "versioningTemplate": "loose", + "autoReplaceStringTemplate": "LIBVIRT_VERSION=\"{{{newValue}}}%2Bbp1877\"" + }, + { + "customType": "regex", + "description": "Update cloud-hypervisor-gl package version for rel-1877-dev", + "managerFilePatterns": ["/features/sci/exec\\.config$/"], + "matchStrings": [ + "CLOUD_HYPERVISOR_VERSION=\"(?[^%]+)%2Bbp1877\"" + ], + "depNameTemplate": "gardenlinux/package-cloud-hypervisor-gl", + "datasourceTemplate": "github-releases", + "extractVersionTemplate": "^(?.+)\\+bp1877$", + "versioningTemplate": "loose", + "autoReplaceStringTemplate": "CLOUD_HYPERVISOR_VERSION=\"{{{newValue}}}%2Bbp1877\"" + }, + { + "customType": "regex", + "description": "Update edk2-cloud-hypervisor-gl package version for rel-1877-dev", + "managerFilePatterns": ["/features/sci/exec\\.config$/"], + "matchStrings": [ + "EDK2_VERSION=\"(?[^%]+)%2Bbp1877\"" + ], + "depNameTemplate": "gardenlinux/package-edk2-cloud-hypervisor-gl", + "datasourceTemplate": "github-releases", + "extractVersionTemplate": "^(?.+)\\+bp1877$", + "versioningTemplate": "loose", + "autoReplaceStringTemplate": "EDK2_VERSION=\"{{{newValue}}}%2Bbp1877\"" + } + ] +}