diff --git a/.github/workflows/podvm_mkosi_ubuntu.yaml b/.github/workflows/podvm_mkosi_ubuntu.yaml new file mode 100644 index 0000000000..b1142cdb43 --- /dev/null +++ b/.github/workflows/podvm_mkosi_ubuntu.yaml @@ -0,0 +1,224 @@ +name: Create Ubuntu Pod VM image with mkosi + +on: + workflow_dispatch: + inputs: + registry: + default: 'quay.io/confidential-containers' + required: false + type: string + image_tag: + default: '' + required: false + type: string + git_ref: + description: Git ref to checkout the cloud-api-adaptor repository. + required: true + type: string + arch: + description: Which arch we are building the mkosi image for + default: 'amd64' + required: false + type: string + debug: + description: Whether to build the image in debug mode + default: false + required: false + type: boolean + + workflow_call: + inputs: + registry: + default: 'quay.io/confidential-containers' + required: false + type: string + image_tag: + default: '' + required: false + type: string + git_ref: + description: Git ref to checkout the cloud-api-adaptor repository. + required: true + type: string + arch: + description: Which arch we are building the mkosi image for + default: 'amd64' + required: false + type: string + debug: + description: Whether to build the image in debug mode + default: false + required: false + type: boolean + secrets: + QUAY_PASSWORD: + required: true + outputs: + qcow2_oras_image: + description: The location of the qcow2 oras container this workflow pushed + value: ${{ jobs.build-image.outputs.qcow2_oras_image }} + docker_oci_image: + description: The location of the docker oci container image this workflow pushed + value: ${{ jobs.build-image.outputs.docker_oci_image }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: src/cloud-api-adaptor + +permissions: {} + +jobs: + build-image: + name: Build mkosi Ubuntu image for ${{ inputs.arch }} + runs-on: ${{ inputs.arch == 's390x' && 's390x' || 'ubuntu-24.04' }} + permissions: + contents: read # Required if we want to run on a fork? + packages: write # Required to publish the oras package to ghcr + id-token: write # Required to publish the attestation provenance to ghcr + attestations: write # Required to publish the attestation provenance to ghcr + outputs: + qcow2_oras_image: ${{ steps.publish_oras_qcow2.outputs.image }}:${{ steps.publish_oras_qcow2.outputs.tag }} + docker_oci_image: ${{ steps.build_docker_oci.outputs.image }} + steps: + - name: Checkout + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + ref: "${{ inputs.git_ref }}" + + # Required by rootless mkosi + - name: Un-restrict user namespaces + if: inputs.arch == 'amd64' + run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + + - name: Rebase the code + if: github.event_name == 'pull_request_target' + working-directory: ./ + run: | + ./hack/ci-helper.sh rebase-atop-of-the-latest-target-branch + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Login to quay Container Registry + if: ${{ startsWith(inputs.registry, 'quay.io') }} + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + registry: quay.io + username: ${{ vars.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + + - name: Login to the ghcr Container registry + if: ${{ startsWith(inputs.registry, 'ghcr.io') }} + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + alien \ + bubblewrap \ + dnf \ + qemu-utils \ + uidmap + sudo snap install yq + + - name: Read properties from versions.yaml + run: | + echo "MKOSI_VERSION=$(yq -e '.tools.mkosi' versions.yaml)" >> "$GITHUB_ENV" + echo "ORAS_VERSION=$(yq -e '.tools.oras' versions.yaml)" >> "$GITHUB_ENV" + + - uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4 + with: + version: ${{ env.ORAS_VERSION }} + + - name: Build binaries for Ubuntu + id: build_binaries + working-directory: src/cloud-api-adaptor/podvm-mkosi + run: make binaries + env: + ARCH: ${{ inputs.arch }} + PODVM_DISTRO: ubuntu + + - name: Build mkosi debug image + if: ${{ inputs.debug == 'true' }} + working-directory: src/cloud-api-adaptor/podvm-mkosi + run: make image-debug + env: + PODVM_DISTRO: ubuntu + + - name: Build mkosi image + if: ${{ inputs.debug != 'true' }} + working-directory: src/cloud-api-adaptor/podvm-mkosi + run: make image + env: + PODVM_DISTRO: ubuntu + + - name: Upload the qcow2 with oras + id: publish_oras_qcow2 + working-directory: src/cloud-api-adaptor/podvm-mkosi + run: | + mkdir oras + cd oras + cp ../build/podvm-*.qcow2 . + tar cJf podvm.tar.xz podvm-*.qcow2 + image=${REGISTRY}/podvm-generic-ubuntu + if [ "${DEBUG}" = "true" ]; then + image=${image}-debug + fi + image=${image}-${ARCH} + tag=$(git rev-parse --short HEAD) + oras push "${image}:${tag}" podvm.tar.xz + + # If the input has a different image-tag then also push it with that tag + if [ -n "$IMAGE_TAG}" ] && [ "${IMAGE_TAG}" != "${tag}" ];then + oras push "${image}:${IMAGE_TAG}" podvm.tar.xz + fi + + # add image and digest to output for attestation + echo "image=${image}" >> "$GITHUB_OUTPUT" + digest="$(oras manifest fetch "${image}:${tag}" --descriptor | jq -r .digest)" + echo "digest=${digest}" >> "$GITHUB_OUTPUT" + echo "tag=${tag}" >> "$GITHUB_OUTPUT" + env: + ARCH: ${{ inputs.arch }} + DEBUG: ${{ inputs.debug }} + IMAGE_TAG: ${{ inputs.image_tag }} + REGISTRY: ${{ inputs.registry }} + + - uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 + with: + subject-name: ${{ steps.publish_oras_qcow2.outputs.image }} + subject-digest: ${{ steps.publish_oras_qcow2.outputs.digest }} + push-to-registry: true + + - name: Clean up some space for the docker provider build + working-directory: src/cloud-api-adaptor/podvm-mkosi + run: | + sudo du --max-depth=2 /home/runner || true + sudo du --max-depth=2 /var/lib || true + sudo rm -rf ./build + sudo rm -rf ./mkosi.cache + + - name: Build and push image for docker provider + id: build_docker_oci + working-directory: src/cloud-api-adaptor/podvm-mkosi + run: | + tag=$(git rev-parse --short HEAD) + PODVM_TAG=${tag} make image-container + PODVM_TAG=${tag} make push-image-container + arch=$(uname -m) + arch=${arch/x86_64/amd64} + echo "image=${REGISTRY}/podvm-docker-image-${arch}:${tag}" >> "$GITHUB_OUTPUT" + env: + REGISTRY: ${{ inputs.registry }} + PODVM_DISTRO: ubuntu diff --git a/.github/workflows/podvm_smoketest_ubuntu.yaml b/.github/workflows/podvm_smoketest_ubuntu.yaml new file mode 100644 index 0000000000..3dfccb138c --- /dev/null +++ b/.github/workflows/podvm_smoketest_ubuntu.yaml @@ -0,0 +1,129 @@ +name: Ubuntu podvm smoke test + +on: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: {} + +jobs: + build: + name: Build the image + runs-on: 'ubuntu-24.04' + + defaults: + run: + working-directory: src/cloud-api-adaptor/podvm-mkosi + + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + # Required by rootless mkosi on Ubuntu 24.04 + - name: Un-restrict user namespaces + run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + genisoimage \ + qemu-utils + sudo snap install yq + + - name: Read properties from versions.yaml + working-directory: src/cloud-api-adaptor + run: | + { + echo "MKOSI_VERSION=$(yq -e '.tools.mkosi' versions.yaml)"; + echo "ORAS_VERSION=$(yq -e '.tools.oras' versions.yaml)"; + echo "KATA_REF=$(yq -e '.oci.kata-containers.reference' versions.yaml)"; + echo "KATA_REG=$(yq -e '.oci.kata-containers.registry' versions.yaml)"; + } >> "$GITHUB_ENV" + + - uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4 + with: + version: ${{ env.ORAS_VERSION }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build binaries + run: make binaries + env: + PODVM_DISTRO: ubuntu + + - name: Disable TLS for agent-protocol-forwarder + run: | + mkdir -p ./resources/binaries-tree/etc/default + echo "TLS_OPTIONS=-disable-tls" > ./resources/binaries-tree/etc/default/agent-protocol-forwarder + + - name: Build Ubuntu image + run: make image-debug + env: + PODVM_DISTRO: ubuntu + + # Upload the image to the artifacts + - name: Upload qcow2 artifact + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: podvm-build-ubuntu + path: src/cloud-api-adaptor/podvm-mkosi/build/podvm-ubuntu-amd64.qcow2 + + test: + name: Test the image + # We're pinning the runner to 22.04 b/c libvirt struggles with the + # OVMF_CODE_4M firmware that is default on 24.04. + runs-on: 'ubuntu-22.04' + needs: build + + strategy: + matrix: + test-mode: + - name: podvm-mkosi-ubuntu + mode: basic + - name: podvm-mkosi-with-scratch-space-ubuntu + mode: scratch-space + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Install test dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + genisoimage \ + qemu-utils\ + socat \ + virt-manager + sudo snap install yq + + - name: Read properties from versions.yaml + working-directory: src/cloud-api-adaptor + run: | + { + echo "KATA_REF=$(yq -e '.oci.kata-containers.reference' versions.yaml)"; + echo "KATA_REG=$(yq -e '.oci.kata-containers.registry' versions.yaml)"; + } >> "$GITHUB_ENV" + + - name: Install kata-agent-ctl + run: | + oras pull "${KATA_REG}/agent-ctl:${KATA_REF}-x86_64" + tar --zstd -xf kata-static-agent-ctl.tar.zst + cp opt/kata/bin/kata-agent-ctl /usr/local/bin + + - name: Download qcow2 artifact + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + with: + name: podvm-build-ubuntu + path: . + + - name: Run smoke test (${{ matrix.test-mode.name }}) + env: + TEST_MODE: ${{ matrix.test-mode.mode }} + run: src/cloud-api-adaptor/podvm/hack/smoke_test.sh -m "$TEST_MODE" podvm-ubuntu-amd64.qcow2 diff --git a/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi b/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi index 4e4a5e6e76..ada4dfafaf 100644 --- a/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi +++ b/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi @@ -35,7 +35,7 @@ COPY mkosi.skeleton-debug /image/mkosi.skeleton-debug COPY mkosi.skeleton-sftp /image/mkosi.skeleton-sftp COPY mkosi.workspace /image/mkosi.workspace COPY resources /image/resources -COPY mkosi.conf /image/mkosi.conf +COPY mkosi.conf.fedora /image/mkosi.conf RUN --security=insecure mkosi --profile=$PROFILE --image-version=$IMAGE_VERSION FROM scratch diff --git a/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi.ubuntu b/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi.ubuntu new file mode 100644 index 0000000000..ce50ef1705 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.mkosi.ubuntu @@ -0,0 +1,47 @@ +# syntax=docker/dockerfile:1.5.0-labs +FROM ubuntu:24.04 AS builder + +ARG MKOSI_VERSION="v22" +ARG PROFILE="debug" +ARG IMAGE_VERSION="0.0.0" + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y \ + bubblewrap \ + git \ + cpio \ + systemd-repart \ + kmod \ + systemd-boot-efi \ + libcryptsetup12 \ + squashfs-tools \ + systemd-ukify \ + dosfstools \ + mtools \ + python3 \ + zstd + +RUN mkdir -p /build +WORKDIR /build +RUN git clone -b "$MKOSI_VERSION" https://github.com/systemd/mkosi +ENV PATH="/build/mkosi/bin:$PATH" +RUN mkosi --version + +RUN mkdir /image +WORKDIR /image +COPY mkosi.postinst /image/mkosi.postinst +COPY mkosi.presets /image/mkosi.presets +COPY mkosi.profiles /image/mkosi.profiles +COPY mkosi.skeleton /image/mkosi.skeleton +COPY mkosi.skeleton-debug /image/mkosi.skeleton-debug +COPY mkosi.skeleton-sftp /image/mkosi.skeleton-sftp +COPY mkosi.workspace /image/mkosi.workspace +COPY resources /image/resources +COPY mkosi.conf.ubuntu /image/mkosi.conf +RUN --security=insecure mkosi --profile=$PROFILE --image-version=$IMAGE_VERSION + +FROM scratch + +COPY --from=builder /image/build/system.raw / diff --git a/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.podvm_docker_provider.ubuntu b/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.podvm_docker_provider.ubuntu new file mode 100644 index 0000000000..863b45099d --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/Dockerfile.podvm_docker_provider.ubuntu @@ -0,0 +1,64 @@ +# Adapted from https://github.com/kubernetes-sigs/kind/blob/main/images/base/Dockerfile + +ARG BASE_IMAGE=ubuntu:24.04 + +FROM $BASE_IMAGE AS iptables + +ARG DEBIAN_FRONTEND=noninteractive + +RUN echo "Building iptables-wrapper... " \ + && apt-get update \ + && apt-get install -y git golang build-essential \ + && git clone https://github.com/kubernetes-sigs/iptables-wrappers.git /iptables \ + && cd /iptables \ + && make BIN_DIR=. build \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +FROM $BASE_IMAGE AS base + +ARG DEBIAN_FRONTEND=noninteractive + +RUN echo "Installing Packages ..." \ + && apt-get update \ + && apt-get install -y \ + systemd \ + conntrack iptables nftables iproute2 ethtool util-linux kmod \ + libseccomp2 pigz fuse-overlayfs \ + nfs-common systemd-sysv \ + bash ca-certificates curl jq procps \ + && rm -f /lib/systemd/system/multi-user.target.wants/* \ + && rm -f /etc/systemd/system/*.wants/* \ + && rm -f /lib/systemd/system/local-fs.target.wants/* \ + && rm -f /lib/systemd/system/sockets.target.wants/*udev* \ + && rm -f /lib/systemd/system/sockets.target.wants/*initctl* \ + && rm -f /lib/systemd/system/basic.target.wants/* \ + && echo "ReadKMsg=no" >> /etc/systemd/journald.conf \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN echo "Enabling / Disabling services ... " \ + && systemctl mask systemd-binfmt.service \ + && systemctl enable systemd-logind dbus.socket + +RUN --mount=type=cache,target=/iptables,from=iptables,source=/iptables,readonly \ + cd /iptables && ./iptables-wrapper-installer.sh --no-sanity-check --no-cleanup + +# Add podvm resources +COPY ./resources/binaries-tree/etc/ /etc/ +COPY ./resources/binaries-tree/usr/ /usr/ +COPY ./resources/binaries-tree/pause_bundle/ /pause_bundle/ + +RUN curl -LO https://raw.githubusercontent.com/confidential-containers/cloud-api-adaptor/main/src/cloud-api-adaptor/podvm/qcow2/misc-settings.sh + +RUN PODVM_DISTRO=ubuntu CLOUD_PROVIDER=generic bash ./misc-settings.sh + +COPY --chmod=0755 entrypoint.sh /usr/local/bin/ + +# https://systemd.io/CONTAINER_INTERFACE/ +ENV container=docker + +# systemd exits on SIGRTMIN+3, not SIGTERM (which re-executes it) +# https://bugzilla.redhat.com/show_bug.cgi?id=1201657 +STOPSIGNAL SIGRTMIN+3 +ENTRYPOINT [ "/usr/local/bin/entrypoint.sh", "/sbin/init" ] diff --git a/src/cloud-api-adaptor/podvm-mkosi/Makefile b/src/cloud-api-adaptor/podvm-mkosi/Makefile index a3b6d05cf6..e043169471 100644 --- a/src/cloud-api-adaptor/podvm-mkosi/Makefile +++ b/src/cloud-api-adaptor/podvm-mkosi/Makefile @@ -35,12 +35,22 @@ sftp:binaries image-sftp .PHONY: container container: binaries image-container +ifeq ($(PODVM_DISTRO),ubuntu) +DISTRO_IMAGE := ubuntu:24.04 +DISTRO_RELEASE := 24.04 +PKG_INSTALL := apt-get update && apt-get install -y +else +DISTRO_IMAGE := fedora:41 +DISTRO_RELEASE := 41 +PKG_INSTALL := dnf install -y +endif + define run_mkosi_in_container docker run --rm --privileged \ -v "$(shell pwd)":/workspace \ -w /workspace \ - fedora:41 \ - bash -c "dnf install -y bubblewrap coreutils git python3; mkdir -p /build; git clone -b $(MKOSI_VERSION) https://github.com/systemd/mkosi /build/mkosi; export PATH="/build/mkosi/bin:$$PATH"; mkosi --tools-tree=default --tools-tree-release=41 $(1)" + $(DISTRO_IMAGE) \ + bash -c "$(PKG_INSTALL) bubblewrap coreutils git python3; mkdir -p /build; git clone -b $(MKOSI_VERSION) https://github.com/systemd/mkosi /build/mkosi; export PATH="/build/mkosi/bin:$$PATH"; mkosi --tools-tree=default --tools-tree-release=$(DISTRO_RELEASE) $(1)" endef binaries: @@ -72,7 +82,7 @@ endif $(if $(DEFAULT_AGENT_POLICY_FILE),--build-arg DEFAULT_AGENT_POLICY_FILE=$(DEFAULT_AGENT_POLICY_FILE),) \ $(if $(filter $(PUSH),true),,-o type=local,dest="./resources/binaries-tree") \ $(DOCKER_OPTS) \ - -f ../podvm/Dockerfile.podvm_binaries.fedora ../../ + -f ../podvm/Dockerfile.podvm_binaries.$(PODVM_DISTRO) ../../ PHONY: insecure-builder insecure-builder: @@ -94,7 +104,7 @@ else ifeq ($(ARCH),s390x) else mkdir -p build docker buildx build \ - -f Dockerfile.mkosi \ + -f Dockerfile.mkosi$(if $(filter $(PODVM_DISTRO),ubuntu),.ubuntu,) \ -t $(PODVM_IMAGE) \ --build-arg PROFILE=production \ --build-arg IMAGE_VERSION \ @@ -121,7 +131,7 @@ else mkdir -p build docker buildx build \ - -f Dockerfile.mkosi \ + -f Dockerfile.mkosi$(if $(filter $(PODVM_DISTRO),ubuntu),.ubuntu,) \ -t $(PODVM_IMAGE) \ --build-arg PROFILE=debug \ --build-arg IMAGE_VERSION \ @@ -147,7 +157,7 @@ else ifeq ($(ARCH),s390x) else mkdir -p build docker buildx build \ - -f Dockerfile.mkosi \ + -f Dockerfile.mkosi$(if $(filter $(PODVM_DISTRO),ubuntu),.ubuntu,) \ -t $(PODVM_IMAGE) \ --build-arg PROFILE=sftp \ --build-arg IMAGE_VERSION \ @@ -166,7 +176,7 @@ image-container: docker buildx build \ -t $(PODVM_CONTAINER_NAME):$(PODVM_TAG) \ -t $(PODVM_CONTAINER_NAME):latest \ - -f Dockerfile.podvm_docker_provider . + -f Dockerfile.podvm_docker_provider$(if $(filter $(PODVM_DISTRO),ubuntu),.ubuntu,) . PHONY: push-image push-image: diff --git a/src/cloud-api-adaptor/podvm-mkosi/README.md b/src/cloud-api-adaptor/podvm-mkosi/README.md index e9b39ac169..4de3b78764 100644 --- a/src/cloud-api-adaptor/podvm-mkosi/README.md +++ b/src/cloud-api-adaptor/podvm-mkosi/README.md @@ -36,6 +36,18 @@ Likewise `TEE_PLATFORM=az-cvm-vtpm` will enable support for Azure vTPM attesters Refer to the following [doc](https://github.com/confidential-containers/guest-components/tree/main?tab=readme-ov-file#build) for accepted values of TEE_PLATFORM. +#### Building Ubuntu 24.04 images + +By default, Fedora images are built. To build Ubuntu 24.04 images: + +```sh +PODVM_DISTRO=ubuntu make # rebuild builder, binaries and OS image for Ubuntu +``` + +```sh +PODVM_DISTRO=ubuntu make image # only rebuild OS image for Ubuntu +``` + ### Upload the image to the desired cloud provider You can upload the image with the tool of your choice, but the recommended way is using [uplosi](https://github.com/edgelesssys/uplosi). Follow the uplosi readme to configure your upload for the desired cloud provider. Then run: @@ -68,6 +80,11 @@ make image-debug # this will only rebuild the OS image Set `TEE_PLATFORM` as explained previously, to add support for specific attester in the debug image. +For Ubuntu debug images: +```sh +PODVM_DISTRO=ubuntu make debug +``` + Notice that building a debug image will overwrite any previous existing debug or production image. For using SSH, create a file `resources/authorized_keys` with your SSH public key. Ensure the permissions @@ -98,8 +115,9 @@ You can easily place additional files in `resources/binaries-tree` after it has `make binaries` step. Notice that systemd units need to be enabled in the presets and links in the tree won't be copied into the image. You can use `./mkosi.postinst` script to create symlinks. -If you want to add additional packages to the image, you can define `mkosi.presets/system/mkosi.conf.d/fedora-extra.conf`: +If you want to add additional packages to the image, you can define distribution-specific config files: +For Fedora (`mkosi.presets/system/mkosi.conf.d/fedora-extra.conf`): ```ini [Match] Distribution=fedora @@ -109,6 +127,16 @@ Packages= cowsay ``` +For Ubuntu (`mkosi.presets/system/mkosi.conf.d/ubuntu-extra.conf`): +```ini +[Match] +Distribution=ubuntu + +[Content] +Packages= + cowsay +``` + ## Limitations The following limitations apply to these images. Notice that the limitations are intentional to diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf index ef67a734de..b3d49f182b 100644 --- a/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf @@ -1,3 +1,15 @@ +# This file is kept for reference only. +# The actual configuration files used are: +# - mkosi.conf.fedora (for Fedora builds) +# - mkosi.conf.ubuntu (for Ubuntu builds) +# +# The Dockerfiles copy the appropriate distribution-specific config +# to mkosi.conf at build time. +# +# If you need to modify the base configuration, update BOTH: +# - mkosi.conf.fedora +# - mkosi.conf.ubuntu + [Content] Environment=SOURCE_DATE_EPOCH=0 RemoveFiles=/var/log @@ -7,4 +19,4 @@ RemoveFiles=/var/cache OutputDirectory=build [Distribution] -Distribution=fedora +# Distribution is set in mkosi.conf.fedora or mkosi.conf.ubuntu diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf.fedora b/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf.fedora new file mode 100644 index 0000000000..ef67a734de --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf.fedora @@ -0,0 +1,10 @@ +[Content] +Environment=SOURCE_DATE_EPOCH=0 +RemoveFiles=/var/log +RemoveFiles=/var/cache + +[Output] +OutputDirectory=build + +[Distribution] +Distribution=fedora diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf.ubuntu b/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf.ubuntu new file mode 100644 index 0000000000..18a5d40f58 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.conf.ubuntu @@ -0,0 +1,10 @@ +[Content] +Environment=SOURCE_DATE_EPOCH=0 +RemoveFiles=/var/log +RemoveFiles=/var/cache + +[Output] +OutputDirectory=build + +[Distribution] +Distribution=ubuntu diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/ubuntu-s390x.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/ubuntu-s390x.conf new file mode 100644 index 0000000000..54f4353e6d --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/ubuntu-s390x.conf @@ -0,0 +1,9 @@ +[Match] +Distribution=ubuntu +Architecture=s390x + +[Content] +Packages=linux-image-generic + +[Host] +ToolsTree=default diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/ubuntu.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/ubuntu.conf new file mode 100644 index 0000000000..66b6588716 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/ubuntu.conf @@ -0,0 +1,11 @@ +[Match] +Distribution=ubuntu + +[Distribution] +Distribution=ubuntu +Release=noble + +[Content] +CleanPackageMetadata=true +Packages=dmsetup +RemoveFiles=/var/cache/ldconfig/aux-cache diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-bootable.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-bootable.conf new file mode 100644 index 0000000000..106526a70f --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-bootable.conf @@ -0,0 +1,6 @@ +[Match] +Distribution=ubuntu +Architecture=!s390x + +[Content] +Packages=systemd-boot-efi diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug-aux.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug-aux.conf new file mode 100644 index 0000000000..d0b4d851ec --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug-aux.conf @@ -0,0 +1,9 @@ +[Match] +Distribution=ubuntu +Profile=debug +# Overwrite default ssh config, but conflict with +# cloud-init which is installed for s390x. +Architecture=!s390x + +[Content] +ExtraTrees=../../mkosi.skeleton-debug diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug-keys.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug-keys.conf new file mode 100644 index 0000000000..23d7b96a01 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug-keys.conf @@ -0,0 +1,7 @@ +[Match] +Distribution=ubuntu +Profile=debug +PathExists=../../resources/authorized_keys + +[Content] +SkeletonTrees=../../resources/authorized_keys:/root/.ssh/authorized_keys diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug.conf new file mode 100644 index 0000000000..c189d75fb2 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-debug.conf @@ -0,0 +1,22 @@ +[Match] +Distribution=ubuntu +Profile=debug + +[Content] +Autologin=true +KernelCommandLine=rd.shell +KernelCommandLine=systemd.setenv=SYSTEMD_SULOGIN_FORCE=1 +Packages= + nano + vim + strace + apt + openssh-client + openssh-server + file + iputils-ping + curl + wget + ncurses-bin + less + qemu-guest-agent diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-s390x.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-s390x.conf new file mode 100644 index 0000000000..0cd2bec140 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-s390x.conf @@ -0,0 +1,19 @@ +[Match] +Distribution=ubuntu +Architecture=s390x + +[Distribution] +Distribution=ubuntu +Release=noble + +[Content] +Bootable=no +Packages=s390-tools + cloud-init + cloud-guest-utils + +[Output] +Format=directory + +[Host] +ToolsTree=default diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-sftp.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-sftp.conf new file mode 100644 index 0000000000..fbf31085f6 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu-sftp.conf @@ -0,0 +1,15 @@ +[Match] +Distribution=ubuntu +Profile=sftp +PathExists=../../resources/authorized_keys + +[Content] +Autologin=true +KernelCommandLine=rd.shell +KernelCommandLine=systemd.setenv=SYSTEMD_SULOGIN_FORCE=1 +#Need to override the sshd-keygen script +ExtraTrees=../../mkosi.skeleton-sftp +ExtraTrees=../../resources/authorized_keys:/home/peerpod/.ssh/authorized_keys +Packages= + openssh-client + openssh-server diff --git a/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu.conf b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu.conf new file mode 100644 index 0000000000..75ebfa5946 --- /dev/null +++ b/src/cloud-api-adaptor/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/ubuntu.conf @@ -0,0 +1,28 @@ +[Match] +Distribution=ubuntu + +[Distribution] +Distribution=ubuntu +Release=noble + +[Content] +CleanPackageMetadata=true +SkeletonTrees=../../resources/binaries-tree +Packages= + linux-image-generic + udev + util-linux + systemd + dbus + tpm2-tools + iproute2 + iptables + e2fsprogs + cryptsetup + +RemoveFiles=/etc/issue +RemoveFiles=/etc/issue.net + +# Remove for reproducible builds +RemoveFiles=/var/log +RemoveFiles=/var/cache diff --git a/src/cloud-api-adaptor/podvm/Dockerfile.podvm_binaries.ubuntu b/src/cloud-api-adaptor/podvm/Dockerfile.podvm_binaries.ubuntu new file mode 100644 index 0000000000..acb372af53 --- /dev/null +++ b/src/cloud-api-adaptor/podvm/Dockerfile.podvm_binaries.ubuntu @@ -0,0 +1,111 @@ +# syntax=docker/dockerfile:1.5-labs +# Copyright Confidential Containers Contributors +# +# SPDX-License-Identifier: Apache-2.0 +# +# Build binaries for mkosi podvm image +# +FROM ubuntu:24.04 AS builder + +ARG ARCH="x86_64" +ARG GO_ARCH="amd64" +ARG DISTRO_ARCH="amd64" +ARG YQ_ARCH="amd64" +ARG PROTOC_ARCH="x86_64" +ARG GO_VERSION +ARG PROTOC_VERSION +ARG YQ_VERSION +ARG YQ_CHECKSUM +ARG ORAS_VERSION + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y build-essential gnupg git perl pkg-config \ + libseccomp-dev libgpgme-dev libdevmapper-dev unzip libassuan-dev \ + libssl-dev libtss2-dev clang xz-utils zstd jq curl ca-certificates && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ADD https://dl.google.com/go/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz go${GO_VERSION}.linux-${GO_ARCH}.tar.gz +RUN rm -rf /usr/local/go && tar -C /usr/local -xzf go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && rm -f go${GO_VERSION}.linux-${GO_ARCH}.tar.gz + +ENV PATH="/usr/local/go/bin:$PATH" + +RUN if [ "$(uname -m)" != "s390x" ]; then \ + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \ + chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \ + apt-get update && \ + apt-get install -y gh && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/*; \ + else git clone https://github.com/cli/cli.git gh-cli && \ + cd gh-cli && mkdir -p /usr/local/gh && make install prefix=/usr/local/gh && cd .. && \ + rm -rf gh-cli; fi + +ENV PATH="/usr/local/gh/bin:$PATH" + +ADD https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${YQ_ARCH} /usr/local/bin/yq +RUN echo "${YQ_CHECKSUM#sha256:} /usr/local/bin/yq" | sha256sum -c +RUN chmod a+x /usr/local/bin/yq + +ADD https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip +RUN unzip protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip -d /usr/local && rm -f protoc-${PROTOC_VERSION}-linux-${PROTOC_ARCH}.zip + +ADD https://github.com/oras-project/oras/releases/download/v${ORAS_VERSION}/oras_${ORAS_VERSION}_linux_${DISTRO_ARCH}.tar.gz oras_${ORAS_VERSION}_linux_${DISTRO_ARCH}.tar.gz +RUN rm -rf /usr/local/bin/oras && tar -C /usr/local/bin -xzf oras_${ORAS_VERSION}_linux_${DISTRO_ARCH}.tar.gz && rm -f oras_${ORAS_VERSION}_linux_${DISTRO_ARCH}.tar.gz + +WORKDIR /src + +ENV GOPATH=/src + +FROM builder AS podvm_binaries_builder + +ARG CLOUD_PROVIDER +ARG PODVM_DISTRO=ubuntu +ARG GUEST_COMPONENTS_VERSION +ARG GUEST_COMPONENTS_REPO +# By default AA will be built with the `all-attesters` feature, +# which doesn't compile on ubuntu. +ARG TEE_PLATFORM=none +# If not provided, uses system architecture +ARG ARCH +#This is the name of the policy file under +#files/etc/kata-opa +ARG DEFAULT_AGENT_POLICY_FILE=allow-all.rego +ARG AUTHFILE +ARG PAUSE_REPO +ARG PAUSE_VERSION +ARG PAUSE_BIN +ARG IMAGE_NAME +ARG VERIFY_PROVENANCE + +ENV AUTHFILE=${AUTHFILE} +ENV PAUSE_REPO=${PAUSE_REPO} +ENV PAUSE_VERSION=${PAUSE_VERSION} +ENV PAUSE_BIN=${PAUSE_BIN} +ENV CLOUD_PROVIDER=${CLOUD_PROVIDER} +ENV PODVM_DISTRO=${PODVM_DISTRO} +ENV GUEST_COMPONENTS_VERSION=${GUEST_COMPONENTS_VERSION} +ENV GUEST_COMPONENTS_REPO=${GUEST_COMPONENTS_REPO} +ENV TEE_PLATFORM=${TEE_PLATFORM} +ENV ARCH=${ARCH} +ENV DEFAULT_AGENT_POLICY_FILE=${DEFAULT_AGENT_POLICY_FILE} +ENV IMAGE_NAME=${IMAGE_NAME} +ENV VERIFY_PROVENANCE=${VERIFY_PROVENANCE} + +# Set these as they are required in the Makefile +ENV IMAGE_URL="none" +ENV IMAGE_CHECKSUM="none" + +COPY . /src + +WORKDIR /src/cloud-api-adaptor/podvm +# Installs add-ons for foreign target, if required +RUN ./hack/cross-build-extras.sh + +RUN LIBC=gnu make binaries + +FROM scratch +COPY --from=podvm_binaries_builder /src/cloud-api-adaptor/podvm/files /