From 159d29665ac18d15864296597a121953c8d2af6b Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 7 Feb 2024 11:22:42 +0000 Subject: [PATCH 1/7] kata-manager: Whitespace fixes Remove extraneous whitespace. Signed-off-by: James O. D. Hunt --- utils/kata-manager.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/utils/kata-manager.sh b/utils/kata-manager.sh index 044432ce77..0dfeb33ae1 100755 --- a/utils/kata-manager.sh +++ b/utils/kata-manager.sh @@ -528,31 +528,31 @@ configure_containerd() then local systemd_unit_dir="/etc/systemd/system" sudo mkdir -p "$systemd_unit_dir" - + local dest="${systemd_unit_dir}/${containerd_service_name}" - + if [ ! -f "$dest" ] then pushd "$tmpdir" >/dev/null - + local service_url service_url=$(printf "%s/%s/%s/%s" \ "https://raw.githubusercontent.com" \ "${containerd_slug}" \ "main" \ "${containerd_service_name}") - + curl -LO "$service_url" - + printf "# %s: Service installed for Kata Containers\n" \ "$(date -Iseconds)" |\ tee -a "$containerd_service_name" - + sudo cp "${containerd_service_name}" "${dest}" sudo systemctl daemon-reload - + info "Installed ${dest}" - + popd >/dev/null fi fi @@ -645,17 +645,17 @@ install_kata() then local version_desc="latest version" [ -n "$requested_version" ] && version_desc="version $requested_version" - + info "Downloading $project release ($version_desc)" - + local results results=$(github_download_package \ "$kata_releases_url" \ "$requested_version" \ "$project") - + [ -z "$results" ] && die "Cannot download $project release file" - + version=$(echo "$results"|cut -d: -f1) [ -z "$version" ] && die "Cannot determine $project resolved version" From ce350450e81daeb725abdd0fceb0fe2301a878de Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 7 Feb 2024 15:16:52 +0000 Subject: [PATCH 2/7] kata-manager: Sort options in usage Ensure the usage statement lists all options in alphabetical order. Signed-off-by: James O. D. Hunt --- utils/kata-manager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/kata-manager.sh b/utils/kata-manager.sh index 0dfeb33ae1..a4bcbc77c1 100755 --- a/utils/kata-manager.sh +++ b/utils/kata-manager.sh @@ -270,12 +270,12 @@ Options: https://containerd.io/releases/#support-horizon -d : Enable debug for all components. -D : Install Docker server and CLI tooling (takes priority over '-c'). - -N : Install nerdctl (takes priority over '-c', only implemented for x86_64 and ARM). -f : Force installation (use with care). -h : Show this help statement. -k : Specify Kata Containers version. -K : Specify local Kata Containers tarball to install (takes priority over '-k'). -l : List installed and available versions only, then exit (uses network). + -N : Install nerdctl (takes priority over '-c', only implemented for x86_64 and ARM). -o : Only install Kata Containers. -r : Don't cleanup on failure (retain files). -t : Disable self test (don't try to create a container after install). From 455637b30a8709d31e8614c2455ed378e93ad194 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 7 Feb 2024 15:27:25 +0000 Subject: [PATCH 3/7] kata-manager: Show message when checking file Add an info message just before the archive file is checked. This keeps the user informed about what is happening as it can take a few seconds to perform the checks on slower systems. Signed-off-by: James O. D. Hunt --- utils/kata-manager.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/kata-manager.sh b/utils/kata-manager.sh index a4bcbc77c1..92b08ab7ad 100755 --- a/utils/kata-manager.sh +++ b/utils/kata-manager.sh @@ -679,6 +679,8 @@ install_kata() local from_dir from_dir=$(printf "%s/bin" "$kata_install_dir") + info "Checking file '$file'" + # Since we're unpacking to the root directory, perform a sanity check # on the archive first. local unexpected From 0bb558c0b91f789c808c88f19d565f064ac2015a Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 7 Feb 2024 15:30:07 +0000 Subject: [PATCH 4/7] kata-manager: Fix symlink handling The `configure_kata()` function modifies the configuration file to enable debug. But it was doing this by calling `sed -i` which, by default, creates a new _file_ from the `configuration.toml` symbolic link. This defeated the point of the symbolic link which is supposed to resolve to the local copy of the pristine config file, so we now use the GNU sed(1) specific `---follow-symlinks` option to retain the sym-link. Signed-off-by: James O. D. Hunt --- utils/kata-manager.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utils/kata-manager.sh b/utils/kata-manager.sh index 92b08ab7ad..fb20144b92 100755 --- a/utils/kata-manager.sh +++ b/utils/kata-manager.sh @@ -736,7 +736,18 @@ configure_kata() sudo install -o root -g root -m 0644 "$cfg_from" "$cfg_to" + # Note that '--follow-symlinks' is essential: without it, + # sed(1) will break the sym-link and convert it into a file, + # which is not desirable behaviour as the whole point of the + # "well known" config file name is that it is a sym-link to + # the actual config file. + # + # However, this option is GNU sed(1) specific so if this + # script is run on a non-Linux system, it may be necessary + # to install GNU sed, or find an equivalent option for the + # local version of sed. sudo sed -i \ + --follow-symlinks \ -e 's/^# *\(enable_debug\).*=.*$/\1 = true/g' \ -e 's/^kernel_params = "\(.*\)"/kernel_params = "\1 agent.log=debug"/g' \ "$cfg_to" From 1ac3caf656901ed501c86431b4196c8a2231aa1e Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Thu, 8 Feb 2024 14:17:11 +0000 Subject: [PATCH 5/7] kata-manager: Allow hypervisor to be changed Add new options to allow the configured hypervisor to be changed: - `-L`: List available _packaged_ hypervisor config short names. - `-e`: List available _local_ hypervisor config names. - `-H `: Install Kata then switch to the specified hypervisor. - `-S `: Switch to the specified hypervisor (by config short name [Errors if Kata not installed]). For example, to install Kata and configure it to use Cloud Hypervisor with the golang Kata runtime: ```bash $ kata-manager.sh -H clh ``` To switch back to the default hypervisor: ```bash $ kata-manager.sh -S default ``` To show details of the available packaged configs: ```bash $ kata-manager.sh -L ``` To show details of the local configs: ```bash $ kata-manager.sh -e ``` > **Notes:** > > - This change **only** applies to the current default (golang) Kata runtime. > > - Although this is mainly for users wishing to switch hypervisor (by > changing the Kata config file to another of the packaged config files > provided for specific hypervisors), strictly it allows users to change > to _any_ config file. For example, if the user has a config file called > `/etc/kata-containers/configuration-my-custom-config.toml`, they could > switch to this by running: > > ```bash > $ kata-manager.sh -S my-custom-config > ``` > > - The "config short names" are the hypervisor specific part of the configuration file name. > For example, the config short name for file `configuration-qemu.toml` is > `qemu` and the config short name for `configuration-clh.toml` is `clh`. Fixes: #8305. Signed-off-by: James O. D. Hunt --- utils/kata-manager.sh | 528 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 496 insertions(+), 32 deletions(-) diff --git a/utils/kata-manager.sh b/utils/kata-manager.sh index fb20144b92..70cbd48e29 100755 --- a/utils/kata-manager.sh +++ b/utils/kata-manager.sh @@ -23,6 +23,8 @@ readonly containerd_slug="containerd/containerd" readonly kata_project_url="https://github.com/${kata_slug}" readonly containerd_project_url="https://github.com/${containerd_slug}" +readonly kata_hypervisors_doc_url='https://github.com/kata-containers/kata-containers/blob/main/docs/hypervisors.md' + readonly kata_releases_url="https://api.github.com/repos/${kata_slug}/releases" readonly containerd_releases_url="https://api.github.com/repos/${containerd_slug}/releases" readonly containerd_io_releases_url="https://raw.githubusercontent.com/containerd/containerd.io/main/content/releases.md" @@ -57,6 +59,33 @@ readonly containerd_service_name="containerd.service" # Containerd configuration file readonly containerd_config="/etc/containerd/config.toml" +# Directory containing packaged configuration files +readonly kata_config_dir_golang="${kata_install_dir}/share/defaults/kata-containers" + +# Directory containing local configuration files +readonly kata_local_config_dir_golang="/etc/kata-containers" + +# Name of the Kata configuration file (or more usually the sym-link +# to the real config file). +readonly kata_config_file_name='configuration.toml' + +readonly kata_config_file_golang="${kata_local_config_dir_golang}/${kata_config_file_name}" + +# Currently, the golang runtime is the default runtime. +readonly default_config_dir="$kata_config_dir_golang" +readonly local_config_dir="$kata_local_config_dir_golang" +readonly kata_config_file="$kata_config_file_golang" +readonly kata_runtime_language='golang' +readonly pristine_config_type='packaged' + +# The string to display to denote a default value. +readonly default_value='default' + +# String to display if a value cannot be determined +readonly unknown_tag='unknown' + +readonly cfg_file_install_perms='0644' + # Directory in which to create symbolic links readonly link_dir=${link_dir:-/usr/bin} @@ -265,31 +294,54 @@ Description: Install $kata_project [1] (and optionally $containerd_project [2]) Options: - -c : Specify containerd flavour ("lts" | "active" - default: "lts"). - Find more details on LTS and Active versions of containerd on - https://containerd.io/releases/#support-horizon - -d : Enable debug for all components. - -D : Install Docker server and CLI tooling (takes priority over '-c'). - -f : Force installation (use with care). - -h : Show this help statement. - -k : Specify Kata Containers version. - -K : Specify local Kata Containers tarball to install (takes priority over '-k'). - -l : List installed and available versions only, then exit (uses network). - -N : Install nerdctl (takes priority over '-c', only implemented for x86_64 and ARM). - -o : Only install Kata Containers. - -r : Don't cleanup on failure (retain files). - -t : Disable self test (don't try to create a container after install). - -T : Only run self test (do not install anything). + -c : Specify containerd flavour ("lts" | "active" - default: "lts"). + Find more details on LTS and Active versions of containerd on + https://containerd.io/releases/#support-horizon + -d : Enable debug for all components. + -D : Install Docker server and CLI tooling (takes priority over '-c'). + -e : List short names and details for local hypervisor configuration files (for '-S'). + -f : Force installation (use with care). + -h : Show this help statement. + -H : Specify the hypervisor name to use when *INSTALLING* a system. + -k : Specify Kata Containers version. + -K : Specify local Kata Containers tarball to install (takes priority over '-k'). + -l : List installed and available versions only, then exit (uses network). + -L : List short names and details for official packaged hypervisor configurations (for '-S'). + -N : Install nerdctl (takes priority over '-c', only implemented for x86_64 and ARM). + -o : Only install Kata Containers. + -r : Don't cleanup on failure (retain files). + -S : Only change the hypervisor config for an *EXISTING* installation. + -t : Disable self test (don't try to create a container after install). + -T : Only run self test (do not install anything). Notes: - The version strings must refer to official GitHub releases for each project. If not specified or set to "", install the latest available version. +- The '-L' option requires an installed system. + + > **Note:** For details of each hypervisor, see [3]. + +- If an invalid hypervisor name is specified with the '-H' option, an + error will be generated, but the system will be left in a working + state and configured to use the hypervisor configured at build time. + + > **Note:** For details of each hypervisor, see [3]. + +- Since '-L' cannot be used until a system is installed, if you wish + to change the configured Kata hypervisor, unless you know the + hypervisor name, the recommended approach is to: + + 1) Install this script with no arguments to install a Kata system. + 2) Run again with '-L' to list the available hypervisor configurations. + 3) Run again with '-S ' to switch to your chosen hypervisor. + See also: [1] - $kata_project_url [2] - $containerd_project_url +[3] - $kata_hypervisors_doc_url $warnings @@ -317,6 +369,26 @@ containerd_installed() return 1 } +# Return 0 if Kata is already installed, else return 1. +kata_installed() +{ + command -v "$kata_shim_v2" &>/dev/null +} + +# Assert that Kata is installed and error with a message if it isn't. +ensure_kata_already_installed() +{ + local msg + msg=$(cat <<-EOF + $kata_project is not yet installed (or is installed in a non-standard directory). + + Run this script with no options to install Kata Containers. + EOF + ) + + kata_installed || die "$msg" +} + pre_checks() { info "Running pre-checks" @@ -717,24 +789,25 @@ configure_kata() local enable_debug="${1:-}" [ -z "$enable_debug" ] && die "no enable debug value" + local force="${2:-}" + [ -z "$force" ] && die "no force value" + + local hypervisor="${3:-}" + [ "$enable_debug" = "false" ] && \ info "Using default $kata_project configuration" && \ return 0 - local config_file='configuration.toml' - local kata_dir='/etc/kata-containers' + local default_hypervisor + default_hypervisor=$(get_default_packaged_hypervisor || true) - sudo mkdir -p "$kata_dir" + [ -z "$hypervisor" ] && \ + hypervisor="$default_hypervisor" && \ + info "Using default $kata_project hypervisor ('$hypervisor')" - local cfg_from - local cfg_to + set_kata_config_file "$force" "$hypervisor" - cfg_from="${kata_install_dir}/share/defaults/kata-containers/${config_file}" - cfg_to="${kata_dir}/${config_file}" - - [ -e "$cfg_from" ] || die "cannot find $kata_project configuration file" - - sudo install -o root -g root -m 0644 "$cfg_from" "$cfg_to" + local cfg_file="$kata_config_file" # Note that '--follow-symlinks' is essential: without it, # sed(1) will break the sym-link and convert it into a file, @@ -750,9 +823,10 @@ configure_kata() --follow-symlinks \ -e 's/^# *\(enable_debug\).*=.*$/\1 = true/g' \ -e 's/^kernel_params = "\(.*\)"/kernel_params = "\1 agent.log=debug"/g' \ - "$cfg_to" + "$cfg_file" - info "Configured $kata_project for full debug (delete '$cfg_to' to use pristine $kata_project configuration)" + info "Configured $kata_project config file '$cfg_file' for full debug" + info "(delete '$cfg_file' to use pristine $kata_project configuration)" } handle_kata() @@ -763,9 +837,14 @@ handle_kata() local enable_debug="${3:-}" [ -z "$enable_debug" ] && die "no enable debug value" + local force="${4:-}" + [ -z "$force" ] && die "no force value" + + local hypervisor="${5:-}" + install_kata "$version" "$tarball" - configure_kata "$enable_debug" + configure_kata "$enable_debug" "$force" "$hypervisor" kata-runtime --version } @@ -942,6 +1021,8 @@ handle_installation() [ -z "$install_nerdctl" ] && die "no install nerdctl value" local kata_tarball="${11:-}" + local hypervisor="${12:-}" + # The tool to be testing the installation with local tool="ctr" @@ -979,7 +1060,12 @@ handle_installation() setup "$cleanup" "$force" "$skip_containerd" - handle_kata "$kata_version" "$kata_tarball" "$enable_debug" + handle_kata \ + "$kata_version" \ + "$kata_tarball" \ + "$enable_debug" \ + "$force" \ + "$hypervisor" [ "$skip_containerd" = "false" ] && \ handle_containerd \ @@ -1066,6 +1152,345 @@ list_versions() info "$docker_project: latest version: $latest_docker" } +# Returns the full path to the specified hypervisors +# configuration file in the specified directory. +# +# Note that the hypervisor "name" argument is not just a literal +# hypervisor name/alias, it is the string that matches the "*" glob +# in the pattern, "configuration-*.toml". +# +# If the specified name is "$default_value", +# use the default hypervisor configuration file name. +# +# If the specified name is not found, return the empty string. +get_hypervisor_config_file() +{ + local name="${1:-}" + [ -z "$name" ] && die "need name" + + local dir="${2:-}" + [ -z "$dir" ] && die "need config directory" + + # Expand the default value to the name of the the default hypervisor + # config file. + if [ "$name" = "$default_value" ] + then + local file + file="${dir}/${kata_config_file_name}" + name=$(readlink -e "$file") + + echo "$name" && return 0 + fi + + local -a cfg_files=() + + mapfile -t cfg_files < <(get_hypervisor_config_file_names "$dir") + + local cfg + for cfg in ${cfg_files[*]} + do + local cfg_name + cfg_name="${cfg#"${dir}/"}" + + local -a possible_names=() + + # Allow a file fragment name or a full name + # to be specified. + possible_names+=("configuration-${name}.toml") + possible_names+=("configuration${name}.toml") + possible_names+=("${name}.toml") + possible_names+=("${name}") + + local possible + + for possible in "${possible_names[@]}" + do + [ "$possible" = "$cfg_name" ] && echo "$cfg" && return 0 + done + done + + # Failed to find config file, but don't fail in case it's a + # local only name. + echo +} + +# Return the name of the config file specified by the name fragment, +# or the empty string if no matching file found. +get_local_cfg_file() +{ + local name="${1:-}" + [ -z "$name" ] && die "need name" + + local dir="$local_config_dir" + + get_hypervisor_config_file "$name" "$dir" +} + +# Return the full path to the pristine config file specified +# by the name fragment. +get_pristine_config_file() +{ + local name="${1:-}" + [ -z "$name" ] && die "need name" + + local dir="${default_config_dir}" + + local result + result=$(get_hypervisor_config_file "$name" "$dir") + + echo "$result" +} + +# Returns a list of available hypervisor configuration files +# (full paths) for the specified directory. +get_hypervisor_config_file_names() +{ + local dir="${1:-}" + [ -z "$dir" ] && die "need directory" + + # Note that we do not check for a trailing dash to also match + # the default config file ("configuration.toml") + echo "${dir}"/configuration*\.toml +} + +# Determine the default hypervisor by looking at sym-link in the +# specified config directory. +get_default_hypervisor_by_dir() +{ + local dir="${1:-}" + [ -z "$dir" ] && die "need directory" + + local -a cfg_files=() + + mapfile -t cfg_files < <(get_hypervisor_config_file_names "$dir") + + local cfg + + local cfg_type="$pristine_config_type" + + local default_cfg= + + # First, establish what the current default is by resolving + # the $kata_config_file_name sym link. + for cfg in ${cfg_files[*]} + do + if grep -q "/${kata_config_file_name}$" <<< "$cfg" && [ -h "$cfg" ] + then + default_cfg=$(readlink -e "$cfg") + default_cfg="${default_cfg#"${dir}/"}" + default_cfg="${default_cfg#configuration-}" + default_cfg="${default_cfg%.toml}" + + break + fi + done + + echo "$default_cfg" +} + +# Determine the default hypervisor by looking at sym-link in the +# packaged config directory. +get_default_packaged_hypervisor() +{ + local dir="$default_config_dir" + + local hypervisor + hypervisor=$(get_default_hypervisor_by_dir "$dir" || true) + + echo "$hypervisor" +} + +# Return a list of pristine hypervisor configs, one per line. +# Each line is a tab separated list of fields: +# +# field 1: hypervisor config name. +# field 2: $default_value if this is the default hypervisor, +# otherwise an empty string. +# field 3: hypervisor config type ($pristine_config_type). +# field 4: hypervisor configs runtime type ($kata_runtime_language). +list_hypervisor_config_file_details_by_dir() +{ + local dir="${1:-}" + [ -n "$dir" ] || die "need directory" + + local dir_type="${2:-}" + [ -n "$dir_type" ] || die "need directory type" + + # Ignore a non-existent directory + [ -d "$dir" ] || return 0 + + # First, establish what the current default hypervisor is. + local default_cfg + default_cfg=$(get_default_hypervisor_by_dir "$dir" || true) + + local -a cfg_files=() + + mapfile -t cfg_files < <(get_hypervisor_config_file_names "$dir") + + local cfg + + local cfg_type="$pristine_config_type" + + for cfg in ${cfg_files[*]} + do + # Ignore the sym-link + grep -q "/${kata_config_file_name}$" <<< "$cfg" && [ -h "$cfg" ] && continue + + local cfg_name + cfg_name="${cfg#"${dir}/"}" + cfg_name="${cfg_name#configuration-}" + cfg_name="${cfg_name%.toml}" + + local cfg_default_value='-' + + [ "$cfg_name" = "$default_cfg" ] && cfg_default_value="$default_value" + + printf "%s\t%s\t%s\t%s\n" \ + "$cfg_name" \ + "$cfg_default_value" \ + "$cfg_type" \ + "$dir_type" + done | sort -u +} + +# Display a list of packaged hypervisor config file name fragments, +# one line per config file. Each line is a set of fields. +# +# See list_hypervisor_config_file_details_by_dir() for the fields +# displayed. +list_packaged_hypervisor_config_names() +{ + ensure_kata_already_installed + + local golang_cfgs + golang_cfgs=$(list_hypervisor_config_file_details_by_dir \ + "$kata_config_dir_golang" \ + "$kata_runtime_language") + + echo "${golang_cfgs}" +} + +# Display a list of local hypervisor config file name fragments, +# one line per config file. Each line is a set of fields. +# +# See list_hypervisor_config_file_details_by_dir() for the fields +# displayed. +list_local_hypervisor_config_names() +{ + ensure_kata_already_installed + + local golang_cfgs + golang_cfgs=$(list_hypervisor_config_file_details_by_dir \ + "$local_config_dir" \ + "$kata_runtime_language") + + echo "${golang_cfgs}" +} + +# Change the configured hypervisor to the one specified. +# +# This function creates a local Kata configuration file if one does +# not exist and creates a symbolic link to it. +set_kata_config_file() +{ + ensure_kata_already_installed + + local force="${1:-}" + [ -z "$force" ] && die "no force value" + + local hypervisor="${2:-}" + [ -z "$hypervisor" ] && die "no hypervisor value" + + local hypervisor_cfg_file + hypervisor_cfg_file=$(get_pristine_config_file "$hypervisor") + + sudo mkdir -p "$local_config_dir" + + # The name of the local config file + local local_cfg_file + + # The name of the local kata config file sym-link + local local_kata_cfg_symlink="$kata_config_file" + + if [ -n "$hypervisor_cfg_file" ] + then + # A pristine hypervisor config file exists + + local hypervisor_cfg_file_name + hypervisor_cfg_file_name=$(basename "$hypervisor_cfg_file") + + sudo mkdir -p "$local_config_dir" + + local_cfg_file="${local_config_dir}/${hypervisor_cfg_file_name}" + + if [ -e "$local_cfg_file" ] + then + if [ -n "$(diff "$local_cfg_file" "$hypervisor_cfg_file")" ] + then + [ "$force" = 'false' ] && \ + die "existing hypervisor config file '$local_cfg_file' differs from pristine version: '$hypervisor_cfg_file'" + fi + fi + + # First, install a copy of the config file to the local config dir. + sudo install \ + -o root \ + -g root \ + -m "$cfg_file_install_perms" \ + "$hypervisor_cfg_file" \ + "$local_cfg_file" + + else + # There is no pristine config file, so look for a + # local-only config file. + local_cfg_file=$(get_local_cfg_file "$hypervisor" || true) + [ -z "$local_cfg_file" ] && \ + die "no packaged or local hypervisor config file found for '$hypervisor'" + fi + + # Next, create the standard sym-link, pointing to the + # requested hypervisor-specific config file, taking care to + # fail if the default config file is not a sym-link already. + if [ -e "$local_kata_cfg_symlink" ] + then + if [ ! -L "$local_kata_cfg_symlink" ] + then + # Don't do this, even if force is in operation + # as we don't know what the contents of the + # file are. + die "not overwriting non-sym-link config file: '$local_kata_cfg_symlink'" + fi + + if [ "$force" = false ] + then + # Back up the existing version of the file + local now + now=$(date '+%Y-%m-%d.%H-%M-%S.%N') + + local backup_name + backup_name="${local_kata_cfg_symlink}.${now}.saved" + + sudo install -o root -g root \ + -m "$cfg_file_install_perms" \ + "$local_kata_cfg_symlink" \ + "$backup_name" + fi + fi + + local default_hypervisor + default_hypervisor=$(get_default_packaged_hypervisor || true) + + # We can now safely force install the sym-link. + sudo ln -sf "$local_cfg_file" "$local_kata_cfg_symlink" + + local hypervisor_descr="'$hypervisor'" + + [ "$hypervisor" = "$default_value" ] || [ "$hypervisor" = "$default_hypervisor" ] && \ + hypervisor_descr="'$default_hypervisor' ($default_value)" + + info "Set config to $hypervisor_descr" +} + handle_args() { local cleanup="true" @@ -1077,6 +1502,10 @@ handle_args() local install_docker="false" local install_nerdctl="false" local list_versions='false' + local hypervisor="$default_value" + local switch_to_hypervisor='' + local list_available_pristine_hypervisor_configs='false' + local list_available_local_hypervisor_configs='false' local opt @@ -1084,20 +1513,24 @@ handle_args() local containerd_flavour="lts" local kata_tarball="" - while getopts "c:dDfhk:K:lNortT" opt "$@" + while getopts "c:dDefhH:k:K:lLNorS:tT" opt "$@" do case "$opt" in c) containerd_flavour="$OPTARG" ;; d) enable_debug="true" ;; D) install_docker="true" ;; + e) list_available_local_hypervisor_configs='true' ;; f) force="true" ;; h) usage; exit 0 ;; + H) hypervisor="$OPTARG" ;; k) kata_version="$OPTARG" ;; K) kata_tarball="$OPTARG" ;; l) list_versions='true' ;; + L) list_available_pristine_hypervisor_configs='true' ;; N) install_nerdctl="true" ;; o) skip_containerd="true" ;; r) cleanup="false" ;; + S) switch_to_hypervisor="$OPTARG" ;; t) disable_test="true" ;; T) only_run_test="true" ;; @@ -1109,6 +1542,36 @@ handle_args() [ "$list_versions" = 'true' ] && list_versions && exit 0 + if [ "$list_available_pristine_hypervisor_configs" = true ] + then + list_packaged_hypervisor_config_names + exit 0 + fi + + if [ "$list_available_local_hypervisor_configs" = true ] + then + list_local_hypervisor_config_names + exit 0 + fi + + if [ -n "$switch_to_hypervisor" ] + then + # XXX: If the user is asking to switch hypervisor + # config, to keep life simpler and to avoid polluting + # config directories with backup files, we make the assumption + # that they have already backed up any needed config + # files. + # + # Note that the function below checks that Kata is + # installed. + force='true' + + set_kata_config_file \ + "$force" \ + "$switch_to_hypervisor" + exit 0 + fi + [ -z "$kata_version" ] && kata_version="${1:-}" || true [ -z "$containerd_flavour" ] && containerd_flavour="${2:-}" || true @@ -1125,7 +1588,8 @@ handle_args() "$containerd_flavour" \ "$install_docker" \ "$install_nerdctl" \ - "$kata_tarball" + "$kata_tarball" \ + "$hypervisor" } main() From 4f6fef1f61d753b469a930053a3c0b3177ffd1f1 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Fri, 9 Feb 2024 16:44:03 +0000 Subject: [PATCH 6/7] docs: Whitespace fix Remove extraneous whitespace from hypervisors doc. Signed-off-by: James O. D. Hunt --- docs/hypervisors.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/hypervisors.md b/docs/hypervisors.md index 5ed990ae3d..7fbdcca886 100644 --- a/docs/hypervisors.md +++ b/docs/hypervisors.md @@ -47,7 +47,6 @@ $ kata-runtime kata-env | awk -v RS= '/\[Hypervisor\]/' | grep Path The table below provides a brief summary of some of the differences between the hypervisors: - | Hypervisor | Summary | Features | Limitations | Container Creation speed | Memory density | Use cases | Comment | |-|-|-|-|-|-|-|-| |[ACRN] | Safety critical and real-time workloads | | | excellent | excellent | Embedded and IOT systems | For advanced users | From 7af892f8d8b77a8589b5dc6f108fc6fe736862fb Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Fri, 9 Feb 2024 16:19:50 +0000 Subject: [PATCH 7/7] docs: Update kata-manager docs for switching hypervisor Add details to the README for `kata-manager` showing how to list available hypervisor configs (packaged and local), and switch between the configurations. Also, update the hypervisors page to show a lot more detail about the hypervisor configurations, including the "short name" used by `kata-manager` for switching hypervisor config. > **Note:** > > These changes only apply to the current default golang runtime. Signed-off-by: James O. D. Hunt --- docs/hypervisors.md | 71 +++++++++++++++----- utils/README.md | 155 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 200 insertions(+), 26 deletions(-) diff --git a/docs/hypervisors.md b/docs/hypervisors.md index 7fbdcca886..1ffc4afb00 100644 --- a/docs/hypervisors.md +++ b/docs/hypervisors.md @@ -16,25 +16,14 @@ which hypervisors you may wish to investigate further. ## Types -Since each hypervisor offers different features and options, Kata Containers -provides a separate -[configuration file](/src/runtime/README.md#configuration) -for each. The configuration files contain comments explaining which options -are available, their default values and how each setting can be used. - -> **Note:** -> -> The simplest way to switch between hypervisors is to create a symbolic link -> to the appropriate hypervisor-specific configuration file. - -| Hypervisor | Written in | Architectures | Type | Configuration file | -|-|-|-|-|-| -|[ACRN] | C | `x86_64` | Type 1 (bare metal) | `configuration-acrn.toml` | -|[Cloud Hypervisor] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | `configuration-clh.toml` | -|[Firecracker] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | `configuration-fc.toml` | +| Hypervisor | Written in | Architectures | Type | +|-|-|-|-| +|[ACRN] | C | `x86_64` | Type 1 (bare metal) | +|[Cloud Hypervisor] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | +|[Firecracker] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | |[QEMU] | C | all | Type 2 ([KVM]) | `configuration-qemu.toml` | -|[`Dragonball`] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | `configuration-dragonball.toml` | -|[StratoVirt] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | `configuration-stratovirt.toml` | +|[`Dragonball`] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | +|[StratoVirt] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) | ## Determine currently configured hypervisor @@ -58,6 +47,52 @@ the hypervisors: For further details, see the [Virtualization in Kata Containers](design/virtualization.md) document and the official documentation for each hypervisor. +## Hypervisor configuration files + +Since each hypervisor offers different features and options, Kata Containers +provides a separate +[configuration file](../src/runtime/README.md#configuration) +for each. The configuration files contain comments explaining which options +are available, their default values and how each setting can be used. + +| Hypervisor | Golang runtime config file | golang runtime short name | golang runtime default | rust runtime config file | rust runtime short name | rust runtime default | +|-|-|-|-|-|-|-| +| [ACRN] | [`configuration-acrn.toml`](../src/runtime/config/configuration-acrn.toml.in) | `acrn` | | | | | +| [Cloud Hypervisor] | [`configuration-clh.toml`](../src/runtime/config/configuration-clh.toml.in) | `clh` | | [`configuration-cloud-hypervisor.toml`](../src/runtime-rs/config/configuration-cloud-hypervisor.toml.in) | `cloud-hypervisor` | | +| [Firecracker] | [`configuration-fc.toml`](../src/runtime/config/configuration-fc.toml.in) | `fc` | | | | | +| [QEMU] | [`configuration-qemu.toml`](../src/runtime/config/configuration-qemu.toml.in) | `qemu` | yes | [`configuration-qemu.toml`](../src/runtime-rs/config/configuration-qemu.toml.in) | `qemu` | | +| [`Dragonball`] | | | | [`configuration-dragonball.toml`](../src/runtime-rs/config/configuration-dragonball.toml.in) | `dragonball` | yes | +| [StratoVirt] | [`configuration-stratovirt.toml`](../src/runtime/config/configuration-stratovirt.toml.in) | `stratovirt` | | | | | + +> **Notes:** +> +> - The short names specified are used by the [`kata-manager`](../utils/README.md) tool. +> - As shown by the default columns, each runtime type has its own default hypervisor. +> - The [golang runtime](../src/runtime) is the current default runtime. +> - The [rust runtime](../src/runtime-rs), also known as `runtime-rs`, +> is the newer runtime written in the rust language. +> - See the [Configuration](../README.md#configuration) for further details. +> - The configuration file links in the table link to the "source" +> versions: these are not usable configuration files as they contain +> variables that need to be expanded: +> - The links are provided for reference only. +> - The final (installed) versions, where all variables have been +> expanded, are built from these source configuration files. +> - The pristine configuration files are usually installed in the +> `/opt/kata/share/defaults/kata-containers/` or +> `/usr/share/defaults/kata-containers/` directories. +> - Some hypervisors may have the same name for both golang and rust +> runtimes, but the file contents may differ. +> - If there is no configuration file listed for the golang or +> rust runtimes, this either means the hypervisor cannot be run with +> a particular runtime, or that a driver has not yet been made +> available for that runtime. + +## Switch configured hypervisor + +To switch the configured hypervisor, you only need to run a single command. +See [the `kata-manager` documentation](../utils/README.md#choose-a-hypervisor) for further details. + [ACRN]: https://projectacrn.org [Cloud Hypervisor]: https://github.com/cloud-hypervisor/cloud-hypervisor [Firecracker]: https://github.com/firecracker-microvm/firecracker diff --git a/utils/README.md b/utils/README.md index ef0457f52d..c3143c3023 100644 --- a/utils/README.md +++ b/utils/README.md @@ -2,15 +2,18 @@ # Kata Manager -> **Note:** +> **Notes:** > -> We recommend users install Kata Containers using -> [official distribution packages](../docs/install/README.md#official-packages), where available. +> - We recommend users install Kata Containers using +> [official distribution packages](../docs/install/README.md#official-packages), where available. +> +> - These instructions only apply to the current default (golang) Kata runtime. +> See https://github.com/kata-containers/kata-containers/issues/9060 for further details. The [`kata-manager.sh`](kata-manager.sh) script automatically installs and -configures Kata Containers and containerd. +configures Kata Containers and a container manager (such as containerd, Docker and `nerdctl`). -This scripted method installs the latest versions of Kata Containers and +By default, the script installs the latest versions of Kata Containers and containerd. However, be aware of the following before proceeding: - Packages will **not** be automatically updated @@ -35,10 +38,22 @@ containerd, and then configure containerd to use Kata Containers. However, the script provides a number of options to allow you to change its behaviour. -> **Note:** +> **Notes:** > -> Before running the script to install Kata Containers, we recommend -> that you [review the available options](#show-available-options). +> - Before running the script to install Kata Containers, we recommend +> that you [review the available options](#show-available-options). +> +> - The `kata-manager.sh` script is +> [now packaged](https://github.com/kata-containers/kata-containers/pull/9091) +> as part of the Kata Containers release and can be called as either +> `kata-manager.sh` or simply `kata-manager`. Some of the sections +> below give two examples of how to run the script: running the +> local version, and by downloading and running the latest version +> in the Kata Containers GitHub repository. If your version of Kata +> Containers includes the `kata-manager.sh` script, you can run +> either version although we would suggest you use the local version +> since: (a) it has been tested with the Kata Containers release you +> are using; and (b) it is simpler to run the command directly. ### Show available options @@ -63,3 +78,127 @@ To install and configure a system with Kata Containers and containerd, run: ```bash $ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh)" ``` + +### Choose a Hypervisor + +Kata works with different [hypervisors](../docs/hypervisors.md). When you install a Kata system, the default hypervisor +will be configured, but all the available hypervisors are installed. +This means you can switch between hypervisors whenever you wish. + +#### List available hypervisors + +Run one of the following commands on an installed system. + +- If you Kata Containers installation includes the `kata-manager.sh` script, run: + + ```bash + $ kata-manager -L + ``` + +- If your Kata Containers installation does not include the `kata-manager.sh` script, run: + + ```bash + $ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh) -L" + ``` + +#### Show the default packaged hypervisor + +To show the default packaged hypervisor, run one of the following +commands on an installed system: + +- If you Kata Containers installation includes the `kata-manager.sh` script, run: + + ```bash + $ kata-manager -L | grep default + ``` + +- If your Kata Containers installation does not include the `kata-manager.sh` script, run: + + ```bash + $ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh) -L | grep default" + ``` + +#### Show the locally configured hypervisor + +`kata-manager.sh` will create a "local" copy of the packaged Kata configuration +file. + +To show details of the _local_ copy of the configuration files, run +one of the following on an installed system. + +- If you Kata Containers installation includes the `kata-manager.sh` script, run: + + ```bash + $ kata-manager -e + ``` + +- If your Kata Containers installation does not include the `kata-manager.sh` script, run: + + ```bash + $ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh) -e" + ``` + +> **Note:** This command can only be run once Kata has been installed. + +> See the [configuration documentation](https://github.com/kata-containers/kata-containers#configuration) +> for further information. + +#### Switch hypervisor + +> **Note:** +> +> If you create your own local configuration files, you should ensure +> they are backed up safely before switching hypervisor configuration +> since the script will overwrite any files that it needs to create in +> the Kata configuration directory (`/etc/kata-containers/` and +> sub-directories). + +##### To install Kata Containers and containerd and configure it for a specific hypervisor + +To specify that Kata be installed and configured to use a specific +hypervisor, use the `-H` option. For example, to select Cloud Hypervisor, run: + +```bash +$ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh) -H clh" +``` + +> **Note:** See the [List available hypervisors](#list-available-hypervisors) section +> for details of how to obtain the list of available hypervisor names. + +##### To switch the locally installed hypervisor + +To switch the local hypervisor config on an installed system use the +`-S` option. For example, to switch to the Cloud Hypervisor hypervisor, +run one of the following commands on an installed system: + +- If you Kata Containers installation includes the `kata-manager.sh` script, run: + + ```bash + $ kata-manager -S clh + ``` + +- If your Kata Containers installation does not include the `kata-manager.sh` script, run: + + ```bash + $ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh) -S clh" + ``` + +> **Note:** See the [List available hypervisors](#list-available-hypervisors) section +> for details of how to obtain the list of available hypervisor names. + +##### Switch to the default packaged hypervisor + +To undo your changes and switch back to the default Kata hypervisor, +specify the hypervisor name as `default`. For example, run one of the following commands on an installed system: + +- If you Kata Containers installation includes the `kata-manager.sh` script, run: + + ```bash + $ kata-manager -S default + ``` + +- If your Kata Containers installation does not include the `kata-manager.sh` script, run: + + ```bash + $ bash -c "$(curl -fsSL https://raw.githubusercontent.com/kata-containers/kata-containers/main/utils/kata-manager.sh) -S default" + ```