From ce21fa6bb01e14d30a467d516eea65631ee76644 Mon Sep 17 00:00:00 2001 From: spline2hg <181270613+spline2hg@users.noreply.github.com> Date: Thu, 22 Jan 2026 05:29:13 +0000 Subject: [PATCH 1/5] feat(urunc-deploy): install artifacts under /opt/urunc and generate urunc config Signed-off-by: spline2hg <181270613+spline2hg@users.noreply.github.com> --- deployment/urunc-deploy/scripts/install.sh | 102 +++++++++++++++------ 1 file changed, 75 insertions(+), 27 deletions(-) diff --git a/deployment/urunc-deploy/scripts/install.sh b/deployment/urunc-deploy/scripts/install.sh index f7cb6f7e..6a0f07d7 100644 --- a/deployment/urunc-deploy/scripts/install.sh +++ b/deployment/urunc-deploy/scripts/install.sh @@ -24,6 +24,14 @@ containerd_conf_tmpl_file="" use_containerd_drop_in_conf_file="false" containerd_drop_in_conf_file="/etc/containerd/config.d/urunc-deploy.toml" +# urunc installation directories +urunc_install_dir="/opt/urunc" +urunc_bin_dir="${urunc_install_dir}/bin" +urunc_share_dir="${urunc_install_dir}/share" +urunc_libexec_dir="${urunc_install_dir}/libexec" +urunc_config_dir="/etc/urunc" +urunc_config_file="${urunc_config_dir}/config.toml" + HYPERVISORS="${HYPERVISORS:-"firecracker qemu solo5-hvt solo5-spt"}" IFS=' ' read -a hypervisors <<< "$HYPERVISORS" @@ -45,6 +53,9 @@ function install_artifact() { function install_artifacts() { echo "copying urunc artifacts onto host" mkdir -p /host/usr/local/bin + mkdir -p /host${urunc_bin_dir} + mkdir -p /host${urunc_share_dir} + mkdir -p /host${urunc_libexec_dir} install_artifact /urunc-artifacts/urunc /host/usr/local/bin/urunc install_artifact /urunc-artifacts/containerd-shim-urunc-v2 /host/usr/local/bin/containerd-shim-urunc-v2 @@ -58,23 +69,22 @@ function install_artifacts() { if which "qemu-system-$(uname -m)" >/dev/null 2>&1; then echo "QEMU is already installed." else - install_artifact /urunc-artifacts/hypervisors/qemu-system-$(uname -m) /host/usr/local/bin/qemu-system-$(uname -m) - install_artifact /urunc-artifacts/libexec/virtiofsd /host/usr/libexec/virtiofsd - mkdir -p /host/usr/local/share/qemu/ - cp -r /urunc-artifacts/opt/kata/share/kata-qemu/qemu /host/usr/local/share + install_artifact /urunc-artifacts/hypervisors/qemu-system-$(uname -m) /host${urunc_bin_dir}/qemu-system-$(uname -m) + install_artifact /urunc-artifacts/libexec/virtiofsd /host${urunc_libexec_dir}/virtiofsd + cp -r /urunc-artifacts/opt/kata/share/kata-qemu/qemu /host${urunc_share_dir}/ fi ;; firecracker) echo "Installing firecracker" - install_artifact /urunc-artifacts/hypervisors/firecracker /host/usr/local/bin/firecracker + install_artifact /urunc-artifacts/hypervisors/firecracker /host${urunc_bin_dir}/firecracker ;; solo5-spt) echo "Installing solo5-spt" - install_artifact /urunc-artifacts/hypervisors/solo5-spt /host/usr/local/bin/solo5-spt + install_artifact /urunc-artifacts/hypervisors/solo5-spt /host${urunc_bin_dir}/solo5-spt ;; solo5-hvt) echo "Installing solo5-hvt" - install_artifact /urunc-artifacts/hypervisors/solo5-hvt /host/usr/local/bin/solo5-hvt + install_artifact /urunc-artifacts/hypervisors/solo5-hvt /host${urunc_bin_dir}/solo5-hvt ;; *) echo "Unsupported hypervisor: $hypervisor" @@ -83,38 +93,75 @@ function install_artifacts() { done } -function remove_artifacts() { - rm -f /host/usr/local/bin/urunc - rm -f /host/usr/local/bin/containerd-shim-urunc-v2 - local hypervisors="${HYPERVISORS:-"firecracker qemu solo5-hvt solo5-spt"}" - for hypervisor in $hypervisors; do +function generate_urunc_config() { + echo "Generating urunc configuration file" + mkdir -p /host${urunc_config_dir} + + local config_content="" + local virtiofsd_content="" + + config_content+="# urunc configuration file generated by urunc-deploy\n" + config_content+="\n" + config_content+="[log]\n" + config_content+="level = \"info\"\n" + config_content+="syslog = false\n" + config_content+="\n" + config_content+="[timestamps]\n" + config_content+="enabled = false\n" + config_content+="destination = \"/var/log/urunc/timestamps.log\"\n" + + for hypervisor in "${hypervisors[@]}" ; do case "$hypervisor" in qemu) - if [ -e "/host/usr/local/bin/qemu-system-$(uname -m)" ]; then - rm -f "/host/usr/local/bin/qemu-system-$(uname -m)" - rm -rf /host/usr/local/share/qemu + if ! which "qemu-system-$(uname -m)" >/dev/null 2>&1; then + config_content+="\n" + config_content+="[monitors.qemu]\n" + config_content+="default_memory_mb = 256\n" + config_content+="default_vcpus = 1\n" + config_content+="path = \"${urunc_bin_dir}/qemu-system-$(uname -m)\"\n" + config_content+="data_path = \"${urunc_share_dir}\"\n" + # Add virtiofsd config for qemu + virtiofsd_content+="\n" + virtiofsd_content+="[extra_binaries.virtiofsd]\n" + virtiofsd_content+="path = \"${urunc_libexec_dir}/virtiofsd\"\n" + virtiofsd_content+="options = \"--cache always --sandbox none\"\n" fi ;; firecracker) - if [ -e "/host/usr/local/bin/firecracker" ]; then - rm -f "/host/usr/local/bin/firecracker" - fi + config_content+="\n" + config_content+="[monitors.firecracker]\n" + config_content+="default_memory_mb = 256\n" + config_content+="default_vcpus = 1\n" + config_content+="path = \"${urunc_bin_dir}/firecracker\"\n" ;; solo5-spt) - if [ -e "/host/usr/local/bin/solo5-spt" ]; then - rm -f "/host/usr/local/bin/solo5-spt" - fi + config_content+="\n" + config_content+="[monitors.spt]\n" + config_content+="default_memory_mb = 256\n" + config_content+="default_vcpus = 1\n" + config_content+="path = \"${urunc_bin_dir}/solo5-spt\"\n" ;; solo5-hvt) - if [ -e "/host/usr/local/bin/solo5-hvt" ]; then - rm -f "/host/usr/local/bin/solo5-hvt" - fi - ;; - *) - echo "Unsupported hypervisor: $hypervisor" + config_content+="\n" + config_content+="[monitors.hvt]\n" + config_content+="default_memory_mb = 256\n" + config_content+="default_vcpus = 1\n" + config_content+="path = \"${urunc_bin_dir}/solo5-hvt\"\n" ;; esac done + + echo -e "${config_content}${virtiofsd_content}" > /host${urunc_config_file} + echo "urunc configuration file created at ${urunc_config_file}" +} + +function remove_artifacts() { + rm -f /host/usr/local/bin/urunc + rm -f /host/usr/local/bin/containerd-shim-urunc-v2 + # Remove urunc installation directory and config + rm -rf /host${urunc_install_dir} + rm -f /host${urunc_config_file} + rmdir /host${urunc_config_dir} 2>/dev/null || true } @@ -377,6 +424,7 @@ function main() { fi fi install_artifacts + generate_urunc_config configure_cri_runtime "$runtime" kubectl label node "$NODE_NAME" --overwrite urunc.io/urunc-runtime=true echo "urunc-deploy completed successfully" From 32d3a324b8970341fe0339ce85a8c9d12d6936cc Mon Sep 17 00:00:00 2001 From: spline2hg <181270613+spline2hg@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:40:44 +0000 Subject: [PATCH 2/5] docs: Update documentation for urunc-deploy Signed-off-by: spline2hg <181270613+spline2hg@users.noreply.github.com> --- docs/configuration.md | 7 +++--- docs/installation.md | 33 ++++++++++++--------------- docs/tutorials/How-to-urunc-on-k8s.md | 6 ++++- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index da4ec77d..32607912 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -113,9 +113,10 @@ Each monitor subsection supports the following options: | `path` | string | (empty) | Optional custom path to the monitor binary. If not specified, urunc will search for the binary in PATH | | `data_path` | string | (empty) | Optional custom path for the monitor's data file directory | -Since Qemu is the only currently supported monitor which requires extra data to -boot a VM, `urunc` wll first check `/usr/local/share` and then `/usr/share` for -Qemu's data files. +Qemu is currently the only supported monitor that requires extra data to boot a VM. +The `data_path` field specifies the directory containing Qemu's data files. +`urunc` searches for data files in the following order: +`/opt/urunc/share`, `/usr/local/share`, and `/usr/share`. **Example:** diff --git a/docs/installation.md b/docs/installation.md index bba086b3..b298502e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -329,33 +329,30 @@ sudo tar Cxzvf /opt release-amd64-FC-v1.7.0_S5-v0.9.3_VFS_-v1.13.0_QM-v10.1.1-9a rm -f release-amd64-FC-v1.7.0_S5-v0.9.3_VFS_-v1.13.0_QM-v10.1.1-9a44e.tar.gz ``` -After downloading all the binaries, we need to instruct `urunc` about the -location of the binaries. Therefore, in [`urunc`'s -configuration](../configuration). there are three three fields that needs to -get updated: +After downloading the binaries, configure `urunc` by updating `/etc/urunc/config.toml`. Refer to [`urunc`'s configuration documentation](../configuration) for details. Set the following fields: -1. in each hypervisor the `binary_path` field, -2. in Qemu, the `data_path` field, -3. in Virtiofsd, the `path` field needs to get updated. +1. In each monitor section, set the `path` field +2. In the `qemu` monitor section only, set the `data_path` field +3. In the `extra_binaries.virtiofsd` section, set the `path` field -Therefore, change or append the following lines in `urunc`'s configuration: +Change or append the following lines: -``` -[hypervisors.qemu] -binary_path = "/opt/urunc/bin/qemu-system-x86_64" +```toml +[monitors.qemu] +path = "/opt/urunc/bin/qemu-system-x86_64" data_path = "/opt/urunc/share/qemu" -[hypervisors.firecracker] -binary_path = "/opt/urunc/bin/firecracker" +[monitors.firecracker] +path = "/opt/urunc/bin/firecracker" -[hypervisors.hvt] -binary_path = "/opt/urunc/bin/solo5-hvt" +[monitors.hvt] +path = "/opt/urunc/bin/solo5-hvt" -[hypervisors.spt] -binary_path = "/opt/urunc/bin/solo5-spt" +[monitors.spt] +path = "/opt/urunc/bin/solo5-spt" [extra_binaries.virtiofsd] -path = "/opt/urunc/bin/virtiofsd" +path = "/opt/urunc/libexec/virtiofsd" ``` ### Option 2: Fetching or building from source diff --git a/docs/tutorials/How-to-urunc-on-k8s.md b/docs/tutorials/How-to-urunc-on-k8s.md index 12001dc6..fc91321c 100644 --- a/docs/tutorials/How-to-urunc-on-k8s.md +++ b/docs/tutorials/How-to-urunc-on-k8s.md @@ -95,7 +95,11 @@ kubectl get pods [`urunc-deploy`](https://github.com/urunc-dev/urunc/tree/main/deployment/urunc-deploy) provides a Dockerfile, which contains all of the binaries and artifacts required to run `urunc`, as well as reference DaemonSets, which can -be utilized to install `urunc` runtime on a running Kubernetes cluster. +be utilized to install `urunc` runtime on a running Kubernetes cluster. + +The `urunc-deploy` daemonset automatically installs all required artifacts under `/opt/urunc` and configures `urunc` via a configuration file at +`/etc/urunc/config.toml`. This approach allows for clean installations without overwriting existing system files or requiring manual configuration +of binary paths. ### urunc-deploy in k3s From 78727200974764a19878e210195231a9d6858406 Mon Sep 17 00:00:00 2001 From: spline2hg <181270613+spline2hg@users.noreply.github.com> Date: Thu, 22 Jan 2026 12:02:07 +0000 Subject: [PATCH 3/5] feat(urunc-deploy): add config.toml and update install script Signed-off-by: spline2hg <181270613+spline2hg@users.noreply.github.com> --- deployment/urunc-deploy/Dockerfile | 1 + deployment/urunc-deploy/config.toml | 33 +++++++++++ deployment/urunc-deploy/scripts/install.sh | 68 +++------------------- 3 files changed, 41 insertions(+), 61 deletions(-) create mode 100644 deployment/urunc-deploy/config.toml diff --git a/deployment/urunc-deploy/Dockerfile b/deployment/urunc-deploy/Dockerfile index 19ccac03..c973d1f6 100644 --- a/deployment/urunc-deploy/Dockerfile +++ b/deployment/urunc-deploy/Dockerfile @@ -95,6 +95,7 @@ COPY --from=intermediate /urunc-artifacts /urunc-artifacts COPY --from=intermediate /usr/bin/jq /usr/bin/jq COPY --from=intermediate /usr/bin/kubectl /usr/bin/kubectl COPY scripts/install.sh /urunc-artifacts/scripts/install.sh +COPY config.toml /deployment/config.toml RUN apk update && \ apk add --no-cache bash curl py3-pip && \ pip install --no-cache-dir --break-system-packages yq==3.2.3 && \ diff --git a/deployment/urunc-deploy/config.toml b/deployment/urunc-deploy/config.toml new file mode 100644 index 00000000..8eeffaf4 --- /dev/null +++ b/deployment/urunc-deploy/config.toml @@ -0,0 +1,33 @@ +# urunc configuration file generated by urunc-deploy + +[log] +level = "info" +syslog = false + +[timestamps] +enabled = false + +[monitors.qemu] +default_memory_mb = 256 +default_vcpus = 1 +path = "/opt/urunc/bin/qemu-system-x86_64" +data_path = "/opt/urunc/share" + +[monitors.firecracker] +default_memory_mb = 256 +default_vcpus = 1 +path = "/opt/urunc/bin/firecracker" + +[monitors.spt] +default_memory_mb = 256 +default_vcpus = 1 +path = "/opt/urunc/bin/solo5-spt" + +[monitors.hvt] +default_memory_mb = 256 +default_vcpus = 1 +path = "/opt/urunc/bin/solo5-hvt" + +[extra_binaries.virtiofsd] +path = "/opt/urunc/libexec/virtiofsd" +options = "--cache always --sandbox none" diff --git a/deployment/urunc-deploy/scripts/install.sh b/deployment/urunc-deploy/scripts/install.sh index 6a0f07d7..1a6e9428 100644 --- a/deployment/urunc-deploy/scripts/install.sh +++ b/deployment/urunc-deploy/scripts/install.sh @@ -93,72 +93,18 @@ function install_artifacts() { done } -function generate_urunc_config() { - echo "Generating urunc configuration file" +function install_urunc_config() { + echo "Installing urunc configuration file" mkdir -p /host${urunc_config_dir} - - local config_content="" - local virtiofsd_content="" - - config_content+="# urunc configuration file generated by urunc-deploy\n" - config_content+="\n" - config_content+="[log]\n" - config_content+="level = \"info\"\n" - config_content+="syslog = false\n" - config_content+="\n" - config_content+="[timestamps]\n" - config_content+="enabled = false\n" - config_content+="destination = \"/var/log/urunc/timestamps.log\"\n" - - for hypervisor in "${hypervisors[@]}" ; do - case "$hypervisor" in - qemu) - if ! which "qemu-system-$(uname -m)" >/dev/null 2>&1; then - config_content+="\n" - config_content+="[monitors.qemu]\n" - config_content+="default_memory_mb = 256\n" - config_content+="default_vcpus = 1\n" - config_content+="path = \"${urunc_bin_dir}/qemu-system-$(uname -m)\"\n" - config_content+="data_path = \"${urunc_share_dir}\"\n" - # Add virtiofsd config for qemu - virtiofsd_content+="\n" - virtiofsd_content+="[extra_binaries.virtiofsd]\n" - virtiofsd_content+="path = \"${urunc_libexec_dir}/virtiofsd\"\n" - virtiofsd_content+="options = \"--cache always --sandbox none\"\n" - fi - ;; - firecracker) - config_content+="\n" - config_content+="[monitors.firecracker]\n" - config_content+="default_memory_mb = 256\n" - config_content+="default_vcpus = 1\n" - config_content+="path = \"${urunc_bin_dir}/firecracker\"\n" - ;; - solo5-spt) - config_content+="\n" - config_content+="[monitors.spt]\n" - config_content+="default_memory_mb = 256\n" - config_content+="default_vcpus = 1\n" - config_content+="path = \"${urunc_bin_dir}/solo5-spt\"\n" - ;; - solo5-hvt) - config_content+="\n" - config_content+="[monitors.hvt]\n" - config_content+="default_memory_mb = 256\n" - config_content+="default_vcpus = 1\n" - config_content+="path = \"${urunc_bin_dir}/solo5-hvt\"\n" - ;; - esac - done - - echo -e "${config_content}${virtiofsd_content}" > /host${urunc_config_file} - echo "urunc configuration file created at ${urunc_config_file}" + cp /deployment/config.toml /host${urunc_config_file} + echo "urunc configuration file installed at ${urunc_config_file}" } function remove_artifacts() { + # Remove urunc related artifacts rm -f /host/usr/local/bin/urunc rm -f /host/usr/local/bin/containerd-shim-urunc-v2 - # Remove urunc installation directory and config + rm -rf /host${urunc_install_dir} rm -f /host${urunc_config_file} rmdir /host${urunc_config_dir} 2>/dev/null || true @@ -424,7 +370,7 @@ function main() { fi fi install_artifacts - generate_urunc_config + install_urunc_config configure_cri_runtime "$runtime" kubectl label node "$NODE_NAME" --overwrite urunc.io/urunc-runtime=true echo "urunc-deploy completed successfully" From 5a060c401ddfee7c50905f181744af7566a0b1b0 Mon Sep 17 00:00:00 2001 From: spline2hg <181270613+spline2hg@users.noreply.github.com> Date: Thu, 22 Jan 2026 13:03:27 +0000 Subject: [PATCH 4/5] feat(urunc-deploy): update findQemuDataDir to search /opt/urunc for Qemu data Signed-off-by: spline2hg <181270613+spline2hg@users.noreply.github.com> --- pkg/unikontainers/utils.go | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/pkg/unikontainers/utils.go b/pkg/unikontainers/utils.go index 38f6b03b..504b41d4 100644 --- a/pkg/unikontainers/utils.go +++ b/pkg/unikontainers/utils.go @@ -300,21 +300,22 @@ func findNS(namespaces []specs.LinuxNamespace, nsType specs.LinuxNamespaceType) } // findQemuDataDir tries to find the location of data and BIOS files for Qemu. -// At first checks /usr/local/share and if it does not exist, it falls back to -// /usr/share. If /usr/local/share is a soft link, it will find its target. +// It searches in order: /opt/urunc/share, /usr/local/share, /usr/share. +// If a path is a soft link, it will find its target. func findQemuDataDir(basename string) (string, error) { - // First check if the file exists under /usr/local/share - qdPath := filepath.Join("/usr/local/share/", basename) - info, err := os.Lstat(qdPath) - if err != nil { - if !os.IsNotExist(err) { + searchPaths := []string{"/opt/urunc/share/", "/usr/local/share/", "/usr/share/"} + + for _, searchPath := range searchPaths { + qdPath := filepath.Join(searchPath, basename) + info, err := os.Lstat(qdPath) + if err != nil { + if os.IsNotExist(err) { + continue + } return "", fmt.Errorf("failed to get info of %s: %w", qdPath, err) } - // The file does not exist under /usr/local/share - // fallback to the usual path /usr/share/ - qdPath = filepath.Join("/usr/share/", basename) - } else { - // The file exists under /usr/local/share, but check if it is a link + + // The file exists, check if it is a link if info.Mode()&os.ModeSymlink != 0 { // It is a link, get the target qdPath, err = os.Readlink(qdPath) @@ -323,11 +324,11 @@ func findQemuDataDir(basename string) (string, error) { } } - // It is not a link, so we found it return qdPath, nil } - return qdPath, nil + // If not found in any path, return the last fallback path + return filepath.Join("/usr/share/", basename), nil } func rmMultipleDirs(prefixPath string, dirs []string) error { From 011f2f21a192db44b485295fecc6c52916e673e3 Mon Sep 17 00:00:00 2001 From: spline2hg <181270613+spline2hg@users.noreply.github.com> Date: Thu, 22 Jan 2026 15:43:50 +0000 Subject: [PATCH 5/5] fix review comments Signed-off-by: spline2hg <181270613+spline2hg@users.noreply.github.com> --- deployment/urunc-deploy/scripts/install.sh | 5 ++-- docs/configuration.md | 7 +++--- docs/installation.md | 15 ++++++----- docs/tutorials/How-to-urunc-on-k8s.md | 17 +++++++------ pkg/unikontainers/utils.go | 29 +++++++++++----------- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/deployment/urunc-deploy/scripts/install.sh b/deployment/urunc-deploy/scripts/install.sh index 1a6e9428..270b7eb9 100644 --- a/deployment/urunc-deploy/scripts/install.sh +++ b/deployment/urunc-deploy/scripts/install.sh @@ -106,9 +106,8 @@ function remove_artifacts() { rm -f /host/usr/local/bin/containerd-shim-urunc-v2 rm -rf /host${urunc_install_dir} - rm -f /host${urunc_config_file} - rmdir /host${urunc_config_dir} 2>/dev/null || true -} + rm -rf /host${urunc_config_dir} + } die() { diff --git a/docs/configuration.md b/docs/configuration.md index 32607912..da4ec77d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -113,10 +113,9 @@ Each monitor subsection supports the following options: | `path` | string | (empty) | Optional custom path to the monitor binary. If not specified, urunc will search for the binary in PATH | | `data_path` | string | (empty) | Optional custom path for the monitor's data file directory | -Qemu is currently the only supported monitor that requires extra data to boot a VM. -The `data_path` field specifies the directory containing Qemu's data files. -`urunc` searches for data files in the following order: -`/opt/urunc/share`, `/usr/local/share`, and `/usr/share`. +Since Qemu is the only currently supported monitor which requires extra data to +boot a VM, `urunc` wll first check `/usr/local/share` and then `/usr/share` for +Qemu's data files. **Example:** diff --git a/docs/installation.md b/docs/installation.md index b298502e..d490884a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -329,15 +329,18 @@ sudo tar Cxzvf /opt release-amd64-FC-v1.7.0_S5-v0.9.3_VFS_-v1.13.0_QM-v10.1.1-9a rm -f release-amd64-FC-v1.7.0_S5-v0.9.3_VFS_-v1.13.0_QM-v10.1.1-9a44e.tar.gz ``` -After downloading the binaries, configure `urunc` by updating `/etc/urunc/config.toml`. Refer to [`urunc`'s configuration documentation](../configuration) for details. Set the following fields: +After downloading all the binaries, we need to instruct `urunc` about the +location of the binaries. Therefore, in [`urunc`'s +configuration](../configuration). there are three fields that need to +get updated: -1. In each monitor section, set the `path` field -2. In the `qemu` monitor section only, set the `data_path` field -3. In the `extra_binaries.virtiofsd` section, set the `path` field +1. in each monitor the `path` field, +2. in Qemu, the `data_path` field, +3. in Virtiofsd, the `path` field needs to get updated. -Change or append the following lines: +Therefore, change or append the following lines in `urunc`'s configuration: -```toml +``` [monitors.qemu] path = "/opt/urunc/bin/qemu-system-x86_64" data_path = "/opt/urunc/share/qemu" diff --git a/docs/tutorials/How-to-urunc-on-k8s.md b/docs/tutorials/How-to-urunc-on-k8s.md index fc91321c..a281b04c 100644 --- a/docs/tutorials/How-to-urunc-on-k8s.md +++ b/docs/tutorials/How-to-urunc-on-k8s.md @@ -97,10 +97,6 @@ kubectl get pods and artifacts required to run `urunc`, as well as reference DaemonSets, which can be utilized to install `urunc` runtime on a running Kubernetes cluster. -The `urunc-deploy` daemonset automatically installs all required artifacts under `/opt/urunc` and configures `urunc` via a configuration file at -`/etc/urunc/config.toml`. This approach allows for clean installations without overwriting existing system files or requiring manual configuration -of binary paths. - ### urunc-deploy in k3s To install in a k3s cluster, first we need to create the RBAC: @@ -178,23 +174,30 @@ Now, we can create new `urunc` deployments using the [instruction provided in ma `urunc-deploy` consists of several components and steps that install `urunc` along with the supported hypervisors, configure `containerd` and Kubernetes (k8s) to use `urunc`, and provide a simple way to remove those components from the cluster. +The daemonset automatically installs all required artifacts under `/opt/urunc` and configures `urunc` via a configuration file at `/etc/urunc/config.toml`. + During installation, the following steps take place: - A RBAC role is created to allow `urunc-deploy` to run with privileged access. - The `urunc-deploy` Pod is deployed with privileges on the host, and the `containerd` configuration is mounted inside the Pod. - `urunc-deploy` performs the following tasks: - * Copies `urunc` and hypervisor binaries to the host under `usr/local/bin`. + * Copies `urunc` and `containerd-shim-urunc-v2` binaries to the host under `/usr/local/bin`. + * Copies hypervisor binaries to the host under `/opt/urunc/bin`. + * Copies QEMU data files to `/opt/urunc/share`. + * Installs a configuration file at `/etc/urunc/config.toml`. * Creates a backup of the current `containerd` configuration file. * Edits the `containerd` configuration file to add `urunc` as a supported runtime. * Restarts `containerd`, if necessary. * Labels the Node with label `urunc.io/urunc-runtime=true`. - Finally, `urunc` is added as a runtime class in k8s. -> Note: `urunc-deploy` will install a static version of QEMU in `/usr/local/bin/` along with the QEMU BIOS files in `/usr/local/share/`. Therefore, files with the same names under these directories will get overwritten. +> Note: `urunc-deploy` will install a static version of QEMU in `/opt/urunc/bin/` along with the QEMU BIOS files in `/opt/urunc/share/`. If QEMU is already installed system-wide, `urunc-deploy` will skip installation and use the existing QEMU binary. During cleanup, these changes are reverted: -- The `urunc` and hypervisor binaries are deleted. +- The `urunc` and `containerd-shim-urunc-v2` binaries are deleted from `/usr/local/bin`. +- The `/opt/urunc` directory containing hypervisor binaries and QEMU data files is deleted. +- The `/etc/urunc` configuration directory is deleted. - The `containerd` configuration file is restored to the pre-`urunc-deploy` state. - The `urunc.io/urunc-runtime=true` label is removed from the Node. - The RBAC role, the `urunc-deploy` Pod and the runtime class are removed. diff --git a/pkg/unikontainers/utils.go b/pkg/unikontainers/utils.go index 504b41d4..38f6b03b 100644 --- a/pkg/unikontainers/utils.go +++ b/pkg/unikontainers/utils.go @@ -300,22 +300,21 @@ func findNS(namespaces []specs.LinuxNamespace, nsType specs.LinuxNamespaceType) } // findQemuDataDir tries to find the location of data and BIOS files for Qemu. -// It searches in order: /opt/urunc/share, /usr/local/share, /usr/share. -// If a path is a soft link, it will find its target. +// At first checks /usr/local/share and if it does not exist, it falls back to +// /usr/share. If /usr/local/share is a soft link, it will find its target. func findQemuDataDir(basename string) (string, error) { - searchPaths := []string{"/opt/urunc/share/", "/usr/local/share/", "/usr/share/"} - - for _, searchPath := range searchPaths { - qdPath := filepath.Join(searchPath, basename) - info, err := os.Lstat(qdPath) - if err != nil { - if os.IsNotExist(err) { - continue - } + // First check if the file exists under /usr/local/share + qdPath := filepath.Join("/usr/local/share/", basename) + info, err := os.Lstat(qdPath) + if err != nil { + if !os.IsNotExist(err) { return "", fmt.Errorf("failed to get info of %s: %w", qdPath, err) } - - // The file exists, check if it is a link + // The file does not exist under /usr/local/share + // fallback to the usual path /usr/share/ + qdPath = filepath.Join("/usr/share/", basename) + } else { + // The file exists under /usr/local/share, but check if it is a link if info.Mode()&os.ModeSymlink != 0 { // It is a link, get the target qdPath, err = os.Readlink(qdPath) @@ -324,11 +323,11 @@ func findQemuDataDir(basename string) (string, error) { } } + // It is not a link, so we found it return qdPath, nil } - // If not found in any path, return the last fallback path - return filepath.Join("/usr/share/", basename), nil + return qdPath, nil } func rmMultipleDirs(prefixPath string, dirs []string) error {