diff --git a/docker/base.dockerfile b/docker/base.dockerfile index afe90c1d..2fd6c589 100644 --- a/docker/base.dockerfile +++ b/docker/base.dockerfile @@ -1,5 +1,5 @@ -FROM csegarragonz/dotfiles:0.2.0 AS dotfiles -FROM ubuntu:22.04 +FROM csegarragonz/dotfiles:0.3.0 AS dotfiles +FROM ubuntu:24.04 # --------------------------- # Work. Env. Set-Up (do this first to benefit from caching) @@ -15,6 +15,7 @@ RUN apt update \ g++ \ gcc \ git \ + gpg \ gopls \ libclang-dev \ libdevmapper-dev \ diff --git a/docker/containerd.dockerfile b/docker/containerd.dockerfile index bb5a61fb..462eb09d 100644 --- a/docker/containerd.dockerfile +++ b/docker/containerd.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 # --------------------------- # containerd source set-up diff --git a/docker/kata.dockerfile b/docker/kata.dockerfile index 6ebaf544..f12932bc 100644 --- a/docker/kata.dockerfile +++ b/docker/kata.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 # --------------------------- # Kata Containers source set-up @@ -7,8 +7,7 @@ FROM ghcr.io/sc2-sys/base:0.10.0 # Install APT dependencies RUN apt install -y \ libseccomp-dev \ - musl-tools \ - wget + musl-tools # --------------------------- # Build Kata diff --git a/docker/nydus.dockerfile b/docker/nydus.dockerfile index c7a53ab3..35baf1b3 100644 --- a/docker/nydus.dockerfile +++ b/docker/nydus.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 # --------------------------- # Nydus daemon set-up @@ -13,6 +13,7 @@ RUN mkdir -p ${CODE_DIR} \ ${CODE_DIR} \ && git config --global --add safe.directory ${CODE_DIR} \ && cd ${CODE_DIR} \ + && rustup toolchain install 1.75.0-x86_64-unknown-linux-gnu \ && DOCKER=false GOPROXY=https://proxy.golang.org make all-release WORKDIR ${CODE_DIR} diff --git a/docker/nydus_snapshotter.dockerfile b/docker/nydus_snapshotter.dockerfile index 9933094c..7e23284a 100644 --- a/docker/nydus_snapshotter.dockerfile +++ b/docker/nydus_snapshotter.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 # --------------------------- # Nydus snapshotter daemon set-up diff --git a/docker/ovmf.dockerfile b/docker/ovmf.dockerfile index b32e501f..eead9d7d 100644 --- a/docker/ovmf.dockerfile +++ b/docker/ovmf.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 RUN apt update \ && apt upgrade -y \ diff --git a/docker/svsm.dockerfile b/docker/svsm.dockerfile index c4ef2b95..ff5bbc09 100644 --- a/docker/svsm.dockerfile +++ b/docker/svsm.dockerfile @@ -1,11 +1,10 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 RUN apt update \ && apt upgrade -y \ && apt install -y \ autoconf \ autoconf-archive \ - libclang-dev \ libssl-dev \ pkg-config diff --git a/docker/svsm_kernel.dockerfile b/docker/svsm_kernel.dockerfile index bb1a73b8..c73d012a 100644 --- a/docker/svsm_kernel.dockerfile +++ b/docker/svsm_kernel.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 RUN apt update \ && apt upgrade -y \ diff --git a/docker/svsm_qemu.dockerfile b/docker/svsm_qemu.dockerfile index 45aaa24a..0c1b3bf0 100644 --- a/docker/svsm_qemu.dockerfile +++ b/docker/svsm_qemu.dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/sc2-sys/base:0.10.0 +FROM ghcr.io/sc2-sys/base:0.12.0 RUN apt update \ && apt upgrade -y \ diff --git a/tasks/__init__.py b/tasks/__init__.py index 9024b708..b15c1ab5 100644 --- a/tasks/__init__.py +++ b/tasks/__init__.py @@ -1,10 +1,10 @@ from invoke import Collection -from . import base from . import coco from . import containerd from . import cosign from . import demo_apps +from . import docker from . import format_code from . import gc from . import kernel @@ -26,11 +26,11 @@ from . import svsm ns = Collection( - base, coco, containerd, cosign, demo_apps, + docker, format_code, gc, k8s, diff --git a/tasks/base.py b/tasks/base.py deleted file mode 100644 index 932529a9..00000000 --- a/tasks/base.py +++ /dev/null @@ -1,22 +0,0 @@ -from invoke import task -from os.path import join -from subprocess import run -from tasks.util.env import BASE_IMAGE_TAG, PROJ_ROOT -from tasks.util.versions import GO_VERSION - - -@task -def build(ctx, nocache=False, push=False): - """ - Build base docker container - """ - docker_cmd = "docker build {} -t {} --build-arg GO_VERSION={} -f {} .".format( - "--no-cache" if nocache else "", - BASE_IMAGE_TAG, - GO_VERSION, - join(PROJ_ROOT, "docker", "base.dockerfile"), - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - - if push: - run(f"docker push {BASE_IMAGE_TAG}", shell=True, check=True) diff --git a/tasks/containerd.py b/tasks/containerd.py index 647e57ee..f83dedee 100644 --- a/tasks/containerd.py +++ b/tasks/containerd.py @@ -3,6 +3,8 @@ from os.path import join from subprocess import run from tasks.util.containerd import ( + CONTAINERD_IMAGE_TAG, + build_containerd_image, is_containerd_active, restart_containerd, wait_for_containerd_socket, @@ -13,8 +15,6 @@ CONF_FILES_DIR, CONTAINERD_CONFIG_FILE, CONTAINERD_CONFIG_ROOT, - GHCR_URL, - GITHUB_ORG, PROJ_ROOT, print_dotted_line, ) @@ -23,9 +23,6 @@ from time import sleep CONTAINERD_CTR_NAME = "containerd-workon" -CONTAINERD_IMAGE_TAG = ( - join(GHCR_URL, GITHUB_ORG, "containerd") + f":{CONTAINERD_VERSION}" -) CONTAINERD_BINARY_NAMES = [ "containerd", @@ -37,24 +34,12 @@ CONTAINERD_HOST_BINPATH = "/usr/bin" -def do_build(nocache=False): - docker_cmd = "docker build{} -t {} -f {} .".format( - " --no-cache" if nocache else "", - CONTAINERD_IMAGE_TAG, - join(PROJ_ROOT, "docker", "containerd.dockerfile"), - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - - @task def build(ctx, nocache=False, push=False): """ - Build the containerd fork for CoCo + Build the containerd fork for SC2 """ - do_build(nocache=nocache) - - if push: - run(f"docker push {CONTAINERD_IMAGE_TAG}", shell=True, check=True) + build_containerd_image(nocache=nocache, push=push) @task diff --git a/tasks/docker.py b/tasks/docker.py new file mode 100644 index 00000000..ad0aa847 --- /dev/null +++ b/tasks/docker.py @@ -0,0 +1,82 @@ +from invoke import task +from os.path import join +from tasks.svsm import build_svsm_image, build_svsm_kernel_image, build_svsm_qemu_image +from tasks.util.containerd import build_containerd_image +from tasks.util.docker import BASE_IMAGE_TAG, build_image +from tasks.util.env import PROJ_ROOT, print_dotted_line +from tasks.util.kata import build_kata_image +from tasks.util.nydus import build_nydus_image +from tasks.util.nydus_snapshotter import build_nydus_snapshotter_image +from tasks.util.ovmf import build_ovmf_image +from tasks.util.versions import ( + CONTAINERD_VERSION, + GO_VERSION, + KATA_VERSION, + NYDUS_VERSION, + NYDUS_SNAPSHOTTER_VERSION, + OVMF_VERSION, +) + + +def build_base_image(nocache, push, debug=True): + build_image( + BASE_IMAGE_TAG, + join(PROJ_ROOT, "docker", "base.dockerfile"), + build_args={"GO_VERSION": GO_VERSION}, + nocache=nocache, + push=push, + debug=debug, + ) + + +@task +def build_base(ctx, nocache=False, push=False): + """ + Build base docker container + """ + build_base_image(nocache, push) + + +@task +def build_all(ctx, nocache=False, push=False): + """ + Build all work-on container images + """ + print_dotted_line("Building base image") + build_base_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line(f"Building containerd image (v{CONTAINERD_VERSION})") + build_containerd_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line(f"Building kata image (v{KATA_VERSION})") + build_kata_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line(f"Building nydus image (v{NYDUS_VERSION})") + build_nydus_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line( + f"Building nydus-snapshotter image (v{NYDUS_SNAPSHOTTER_VERSION})" + ) + build_nydus_snapshotter_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line(f"Building OVMF image ({OVMF_VERSION})") + build_ovmf_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line("Building SVSM guest kernel image") + build_svsm_kernel_image(nocache, push, debug=False) + print("Success!") + + print_dotted_line("Building SVSM QEMU image") + build_svsm_qemu_image(nocache, push, debug=False) + print("Success!") + + # This must be after SVSM's qemu and kernel + print_dotted_line("Building SVSM IGVM image") + build_svsm_image(nocache, push, debug=False) + print("Success!") diff --git a/tasks/kata.py b/tasks/kata.py index 3548e45a..244f0d53 100644 --- a/tasks/kata.py +++ b/tasks/kata.py @@ -4,7 +4,6 @@ from tasks.util.containerd import restart_containerd from tasks.util.env import ( KATA_CONFIG_DIR, - KATA_IMAGE_TAG, KATA_IMG_DIR, KATA_ROOT, KATA_RUNTIMES, @@ -13,58 +12,13 @@ SC2_RUNTIMES, ) from tasks.util.kata import ( + build_kata_image, replace_agent as replace_kata_agent, replace_shim as replace_kata_shim, run_kata_workon_ctr, stop_kata_workon_ctr, ) from tasks.util.toml import read_value_from_toml, update_toml -from tasks.util.versions import RUST_VERSION - - -@task -def build(ctx, nocache=False, push=False): - """ - Build the Kata Containers workon docker image - """ - build_args = { - "RUST_VERSION": RUST_VERSION, - } - build_args_str = [ - "--build-arg {}={}".format(key, build_args[key]) for key in build_args - ] - build_args_str = " ".join(build_args_str) - - docker_cmd = "docker build {} {} -t {} -f {} .".format( - "--no-cache" if nocache else "", - build_args_str, - KATA_IMAGE_TAG, - join(PROJ_ROOT, "docker", "kata.dockerfile"), - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - - if push: - run(f"docker push {KATA_IMAGE_TAG}", shell=True, check=True) - - -@task -def cli(ctx, mount_path=join(PROJ_ROOT, "..", "kata-containers")): - """ - Get a working environemnt to develop Kata - """ - if mount_path is not None: - mount_path = abspath(mount_path) - - run_kata_workon_ctr(mount_path=mount_path) - run("docker exec -it {} bash".format(KATA_WORKON_CTR_NAME), shell=True, check=True) - - -@task -def stop(ctx): - """ - Remove the Kata developement environment - """ - stop_kata_workon_ctr() def set_log_level(log_level): @@ -91,8 +45,31 @@ def set_log_level(log_level): update_toml(conf_file_path, updated_toml_str) +@task +def build(ctx, nocache=False, push=False): + """ + Build the Kata Containers workon docker image + """ + build_kata_image(nocache, push) + + +@task +def cli(ctx, mount_path=join(PROJ_ROOT, "..", "kata-containers")): + """ + Get a working environemnt to develop Kata + """ + if mount_path is not None: + mount_path = abspath(mount_path) + + run_kata_workon_ctr(mount_path=mount_path) + run("docker exec -it {} bash".format(KATA_WORKON_CTR_NAME), shell=True, check=True) + + @task def enable_annotation(ctx, annotation, runtime="qemu-snp-sc2"): + """ + Enable Kata annotation in config file + """ conf_file_path = join(KATA_CONFIG_DIR, "configuration-{}.toml".format(runtime)) enabled_annotations = read_value_from_toml( conf_file_path, "hypervisor.qemu.enable_annotations" @@ -113,6 +90,9 @@ def enable_annotation(ctx, annotation, runtime="qemu-snp-sc2"): @task def hot_replace_agent(ctx, debug=False, runtime="qemu-snp-sc2"): + """ + Replace Kata Agent from built version in work-on container + """ replace_kata_agent( dst_initrd_path=join( KATA_IMG_DIR, "kata-containers-initrd-confidential-sc2.img" @@ -125,6 +105,9 @@ def hot_replace_agent(ctx, debug=False, runtime="qemu-snp-sc2"): @task def hot_replace_shim(ctx, runtime="qemu-snp-sc2"): + """ + Replace Kata Shim from built version in work-on container + """ replace_kata_shim( dst_shim_binary=join( KATA_ROOT, @@ -140,3 +123,11 @@ def hot_replace_shim(ctx, runtime="qemu-snp-sc2"): ) restart_containerd() + + +@task +def stop(ctx): + """ + Remove the Kata developement environment + """ + stop_kata_workon_ctr() diff --git a/tasks/kernel.py b/tasks/kernel.py index 5e090f93..b61f3bc6 100644 --- a/tasks/kernel.py +++ b/tasks/kernel.py @@ -129,6 +129,9 @@ def hot_replace_guest(ctx, debug=False): @task def install_host_kernel_from_upstream(ctx): + """ + Install host kernel from a stable release + """ # TODO: find a way to automate the grepping of deb files and kernel name kernel_ver = "6.13" kernel_name = f"{kernel_ver}.0-061300-generic" diff --git a/tasks/nydus.py b/tasks/nydus.py index 8609a53b..9ff91a54 100644 --- a/tasks/nydus.py +++ b/tasks/nydus.py @@ -2,32 +2,19 @@ from os.path import join from subprocess import run from tasks.util.docker import copy_from_ctr_image, is_ctr_running -from tasks.util.env import GHCR_URL, GITHUB_ORG, PROJ_ROOT, print_dotted_line -from tasks.util.nydus import NYDUS_IMAGE_HOST_PATH, NYDUSIFY_PATH +from tasks.util.env import PROJ_ROOT, print_dotted_line +from tasks.util.nydus import ( + NYDUS_IMAGE_HOST_PATH, + NYDUS_IMAGE_TAG, + NYDUSIFY_PATH, + build_nydus_image, +) from tasks.util.versions import NYDUS_VERSION NYDUS_CTR_NAME = "nydus-workon" -NYDUS_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, "nydus") + f":{NYDUS_VERSION}" - NYDUS_IMAGE_CTR_PATH = "/go/src/github.com/sc2-sys/nydus/target/release/nydus-image" -@task -def build(ctx, nocache=False, push=False): - """ - Build the nydusd and nydus-snapshotter images - """ - docker_cmd = "docker build {} -t {} -f {} .".format( - "--no-cache" if nocache else "", - NYDUS_IMAGE_TAG, - join(PROJ_ROOT, "docker", "nydus.dockerfile"), - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - - if push: - run(f"docker push {NYDUS_IMAGE_TAG}", shell=True, check=True) - - def do_install(): print_dotted_line(f"Installing nydus image services (v{NYDUS_VERSION})") @@ -47,11 +34,11 @@ def do_install(): @task -def install(ctx): +def build(ctx, nocache=False, push=False): """ - Install the nydusify CLI tool + Build the nydusd and nydus-snapshotter images """ - do_install() + build_nydus_image(nocache, push) @task @@ -80,20 +67,6 @@ def cli(ctx, mount_path=join(PROJ_ROOT, "..", "nydus")): ) -@task -def stop(ctx): - """ - Remove the Kata developement environment - """ - result = run( - "docker rm -f {}".format(NYDUS_CTR_NAME), - shell=True, - check=True, - capture_output=True, - ) - assert result.returncode == 0 - - @task def hot_replace(ctx): """ @@ -110,3 +83,25 @@ def hot_replace(ctx): ) result = run(docker_cmd, shell=True, capture_output=True) assert result.returncode == 0 + + +@task +def install(ctx): + """ + Install the nydusify CLI tool + """ + do_install() + + +@task +def stop(ctx): + """ + Remove the Kata developement environment + """ + result = run( + "docker rm -f {}".format(NYDUS_CTR_NAME), + shell=True, + check=True, + capture_output=True, + ) + assert result.returncode == 0 diff --git a/tasks/nydus_snapshotter.py b/tasks/nydus_snapshotter.py index 7abd96f0..142fbf57 100644 --- a/tasks/nydus_snapshotter.py +++ b/tasks/nydus_snapshotter.py @@ -10,14 +10,16 @@ COCO_ROOT, CONTAINERD_CONFIG_FILE, CONTAINERD_CONFIG_ROOT, - GHCR_URL, - GITHUB_ORG, KATA_RUNTIMES, LOCAL_REGISTRY_URL, PROJ_ROOT, SC2_RUNTIMES, print_dotted_line, ) +from tasks.util.nydus_snapshotter import ( + NYDUS_SNAPSHOTTER_IMAGE_TAG, + build_nydus_snapshotter_image, +) from tasks.util.toml import read_value_from_toml, update_toml from tasks.util.versions import NYDUS_SNAPSHOTTER_VERSION from time import sleep @@ -38,9 +40,6 @@ NYDUS_SNAPSHOTTER_HOST_SHARE_CONFIG, ] NYDUS_SNAPSHOTTER_CTR_NAME = "nydus-snapshotter-workon" -NYDUS_SNAPSHOTTER_IMAGE_TAG = ( - join(GHCR_URL, GITHUB_ORG, "nydus-snapshotter") + f":{NYDUS_SNAPSHOTTER_VERSION}" -) NYDUS_SNAPSHOTTER_BINARY_NAMES = [ "containerd-nydus-grpc", @@ -53,76 +52,6 @@ # https://github.com/containerd/nydus-snapshotter/blob/main/misc/snapshotter/config.toml -def restart_nydus_snapshotter(): - run("sudo service nydus-snapshotter restart", shell=True, check=True) - - -def wait_for_snapshot_metadata_to_be_gced(snapshotter, debug=False): - """ - After restarting containerd it may take a while for the GC to kick in and - delete the metadata corresponding to previous snapshots. This metadata - is stored in a Bolt DB in /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db - - Annoyingly, it is hard to manually delete files from the database w/out - writting a small Go script. Instead, we rely on the bbolt CLI tool to - poll the DB until the GC has done its job. - """ - bbolt_path = join(BIN_DIR, "bbolt") - db_path = "/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db" - tmp_db_path = "/tmp/containerd_meta_copy.db" - bbolt_cmd = f"{bbolt_path} keys {tmp_db_path} v1 k8s.io snapshots {snapshotter}" - - while True: - # Make a user-owned copy of the DB (bbolt complains otherwise) - run(f"sudo cp {db_path} {tmp_db_path}", shell=True, check=True) - run( - "sudo chown {}:{} {}".format(getuid(), getgid(), tmp_db_path), - shell=True, - check=True, - ) - - result = run(bbolt_cmd, shell=True, capture_output=True) - stdout = result.stdout.decode("utf-8").strip() - - if result.returncode == 1: - # This can be a benign error if the snapshotter has not been used - # at all, never - if stdout == "bucket not found": - if debug: - print(f"WARNING: bucket {snapshotter} not found in metadata") - run(f"rm {tmp_db_path}", shell=True, check=True) - return - else: - print( - "ERROR: running bbolt command: stdout: {}, stderr: {}".format( - stdout, result.stderr.decode("utf-8").strip() - ) - ) - run(f"rm {tmp_db_path}", shell=True, check=True) - - raise RuntimeError("Error running bbolt command!") - elif result.returncode == 0: - if len(stdout) == 0: - run(f"rm {tmp_db_path}", shell=True, check=True) - return - - print( - "Got {} snapshot's metadata for snapshotter: {}".format( - len(stdout.split("\n")), snapshotter - ) - ) - sleep(2) - else: - print( - "ERROR: running bbolt command: stdout: {}, stderr: {}".format( - stdout, result.stderr.decode("utf-8").strip() - ) - ) - run(f"rm {tmp_db_path}", shell=True, check=True) - - raise RuntimeError("Error running bbolt command!") - - def do_purge(debug=False): """ Purging the snapshotters for a fresh-start is a two step process. First, @@ -201,15 +130,6 @@ def do_purge(debug=False): wait_for_snapshot_metadata_to_be_gced(snap, debug=debug) -@task -def purge(ctx): - """ - Remove all cached snapshots in the snapshotter cache - """ - wait_for_containerd_socket() - do_purge(debug=True) - - def install(debug=False, clean=False): """ Install the nydus snapshotter binaries @@ -315,20 +235,8 @@ def install(debug=False, clean=False): print("Success!") -@task -def build(ctx, nocache=False, push=False): - """ - Build the nydus-snapshotter image - """ - docker_cmd = "docker build {} -t {} -f {} .".format( - "--no-cache" if nocache else "", - NYDUS_SNAPSHOTTER_IMAGE_TAG, - join(PROJ_ROOT, "docker", "nydus_snapshotter.dockerfile"), - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - - if push: - run(f"docker push {NYDUS_SNAPSHOTTER_IMAGE_TAG}", shell=True, check=True) +def restart_nydus_snapshotter(): + run("sudo service nydus-snapshotter restart", shell=True, check=True) def set_log_level(log_level): @@ -347,6 +255,85 @@ def set_log_level(log_level): restart_nydus_snapshotter() +def wait_for_snapshot_metadata_to_be_gced(snapshotter, debug=False): + """ + After restarting containerd it may take a while for the GC to kick in and + delete the metadata corresponding to previous snapshots. This metadata + is stored in a Bolt DB in /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db + + Annoyingly, it is hard to manually delete files from the database w/out + writting a small Go script. Instead, we rely on the bbolt CLI tool to + poll the DB until the GC has done its job. + """ + bbolt_path = join(BIN_DIR, "bbolt") + db_path = "/var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db" + tmp_db_path = "/tmp/containerd_meta_copy.db" + bbolt_cmd = f"{bbolt_path} keys {tmp_db_path} v1 k8s.io snapshots {snapshotter}" + + while True: + # Make a user-owned copy of the DB (bbolt complains otherwise) + run(f"sudo cp {db_path} {tmp_db_path}", shell=True, check=True) + run( + "sudo chown {}:{} {}".format(getuid(), getgid(), tmp_db_path), + shell=True, + check=True, + ) + + result = run(bbolt_cmd, shell=True, capture_output=True) + stdout = result.stdout.decode("utf-8").strip() + + if result.returncode == 1: + # This can be a benign error if the snapshotter has not been used + # at all, never + if stdout == "bucket not found": + if debug: + print(f"WARNING: bucket {snapshotter} not found in metadata") + run(f"rm {tmp_db_path}", shell=True, check=True) + return + else: + print( + "ERROR: running bbolt command: stdout: {}, stderr: {}".format( + stdout, result.stderr.decode("utf-8").strip() + ) + ) + run(f"rm {tmp_db_path}", shell=True, check=True) + + raise RuntimeError("Error running bbolt command!") + elif result.returncode == 0: + if len(stdout) == 0: + run(f"rm {tmp_db_path}", shell=True, check=True) + return + + print( + "Got {} snapshot's metadata for snapshotter: {}".format( + len(stdout.split("\n")), snapshotter + ) + ) + sleep(2) + else: + print( + "ERROR: running bbolt command: stdout: {}, stderr: {}".format( + stdout, result.stderr.decode("utf-8").strip() + ) + ) + run(f"rm {tmp_db_path}", shell=True, check=True) + + raise RuntimeError("Error running bbolt command!") + + +# ------------------------------------------------------------------------------ +# Main entrypoint tasks +# ------------------------------------------------------------------------------ + + +@task +def build(ctx, nocache=False, push=False): + """ + Build the nydus-snapshotter image + """ + build_nydus_snapshotter_image(nocache, push) + + @task def cli(ctx, mount_path=join(PROJ_ROOT, "..", "nydus-snapshotter")): """ @@ -373,20 +360,6 @@ def cli(ctx, mount_path=join(PROJ_ROOT, "..", "nydus-snapshotter")): ) -@task -def stop(ctx): - """ - Stop the nydus-snapshotter work-on container - """ - result = run( - "docker rm -f {}".format(NYDUS_SNAPSHOTTER_CTR_NAME), - shell=True, - check=True, - capture_output=True, - ) - assert result.returncode == 0 - - @task def hot_replace(ctx): """ @@ -413,6 +386,15 @@ def hot_replace(ctx): restart_nydus_snapshotter() +@task +def purge(ctx): + """ + Remove all cached snapshots in the snapshotter cache + """ + wait_for_containerd_socket() + do_purge(debug=True) + + @task def set_mode(ctx, mode): """ @@ -479,3 +461,17 @@ def set_mode(ctx, mode): run("sudo systemctl daemon-reload", shell=True, check=True) restart_nydus_snapshotter() + + +@task +def stop(ctx): + """ + Stop the nydus-snapshotter work-on container + """ + result = run( + "docker rm -f {}".format(NYDUS_SNAPSHOTTER_CTR_NAME), + shell=True, + check=True, + capture_output=True, + ) + assert result.returncode == 0 diff --git a/tasks/ovmf.py b/tasks/ovmf.py index c4af35d0..dce8e609 100644 --- a/tasks/ovmf.py +++ b/tasks/ovmf.py @@ -1,28 +1,8 @@ from invoke import task from os.path import join -from subprocess import run from tasks.util.docker import copy_from_ctr_image -from tasks.util.env import GHCR_URL, GITHUB_ORG, KATA_ROOT, PROJ_ROOT -from tasks.util.versions import OVMF_VERSION - -OVMF_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, f"ovmf:{OVMF_VERSION}") - - -def do_ovmf_build(nocache=False, push=False): - docker_cmd = [ - "docker build", - f"--build-arg OVMF_VERSION={OVMF_VERSION}", - f"-t {OVMF_IMAGE_TAG}", - "--nocache" if nocache else "", - "-f {} .".format(join(PROJ_ROOT, "docker", "ovmf.dockerfile")), - ] - docker_cmd = " ".join(docker_cmd) - result = run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - assert result.returncode == 0, print(result.stderr.decode("utf-8").strip()) - - if push: - result = run(f"docker push {OVMF_IMAGE_TAG}", shell=True, capture_output=True) - assert result.returncode == 0, print(result.stderr.decode("utf-8").strip()) +from tasks.util.env import KATA_ROOT +from tasks.util.ovmf import OVMF_IMAGE_TAG, build_ovmf_image def install(): @@ -39,4 +19,4 @@ def build(ctx, nocache=False, push=False): """ Build the OVMF work-on container image """ - do_ovmf_build(nocache=nocache, push=push) + build_ovmf_image(nocache, push) diff --git a/tasks/sc2.py b/tasks/sc2.py index fc227f0b..6fd32b89 100644 --- a/tasks/sc2.py +++ b/tasks/sc2.py @@ -412,7 +412,7 @@ def destroy(ctx, debug=False): @task def set_log_level(ctx, log_level): """ - Set log level for all SC2 containers: containerd, kata, and nydus-snapshotter + Set log level for all SC2 containers: 'info' or 'debug' """ allowed_log_levels = ["info", "debug"] if log_level not in allowed_log_levels: diff --git a/tasks/svsm.py b/tasks/svsm.py index 5ccd4a8b..53917e82 100644 --- a/tasks/svsm.py +++ b/tasks/svsm.py @@ -1,7 +1,7 @@ from invoke import task from os.path import exists, join from subprocess import run -from tasks.util.docker import copy_from_ctr_image +from tasks.util.docker import build_image, copy_from_ctr_image from tasks.util.env import GHCR_URL, GITHUB_ORG, PROJ_ROOT, SC2_ROOT from tasks.util.kata import KATA_AGENT_SOURCE_DIR, KATA_IMAGE_TAG, KATA_SOURCE_DIR from tasks.util.kernel import get_host_kernel_version @@ -17,22 +17,6 @@ SVSM_GUEST_INITRD = join(SVSM_ROOT, "share", "sc2", "initrd-kata.img") -def get_kernel_version_from_ctr_image(): - tmp_file = "/tmp/sc2_kernel_release" - copy_from_ctr_image( - SVSM_KERNEL_IMAGE_TAG, - ["/git/coconut-svsm/linux/include/config/kernel.release"], - [tmp_file], - ) - with open(tmp_file, "r") as fh: - kernel_version = fh.read().strip() - kernel_version_trimmed = ( - kernel_version if not kernel_version.endswith("+") else kernel_version[:-1] - ) - - return kernel_version, kernel_version_trimmed - - def do_build_initrd(clean=False): if clean and exists(SVSM_GUEST_INITRD): run(f"sudo rm -f {SVSM_GUEST_INITRD}", shell=True, check=True) @@ -95,7 +79,21 @@ def do_build_initrd(clean=False): assert result.returncode == 0, print(result.stderr.decode("utf-8").strip()) -def do_build_kernel(nocache=False): +def build_svsm_image(nocache, push, debug=True): + do_install_qemu(debug=False, clean=False) + + build_image( + SVSM_IMAGE_TAG, + join(PROJ_ROOT, "docker", "svsm.dockerfile"), + build_args={"OVMF_FILE": "OVMF.fd"}, + cwd=join(SVSM_ROOT, "share", "ovmf"), + nocache=nocache, + push=push, + debug=debug, + ) + + +def build_svsm_kernel_image(nocache, push, debug=True): """ This method builds the forked kernel needed in the SVSM. It is used for the __guest__ kernel only. @@ -135,42 +133,33 @@ def do_build_kernel(nocache=False): # that panic when booting the SVSM. For the time being, the config in # milan2 seems to work, whereas the one in milan1 does not. The diff # gives many differences, we should address this as part of #148. - build_args = { - "KERNEL_CONFIG_FILE": "config-milan2", # basename(tmp_file), - "MODULES_OUTDIR": join(SVSM_ROOT, "share", "linux", "modules"), - } - build_args_str = [ - "--build-arg {}={}".format(key, build_args[key]) for key in build_args - ] - build_args_str = " ".join(build_args_str) - - docker_cmd = "docker build{} {} -t {} -f {} /tmp".format( - " --no-cache" if nocache else "", - build_args_str, + build_image( SVSM_KERNEL_IMAGE_TAG, join(PROJ_ROOT, "docker", "svsm_kernel.dockerfile"), + build_args={ + "KERNEL_CONFIG_FILE": "config-milan2", # basename(tmp_file), + "MODULES_OUTDIR": join(SVSM_ROOT, "share", "linux", "modules"), + }, + cwd="/tmp", + nocache=nocache, + push=push, + debug=debug, ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - -def do_build_qemu(nocache=False): - build_args = { - "IGVM_VERSION": IGVM_VERSION, - "QEMU_DATADIR": SVSM_QEMU_DATA_DIR, - "QEMU_PREFIX": SVSM_ROOT, - } - build_args_str = [ - "--build-arg {}={}".format(key, build_args[key]) for key in build_args - ] - build_args_str = " ".join(build_args_str) - docker_cmd = "docker build{} {} -t {} -f {} .".format( - " --no-cache" if nocache else "", - build_args_str, +def build_svsm_qemu_image(nocache, push, debug=True): + build_image( SVSM_QEMU_IMAGE_TAG, join(PROJ_ROOT, "docker", "svsm_qemu.dockerfile"), + build_args={ + "IGVM_VERSION": IGVM_VERSION, + "QEMU_DATADIR": SVSM_QEMU_DATA_DIR, + "QEMU_PREFIX": SVSM_ROOT, + }, + nocache=nocache, + push=push, + debug=debug, ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) def do_install_qemu(debug, clean): @@ -219,6 +208,22 @@ def do_install(debug, clean): ) +def get_kernel_version_from_ctr_image(): + tmp_file = "/tmp/sc2_kernel_release" + copy_from_ctr_image( + SVSM_KERNEL_IMAGE_TAG, + ["/git/coconut-svsm/linux/include/config/kernel.release"], + [tmp_file], + ) + with open(tmp_file, "r") as fh: + kernel_version = fh.read().strip() + kernel_version_trimmed = ( + kernel_version if not kernel_version.endswith("+") else kernel_version[:-1] + ) + + return kernel_version, kernel_version_trimmed + + # ------------------------------------------------------------------------------ # Entry-point tasks # ------------------------------------------------------------------------------ @@ -229,13 +234,13 @@ def build_guest_kernel(ctx, nocache=False, push=False): """ Build the host/guest kernel fork to use with the SVSM """ - do_build_kernel(nocache=nocache) + build_svsm_kernel_image(nocache=nocache, push=push) @task def build_initrd(ctx, clean=False): """ - Generate an initrd with the kata agent and the different kernel modules. + Generate an initrd with the kata agent and the different kernel modules """ do_build_initrd(clean=clean) @@ -245,32 +250,15 @@ def build_qemu(ctx, nocache=False, push=False): """ Build the QEMU fork for its use with the SVSM """ - do_build_qemu(nocache=nocache) - - if push: - run(f"docker push {SVSM_QEMU_IMAGE_TAG}", shell=True, check=True) + build_svsm_qemu_image(nocache, push) @task -def build_svsm(ctx, nocache=False): - do_install_qemu(debug=False, clean=False) - - build_args = { - "OVMF_FILE": "OVMF.fd", - } - build_args_str = [ - "--build-arg {}={}".format(key, build_args[key]) for key in build_args - ] - build_args_str = " ".join(build_args_str) - - docker_cmd = "docker build{} {} -t {} -f {} {}".format( - " --no-cache" if nocache else "", - build_args_str, - SVSM_IMAGE_TAG, - join(PROJ_ROOT, "docker", "svsm.dockerfile"), - join(SVSM_ROOT, "share", "ovmf"), - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) +def build_svsm(ctx, nocache=False, push=False): + """ + Build the SVSM IGVM image + """ + build_svsm_image(nocache, push) @task diff --git a/tasks/util/containerd.py b/tasks/util/containerd.py index ac530fb0..9b44b14f 100644 --- a/tasks/util/containerd.py +++ b/tasks/util/containerd.py @@ -1,42 +1,24 @@ from json import loads as json_loads -from os.path import exists +from os.path import exists, join from subprocess import CalledProcessError, run +from tasks.util.docker import build_image +from tasks.util.env import GHCR_URL, GITHUB_ORG, PROJ_ROOT +from tasks.util.versions import CONTAINERD_VERSION from time import sleep, time +CONTAINERD_IMAGE_TAG = ( + join(GHCR_URL, GITHUB_ORG, "containerd") + f":{CONTAINERD_VERSION}" +) -def wait_for_containerd_socket(): - timeout = 10 - interval = 1 - socket_path = "/run/containerd/containerd.sock" - - # Socket is root-owned, so we need to be careful when probing it - socket_test_script = f""" -import socket -try: - with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: - s.connect('{socket_path}') -except Exception as e: - exit(1) -exit(0) -""" - - start_time = time() - while time() - start_time < timeout: - if exists(socket_path): - try: - run( - f'sudo python3 -c "{socket_test_script}"', - shell=True, - check=True, - ) - return - except CalledProcessError: - pass - - sleep(interval) - - raise RuntimeError("Error dialing containerd socket!") +def build_containerd_image(nocache, push, debug=True): + build_image( + CONTAINERD_IMAGE_TAG, + join(PROJ_ROOT, "docker", "containerd.dockerfile"), + nocache=nocache, + push=push, + debug=debug, + ) def is_containerd_active(): @@ -248,3 +230,37 @@ def get_all_events_in_between( events_json.append(o_json) return events_json + + +def wait_for_containerd_socket(): + timeout = 10 + interval = 1 + socket_path = "/run/containerd/containerd.sock" + + # Socket is root-owned, so we need to be careful when probing it + socket_test_script = f""" +import socket +try: + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: + s.connect('{socket_path}') +except Exception as e: + exit(1) +exit(0) +""" + start_time = time() + while time() - start_time < timeout: + if exists(socket_path): + try: + run( + f'sudo python3 -c "{socket_test_script}"', + shell=True, + check=True, + ) + + return + except CalledProcessError: + pass + + sleep(interval) + + raise RuntimeError("Error dialing containerd socket!") diff --git a/tasks/util/docker.py b/tasks/util/docker.py index ebfa2e41..c0cd7d9e 100644 --- a/tasks/util/docker.py +++ b/tasks/util/docker.py @@ -1,4 +1,4 @@ -from os.path import dirname, exists +from os.path import dirname, exists, join from subprocess import run from tasks.util.env import GHCR_URL, GITHUB_ORG, PROJ_ROOT, print_dotted_line from tasks.util.versions import ( @@ -9,19 +9,54 @@ OVMF_VERSION, ) +# Base software image (note that we tag with a CoCo release version, but we +# allow it to fall behind as we should not re-build the base image often) +BASE_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, "base") + ":0.12.0" + +ALL_CTR_IMAGES = [ + (join(GHCR_URL, GITHUB_ORG, f"kata-containers:{KATA_VERSION}"), "kata.dockerfile"), + (join(GHCR_URL, GITHUB_ORG, f"nydus:{NYDUS_VERSION}"), "nydus.dockerfile"), + ( + join(GHCR_URL, GITHUB_ORG, f"nydus-snapshotter:{NYDUS_SNAPSHOTTER_VERSION}"), + "nydus_snapshotter.dockerfile", + ), + (join(GHCR_URL, GITHUB_ORG, f"ovmf:{OVMF_VERSION}"), "ovmf.dockerfile"), + (join(GHCR_URL, GITHUB_ORG, "svsm:main"), "svsm.dockerfile"), + # (join(GHCR_URL, GITHUB_ORG, "linux:svsm"), "svsm_kernel.dockerfile"), + (join(GHCR_URL, GITHUB_ORG, "qemu:svsm"), "svsm_qemu.dockerfile"), +] + + +def build_image( + image_tag, + dockerfile, + build_args=None, + cwd=PROJ_ROOT, + nocache=False, + push=False, + debug=False, +): + build_args_cmd = "" + if build_args: + build_args_cmd = " ".join( + [ + "--build-arg {}={}".format(key, value) + for key, value in build_args.items() + ] + ) + docker_cmd = "docker build {} {} -t {} -f {} .".format( + "--no-cache" if nocache else "", build_args_cmd, image_tag, dockerfile + ) + result = run(docker_cmd, shell=True, capture_output=True, cwd=cwd) + assert result.returncode == 0, print(result.stderr.decode("utf-8").strip()) + if debug: + print(result.stdout.decode("utf-8").strip()) -def is_ctr_running(ctr_name): - """ - Work out whether a container is running or not - """ - docker_cmd = ["docker container inspect", "-f '{{.State.Running}}'", ctr_name] - docker_cmd = " ".join(docker_cmd) - out = run(docker_cmd, shell=True, capture_output=True) - if out.returncode == 0: - value = out.stdout.decode("utf-8").strip() - return value == "true" - - return False + if push: + result = run(f"docker push {image_tag}", shell=True, capture_output=True) + assert result.returncode == 0, print(result.stderr.decode("utf-8").strip()) + if debug: + print(result.stdout.decode("utf-8").strip()) def copy_from_ctr_image(ctr_image, ctr_paths, host_paths, requires_sudo=False): @@ -64,34 +99,18 @@ def cleanup(): cleanup() -def build_image(image_tag, dockerfile, build_args=None): - build_args_cmd = "" - if build_args: - build_args_cmd = " ".join( - [ - "--build-arg {}={}".format(key, value) - for key, value in build_args.items() - ] - ) - docker_cmd = "docker build {} -t {} -f {} .".format( - build_args_cmd, image_tag, dockerfile - ) - run(docker_cmd, shell=True, check=True, cwd=PROJ_ROOT) - - -def run_container(image_tag, ctr_name): - docker_cmd = "docker run -td --name {} {}".format(ctr_name, image_tag) - run(docker_cmd, shell=True, check=True) - - -def stop_container(ctr_name): - docker_cmd = "docker rm -f {}".format(ctr_name) - run(docker_cmd, shell=True, check=True) - +def is_ctr_running(ctr_name): + """ + Work out whether a container is running or not + """ + docker_cmd = ["docker container inspect", "-f '{{.State.Running}}'", ctr_name] + docker_cmd = " ".join(docker_cmd) + out = run(docker_cmd, shell=True, capture_output=True) + if out.returncode == 0: + value = out.stdout.decode("utf-8").strip() + return value == "true" -def build_image_and_run(image_tag, dockerfile, ctr_name, build_args=None): - build_image(image_tag, dockerfile, build_args) - run_container(image_tag, ctr_name) + return False def pull_artifact_images(debug=False): diff --git a/tasks/util/env.py b/tasks/util/env.py index 6cdfc669..107c54fd 100644 --- a/tasks/util/env.py +++ b/tasks/util/env.py @@ -1,6 +1,6 @@ from os.path import dirname, expanduser, realpath, join from subprocess import run -from tasks.util.versions import KATA_VERSION, PAUSE_IMAGE_VERSION +from tasks.util.versions import PAUSE_IMAGE_VERSION PROJ_ROOT = dirname(dirname(dirname(realpath(__file__)))) @@ -37,14 +37,7 @@ KUBEADM_KUBECONFIG_FILE = join(K8S_CONFIG_DIR, "kubeadm_kubeconfig") # CoCo config - COCO_ROOT = join("/opt", "confidential-containers") - -# Base software image (note that we tag with a CoCo release version, but we -# allow it to fall behind as we should not re-build the base image often) -BASE_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, "base") + ":0.10.0" - -# Kata Version is determined by CoCo version KATA_ROOT = join("/opt", "kata") # ---------- Kata config ---------- @@ -52,7 +45,6 @@ KATA_CONFIG_DIR = join(KATA_ROOT, "share", "defaults", "kata-containers") KATA_IMG_DIR = join(KATA_ROOT, "share", "kata-containers") KATA_WORKON_CTR_NAME = "kata-workon" -KATA_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, "kata-containers") + f":{KATA_VERSION}" KATA_RUNTIMES = ["qemu-coco-dev", "qemu-snp", "qemu-tdx"] # ---------- SC2 config ---------- diff --git a/tasks/util/kata.py b/tasks/util/kata.py index 8d896d6f..98b3a709 100644 --- a/tasks/util/kata.py +++ b/tasks/util/kata.py @@ -1,22 +1,26 @@ from os import environ, makedirs from os.path import dirname, exists, join from subprocess import run -from tasks.util.docker import copy_from_ctr_image, is_ctr_running +from tasks.util.docker import build_image, copy_from_ctr_image, is_ctr_running from tasks.util.env import ( CONTAINERD_CONFIG_FILE, + GHCR_URL, + GITHUB_ORG, KATA_CONFIG_DIR, KATA_IMG_DIR, KATA_ROOT, KATA_RUNTIMES, KATA_WORKON_CTR_NAME, - KATA_IMAGE_TAG, PAUSE_IMAGE_REPO, + PROJ_ROOT, SC2_RUNTIMES, ) from tasks.util.registry import HOST_CERT_PATH -from tasks.util.versions import PAUSE_IMAGE_VERSION +from tasks.util.versions import KATA_VERSION, PAUSE_IMAGE_VERSION, RUST_VERSION from tasks.util.toml import remove_entry_from_toml, update_toml +KATA_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, "kata-containers") + f":{KATA_VERSION}" + # These paths are hardcoded in the docker image: ./docker/kata.dockerfile KATA_SOURCE_DIR = "/go/src/github.com/kata-containers/kata-containers-sc2" KATA_AGENT_SOURCE_DIR = join(KATA_SOURCE_DIR, "src", "agent") @@ -26,6 +30,80 @@ KATA_BASELINE_SHIM_SOURCE_DIR = join(KATA_BASELINE_SOURCE_DIR, "src", "runtime") +def build_kata_image(nocache, push, debug=True): + build_image( + KATA_IMAGE_TAG, + join(PROJ_ROOT, "docker", "kata.dockerfile"), + build_args={"RUST_VERSION": RUST_VERSION}, + nocache=nocache, + push=push, + debug=debug, + ) + + +def build_pause_image(sc2, debug, hot_replace): + """ + When we create a rootfs for CoCo, we need to embed the pause image into + it. As a consequence, we need to build the tarball first. + """ + pause_image_build_dir = "/tmp/sc2-pause-image-build-dir" + + if exists(pause_image_build_dir): + run(f"sudo rm -rf {pause_image_build_dir}", shell=True, check=True) + + makedirs(pause_image_build_dir) + makedirs(join(pause_image_build_dir, "static-build")) + makedirs(join(pause_image_build_dir, "scripts")) + + script_files = ["static-build/pause-image", "scripts/lib.sh"] + for ctr_path, host_path in zip( + [ + join( + KATA_SOURCE_DIR if sc2 else KATA_BASELINE_SOURCE_DIR, + "tools/packaging", + script, + ) + for script in script_files + ], + [join(pause_image_build_dir, script) for script in script_files], + ): + copy_from_kata_workon_ctr( + ctr_path, host_path, sudo=False, debug=debug, hot_replace=hot_replace + ) + + # Build pause image + work_env = environ.update( + { + "pause_image_repo": PAUSE_IMAGE_REPO, + "pause_image_version": PAUSE_IMAGE_VERSION, + } + ) + out = run( + "./build.sh", + shell=True, + cwd=join(pause_image_build_dir, "static-build", "pause-image"), + env=work_env, + capture_output=True, + ) + assert out.returncode == 0, "Error building pause image: {}".format( + out.stderr.decode("utf-8") + ) + + # Generate tarball of pause bundle + pause_bundle_tarball_name = "pause_bundle_sc2.tar.xz" + tar_cmd = f"tar -cJf {pause_bundle_tarball_name} pause_bundle" + run( + tar_cmd, + shell=True, + check=True, + cwd=join(pause_image_build_dir, "static-build", "pause-image"), + ) + + return join( + pause_image_build_dir, "static-build", "pause-image", pause_bundle_tarball_name + ) + + def run_kata_workon_ctr(mount_path=None): """ Start Kata workon container image if it is not running. Return `True` if @@ -94,69 +172,6 @@ def copy_from_kata_workon_ctr( copy_from_ctr_image(KATA_IMAGE_TAG, [ctr_path], [host_path], requires_sudo=sudo) -def build_pause_image(sc2, debug, hot_replace): - """ - When we create a rootfs for CoCo, we need to embed the pause image into - it. As a consequence, we need to build the tarball first. - """ - pause_image_build_dir = "/tmp/sc2-pause-image-build-dir" - - if exists(pause_image_build_dir): - run(f"sudo rm -rf {pause_image_build_dir}", shell=True, check=True) - - makedirs(pause_image_build_dir) - makedirs(join(pause_image_build_dir, "static-build")) - makedirs(join(pause_image_build_dir, "scripts")) - - script_files = ["static-build/pause-image", "scripts/lib.sh"] - for ctr_path, host_path in zip( - [ - join( - KATA_SOURCE_DIR if sc2 else KATA_BASELINE_SOURCE_DIR, - "tools/packaging", - script, - ) - for script in script_files - ], - [join(pause_image_build_dir, script) for script in script_files], - ): - copy_from_kata_workon_ctr( - ctr_path, host_path, sudo=False, debug=debug, hot_replace=hot_replace - ) - - # Build pause image - work_env = environ.update( - { - "pause_image_repo": PAUSE_IMAGE_REPO, - "pause_image_version": PAUSE_IMAGE_VERSION, - } - ) - out = run( - "./build.sh", - shell=True, - cwd=join(pause_image_build_dir, "static-build", "pause-image"), - env=work_env, - capture_output=True, - ) - assert out.returncode == 0, "Error building pause image: {}".format( - out.stderr.decode("utf-8") - ) - - # Generate tarball of pause bundle - pause_bundle_tarball_name = "pause_bundle_sc2.tar.xz" - tar_cmd = f"tar -cJf {pause_bundle_tarball_name} pause_bundle" - run( - tar_cmd, - shell=True, - check=True, - cwd=join(pause_image_build_dir, "static-build", "pause-image"), - ) - - return join( - pause_image_build_dir, "static-build", "pause-image", pause_bundle_tarball_name - ) - - def prepare_rootfs(tmp_rootfs_base_dir, debug=False, sc2=False, hot_replace=False): """ This function takes a directory as input, and generates the root-filesystem diff --git a/tasks/util/nydus.py b/tasks/util/nydus.py index bb6f5e8a..5e8f0ba1 100644 --- a/tasks/util/nydus.py +++ b/tasks/util/nydus.py @@ -1,13 +1,26 @@ from os import environ from os.path import dirname, join from subprocess import run -from tasks.util.env import COCO_ROOT, PROJ_ROOT +from tasks.util.docker import build_image +from tasks.util.env import COCO_ROOT, GHCR_URL, GITHUB_ORG, PROJ_ROOT +from tasks.util.versions import NYDUS_VERSION NYDUSIFY_PATH = join(PROJ_ROOT, "bin", "nydusify") +NYDUS_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, "nydus") + f":{NYDUS_VERSION}" NYDUS_IMAGE_HOST_PATH = join(COCO_ROOT, "bin", "nydus-image") +def build_nydus_image(nocache, push, debug=True): + build_image( + NYDUS_IMAGE_TAG, + join(PROJ_ROOT, "docker", "nydus.dockerfile"), + nocache=nocache, + push=push, + debug=debug, + ) + + def nydusify(src_tag, dst_tag): # Add nydus-image to path work_env = environ.copy() diff --git a/tasks/util/nydus_snapshotter.py b/tasks/util/nydus_snapshotter.py new file mode 100644 index 00000000..67c7bfc3 --- /dev/null +++ b/tasks/util/nydus_snapshotter.py @@ -0,0 +1,18 @@ +from os.path import join +from tasks.util.env import GHCR_URL, GITHUB_ORG, PROJ_ROOT +from tasks.util.docker import build_image +from tasks.util.versions import NYDUS_SNAPSHOTTER_VERSION + +NYDUS_SNAPSHOTTER_IMAGE_TAG = ( + join(GHCR_URL, GITHUB_ORG, "nydus-snapshotter") + f":{NYDUS_SNAPSHOTTER_VERSION}" +) + + +def build_nydus_snapshotter_image(nocache, push, debug=True): + build_image( + NYDUS_SNAPSHOTTER_IMAGE_TAG, + join(PROJ_ROOT, "docker", "nydus_snapshotter.dockerfile"), + nocache=nocache, + push=push, + debug=debug, + ) diff --git a/tasks/util/ovmf.py b/tasks/util/ovmf.py index 09d4a7e6..e4b18fb6 100644 --- a/tasks/util/ovmf.py +++ b/tasks/util/ovmf.py @@ -1,12 +1,28 @@ from re import search as re_search +from os.path import join +from tasks.util.env import GHCR_URL, GITHUB_ORG, PROJ_ROOT +from tasks.util.docker import build_image +from tasks.util.versions import OVMF_VERSION +OVMF_IMAGE_TAG = join(GHCR_URL, GITHUB_ORG, f"ovmf:{OVMF_VERSION}") # This is hard-coded in the bash redirection output. It is not very straight # forward to change it there, so we keep it like this for the time being # (e.g. we could template the bash script, but I cba atm) OVMF_SERIAL_OUTPUT = "/tmp/qemu-serial.log" +def build_ovmf_image(nocache, push, debug=True): + build_image( + OVMF_IMAGE_TAG, + join(PROJ_ROOT, "docker", "ovmf.dockerfile"), + build_args={"OVMF_VERSION": OVMF_VERSION}, + nocache=nocache, + push=push, + debug=debug, + ) + + def get_ovmf_boot_events(events_ts, guest_kernel_start_ts): """ Parse the OVMF boot events from the serial output, and create timestamps as