From 902843c0ef2af6cf4dd9b2cead32f78901d8f1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Tue, 21 Apr 2026 18:38:02 +0200 Subject: [PATCH] tools: Fix shellcheck issues in rootfs.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix shellcheck warnings and notes identified by running shellcheck --severity=style. Signed-off-by: Fabiano FidĂȘncio --- tools/osbuilder/rootfs-builder/rootfs.sh | 279 ++++++++++++----------- 1 file changed, 151 insertions(+), 128 deletions(-) diff --git a/tools/osbuilder/rootfs-builder/rootfs.sh b/tools/osbuilder/rootfs-builder/rootfs.sh index deafb0ec5f..76ba3d5a50 100755 --- a/tools/osbuilder/rootfs-builder/rootfs.sh +++ b/tools/osbuilder/rootfs-builder/rootfs.sh @@ -8,10 +8,10 @@ set -o errexit set -o pipefail set -o errtrace -[ -n "$DEBUG" ] && set -x +[[ -n "${DEBUG}" ]] && set -x script_name="${0##*/}" -script_dir="$(dirname $(readlink -f $0))" +script_dir="$(dirname "$(readlink -f "$0")")" AGENT_VERSION=${AGENT_VERSION:-} RUST_VERSION="null" AGENT_BIN=${AGENT_BIN:-kata-agent} @@ -39,7 +39,9 @@ DISTRO_REPO=${DISTRO_REPO:-""} PKG_MANAGER=${PKG_MANAGER:-""} lib_file="${script_dir}/../scripts/lib.sh" -source "$lib_file" +# shellcheck source=../scripts/lib.sh +# shellcheck disable=SC1091 +source "${lib_file}" if [[ "${AGENT_POLICY}" == "yes" ]]; then agent_policy_file="$(readlink -f -v "${AGENT_POLICY_FILE:-"${script_dir}/../../../src/kata-opa/allow-all.rego"}")" @@ -62,6 +64,7 @@ KBUILD_SIGN_PIN=${KBUILD_SIGN_PIN:-""} NVIDIA_GPU_STACK=${NVIDIA_GPU_STACK:-""} BUILD_VARIANT=${BUILD_VARIANT:-""} +# shellcheck source=/dev/null [[ "${BUILD_VARIANT}" == "nvidia-gpu"* ]] && source "${script_dir}/nvidia/nvidia_rootfs.sh" #For cross build @@ -70,11 +73,13 @@ BUILDX="" PLATFORM="" TARGET_ARCH=${TARGET_ARCH:-$(uname -m)} ARCH=${ARCH:-$(uname -m)} -[ "${TARGET_ARCH}" == "aarch64" ] && TARGET_ARCH=arm64 +[[ "${TARGET_ARCH}" == "aarch64" ]] && TARGET_ARCH=arm64 TARGET_OS=${TARGET_OS:-linux} stripping_tool="strip" -if [ "${CROSS_BUILD}" == "true" ]; then +if [[ "${CROSS_BUILD}" == "true" ]]; then + # shellcheck disable=SC2034 BUILDX=buildx + # shellcheck disable=SC2034 PLATFORM="--platform=${TARGET_OS}/${TARGET_ARCH}" if command -v "${TARGET_ARCH}-linux-gnu-strip" >/dev/null; then stripping_tool="${TARGET_ARCH}-linux-gnu-strip" @@ -112,16 +117,16 @@ typeset should_delete_unnecessary_files="no" handle_error() { local exit_code="${?}" local line_number="${1:-}" - echo "Failed at $line_number: ${BASH_COMMAND}" + echo "Failed at ${line_number}: ${BASH_COMMAND}" exit "${exit_code}" } trap 'handle_error $LINENO' ERR # Default architecture -if [ "$ARCH" == "ppc64le" ] || [ "$ARCH" == "s390x" ]; then +if [[ "${ARCH}" == "ppc64le" ]] || [[ "${ARCH}" == "s390x" ]]; then LIBC=gnu - echo "WARNING: Forcing LIBC=gnu because $ARCH has no musl Rust target" + echo "WARNING: Forcing LIBC=gnu because ${ARCH} has no musl Rust target" fi # distro-specific config file @@ -269,17 +274,18 @@ exit "${error}" get_distros() { cdirs=$(find "${script_dir}" -maxdepth 1 -type d) - find ${cdirs} -maxdepth 1 -name "${CONFIG_SH}" -printf '%H\n' | while read dir; do + find "${cdirs}" -maxdepth 1 -name "${CONFIG_SH}" -printf '%H\n' | while read -r dir; do basename "${dir}" done } get_test_config() { local -r distro="$1" - [ -z "$distro" ] && die "No distro name specified" + [[ -z "${distro}" ]] && die "No distro name specified" local config="${script_dir}/${distro}/config.sh" - source ${config} + # shellcheck source=/dev/null + source "${config}" printf "INIT_PROCESS:\t\t%s\n" "${INIT_PROCESS:-}" printf "ARCH_EXCLUDE_LIST:\t\t%s\n" "${ARCH_EXCLUDE_LIST[@]:-}" @@ -288,7 +294,7 @@ get_test_config() { check_function_exist() { function_name="$1" - [ "$(type -t ${function_name})" == "function" ] || die "${function_name} function was not defined" + [[ "$(type -t "${function_name}")" == "function" ]] || die "${function_name} function was not defined" } docker_extra_args() @@ -307,13 +313,15 @@ docker_extra_args() # Required to build glibc args+=" --cap-add SYS_PTRACE" # mount portage volume + # shellcheck disable=SC2154 args+=" -v ${gentoo_local_portage_dir}:/usr/portage/packages" + # shellcheck disable=SC2154 args+=" --volumes-from ${gentoo_portage_container}" ;; debian | ubuntu | suse) source /etc/os-release - case "$ID" in + case "${ID}" in fedora | centos | rhel) # Depending on the podman version, we'll face issues when passing # `--security-opt apparmor=unconfined` on a system where not apparmor is not installed. @@ -332,7 +340,7 @@ docker_extra_args() ;; esac - echo "$args" + echo "${args}" } setup_agent_init() @@ -340,11 +348,11 @@ setup_agent_init() agent_bin="$1" init_bin="$2" - [ -z "$agent_bin" ] && die "need agent binary path" - [ -z "$init_bin" ] && die "need init bin path" + [[ -z "${agent_bin}" ]] && die "need agent binary path" + [[ -z "${init_bin}" ]] && die "need init bin path" - info "Install $agent_bin as init process" - mv -f "${agent_bin}" ${init_bin} + info "Install ${agent_bin} as init process" + mv -f "${agent_bin}" "${init_bin}" OK "Agent is installed as init process" } @@ -353,8 +361,8 @@ copy_kernel_modules() local module_dir="$1" local rootfs_dir="$2" - [ -z "$module_dir" ] && die "need module directory" - [ -z "$rootfs_dir" ] && die "need rootfs directory" + [[ -z "${module_dir}" ]] && die "need module directory" + [[ -z "${rootfs_dir}" ]] && die "need rootfs directory" local dest_dir="${rootfs_dir}/lib/modules" @@ -366,11 +374,11 @@ copy_kernel_modules() error_handler() { - [ "$?" -eq 0 ] && return + [[ "$?" -eq 0 ]] && return - if [ -n "$GRACEFUL_EXIT" ] && [ -n "$BUILD_CAN_FAIL" ]; then - info "Detected a build error, but $distro is allowed to fail (BUILD_CAN_FAIL specified), so exiting sucessfully" - touch "$(dirname ${ROOTFS_DIR})/${distro}_fail" + if [[ -n "${GRACEFUL_EXIT}" ]] && [[ -n "${BUILD_CAN_FAIL}" ]]; then + info "Detected a build error, but ${distro} is allowed to fail (BUILD_CAN_FAIL specified), so exiting sucessfully" + touch "$(dirname "${ROOTFS_DIR}")/${distro}_fail" exit 0 fi } @@ -382,20 +390,25 @@ error_handler() # code otherwise. compare_versions() { - typeset -i -a v1=($(echo "$1" | awk 'BEGIN {FS = "."} {print $1" "$2}')) - typeset -i -a v2=($(echo "$2" | awk 'BEGIN {FS = "."} {print $1" "$2}')) + local v1_str v2_str + v1_str=$(echo "$1" | awk 'BEGIN {FS = "."} {print $1" "$2}') + v2_str=$(echo "$2" | awk 'BEGIN {FS = "."} {print $1" "$2}') + typeset -i -a v1 + read -ra v1 <<< "${v1_str}" + typeset -i -a v2 + read -ra v2 <<< "${v2_str}" # Sanity check: first version can't be all zero - [ "${v1[0]}" -eq "0" ] && \ - [ "${v1[1]}" -eq "0" ] && \ + [[ "${v1[0]}" -eq "0" ]] && \ + [[ "${v1[1]}" -eq "0" ]] && \ die "Failed to parse version number" # Major - [ "${v1[0]}" -gt "${v2[0]}" ] && { false; return; } + [[ "${v1[0]}" -gt "${v2[0]}" ]] && { false; return; } # Minor - [ "${v1[0]}" -eq "${v2[0]}" ] && \ - [ "${v1[1]}" -gt "${v2[1]}" ] && { false; return; } + [[ "${v1[0]}" -eq "${v2[0]}" ]] && \ + [[ "${v1[1]}" -gt "${v2[1]}" ]] && { false; return; } true } @@ -405,85 +418,90 @@ check_env_variables() # this will be mounted to container for using yq on the host side. GOPATH_LOCAL="${GOPATH%%:*}" - [ "$AGENT_INIT" == "yes" -o "$AGENT_INIT" == "no" ] || die "AGENT_INIT($AGENT_INIT) is invalid (must be yes or no)" - [ "$AGENT_POLICY" == "yes" -o "$AGENT_POLICY" == "no" ] || die "AGENT_POLICY($AGENT_POLICY) is invalid (must be yes or no)" + [[ "${AGENT_INIT}" == "yes" ]] || [[ "${AGENT_INIT}" == "no" ]] || die "AGENT_INIT(${AGENT_INIT}) is invalid (must be yes or no)" + [[ "${AGENT_POLICY}" == "yes" ]] || [[ "${AGENT_POLICY}" == "no" ]] || die "AGENT_POLICY(${AGENT_POLICY}) is invalid (must be yes or no)" - [ -n "${KERNEL_MODULES_DIR}" ] && [ ! -d "${KERNEL_MODULES_DIR}" ] && die "KERNEL_MODULES_DIR defined but is not an existing directory" + [[ -n "${KERNEL_MODULES_DIR}" ]] && [[ ! -d "${KERNEL_MODULES_DIR}" ]] && die "KERNEL_MODULES_DIR defined but is not an existing directory" if [[ "${AGENT_POLICY}" == "yes" ]]; then - [ ! -f "${agent_policy_file}" ] && die "agent policy file not found in '${agent_policy_file}'" + [[ ! -f "${agent_policy_file}" ]] && die "agent policy file not found in '${agent_policy_file}'" fi - [ -n "${OSBUILDER_VERSION}" ] || die "need osbuilder version" + [[ -n "${OSBUILDER_VERSION}" ]] || die "need osbuilder version" } # Builds a rootfs based on the distro name provided as argument build_rootfs_distro() { repo_dir="${script_dir}/../../../" - [ -n "${distro}" ] || usage 1 + [[ -n "${distro}" ]] || usage 1 distro_config_dir="${script_dir}/${distro}" - [ -d "${distro_config_dir}" ] || die "Not found configuration directory ${distro_config_dir}" + [[ -d "${distro_config_dir}" ]] || die "Not found configuration directory ${distro_config_dir}" # Source config.sh from distro rootfs_config="${distro_config_dir}/${CONFIG_SH}" + # shellcheck source=/dev/null source "${rootfs_config}" - if [ -z "$ROOTFS_DIR" ]; then + if [[ -z "${ROOTFS_DIR}" ]]; then + # shellcheck disable=SC2154 ROOTFS_DIR="${script_dir}/rootfs-${OS_NAME}" fi - if [ -e "${distro_config_dir}/${LIB_SH}" ];then + if [[ -e "${distro_config_dir}/${LIB_SH}" ]];then rootfs_lib="${distro_config_dir}/${LIB_SH}" info "rootfs_lib.sh file found. Loading content" + # shellcheck source=/dev/null source "${rootfs_lib}" fi + # shellcheck disable=SC2034 CONFIG_DIR=${distro_config_dir} check_function_exist "build_rootfs" - if [ -z "$INSIDE_CONTAINER" ] ; then + if [[ -z "${INSIDE_CONTAINER}" ]] ; then # Capture errors, but only outside of the docker container trap error_handler ERR fi - if [ -d "${ROOTFS_DIR}" ] && [ "${ROOTFS_DIR}" != "/" ]; then - rm -rf "${ROOTFS_DIR}"/* + if [[ -d "${ROOTFS_DIR}" ]] && [[ "${ROOTFS_DIR}" != "/" ]]; then + rm -rf "${ROOTFS_DIR:?}"/* else - mkdir -p ${ROOTFS_DIR} + mkdir -p "${ROOTFS_DIR}" fi - if [ "${SELINUX}" == "yes" ]; then - if [ "${AGENT_INIT}" == "yes" ]; then + if [[ "${SELINUX}" == "yes" ]]; then + if [[ "${AGENT_INIT}" == "yes" ]]; then die "Guest SELinux with the agent init is not supported yet" fi - if [ "${distro}" != "centos" ]; then + if [[ "${distro}" != "centos" ]]; then die "The guest rootfs must be CentOS to enable guest SELinux" fi fi - if [ -z "${USE_DOCKER}" ] && [ -z "${USE_PODMAN}" ]; then + if [[ -z "${USE_DOCKER}" ]] && [[ -z "${USE_PODMAN}" ]]; then info "build directly" - build_rootfs ${ROOTFS_DIR} + build_rootfs "${ROOTFS_DIR}" else engine_build_args="" - if [ -n "${USE_DOCKER}" ]; then + if [[ -n "${USE_DOCKER}" ]]; then container_engine="docker" - elif [ -n "${USE_PODMAN}" ]; then + elif [[ -n "${USE_PODMAN}" ]]; then container_engine="podman" engine_build_args+=" --runtime ${DOCKER_RUNTIME}" fi image_name="${distro}-rootfs-osbuilder" - if [ -n "${IMAGE_REGISTRY}" ]; then + if [[ -n "${IMAGE_REGISTRY}" ]]; then engine_build_args+=" --build-arg IMAGE_REGISTRY=${IMAGE_REGISTRY}" fi # setup to install rust here generate_dockerfile "${distro_config_dir}" - "$container_engine" build \ + # shellcheck disable=SC2086 + "${container_engine}" build \ ${engine_build_args} \ --build-arg http_proxy="${http_proxy}" \ --build-arg https_proxy="${https_proxy}" \ @@ -500,39 +518,39 @@ build_rootfs_distro() engine_run_args+=" --ulimit nofile=262144:262144" engine_run_args+=" --runtime ${DOCKER_RUNTIME}" - if [ -n "${AGENT_SOURCE_BIN}" ] && [ -n "${AGENT_TARBALL}" ]; then + if [[ -n "${AGENT_SOURCE_BIN}" ]] && [[ -n "${AGENT_TARBALL}" ]]; then die "AGENT_SOURCE_BIN and AGENT_TARBALL should never be used together!" fi - if [ -n "${AGENT_SOURCE_BIN}" ] ; then + if [[ -n "${AGENT_SOURCE_BIN}" ]] ; then engine_run_args+=" --env AGENT_SOURCE_BIN=${AGENT_SOURCE_BIN}" engine_run_args+=" -v ${AGENT_SOURCE_BIN}:${AGENT_SOURCE_BIN}" fi - if [ -n "${AGENT_TARBALL}" ] ; then + if [[ -n "${AGENT_TARBALL}" ]] ; then engine_run_args+=" --env AGENT_TARBALL=${AGENT_TARBALL}" - engine_run_args+=" -v $(dirname ${AGENT_TARBALL}):$(dirname ${AGENT_TARBALL})" + engine_run_args+=" -v $(dirname "${AGENT_TARBALL}"):$(dirname "${AGENT_TARBALL}")" fi - if [ -n "${COCO_GUEST_COMPONENTS_TARBALL}" ] ; then + if [[ -n "${COCO_GUEST_COMPONENTS_TARBALL}" ]] ; then CONFIDENTIAL_GUEST="yes" engine_run_args+=" --env COCO_GUEST_COMPONENTS_TARBALL=${COCO_GUEST_COMPONENTS_TARBALL}" - engine_run_args+=" -v $(dirname ${COCO_GUEST_COMPONENTS_TARBALL}):$(dirname ${COCO_GUEST_COMPONENTS_TARBALL})" + engine_run_args+=" -v $(dirname "${COCO_GUEST_COMPONENTS_TARBALL}"):$(dirname "${COCO_GUEST_COMPONENTS_TARBALL}")" fi - if [ -n "${PAUSE_IMAGE_TARBALL}" ]; then + if [[ -n "${PAUSE_IMAGE_TARBALL}" ]]; then engine_run_args+=" --env PAUSE_IMAGE_TARBALL=${PAUSE_IMAGE_TARBALL}" - engine_run_args+=" -v $(dirname ${PAUSE_IMAGE_TARBALL}):$(dirname ${PAUSE_IMAGE_TARBALL})" + engine_run_args+=" -v $(dirname "${PAUSE_IMAGE_TARBALL}"):$(dirname "${PAUSE_IMAGE_TARBALL}")" fi if [[ -n "${GUEST_HOOKS_TARBALL}" ]]; then engine_run_args+=" --env GUEST_HOOKS_TARBALL=${GUEST_HOOKS_TARBALL}" - engine_run_args+=" -v $(dirname ${GUEST_HOOKS_TARBALL}):$(dirname ${GUEST_HOOKS_TARBALL})" + engine_run_args+=" -v $(dirname "${GUEST_HOOKS_TARBALL}"):$(dirname "${GUEST_HOOKS_TARBALL}")" fi engine_run_args+=" -v ${GOPATH_LOCAL}:${GOPATH_LOCAL} --env GOPATH=${GOPATH_LOCAL}" - engine_run_args+=" $(docker_extra_args $distro)" + engine_run_args+=" $(docker_extra_args "${distro}")" # Relabel volumes so SELinux allows access (see docker-run(1)) if command -v selinuxenabled > /dev/null && selinuxenabled ; then @@ -543,7 +561,7 @@ build_rootfs_distro() "${script_dir}/../scripts" \ "${kernel_mod_dir}" \ "${SRC_VOL[@]}"; do - chcon -Rt svirt_sandbox_file_t "$volume_dir" + chcon -Rt svirt_sandbox_file_t "${volume_dir}" done fi @@ -553,7 +571,8 @@ build_rootfs_distro() #Make sure we use a compatible runtime to build rootfs # In case Clear Containers Runtime is installed we dont want to hit issue: #https://github.com/clearcontainers/runtime/issues/828 - "$container_engine" run \ + # shellcheck disable=SC2086,SC2154 + "${container_engine}" run \ --env https_proxy="${https_proxy}" \ --env http_proxy="${http_proxy}" \ --env AGENT_VERSION="${AGENT_VERSION}" \ @@ -587,7 +606,7 @@ build_rootfs_distro() -v "${ROOTFS_DIR}":"/rootfs" \ -v "${script_dir}/../scripts":"/scripts" \ -v "${kernel_mod_dir}":"${kernel_mod_dir}" \ - $engine_run_args \ + ${engine_run_args} \ ${image_name} \ bash /kata-containers/tools/osbuilder/rootfs-builder/rootfs.sh "${distro}" @@ -606,7 +625,7 @@ prepare_overlay() # validation work correctly for the dracut case. # We skip this if /sbin/init exists in the rootfs, meaning # we were passed a pre-populated rootfs directory - if [ ! -e ./sbin/init ]; then + if [[ ! -e ./sbin/init ]]; then ln -sf ./usr/lib/systemd/systemd ./init ln -sf /init ./sbin/init fi @@ -620,20 +639,20 @@ setup_rootfs() { info "Create symlink to /tmp in /var to create private temporal directories with systemd" pushd "${ROOTFS_DIR}" >> /dev/null - if [ "$PWD" != "/" ] ; then + if [[ "${PWD}" != "/" ]] ; then rm -rf ./var/cache/ ./var/lib ./var/log ./var/tmp fi ln -s ../tmp ./var/ # For some distros tmp.mount may not be installed by default in systemd paths - if ! [ -f "./etc/systemd/system/tmp.mount" ] && \ - ! [ -f "./usr/lib/systemd/system/tmp.mount" ] && - [ "$AGENT_INIT" != "yes" ]; then + if ! [[ -f "./etc/systemd/system/tmp.mount" ]] && \ + ! [[ -f "./usr/lib/systemd/system/tmp.mount" ]] && + [[ "${AGENT_INIT}" != "yes" ]]; then local unitFile="./etc/systemd/system/tmp.mount" info "Install tmp.mount in ./etc/systemd/system" - mkdir -p `dirname "$unitFile"` - cp ./usr/share/systemd/tmp.mount "$unitFile" || cat > "$unitFile" << EOF + mkdir -p "$(dirname "${unitFile}")" + cp ./usr/share/systemd/tmp.mount "${unitFile}" || cat > "${unitFile}" << EOF # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it @@ -661,7 +680,7 @@ EOF popd >> /dev/null - [ -n "${KERNEL_MODULES_DIR}" ] && copy_kernel_modules ${KERNEL_MODULES_DIR} ${ROOTFS_DIR} + [[ -n "${KERNEL_MODULES_DIR}" ]] && copy_kernel_modules "${KERNEL_MODULES_DIR}" "${ROOTFS_DIR}" info "Create ${ROOTFS_DIR}/etc" mkdir -p "${ROOTFS_DIR}/etc" @@ -672,11 +691,6 @@ EOF chrony_conf_file="${ROOTFS_DIR}/etc/chrony/chrony.conf" chrony_systemd_service="${ROOTFS_DIR}/lib/systemd/system/chrony.service" ;; - "ubuntu") - # Fix for #4932 - Boot hang at: "A start job is running for /dev/ttyS0" - mkdir -p "${ROOTFS_DIR}/etc/systemd/system/getty.target.wants" - ln -sf "/lib/systemd/system/getty@.service" "${ROOTFS_DIR}/etc/systemd/system/getty.target.wants/getty@ttyS0.service" - ;; *) chrony_conf_file="${ROOTFS_DIR}/etc/chrony.conf" chrony_systemd_service="${ROOTFS_DIR}/usr/lib/systemd/system/chronyd.service" @@ -693,9 +707,9 @@ EOF # Comment out ntp sources for chrony to be extra careful # Reference: https://chrony.tuxfamily.org/doc/3.4/chrony.conf.html - sed -i 's/^\(server \|pool \|peer \)/# &/g' ${chrony_conf_file} + sed -i 's/^\(server \|pool \|peer \)/# &/g' "${chrony_conf_file}" - if [ -f "$chrony_systemd_service" ]; then + if [[ -f "${chrony_systemd_service}" ]]; then # Remove user option, user could not exist in the rootfs # Set the /var/lib/chrony for ReadWritePaths to be ignored if # its nonexistent, this broke the service on boot previously @@ -703,37 +717,41 @@ EOF sed -i -e 's/^\(ExecStart=.*\)-u [[:alnum:]]*/\1/g' \ -e '/^\[Unit\]/a ConditionPathExists=\/dev\/ptp0' \ -e 's/^ReadWritePaths=\(.\+\) \/var\/lib\/chrony \(.\+\)$/ReadWritePaths=\1 -\/var\/lib\/chrony \2/m' \ - ${chrony_systemd_service} + "${chrony_systemd_service}" # Disable automatic directory creation sed -i -e 's/^\(StateDirectory=\)/#\1/g' \ -e 's/^\(LogsDirectory=\)/#\1/g' \ - ${chrony_systemd_service} + "${chrony_systemd_service}" fi AGENT_DIR="${ROOTFS_DIR}/usr/bin" AGENT_DEST="${AGENT_DIR}/${AGENT_BIN}" - if [ -z "${AGENT_SOURCE_BIN}" ] && [ -z "${AGENT_TARBALL}" ] ; then + if [[ -z "${AGENT_SOURCE_BIN}" ]] && [[ -z "${AGENT_TARBALL}" ]] ; then + # shellcheck disable=SC1091 test -r "${HOME}/.cargo/env" && source "${HOME}/.cargo/env" # rust agent needs ${ARCH}-unknown-linux-${LIBC} - if ! (rustup show | grep -v linux-${LIBC} > /dev/null); then - if [ "$RUST_VERSION" == "null" ]; then + if ! (rustup show | grep -v linux-"${LIBC}" > /dev/null); then + if [[ "${RUST_VERSION}" == "null" ]]; then detect_rust_version || \ die "Could not detect the required rust version for AGENT_VERSION='${AGENT_VERSION:-main}'." fi - bash ${script_dir}/../../../tests/install_rust.sh ${RUST_VERSION} + bash "${script_dir}"/../../../tests/install_rust.sh "${RUST_VERSION}" fi + # shellcheck disable=SC1091 test -r "${HOME}/.cargo/env" && source "${HOME}/.cargo/env" agent_dir="${script_dir}/../../../src/agent/" - if [ "${SECCOMP}" == "yes" ]; then + if [[ "${SECCOMP}" == "yes" ]]; then info "Set up libseccomp" detect_libseccomp_info || \ die "Could not detect the required libseccomp version and url" - export libseccomp_install_dir=$(mktemp -d -t libseccomp.XXXXXXXXXX) - export gperf_install_dir=$(mktemp -d -t gperf.XXXXXXXXXX) - ${script_dir}/../../../ci/install_libseccomp.sh "${libseccomp_install_dir}" "${gperf_install_dir}" + libseccomp_install_dir=$(mktemp -d -t libseccomp.XXXXXXXXXX) + export libseccomp_install_dir + gperf_install_dir=$(mktemp -d -t gperf.XXXXXXXXXX) + export gperf_install_dir + "${script_dir}"/../../../ci/install_libseccomp.sh "${libseccomp_install_dir}" "${gperf_install_dir}" echo "Set environment variables for the libseccomp crate to link the libseccomp library statically" export LIBSECCOMP_LINK_TYPE=static export LIBSECCOMP_LIB_PATH="${libseccomp_install_dir}/lib" @@ -741,30 +759,34 @@ EOF info "Build agent" pushd "${agent_dir}" - if [ -n "${AGENT_VERSION}" ]; then - git checkout "${AGENT_VERSION}" && OK "git checkout successful" || die "checkout agent ${AGENT_VERSION} failed!" + if [[ -n "${AGENT_VERSION}" ]]; then + if git checkout "${AGENT_VERSION}"; then + OK "git checkout successful" + else + die "checkout agent ${AGENT_VERSION} failed!" + fi fi make clean - make LIBC=${LIBC} INIT=${AGENT_INIT} SECCOMP=${SECCOMP} AGENT_POLICY=${AGENT_POLICY} - make install DESTDIR="${ROOTFS_DIR}" LIBC=${LIBC} INIT=${AGENT_INIT} - if [ "${SECCOMP}" == "yes" ]; then + make LIBC="${LIBC}" INIT="${AGENT_INIT}" SECCOMP="${SECCOMP}" AGENT_POLICY="${AGENT_POLICY}" + make install DESTDIR="${ROOTFS_DIR}" LIBC="${LIBC}" INIT="${AGENT_INIT}" + if [[ "${SECCOMP}" == "yes" ]]; then rm -rf "${libseccomp_install_dir}" "${gperf_install_dir}" fi popd - elif [ -n "${AGENT_SOURCE_BIN}" ]; then - mkdir -p ${AGENT_DIR} - cp ${AGENT_SOURCE_BIN} ${AGENT_DEST} + elif [[ -n "${AGENT_SOURCE_BIN}" ]]; then + mkdir -p "${AGENT_DIR}" + cp "${AGENT_SOURCE_BIN}" "${AGENT_DEST}" OK "cp ${AGENT_SOURCE_BIN} ${AGENT_DEST}" else - tar --zstd -xvf ${AGENT_TARBALL} -C ${ROOTFS_DIR} + tar --zstd -xvf "${AGENT_TARBALL}" -C "${ROOTFS_DIR}" fi - ${stripping_tool} ${ROOTFS_DIR}/usr/bin/kata-agent + ${stripping_tool} "${ROOTFS_DIR}"/usr/bin/kata-agent - [ -x "${AGENT_DEST}" ] || die "${AGENT_DEST} is not installed in ${ROOTFS_DIR}" + [[ -x "${AGENT_DEST}" ]] || die "${AGENT_DEST} is not installed in ${ROOTFS_DIR}" OK "Agent installed" - if [ "${AGENT_INIT}" == "yes" ]; then + if [[ "${AGENT_INIT}" == "yes" ]]; then setup_agent_init "${AGENT_DEST}" "${init}" else info "Setup systemd-base environment for kata-agent" @@ -775,18 +797,18 @@ EOF ln -sf "/usr/lib/systemd/system/dbus.socket" "${ROOTFS_DIR}/etc/systemd/system/kata-containers.target.wants/dbus.socket" chmod g+rx,o+x "${ROOTFS_DIR}" - if [ "${CONFIDENTIAL_GUEST}" == "yes" ]; then + if [[ "${CONFIDENTIAL_GUEST}" == "yes" ]]; then info "Tweaking /run to use 50% of the available memory" # Tweak the kata-agent service to have /run using 50% of the memory available # This is needed as, by default, systemd would only allow 10%, which is way # too low, even for very small test images fstab_file="${ROOTFS_DIR}/etc/fstab" - [ -e ${fstab_file} ] && sed -i '/\/run/d' ${fstab_file} - echo "tmpfs /run tmpfs nodev,nosuid,size=50% 0 0" >> ${fstab_file} + [[ -e "${fstab_file}" ]] && sed -i '/\/run/d' "${fstab_file}" + echo "tmpfs /run tmpfs nodev,nosuid,size=50% 0 0" >> "${fstab_file}" kata_systemd_target="${ROOTFS_DIR}/usr/lib/systemd/system/kata-containers.target" - grep -qE "^Requires=.*systemd-remount-fs.service.*" ${kata_systemd_target} || \ - echo "Requires=systemd-remount-fs.service" >> ${kata_systemd_target} + grep -qE "^Requires=.*systemd-remount-fs.service.*" "${kata_systemd_target}" || \ + echo "Requires=systemd-remount-fs.service" >> "${kata_systemd_target}" fi fi @@ -794,7 +816,8 @@ EOF info "Install the default policy" # Install default settings for the kata-opa service. local opa_settings_dir="/etc/kata-opa" - local policy_file_name="$(basename ${agent_policy_file})" + local policy_file_name + policy_file_name="$(basename "${agent_policy_file}")" local policy_dir="${ROOTFS_DIR}/${opa_settings_dir}" mkdir -p "${policy_dir}" install -D -o root -g root -m 0644 "${agent_policy_file}" -T "${policy_dir}/${policy_file_name}" @@ -807,27 +830,27 @@ EOF fi info "Check init is installed" - [ -x "${init}" ] || [ -L "${init}" ] || die "/sbin/init is not installed in ${ROOTFS_DIR}" + [[ -x "${init}" ]] || [[ -L "${init}" ]] || die "/sbin/init is not installed in ${ROOTFS_DIR}" OK "init is installed" - if [ -n "${PAUSE_IMAGE_TARBALL}" ] ; then + if [[ -n "${PAUSE_IMAGE_TARBALL}" ]] ; then info "Installing the pause image tarball" - tar --zstd -xvf ${PAUSE_IMAGE_TARBALL} -C ${ROOTFS_DIR} + tar --zstd -xvf "${PAUSE_IMAGE_TARBALL}" -C "${ROOTFS_DIR}" fi - if [ -n "${COCO_GUEST_COMPONENTS_TARBALL}" ] ; then + if [[ -n "${COCO_GUEST_COMPONENTS_TARBALL}" ]] ; then info "Installing the Confidential Containers guest components tarball" - tar --zstd -xvf ${COCO_GUEST_COMPONENTS_TARBALL} -C ${ROOTFS_DIR} + tar --zstd -xvf "${COCO_GUEST_COMPONENTS_TARBALL}" -C "${ROOTFS_DIR}" fi # Create an empty /etc/resolv.conf, to allow agent to bind mount container resolv.conf to Kata VM dns_file="${ROOTFS_DIR}/etc/resolv.conf" - if [ -L "$dns_file" ]; then + if [[ -L "${dns_file}" ]]; then # if /etc/resolv.conf is a link, it cannot be used for bind mount - rm -f "$dns_file" + rm -f "${dns_file}" fi info "Create /etc/resolv.conf file in rootfs if not exist" - touch "$dns_file" + touch "${dns_file}" if [[ "${should_delete_unnecessary_files}" == "yes" ]]; then delete_unnecessary_files @@ -839,11 +862,11 @@ EOF parse_arguments() { - [ "$#" -eq 0 ] && usage && return 0 + [[ "$#" -eq 0 ]] && usage && return 0 while getopts a:dhlo:r:t: opt do - case $opt in + case ${opt} in a) AGENT_VERSION="${OPTARG}" ;; d) should_delete_unnecessary_files="yes" ;; h) usage ;; @@ -855,7 +878,7 @@ parse_arguments() esac done - shift $(($OPTIND - 1)) + shift $((OPTIND - 1)) distro="$1" } @@ -863,12 +886,12 @@ detect_host_distro() { source /etc/os-release - case "$ID" in + case "${ID}" in "*suse*") distro="suse" ;; *) - distro="$ID" + distro="${ID}" ;; esac } @@ -896,14 +919,14 @@ delete_unnecessary_files() main() { - parse_arguments $* + parse_arguments "$@" check_env_variables - if [ -n "$distro" ]; then + if [[ -n "${distro}" ]]; then build_rootfs_distro else #Make sure ROOTFS_DIR is set correctly - [ -d "${ROOTFS_DIR}" ] || die "Invalid rootfs directory: '$ROOTFS_DIR'" + [[ -d "${ROOTFS_DIR}" ]] || die "Invalid rootfs directory: '${ROOTFS_DIR}'" # Set the distro for dracut build method detect_host_distro @@ -913,17 +936,17 @@ main() init="${ROOTFS_DIR}/sbin/init" setup_rootfs - if [ "${BUILD_VARIANT}" = "nvidia-gpu" ]; then + if [[ "${BUILD_VARIANT}" = "nvidia-gpu" ]]; then setup_nvidia_gpu_rootfs_stage_one setup_nvidia_gpu_rootfs_stage_two return $? fi - if [ "${BUILD_VARIANT}" = "nvidia-gpu-confidential" ]; then + if [[ "${BUILD_VARIANT}" = "nvidia-gpu-confidential" ]]; then setup_nvidia_gpu_rootfs_stage_one "confidential" setup_nvidia_gpu_rootfs_stage_two "confidential" return $? fi } -main $* +main "$@"