mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 01:13:02 +00:00 
			
		
		
		
	osbuilder: Multistrap Ubuntu
Use `multistrap` for building Ubuntu rootfs. Adds support for building for foreign architectures using the `ARCH` environment variable. In the process, the Ubuntu rootfs workflow is vastly simplified. Signed-off-by: Jakob Naucke <jakob.naucke@ibm.com>
This commit is contained in:
		| @@ -39,7 +39,11 @@ handle_error() { | |||||||
| trap 'handle_error $LINENO' ERR | trap 'handle_error $LINENO' ERR | ||||||
|  |  | ||||||
| # Default architecture | # Default architecture | ||||||
| ARCH=$(uname -m) | export ARCH=${ARCH:-$(uname -m)} | ||||||
|  | if [ "$ARCH" == "ppc64le" ] || [ "$ARCH" == "s390x" ]; then | ||||||
|  | 	LIBC=gnu | ||||||
|  | 	echo "WARNING: Forcing LIBC=gnu because $ARCH has no musl Rust target" | ||||||
|  | fi | ||||||
|  |  | ||||||
| # distro-specific config file | # distro-specific config file | ||||||
| typeset -r CONFIG_SH="config.sh" | typeset -r CONFIG_SH="config.sh" | ||||||
| @@ -103,6 +107,11 @@ AGENT_SOURCE_BIN    Path to the directory of agent binary. | |||||||
| AGENT_VERSION       Version of the agent to include in the rootfs. | AGENT_VERSION       Version of the agent to include in the rootfs. | ||||||
|                     Default value: ${AGENT_VERSION:-<not set>} |                     Default value: ${AGENT_VERSION:-<not set>} | ||||||
|  |  | ||||||
|  | ARCH                Target architecture (according to \`uname -m\`). | ||||||
|  |                     Foreign bootstraps are currently only supported for Ubuntu | ||||||
|  |                     and glibc agents. | ||||||
|  |                     Default value: $(uname -m) | ||||||
|  |  | ||||||
| DISTRO_REPO         Use host repositories to install guest packages. | DISTRO_REPO         Use host repositories to install guest packages. | ||||||
|                     Default value: <not set> |                     Default value: <not set> | ||||||
|  |  | ||||||
| @@ -408,6 +417,7 @@ build_rootfs_distro() | |||||||
| 			--env ROOTFS_DIR="/rootfs" \ | 			--env ROOTFS_DIR="/rootfs" \ | ||||||
| 			--env AGENT_BIN="${AGENT_BIN}" \ | 			--env AGENT_BIN="${AGENT_BIN}" \ | ||||||
| 			--env AGENT_INIT="${AGENT_INIT}" \ | 			--env AGENT_INIT="${AGENT_INIT}" \ | ||||||
|  | 			--env ARCH="${ARCH}" \ | ||||||
| 			--env CI="${CI}" \ | 			--env CI="${CI}" \ | ||||||
| 			--env KERNEL_MODULES_DIR="${KERNEL_MODULES_DIR}" \ | 			--env KERNEL_MODULES_DIR="${KERNEL_MODULES_DIR}" \ | ||||||
| 			--env LIBC="${LIBC}" \ | 			--env LIBC="${LIBC}" \ | ||||||
| @@ -538,10 +548,6 @@ EOT | |||||||
| 	AGENT_DEST="${AGENT_DIR}/${AGENT_BIN}" | 	AGENT_DEST="${AGENT_DIR}/${AGENT_BIN}" | ||||||
|  |  | ||||||
| 	if [ -z "${AGENT_SOURCE_BIN}" ] ; then | 	if [ -z "${AGENT_SOURCE_BIN}" ] ; then | ||||||
| 		if [ "$ARCH" == "ppc64le" ] || [ "$ARCH" == "s390x" ]; then |  | ||||||
| 			LIBC=gnu |  | ||||||
| 			echo "WARNING: Forcing LIBC=gnu because $ARCH has no musl Rust target" |  | ||||||
| 		fi |  | ||||||
| 		test -r "${HOME}/.cargo/env" && source "${HOME}/.cargo/env" | 		test -r "${HOME}/.cargo/env" && source "${HOME}/.cargo/env" | ||||||
| 		# rust agent needs ${arch}-unknown-linux-${LIBC} | 		# rust agent needs ${arch}-unknown-linux-${LIBC} | ||||||
| 		if ! (rustup show | grep -v linux-${LIBC} > /dev/null); then | 		if ! (rustup show | grep -v linux-${LIBC} > /dev/null); then | ||||||
| @@ -559,7 +565,7 @@ EOT | |||||||
| 			info "Set up libseccomp" | 			info "Set up libseccomp" | ||||||
| 			libseccomp_install_dir=$(mktemp -d -t libseccomp.XXXXXXXXXX) | 			libseccomp_install_dir=$(mktemp -d -t libseccomp.XXXXXXXXXX) | ||||||
| 			gperf_install_dir=$(mktemp -d -t gperf.XXXXXXXXXX) | 			gperf_install_dir=$(mktemp -d -t gperf.XXXXXXXXXX) | ||||||
| 			bash ${script_dir}/../../../ci/install_libseccomp.sh "${libseccomp_install_dir}" "${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" | 			echo "Set environment variables for the libseccomp crate to link the libseccomp library statically" | ||||||
| 			export LIBSECCOMP_LINK_TYPE=static | 			export LIBSECCOMP_LINK_TYPE=static | ||||||
| 			export LIBSECCOMP_LIB_PATH="${libseccomp_install_dir}/lib" | 			export LIBSECCOMP_LIB_PATH="${libseccomp_install_dir}/lib" | ||||||
|   | |||||||
| @@ -1,45 +1,29 @@ | |||||||
| # | # Copyright (c) 2018 Yash Jain, 2022 IBM Corp. | ||||||
| # Copyright (c) 2018  Yash Jain |  | ||||||
| # | # | ||||||
| # SPDX-License-Identifier: Apache-2.0 | # SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  | ||||||
| ARG IMAGE_REGISTRY=docker.io | ARG IMAGE_REGISTRY=docker.io | ||||||
| #ubuntu: docker image to be used to create a rootfs |  | ||||||
| #@OS_VERSION@: Docker image version to build this dockerfile |  | ||||||
| FROM ${IMAGE_REGISTRY}/ubuntu:@OS_VERSION@ | FROM ${IMAGE_REGISTRY}/ubuntu:@OS_VERSION@ | ||||||
|  | @SET_PROXY@ | ||||||
|  |  | ||||||
| # This dockerfile needs to provide all the componets need to build a rootfs | RUN apt-get update && \ | ||||||
| # Install any package need to create a rootfs (package manager, extra tools) |     DEBIAN_FRONTEND=noninteractive \ | ||||||
|  |     apt-get --no-install-recommends -y install \ | ||||||
| # RUN commands |  | ||||||
| RUN apt-get update && apt-get --no-install-recommends install -y \ |  | ||||||
|     apt-utils \ |  | ||||||
|     autoconf \ |  | ||||||
|     automake \ |  | ||||||
|     binutils \ |  | ||||||
|     build-essential \ |  | ||||||
|     ca-certificates \ |     ca-certificates \ | ||||||
|     chrony \ |  | ||||||
|     coreutils \ |  | ||||||
|     curl \ |     curl \ | ||||||
|     debianutils \ |  | ||||||
|     debootstrap \ |  | ||||||
|     g++ \ |     g++ \ | ||||||
|     gcc \ |     $(gcc_arch="@ARCH@" && [ "$(uname -m)" != "$gcc_arch" ] && ( \ | ||||||
|  |          libc_arch="$gcc_arch" && \ | ||||||
|  |          [ "$gcc_arch" = aarch64 ] && libc_arch=arm64; \ | ||||||
|  |          [ "$gcc_arch" = ppc64le ] && gcc_arch=powerpc64le && libc_arch=ppc64el; \ | ||||||
|  |          [ "$gcc_arch" = x86_64 ] && gcc_arch=x86-64 && libc_arch=amd64; \ | ||||||
|  |          echo "gcc-$gcc_arch-linux-gnu libc6-dev-$libc_arch-cross")) \ | ||||||
|     git \ |     git \ | ||||||
|     libc6-dev \ |  | ||||||
|     libstdc++-8-dev \ |  | ||||||
|     m4 \ |  | ||||||
|     make \ |     make \ | ||||||
|  |     multistrap \ | ||||||
|     musl-tools \ |     musl-tools \ | ||||||
|     protobuf-compiler \ |     protobuf-compiler | ||||||
|     sed \ |  | ||||||
|     systemd \ |  | ||||||
|     tar \ |  | ||||||
|     vim \ |  | ||||||
|     wget |  | ||||||
| # aarch64 requires this name -- link for all | # aarch64 requires this name -- link for all | ||||||
| RUN ln -s /usr/bin/musl-gcc "/usr/bin/$(uname -m)-linux-musl-gcc" | RUN ln -s /usr/bin/musl-gcc "/usr/bin/$(uname -m)-linux-musl-gcc" | ||||||
|  |  | ||||||
| # This will install the proper packages to build Kata components |  | ||||||
| @INSTALL_RUST@ | @INSTALL_RUST@ | ||||||
|   | |||||||
| @@ -1,34 +1,28 @@ | |||||||
| # This is a configuration file add extra variables to | # Copyright (c) 2018 Yash Jain, 2022 IBM Corp. | ||||||
| # |  | ||||||
| # Copyright (c) 2018  Yash Jain |  | ||||||
| # | # | ||||||
| # SPDX-License-Identifier: Apache-2.0 | # SPDX-License-Identifier: Apache-2.0 | ||||||
| # be used by build_rootfs() from rootfs_lib.sh the variables will be |  | ||||||
| # loaded just before call the function. For more information see the |  | ||||||
| # rootfs-builder/README.md file. |  | ||||||
|  |  | ||||||
| OS_VERSION=${OS_VERSION:-20.04} | OS_NAME=ubuntu | ||||||
| # This should be Ubuntu's code name, e.g. "focal" (Focal Fossa) for 20.04 | # This should be Ubuntu's code name, e.g. "focal" (Focal Fossa) for 20.04 | ||||||
| OS_NAME=${OS_NAME:-"focal"} | OS_VERSION=${OS_VERSION:-focal} | ||||||
|  | PACKAGES=chrony | ||||||
|  | [ "$AGENT_INIT" = no ] && PACKAGES+=" init" | ||||||
|  | [ "$SECCOMP" = yes ] && PACKAGES+=" libseccomp2" | ||||||
|  | REPO_URL=http://ports.ubuntu.com | ||||||
|  |  | ||||||
| # packages to be installed by default | case "$ARCH" in | ||||||
| PACKAGES="systemd coreutils init kmod" | 	aarch64) DEB_ARCH=arm64;; | ||||||
| EXTRA_PKGS+=" chrony" | 	ppc64le) DEB_ARCH=ppc64el;; | ||||||
|  | 	s390x) DEB_ARCH="$ARCH";; | ||||||
| DEBOOTSTRAP=${PACKAGE_MANAGER:-"debootstrap"} | 	x86_64) DEB_ARCH=amd64; REPO_URL=http://archive.ubuntu.com/ubuntu;; | ||||||
|  | 	*) die "$ARCH not supported" | ||||||
| case $(uname -m) in |  | ||||||
| 	x86_64) ARCHITECTURE="amd64";; |  | ||||||
| 	ppc64le) ARCHITECTURE="ppc64el";; |  | ||||||
| 	aarch64) ARCHITECTURE="arm64";; |  | ||||||
| 	s390x)	ARCHITECTURE="s390x";; |  | ||||||
| 	(*) die "$(uname -m) not supported " |  | ||||||
| esac | esac | ||||||
|  |  | ||||||
| # Init process must be one of {systemd,kata-agent} | if [ "$(uname -m)" != "$ARCH" ]; then | ||||||
| INIT_PROCESS=systemd | 	case "$ARCH" in | ||||||
| # List of zero or more architectures to exclude from build, | 		ppc64le) cc_arch=powerpc64le;; | ||||||
| # as reported by  `uname -m` | 		x86_64) cc_arch=x86-64;; | ||||||
| ARCH_EXCLUDE_LIST=() | 		*) cc_arch="$ARCH" | ||||||
|  | 	esac | ||||||
| [ "$SECCOMP" = "yes" ] && PACKAGES+=" libseccomp2" || true | 	export CC="$cc_arch-linux-gnu-gcc" | ||||||
|  | fi | ||||||
|   | |||||||
| @@ -1,78 +1,29 @@ | |||||||
| # - Arguments | # Copyright (c) 2018 Yash Jain, 2022 IBM Corp. | ||||||
| # |  | ||||||
| # Copyright (c) 2018  Yash Jain |  | ||||||
| # | # | ||||||
| # SPDX-License-Identifier: Apache-2.0 | # SPDX-License-Identifier: Apache-2.0 | ||||||
| # |  | ||||||
| # |  | ||||||
| # rootfs_dir=$1 |  | ||||||
| # |  | ||||||
| # - Optional environment variables |  | ||||||
| # |  | ||||||
| # EXTRA_PKGS: Variable to add extra PKGS provided by the user |  | ||||||
| # |  | ||||||
| # BIN_AGENT: Name of the Kata-Agent binary |  | ||||||
| # |  | ||||||
| # REPO_URL: URL to distribution repository ( should be configured in |  | ||||||
| #			config.sh file) |  | ||||||
| # |  | ||||||
| # Any other configuration variable for a specific distro must be added |  | ||||||
| # and documented on its own config.sh |  | ||||||
| # |  | ||||||
| # - Expected result |  | ||||||
| # |  | ||||||
| # rootfs_dir populated with rootfs pkgs |  | ||||||
| # It must provide a binary in /sbin/init |  | ||||||
| # |  | ||||||
| build_rootfs() { | build_rootfs() { | ||||||
| 	# Mandatory | 	local rootfs_dir=$1 | ||||||
| 	local ROOTFS_DIR=$1 | 	local multistrap_conf=multistrap.conf | ||||||
|  |  | ||||||
| 	# Name of the Kata-Agent binary | 	# For simplicity's sake, use multistrap for foreign and native bootstraps. | ||||||
| 	local BIN_AGENT=${BIN_AGENT} | 	cat > "$multistrap_conf" << EOF | ||||||
|  | [General] | ||||||
|  | cleanup=true | ||||||
|  | aptsources=Ubuntu | ||||||
|  | bootstrap=Ubuntu | ||||||
|  |  | ||||||
| 	# In case of support EXTRA packages, use it to allow | [Ubuntu] | ||||||
| 	# users to add more packages to the base rootfs | source=$REPO_URL | ||||||
| 	local EXTRA_PKGS=${EXTRA_PKGS:-} | keyring=ubuntu-keyring | ||||||
|  | suite=focal | ||||||
|  | packages=$PACKAGES $EXTRA_PKGS | ||||||
|  | EOF | ||||||
|  | 	multistrap -a "$DEB_ARCH" -d "$rootfs_dir" -f "$multistrap_conf" | ||||||
|  | 	rm -rf "$rootfs_dir/var/run" | ||||||
|  | 	ln -s /run "$rootfs_dir/var/run" | ||||||
|  | 	cp --remove-destination /etc/resolv.conf "$rootfs_dir/etc" | ||||||
|  |  | ||||||
| 	# In case rootfs is created using repositories allow user to modify | 	# Reduce image size and memory footprint by removing unnecessary files and directories. | ||||||
| 	# the default URL | 	rm -rf $rootfs_dir/usr/share/{bash-completion,bug,doc,info,lintian,locale,man,menu,misc,pixmaps,terminfo,zsh} | ||||||
| 	local REPO_URL=${REPO_URL:-YOUR_REPO} |  | ||||||
|  |  | ||||||
| 	# PATH where files this script is placed |  | ||||||
| 	# Use it to refer to files in the same directory |  | ||||||
| 	# Example: ${CONFIG_DIR}/foo |  | ||||||
| 	local CONFIG_DIR=${CONFIG_DIR} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	# Populate ROOTFS_DIR |  | ||||||
| 	# Must provide /sbin/init and /bin/${BIN_AGENT} |  | ||||||
| 	DEBOOTSTRAP="debootstrap" |  | ||||||
| 	check_root |  | ||||||
| 	mkdir -p "${ROOTFS_DIR}" |  | ||||||
| 	if [ -n "${PKG_MANAGER}"  ]; then |  | ||||||
| 		info "debootstrap path provided by user: ${PKG_MANAGER}" |  | ||||||
| 	elif check_program $DEBOOTSTRAP ; then |  | ||||||
| 		PKG_MANAGER=$DEBOOTSTRAP |  | ||||||
| 	else |  | ||||||
| 		die "$DEBOOTSTRAP is not installed" |  | ||||||
| 	fi |  | ||||||
| 	# trim whitespace |  | ||||||
| 	PACKAGES=$(echo $PACKAGES |xargs ) |  | ||||||
| 	# add comma as debootstrap needs , separated package names. |  | ||||||
| 	# Don't change $PACKAGES in config.sh to include ',' |  | ||||||
| 	# This is done to maintain consistency |  | ||||||
| 	PACKAGES=$(echo $PACKAGES | sed  -e 's/ /,/g' ) |  | ||||||
|  |  | ||||||
| 	${PKG_MANAGER} --variant=minbase \ |  | ||||||
| 		--arch=${ARCHITECTURE}\ |  | ||||||
| 		--include="$PACKAGES" \ |  | ||||||
| 		${OS_NAME} \ |  | ||||||
| 		${ROOTFS_DIR} |  | ||||||
|  |  | ||||||
| 	[ -n "${EXTRA_PKGS}" ] && chroot $ROOTFS_DIR apt-get install -y ${EXTRA_PKGS} |  | ||||||
|  |  | ||||||
|     # Reduce image size and memory footprint |  | ||||||
|     # removing not needed files and directories. |  | ||||||
|     chroot $ROOTFS_DIR rm -rf /usr/share/{bash-completion,bug,doc,info,lintian,locale,man,menu,misc,pixmaps,terminfo,zoneinfo,zsh} |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -203,8 +203,8 @@ generate_dockerfile() | |||||||
| 	dir="$1" | 	dir="$1" | ||||||
| 	[ -d "${dir}" ] || die "${dir}: not a directory" | 	[ -d "${dir}" ] || die "${dir}: not a directory" | ||||||
|  |  | ||||||
| 	local rustarch=$(uname -m) | 	local rustarch="$ARCH" | ||||||
| 	[ "$rustarch" = ppc64le ] && rustarch=powerpc64le | 	[ "$ARCH" = ppc64le ] && rustarch=powerpc64le | ||||||
|  |  | ||||||
| 	[ -n "${http_proxy:-}" ] && readonly set_proxy="RUN sed -i '$ a proxy="${http_proxy:-}"' /etc/dnf/dnf.conf /etc/yum.conf; true" | 	[ -n "${http_proxy:-}" ] && readonly set_proxy="RUN sed -i '$ a proxy="${http_proxy:-}"' /etc/dnf/dnf.conf /etc/yum.conf; true" | ||||||
|  |  | ||||||
| @@ -220,6 +220,7 @@ RUN . /root/.cargo/env; cargo install cargo-when | |||||||
|  |  | ||||||
| 	sed \ | 	sed \ | ||||||
| 		-e "s#@OS_VERSION@#${OS_VERSION:-}#g" \ | 		-e "s#@OS_VERSION@#${OS_VERSION:-}#g" \ | ||||||
|  | 		-e "s#@ARCH@#$ARCH#g" \ | ||||||
| 		-e "s#@INSTALL_RUST@#${install_rust//$'\n'/\\n}#g" \ | 		-e "s#@INSTALL_RUST@#${install_rust//$'\n'/\\n}#g" \ | ||||||
| 		-e "s#@SET_PROXY@#${set_proxy:-}#g" \ | 		-e "s#@SET_PROXY@#${set_proxy:-}#g" \ | ||||||
| 		Dockerfile.in > Dockerfile | 		Dockerfile.in > Dockerfile | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user