diff --git a/.ci/run.sh b/.ci/run.sh index fb0b70e073..7439a9d752 100755 --- a/.ci/run.sh +++ b/.ci/run.sh @@ -13,3 +13,6 @@ export GOPATH="${GOPATH:-/tmp/go}" script_dir="$(dirname $(readlink -f $0))" sudo -E PATH="$PATH" bash "${script_dir}/../tests/test_images.sh" + +# run again to build rust agent +sudo -E RUST_AGENT="yes" PATH="$PATH" bash "${script_dir}/../tests/test_images.sh" diff --git a/.travis.yml b/.travis.yml index c306ff60b4..d3cff59311 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,4 +24,4 @@ before_script: - ".ci/setup.sh" script: -- "travis_wait 50 .ci/run.sh" + - "travis_wait 50 .ci/run.sh" diff --git a/dracut/Dockerfile.in b/dracut/Dockerfile.in index 227142ed75..9d3a7c75e4 100644 --- a/dracut/Dockerfile.in +++ b/dracut/Dockerfile.in @@ -6,9 +6,33 @@ from opensuse/tumbleweed RUN zypper --non-interactive refresh; \ - zypper --non-interactive install --no-recommends --force-resolution cpio curl dracut gcc git-core make tar; \ + zypper --non-interactive install --no-recommends --force-resolution \ + autoconf \ + automake \ + binutils \ + cmake \ + coreutils \ + cpio \ + curl \ + dracut \ + gcc \ + gcc-c++ \ + git-core \ + glibc-devel \ + glibc-devel-static \ + glibc-utils \ + libstdc++-devel \ + linux-glibc-devel \ + m4 \ + make \ + sed \ + tar \ + vim \ + which; \ zypper --non-interactive clean --all; # This will install the proper golang to build Kata components +@INSTALL_MUSL@ @INSTALL_GO@ +@INSTALL_RUST@ diff --git a/rootfs-builder/alpine/Dockerfile.in b/rootfs-builder/alpine/Dockerfile.in index 24fb8610c7..dba67a9fe4 100644 --- a/rootfs-builder/alpine/Dockerfile.in +++ b/rootfs-builder/alpine/Dockerfile.in @@ -6,13 +6,36 @@ From docker.io/golang:@GO_VERSION@-alpine RUN apk update && apk add \ - git \ - make \ - bash \ - gcc \ - musl-dev \ - linux-headers \ apk-tools-static \ + autoconf \ + automake \ + bash \ + binutils \ + cmake \ + coreutils \ + curl \ + g++ \ + gcc \ + git \ + libc-dev \ libseccomp \ libseccomp-dev \ - curl + linux-headers \ + m4 \ + make \ + musl \ + musl-dev \ + tar \ + vim +# alpine doesn't support x86_64-unknown-linux-gnu +# It only support x86_64-unknown-linux-musl. Even worse, +# it doesn't support proc-macro, which is needed for serde_derive +# +# See issue: https://github.com/kata-containers/osbuilder/issues/386 +# -- FIXME +# +# Thus, we cannot build rust agent on alpine +# The way to use alpine is to generate rootfs or build +# go agent to get rootfs and then cp rust agent to rootfs. +# pity.. +# RUN ln -svf /usr/bin/gcc /bin/musl-gcc; ln -svf /usr/bin/g++ /bin/musl-g++ diff --git a/rootfs-builder/centos/Dockerfile.in b/rootfs-builder/centos/Dockerfile.in index 3b027afb0a..c7714ad18c 100644 --- a/rootfs-builder/centos/Dockerfile.in +++ b/rootfs-builder/centos/Dockerfile.in @@ -8,14 +8,34 @@ From docker.io/centos:@OS_VERSION@ @SET_PROXY@ RUN yum -y update && yum install -y \ -git \ -make \ -gcc \ -coreutils \ -libseccomp \ -libseccomp-devel \ -chrony \ -curl + autoconf \ + automake \ + binutils \ + chrony \ + coreutils \ + curl \ + gcc \ + gcc-c++ \ + git \ + glibc-common \ + glibc-devel \ + glibc-headers \ + glibc-static \ + glibc-utils \ + libseccomp \ + libseccomp-devel \ + libstdc++-devel \ + libstdc++-static \ + m4 \ + make \ + sed \ + tar \ + vim \ + which +# install cmake because centos7's cmake is too old +@INSTALL_CMAKE@ +@INSTALL_MUSL@ # This will install the proper golang to build Kata components @INSTALL_GO@ +@INSTALL_RUST@ diff --git a/rootfs-builder/clearlinux/Dockerfile.in b/rootfs-builder/clearlinux/Dockerfile.in index 5ed047bba0..949812541e 100644 --- a/rootfs-builder/clearlinux/Dockerfile.in +++ b/rootfs-builder/clearlinux/Dockerfile.in @@ -8,15 +8,36 @@ From docker.io/fedora:30 @SET_PROXY@ RUN dnf -y update && dnf install -y \ -chrony \ -curl \ -gcc \ -git \ -libseccomp \ -libseccomp-devel \ -make \ -pkgconfig \ -systemd + autoconf \ + automake \ + binutils \ + chrony \ + cmake \ + coreutils \ + curl \ + curl \ + gcc \ + gcc-c++ \ + git \ + glibc-common \ + glibc-devel \ + glibc-headers \ + glibc-static \ + glibc-utils \ + libseccomp \ + libseccomp-devel \ + libstdc++-devel \ + libstdc++-static \ + m4 \ + make \ + pkgconfig \ + sed \ + systemd \ + tar \ + vim \ + which # This will install the proper golang to build Kata components +@INSTALL_MUSL@ @INSTALL_GO@ +@INSTALL_RUST@ diff --git a/rootfs-builder/debian/Dockerfile.in b/rootfs-builder/debian/Dockerfile.in index b524d5005c..ed57ec1a4f 100644 --- a/rootfs-builder/debian/Dockerfile.in +++ b/rootfs-builder/debian/Dockerfile.in @@ -7,7 +7,33 @@ from docker.io/debian:@OS_VERSION@ # RUN commands -RUN apt-get update && apt-get install -y curl wget systemd debootstrap git build-essential chrony +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + binutils \ + build-essential \ + chrony \ + cmake \ + coreutils \ + curl \ + debianutils \ + debootstrap \ + g++ \ + gcc \ + git \ + libc-dev \ + libstdc++-6-dev \ + m4 \ + make \ + musl \ + musl-dev \ + musl-tools \ + sed \ + systemd \ + tar \ + vim \ + wget + # This will install the proper golang to build Kata components @INSTALL_GO@ - +@INSTALL_RUST@ diff --git a/rootfs-builder/euleros/Dockerfile.in b/rootfs-builder/euleros/Dockerfile.in index 3868b2b26f..b57dece7d1 100644 --- a/rootfs-builder/euleros/Dockerfile.in +++ b/rootfs-builder/euleros/Dockerfile.in @@ -8,13 +8,39 @@ FROM docker.io/euleros:@OS_VERSION@ @SET_PROXY@ RUN yum -y update && yum install -y \ -yum \ -git \ -make \ -gcc \ -coreutils \ -chrony \ -curl + autoconf \ + automake \ + binutils \ + chrony \ + coreutils \ + curl \ + gcc \ + gcc-c++ \ + git \ + glibc-common \ + glibc-devel \ + glibc-headers \ + glibc-static \ + glibc-utils \ + libstdc++-devel \ + libstdc++-static \ + m4 \ + make \ + sed \ + tar \ + vim \ + which \ + yum # This will install the proper golang to build Kata components @INSTALL_GO@ + +# several problems prevent us from building rust agent on euleros +# 1. There is no libstdc++.a. copy one from somewhere get through +# compilation +# 2. The kernel (3.10.x) is too old, kernel-headers pacakge +# has no vm_socket.h because kernel has no vsock support or +# vsock header files + +# We will disable rust agent build in rootfs.sh for euleros +# and alpine(musl cannot support proc-macro) diff --git a/rootfs-builder/fedora/Dockerfile.in b/rootfs-builder/fedora/Dockerfile.in index 3aa3d6e441..b67203341f 100644 --- a/rootfs-builder/fedora/Dockerfile.in +++ b/rootfs-builder/fedora/Dockerfile.in @@ -8,16 +8,36 @@ From docker.io/fedora:@OS_VERSION@ @SET_PROXY@ RUN dnf -y update && dnf install -y \ -chrony \ -curl \ -gcc \ -git \ -libseccomp \ -libseccomp-devel \ -make \ -pkgconfig \ -redhat-release \ -systemd + autoconf \ + automake \ + binutils \ + chrony \ + cmake \ + coreutils \ + curl \ + gcc \ + gcc-c++ \ + git \ + glibc-common \ + glibc-devel \ + glibc-headers \ + glibc-static \ + glibc-utils \ + libseccomp \ + libseccomp-devel \ + libstdc++-devel \ + libstdc++-static \ + m4 \ + make \ + pkgconfig \ + redhat-release \ + sed \ + systemd \ + tar \ + vim \ + which # This will install the proper golang to build Kata components +@INSTALL_MUSL@ @INSTALL_GO@ +@INSTALL_RUST@ diff --git a/rootfs-builder/rootfs.sh b/rootfs-builder/rootfs.sh index f2d283e6de..5a5655ec17 100755 --- a/rootfs-builder/rootfs.sh +++ b/rootfs-builder/rootfs.sh @@ -14,6 +14,12 @@ script_name="${0##*/}" script_dir="$(dirname $(readlink -f $0))" AGENT_VERSION=${AGENT_VERSION:-} GO_AGENT_PKG=${GO_AGENT_PKG:-github.com/kata-containers/agent} +RUST_AGENT_PKG=${RUST_AGENT_PKG:-github.com/kata-containers/kata-containers} +RUST_AGENT=${RUST_AGENT:-no} +RUST_VERSION="null" +RUST_SRC_PATH=${RUST_SRC_PATH:-${HOME}/rust} +CMAKE_VERSION=${CMAKE_VERSION:-"null"} +MUSL_VERSION=${MUSL_VERSION:-"null"} AGENT_BIN=${AGENT_BIN:-kata-agent} AGENT_INIT=${AGENT_INIT:-no} KERNEL_MODULES_DIR=${KERNEL_MODULES_DIR:-""} @@ -95,6 +101,15 @@ AGENT_INIT When set to "yes", use ${AGENT_BIN} as init process in place of systemd. Default value: no +RUST_AGENT When set to "yes", build kata-agent from kata-rust-agent instead of go agent + Default value: "no" + +RUST_AGENT_PKG URL of the Git repository hosting the agent package. + Default value: ${RUST_AGENT_PKG} + +RUST_SRC_PATH Path of the source code + Default value: ${RUST_SRC_PATH} + AGENT_VERSION Version of the agent to include in the rootfs. Default value: ${AGENT_VERSION:-} @@ -264,6 +279,11 @@ check_env_variables() [ "$AGENT_INIT" == "yes" -o "$AGENT_INIT" == "no" ] || die "AGENT_INIT($AGENT_INIT) is invalid (must be yes or no)" + if [ -z "${AGENT_SOURCE_BIN}" ]; then + [ "$RUST_AGENT" == "yes" -o "$RUST_AGENT" == "no" ] || die "RUST_AGENT($RUST_AGENT) is invalid (must be yes or no)" + mkdir -p ${RUST_SRC_PATH} || : + fi + [ -n "${KERNEL_MODULES_DIR}" ] && [ ! -d "${KERNEL_MODULES_DIR}" ] && die "KERNEL_MODULES_DIR defined but is not an existing directory" [ -n "${OSBUILDER_VERSION}" ] || die "need osbuilder version" @@ -312,12 +332,39 @@ build_rootfs_distro() echo "Required Go version: $GO_VERSION" + # need to detect rustc's version too? + detect_rust_version || + die "Could not detect the required rust version for AGENT_VERSION='${AGENT_VERSION:-master}'." + + echo "Required rust version: $RUST_VERSION" + + detect_cmake_version || + die "Could not detect the required cmake version for AGENT_VERSION='${AGENT_VERSION:-master}'." + + echo "Required cmake version: $CMAKE_VERSION" + + detect_musl_version || + die "Could not detect the required musl version for AGENT_VERSION='${AGENT_VERSION:-master}'." + + echo "Required musl version: $MUSL_VERSION" + if [ -z "${USE_DOCKER}" ] && [ -z "${USE_PODMAN}" ]; then #Generate an error if the local Go version is too old foundVersion=$(go version | sed -E "s/^.+([0-9]+\.[0-9]+\.[0-9]+).*$/\1/g") - compare_versions "$GO_VERSION" $foundVersion || \ - die "Your Go version $foundVersion is older than the minimum expected Go version $GO_VERSION" + compare_versions "${GO_VERSION}" "${foundVersion}" || \ + die "Your Go version ${foundVersion} is older than the minimum expected Go version ${GO_VERSION}" + + if [ "${RUST_AGENT}" == "yes" ]; then + source "${HOME}/.cargo/env" + foundVersion=$(rustc --version | sed -E "s/^.+([0-9]+\.[0-9]+\.[0-9]+).*$/\1/g") + + compare_versions "${RUST_VERSION}" "${foundVersion}" || \ + die "Your rust version ${foundVersion} is older than the minimum expected rust version ${RUST_VERSION}" + + foundVersion=$(cmake --version | grep "[0-9]\+.[0-9]\+.[0-9]\+" | sed -E "s/^.+([0-9]+\.[0-9]+\.[0-9]+).*$/\1/g") + + fi else if [ -n "${USE_DOCKER}" ]; then container_engine="docker" @@ -327,6 +374,7 @@ build_rootfs_distro() image_name="${distro}-rootfs-osbuilder" + # setup to install go or rust here generate_dockerfile "${distro_config_dir}" "$container_engine" build \ --build-arg http_proxy="${http_proxy}" \ @@ -341,7 +389,12 @@ build_rootfs_distro() docker_run_args+=" --runtime ${DOCKER_RUNTIME}" if [ -z "${AGENT_SOURCE_BIN}" ] ; then - docker_run_args+=" --env GO_AGENT_PKG=${GO_AGENT_PKG}" + if [ "$RUST_AGENT" == "no" ]; then + docker_run_args+=" --env GO_AGENT_PKG=${GO_AGENT_PKG}" + else + docker_run_args+=" --env RUST_AGENT_PKG=${RUST_AGENT_PKG} -v ${RUST_SRC_PATH}:${RUST_SRC_PATH} --env RUST_SRC_PATH=${RUST_SRC_PATH}" + fi + docker_run_args+=" --env RUST_AGENT=${RUST_AGENT} -v ${GOPATH_LOCAL}:${GOPATH_LOCAL} --env GOPATH=${GOPATH_LOCAL}" else docker_run_args+=" --env AGENT_SOURCE_BIN=${AGENT_SOURCE_BIN}" docker_run_args+=" -v ${AGENT_SOURCE_BIN}:${AGENT_SOURCE_BIN}" @@ -351,11 +404,16 @@ build_rootfs_distro() # Relabel volumes so SELinux allows access (see docker-run(1)) if command -v selinuxenabled > /dev/null && selinuxenabled ; then + SRC_VOL=("${GOPATH_LOCAL}") + if [ "${RUST_AGENT}" == "yes" ]; then + SRC_VOL+=("${RUST_SRC_PATH}") + fi + for volume_dir in "${script_dir}" \ "${ROOTFS_DIR}" \ "${script_dir}/../scripts" \ "${kernel_mod_dir}" \ - "${GOPATH_LOCAL}"; do + "${SRC_VOL[@]}"; do chcon -Rt svirt_sandbox_file_t "$volume_dir" done fi @@ -370,18 +428,17 @@ build_rootfs_distro() --env ROOTFS_DIR="/rootfs" \ --env AGENT_BIN="${AGENT_BIN}" \ --env AGENT_INIT="${AGENT_INIT}" \ - --env GOPATH="${GOPATH_LOCAL}" \ --env KERNEL_MODULES_DIR="${KERNEL_MODULES_DIR}" \ --env EXTRA_PKGS="${EXTRA_PKGS}" \ --env OSBUILDER_VERSION="${OSBUILDER_VERSION}" \ --env INSIDE_CONTAINER=1 \ --env SECCOMP="${SECCOMP}" \ --env DEBUG="${DEBUG}" \ + --env HOME="/root" \ -v "${script_dir}":"/osbuilder" \ -v "${ROOTFS_DIR}":"/rootfs" \ -v "${script_dir}/../scripts":"/scripts" \ -v "${kernel_mod_dir}":"${kernel_mod_dir}" \ - -v "${GOPATH_LOCAL}":"${GOPATH_LOCAL}" \ $docker_run_args \ ${image_name} \ bash /osbuilder/rootfs.sh "${distro}" @@ -501,11 +558,31 @@ EOT info "Build agent" pushd "${GOPATH_LOCAL}/src/${GO_AGENT_PKG}" - [ -n "${AGENT_VERSION}" ] && git checkout "${AGENT_VERSION}" && OK "git checkout successful" + [ -n "${AGENT_VERSION}" ] && git checkout "${AGENT_VERSION}" && OK "git checkout successful" || info "checkout failed!" make clean make INIT=${AGENT_INIT} make install DESTDIR="${ROOTFS_DIR}" INIT=${AGENT_INIT} SECCOMP=${SECCOMP} popd + if [ "$RUST_AGENT" == "yes" ]; then + # build rust agent + info "Build rust agent" + # The PATH /.cargo/bin is apparently wrong + # looks like $HOME is resolved to empty when + # container is started + source "${HOME}/.cargo/env" + local -r agent_dir="$(basename ${RUST_AGENT_PKG})/src/agent" + pushd "${RUST_SRC_PATH}" + if [ ! -d ${RUST_SRC_PATH}/${agent_dir} ]; then + git clone https://${RUST_AGENT_PKG}.git + fi + cd ${agent_dir} + # checkout correct version + [ -n "${AGENT_VERSION}" ] && git checkout "${AGENT_VERSION}" && OK "git checkout successful" + make clean + make + make install DESTDIR="${ROOTFS_DIR}" + popd + fi else cp ${AGENT_SOURCE_BIN} ${AGENT_DEST} OK "cp ${AGENT_SOURCE_BIN} ${AGENT_DEST}" @@ -550,6 +627,29 @@ parse_arguments() shift $(($OPTIND - 1)) distro="$1" + arch=$(uname -m) + + if [ "${distro}" == "alpine" -o "${distro}" == "euleros" ]; then + if [ "${RUST_AGENT}" == "yes" ]; then + die "rust agent cannot be built on ${distro}. +alpine: only has stable/nightly-x86_64-unknown-linux-musl toolchain. It does not support proc-macro compilation. +See issue: https://github.com/kata-containers/osbuilder/issues/386 +euleros: 1. Missing libstdc++.a + 2. kernel is 3.10.x, there is no vsock support +You can build rust agent on your host and then copy it into +image's rootfs(eg. rootfs-builder/rootfs/usr/bin), and then +use image_builder.sh to build image with the rootfs. Please +refer to documentation for how to use customer agent. +See issue: https://github.com/kata-containers/osbuilder/issues/387" + fi + fi + + if [ "${RUST_AGENT}" == "yes" ] && [ "${arch}" == "s390x" -o "${arch}" == "ppc64le" ]; then + die "Cannot build rust agent on ppc64le. +musl cannot be built on ppc64le because of long double +reprentation is broken. And rust has no musl target on ppc64le. +See issue: https://github.com/kata-containers/osbuilder/issues/388" + fi } detect_host_distro() diff --git a/rootfs-builder/suse/Dockerfile.in b/rootfs-builder/suse/Dockerfile.in index 72d4c7b44c..3daa8dfb41 100644 --- a/rootfs-builder/suse/Dockerfile.in +++ b/rootfs-builder/suse/Dockerfile.in @@ -15,4 +15,6 @@ COPY install-packages.sh config.sh / RUN chmod +x /install-packages.sh; /install-packages.sh # This will install the proper golang to build Kata components +@INSTALL_MUSL@ @INSTALL_GO@ +@INSTALL_RUST@ diff --git a/rootfs-builder/suse/install-packages.sh b/rootfs-builder/suse/install-packages.sh index 8bfa9c0505..f26339b884 100644 --- a/rootfs-builder/suse/install-packages.sh +++ b/rootfs-builder/suse/install-packages.sh @@ -24,6 +24,27 @@ zypper --non-interactive addrepo ${SUSE_FULLURL_UPDATE} osbuilder-update # in Leap ulimit -n 1024 zypper --non-interactive refresh -zypper --non-interactive install --no-recommends --force-resolution curl git gcc make python3-kiwi tar +zypper --non-interactive install --no-recommends --force-resolution \ + autoconf \ + automake \ + binutils \ + cmake \ + coreutils \ + curl \ + gcc \ + gcc-c++ \ + git \ + glibc-devel \ + glibc-devel-static \ + glibc-utils \ + libstdc++-devel \ + linux-glibc-devel \ + m4 \ + make \ + python3-kiwi \ + sed \ + tar \ + vim \ + which zypper --non-interactive clean --all diff --git a/rootfs-builder/ubuntu/Dockerfile.in b/rootfs-builder/ubuntu/Dockerfile.in index 2b3f3f4365..f54b04db0c 100644 --- a/rootfs-builder/ubuntu/Dockerfile.in +++ b/rootfs-builder/ubuntu/Dockerfile.in @@ -11,7 +11,32 @@ from docker.io/ubuntu:@OS_VERSION@ # Install any package need to create a rootfs (package manager, extra tools) # RUN commands -RUN apt-get update && apt-get install -y curl wget systemd debootstrap git build-essential chrony +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + binutils \ + build-essential \ + chrony \ + cmake \ + coreutils \ + curl \ + debianutils \ + debootstrap \ + g++ \ + gcc \ + git \ + libc6-dev \ + libstdc++-8-dev \ + m4 \ + make \ + musl \ + musl-dev \ + musl-tools \ + sed \ + systemd \ + tar \ + vim \ + wget # This will install the proper golang to build Kata components @INSTALL_GO@ - +@INSTALL_RUST@ diff --git a/scripts/lib.sh b/scripts/lib.sh index 218eef5515..1ddaa5fce1 100644 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -8,6 +8,9 @@ set -e GO_AGENT_PKG=${GO_AGENT_PKG:-github.com/kata-containers/agent} GO_RUNTIME_PKG=${GO_RUNTIME_PKG:-github.com/kata-containers/runtime} +RUST_AGENT_PKG=${RUST_AGENT_PKG:-github.com/kata-containers/kata-rust-agent} +CMAKE_VERSION=${CMAKE_VERSION:-"null"} +MUSL_VERSION=${MUSL_VERSION:-"null"} #https://github.com/kata-containers/tests/blob/master/.ci/jenkins_job_build.sh # Give preference to variable set by CI KATA_BRANCH=${branch:-} @@ -192,7 +195,21 @@ create_summary_file() local agent="${AGENT_DEST}" [ "$AGENT_INIT" = yes ] && agent="${init}" - local -r agent_version=$("$agent" --version|awk '{print $NF}') + local agent_version + if [ "${RUST_AGENT}" == "no" ]; then + agent_version=$("$agent" --version|awk '{print $NF}') + else + local -r agentdir="${RUST_SRC_PATH}/$(basename ${RUST_AGENT_PKG} .git)/src/agent" + agent_version=$(cat ${agentdir}/VERSION) + fi + + local REAL_AGENT_PKG + + if [ "$RUST_AGENT" == "no" ]; then + REAL_AGENT_PKG=${GO_AGENT_PKG} + else + REAL_AGENT_PKG=${RUST_AGENT_PKG} + fi cat >"$file"<<-EOT --- @@ -212,7 +229,7 @@ ${packages} extra: ${extra} agent: - url: "https://${GO_AGENT_PKG}" + url: "https://${REAL_AGENT_PKG}" name: "${AGENT_BIN}" version: "${agent_version}" agent-is-init-daemon: "${AGENT_INIT}" @@ -230,9 +247,14 @@ generate_dockerfile() dir="$1" [ -d "${dir}" ] || die "${dir}: not a directory" + local architecture=$(uname -m) + local rustarch=${architecture} + local muslarch=${architecture} case "$(uname -m)" in "ppc64le") goarch=ppc64le + rustarch=powerpc64le + muslarch=powerpc64 ;; "aarch64") @@ -251,6 +273,8 @@ generate_dockerfile() curlOptions=("-OL") [ -n "${http_proxy:-}" ] && curlOptions+=("-x ${http_proxy:-}") + + readonly dockerfile_template="Dockerfile.in" readonly install_go=" RUN cd /tmp ; curl ${curlOptions[@]} https://storage.googleapis.com/golang/go${GO_VERSION}.linux-${goarch}.tar.gz RUN tar -C /usr/ -xzf /tmp/go${GO_VERSION}.linux-${goarch}.tar.gz @@ -258,15 +282,77 @@ ENV GOROOT=/usr/go ENV PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin " - readonly dockerfile_template="Dockerfile.in" + # Rust agent + # rust installer should set path apropiately, just in case + local cmake_file="cmake-${CMAKE_VERSION}.tar.gz" + local cmake_dir="cmake-${CMAKE_VERSION}" + readonly install_cmake=" +RUN pushd /root; \ + curl -sLO https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${cmake_file}; \ + tar -zxf ${cmake_file}; \ + cd ${cmake_dir}; \ + ./bootstrap > /dev/null 2>\&1; \ + make > /dev/null 2>\&1; \ + make install > /dev/null 2>\&1; \ + popd +" + local musl_tar="musl-${MUSL_VERSION}.tar.gz" + local musl_dir="musl-${MUSL_VERSION}" + readonly install_musl=" +RUN pushd /root; \ + curl -sLO https://www.musl-libc.org/releases/${musl_tar}; tar -zxf ${musl_tar}; \ + cd ${musl_dir}; \ + sed -i \"s/^ARCH = .*/ARCH = ${muslarch}/g\" dist/config.mak; \ + ./configure > /dev/null 2>\&1; \ + make > /dev/null 2>\&1; \ + make install > /dev/null 2>\&1; \ + echo \"/usr/local/musl/lib\" > /etc/ld-musl-${muslarch}.path; \ + popd +ENV PATH=\$PATH:/usr/local/musl/bin +" + readonly install_rust=" +RUN curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSLf --output /tmp/rust-init; \ + chmod a+x /tmp/rust-init; \ + export http_proxy=${http_proxy:-}; \ + export https_proxy=${http_proxy:-}; \ + /tmp/rust-init -y +RUN . /root/.cargo/env; \ + export http_proxy=${http_proxy:-}; \ + export https_proxy=${http_proxy:-}; \ + cargo install cargo-when; \ + rustup toolchain install ${RUST_VERSION}; \ + rustup default ${RUST_VERSION}; \ + rustup target install ${rustarch}-unknown-linux-musl +RUN ln -sf /usr/bin/g++ /bin/musl-g++ +" + # rust agent still need go to build + # because grpc-sys need go to build pushd ${dir} [ -f "${dockerfile_template}" ] || die "${dockerfile_template}: file not found" - sed \ - -e "s|@GO_VERSION@|${GO_VERSION}|g" \ - -e "s|@OS_VERSION@|${OS_VERSION:-}|g" \ - -e "s|@INSTALL_GO@|${install_go//$'\n'/\\n}|g" \ - -e "s|@SET_PROXY@|${set_proxy:-}|g" \ - ${dockerfile_template} > Dockerfile + # powerpc have no musl target, don't setup rust enviroment + # since we cannot static link agent. Besides, there is + # also long double representation problem when building musl-libc + if [ "${architecture}" == "ppc64le" ]; then + sed \ + -e "s|@GO_VERSION@|${GO_VERSION}|g" \ + -e "s|@OS_VERSION@|${OS_VERSION:-}|g" \ + -e "s|@INSTALL_CMAKE@||g" \ + -e "s|@INSTALL_MUSL@||g" \ + -e "s|@INSTALL_GO@|${install_go//$'\n'/\\n}|g" \ + -e "s|@INSTALL_RUST@||g" \ + -e "s|@SET_PROXY@|${set_proxy:-}|g" \ + ${dockerfile_template} > Dockerfile + else + sed \ + -e "s|@GO_VERSION@|${GO_VERSION}|g" \ + -e "s|@OS_VERSION@|${OS_VERSION:-}|g" \ + -e "s|@INSTALL_CMAKE@|${install_cmake//$'\n'/\\n}|g" \ + -e "s|@INSTALL_MUSL@|${install_musl//$'\n'/\\n}|g" \ + -e "s|@INSTALL_GO@|${install_go//$'\n'/\\n}|g" \ + -e "s|@INSTALL_RUST@|${install_rust//$'\n'/\\n}|g" \ + -e "s|@SET_PROXY@|${set_proxy:-}|g" \ + ${dockerfile_template} > Dockerfile + fi popd } @@ -289,7 +375,7 @@ detect_go_version() typeset -r runtimeVersionsURL="https://raw.githubusercontent.com/kata-containers/runtime/${runtimeRevision}/versions.yaml" info "Getting golang version from ${runtimeVersionsURL}" # This may fail if we are a kata bump. - if GO_VERSION="$(curl -fsSL "$runtimeVersionsURL" | tac | tac | $yq r - "languages.golang.version")"; then + if GO_VERSION="$(curl -fsSL "$runtimeVersionsURL" | $yq r - "languages.golang.version")"; then [ "$GO_VERSION" != "null" ] return 0 fi @@ -301,7 +387,7 @@ detect_go_version() info "There is not runtime repository in filesystem (${kata_runtime_pkg_dir})" local runtime_versions_url="https://raw.githubusercontent.com/kata-containers/runtime/${KATA_BRANCH}/versions.yaml" info "Get versions file from ${runtime_versions_url}" - GO_VERSION="$(curl -fsSL "${runtime_versions_url}" | tac | tac | $yq r - "languages.golang.version")" + GO_VERSION="$(curl -fsSL "${runtime_versions_url}" | $yq r - "languages.golang.version")" if [ "$?" == "0" ] && [ "$GO_VERSION" != "null" ]; then return 0 fi @@ -316,3 +402,142 @@ detect_go_version() [ "$?" == "0" ] && [ "$GO_VERSION" != "null" ] } +detect_rust_version() +{ + info "Detecting agent rust version" + typeset -r yq=$(command -v yq || command -v ${GOPATH}/bin/yq) + if [ -z "$yq" ]; then + source "$yq_file" + fi + + local runtimeRevision="" + + # Detect runtime revision by fetching the agent's VERSION file + local runtime_version_url="https://raw.githubusercontent.com/kata-containers/agent/${AGENT_VERSION:-master}/VERSION" + info "Detecting runtime version using ${runtime_version_url}" + + if runtimeRevision="$(curl -fsSL ${runtime_version_url})"; then + [ -n "${runtimeRevision}" ] || die "failed to get agent version" + typeset -r runtimeVersionsURL="https://raw.githubusercontent.com/kata-containers/runtime/${runtimeRevision}/versions.yaml" + info "Getting rust version from ${runtimeVersionsURL}" + # This may fail if we are a kata bump. + if RUST_VERSION="$(curl -fsSL "$runtimeVersionsURL" | $yq r - "languages.rust.version")"; then + [ "$RUST_VERSION" != "null" ] + return 0 + fi + fi + + info "Agent version has not match with a runtime version, assumming it is a PR" + local kata_runtime_pkg_dir="${GOPATH}/src/${GO_RUNTIME_PKG}" + if [ ! -d "${kata_runtime_pkg_dir}" ];then + info "There is not runtime repository in filesystem (${kata_runtime_pkg_dir})" + local runtime_versions_url="https://raw.githubusercontent.com/kata-containers/runtime/${KATA_BRANCH}/versions.yaml" + info "Get versions file from ${runtime_versions_url}" + RUST_VERSION="$(curl -fsSL "${runtime_versions_url}" | $yq r - "languages.rust.version")" + if [ "$?" == "0" ] && [ "$RUST_VERSION" != "null" ]; then + return 0 + fi + + return 1 + fi + + local kata_versions_file="${kata_runtime_pkg_dir}/versions.yaml" + info "Get rust version from ${kata_versions_file}" + RUST_VERSION="$(cat "${kata_versions_file}" | $yq r - "languages.rust.version")" + + [ "$?" == "0" ] && [ "$RUST_VERSION" != "null" ] +} + +detect_cmake_version() +{ + info "Detecting cmake version" + + typeset -r yq=$(command -v yq || command -v ${GOPATH}/bin/yq) + if [ -z "$yq" ]; then + source "$yq_file" + fi + + local runtimeRevision="" + + # Detect runtime revision by fetching the agent's VERSION file + local runtime_version_url="https://raw.githubusercontent.com/kata-containers/agent/${AGENT_VERSION:-master}/VERSION" + info "Detecting runtime version using ${runtime_version_url}" + + if runtimeRevision="$(curl -fsSL ${runtime_version_url})"; then + [ -n "${runtimeRevision}" ] || die "failed to get agent version" + typeset -r runtimeVersionsURL="https://raw.githubusercontent.com/kata-containers/runtime/${runtimeRevision}/versions.yaml" + info "Getting cmake version from ${runtimeVersionsURL}" + # This may fail if we are a kata bump. + if CMAKE_VERSION="$(curl -fsSL "$runtimeVersionsURL" | $yq r - "externals.cmake.version")"; then + [ "$CMAKE_VERSION" != "null" ] + return 0 + fi + fi + + info "Agent version has not match with a runtime version, assumming it is a PR" + local kata_runtime_pkg_dir="${GOPATH}/src/${GO_RUNTIME_PKG}" + if [ ! -d "${kata_runtime_pkg_dir}" ];then + info "There is not runtime repository in filesystem (${kata_runtime_pkg_dir})" + local runtime_versions_url="https://raw.githubusercontent.com/kata-containers/runtime/${KATA_BRANCH}/versions.yaml" + info "Get versions file from ${runtime_versions_url}" + CMAKE_VERSION="$(curl -fsSL "${runtime_versions_url}" | $yq r - "externals.cmake.version")" + if [ "$?" == "0" ] && [ "$CMAKE_VERSION" != "null" ]; then + return 0 + fi + + return 1 + fi + + local kata_versions_file="${kata_runtime_pkg_dir}/versions.yaml" + info "Get cmake version from ${kata_versions_file}" + CMAKE_VERSION="$(cat "${kata_versions_file}" | $yq r - "externals.cmake.version")" + + [ "$?" == "0" ] && [ "$CMAKE_VERSION" != "null" ] +} + +detect_musl_version() +{ + info "Detecting musl version" + + typeset -r yq=$(command -v yq || command -v ${GOPATH}/bin/yq) + if [ -z "$yq" ]; then + source "$yq_file" + fi + + local runtimeRevision="" + + # Detect runtime revision by fetching the agent's VERSION file + local runtime_version_url="https://raw.githubusercontent.com/kata-containers/agent/${AGENT_VERSION:-master}/VERSION" + info "Detecting runtime version using ${runtime_version_url}" + + if runtimeRevision="$(curl -fsSL ${runtime_version_url})"; then + [ -n "${runtimeRevision}" ] || die "failed to get agent version" + typeset -r runtimeVersionsURL="https://raw.githubusercontent.com/kata-containers/runtime/${runtimeRevision}/versions.yaml" + info "Getting musl version from ${runtimeVersionsURL}" + # This may fail if we are a kata bump. + if MUSL_VERSION="$(curl -fsSL "$runtimeVersionsURL" | $yq r - "externals.musl.version")"; then + [ "$MUSL_VERSION" != "null" ] + return 0 + fi + fi + + info "Agent version has not match with a runtime version, assumming it is a PR" + local kata_runtime_pkg_dir="${GOPATH}/src/${GO_RUNTIME_PKG}" + if [ ! -d "${kata_runtime_pkg_dir}" ];then + info "There is not runtime repository in filesystem (${kata_runtime_pkg_dir})" + local runtime_versions_url="https://raw.githubusercontent.com/kata-containers/runtime/${KATA_BRANCH}/versions.yaml" + info "Get versions file from ${runtime_versions_url}" + MUSL_VERSION="$(curl -fsSL "${runtime_versions_url}" | $yq r - "externals.musl.version")" + if [ "$?" == "0" ] && [ "$MUSL_VERSION" != "null" ]; then + return 0 + fi + + return 1 + fi + + local kata_versions_file="${kata_runtime_pkg_dir}/versions.yaml" + info "Get musl version from ${kata_versions_file}" + MUSL_VERSION="$(cat "${kata_versions_file}" | $yq r - "externals.musl.version")" + + [ "$?" == "0" ] && [ "$MUSL_VERSION" != "null" ] +} diff --git a/tests/test_config.sh b/tests/test_config.sh index 357938d226..3a5279bbde 100644 --- a/tests/test_config.sh +++ b/tests/test_config.sh @@ -5,9 +5,64 @@ # List of distros not to test, when running all tests with test_images.sh typeset -a skipWhenTestingAll +typeset -a distros +arch="$(uname -m)" +sdir="${BASH_SOURCE[0]%/*}" +for distro in $(${sdir}/../rootfs-builder/rootfs.sh -l); do + distros+=("${distro}") +done +test_distros=() +test_distros+=("clearlinux") +test_distros+=("ubuntu") + +skipForRustDistros=() +skipForRustDistros+=("alpine") +skipForRustDistros+=("euleros") + +skipForRustArch=() +skipForRustArch+=("ppc64le") +skipForRustArch+=("s390x") + +distro_in_set() { + local d=$1 + shift + local dt + for dt in "$@"; do + if [ "${dt}" == "${d}" ]; then + return 0 + fi + done + return 1 +} if [ -n "${CI:-}" ]; then # CI tests may timeout with euleros, see: # https://github.com/kata-containers/osbuilder/issues/46" - skipWhenTestingAll+=(euleros) + # Since too many distros timeout for now, we only test clearlinux and ubuntu. We can enable other distros when we fix timeout problem. + for distro in "${distros[@]}"; do + if distro_in_set "${distro}" "${test_distros[@]}"; then + continue + fi + skipWhenTestingAll+=("${distro}") + done + + if [ "${RUST_AGENT:-}" == "yes" ]; then + # add skipForRustDistros to skipWhenTestingAll if it is not + for td in "${skipForRustDistros[@]}"; do + if distro_in_set "${td}" "${skipWhenTestingAll[@]}"; then + continue + fi + # not found in skipWhenTestingAll, add to it + skipWhenTestingAll+=("${td}") + done + + if distro_in_set "${arch}" "${skipForRustArch[@]}"; then + for distro in "${test_distros[@]}"; do + if distro_in_set "${distro}" "${skipWhenTestingAll[@]}"; then + continue + fi + skipWhenTestingAll+=("${distro}") + done + fi + fi fi diff --git a/tests/test_images.sh b/tests/test_images.sh index afd301040f..73c0ba57d3 100755 --- a/tests/test_images.sh +++ b/tests/test_images.sh @@ -36,6 +36,8 @@ readonly docker_build_runtime="runc" build_images=1 build_initrds=1 typeset -a distrosSystemd distrosAgent +distrosSystemd=() +distrosAgent=() # Hashes used to keep track of image sizes. # - Key: name of distro. # - Value: colon-separated roots and image sizes ("${rootfs_size}:${image_size}"). @@ -312,7 +314,7 @@ get_distros_config() distrosList=($(make list-distros)) fi - for d in ${distrosList[@]}; do + for d in ${distrosList[@]:-}; do debug "Getting config for distro $d" distroPattern="\<${d}\>" if [[ "${skipWhenTestingAll[@]:-}" =~ $distroPattern ]]; then @@ -372,6 +374,9 @@ install_image_create_container() showKataRunFailure=1 silent_run $mgr reset-config + if [ "${RUST_AGENT:-}" = "yes" ]; then + silent_run $mgr enable-vsock + fi silent_run $mgr configure-image "$file" create_container showKataRunFailure= @@ -389,6 +394,9 @@ install_initrd_create_container() showKataRunFailure=1 silent_run $mgr reset-config + if [ "${RUST_AGENT:-}" = "yes" ]; then + silent_run $mgr enable-vsock + fi silent_run $mgr configure-initrd "$file" create_container showKataRunFailure= @@ -397,7 +405,7 @@ install_initrd_create_container() # Displays a list of distros which can be tested list_distros() { - tr " " "\n" <<< "${distrosSystemd[@]} ${distrosAgent[@]}" | sort + tr " " "\n" <<< "${distrosSystemd[@]:-} ${distrosAgent[@]:-}" | sort } # @@ -497,10 +505,10 @@ test_distros() # If a distro was specified, filter out the distro list to only include that distro if [ -n "$distro" ]; then pattern="\<$distro\>" - if [[ "${distrosAgent[@]}" =~ $pattern ]]; then + if [[ "${distrosAgent[@]:-}" =~ $pattern ]]; then distrosAgent=($distro) distrosSystemd=() - elif [[ "${distrosSystemd[@]}" =~ $pattern ]]; then + elif [[ "${distrosSystemd[@]:-}" =~ $pattern ]]; then distrosSystemd=($distro) distrosAgent=() build_initrds= @@ -547,7 +555,7 @@ test_distros() local marker=$(make print-ROOTFS_MARKER_SUFFIX) [ -z "$marker" ] && die "Invalid rootfs marker" typeset -a completed=($(find ${tmp_rootfs} -name ".*${marker}" -exec basename {} \; | sed -E "s/\.(.+)${marker}/\1/")) - for d in "${distrosSystemd[@]}" "${distrosAgent[@]}"; do + for d in "${distrosSystemd[@]:-}" "${distrosAgent[@]:-}"; do if [[ "${completed[@]}" =~ $d ]]; then info "- $d : completed" else @@ -561,7 +569,7 @@ test_distros() # TODO: once support for rootfs images with kata-agent as init is in place, # uncomment the following line # for d in ${distrosSystemd[@]} ${distrosAgent[@]}; do - for d in ${distrosSystemd[@]}; do + for d in ${distrosSystemd[@]:-}; do local rootfs_path="${tmp_rootfs}/${d}_rootfs" local image_path="${images_dir}/kata-containers-image-$d.img" local rootfs_size=$(get_rootfs_size "$rootfs_path") @@ -583,7 +591,7 @@ test_distros() install_image_create_container $image_path done - for d in ${distrosAgent[@]}; do + for d in ${distrosAgent[@]:-}; do local rootfs_path="${tmp_rootfs}/${d}_rootfs" local initrd_path="${images_dir}/kata-containers-initrd-$d.img" local rootfs_size=$(get_rootfs_size "$rootfs_path") @@ -618,6 +626,13 @@ test_dracut() detect_go_version || die "Could not detect the required Go version for AGENT_VERSION='${AGENT_VERSION:-master}'." + detect_rust_version || + die "Could not detect the required rust version for AGENT_VERSION='${AGENT_VERSION:-master}'." + detect_cmake_version || + die "Could not detect the required cmake version for AGENT_VERSION='${AGENT_VERSION:-master}'." + detect_musl_version || + die "Could not detect the required musl version for AGENT_VERSION='${AGENT_VERSION:-master}'." + generate_dockerfile ${dracut_dir} info "Creating container for dracut" silent_run docker build -t dracut-test-osbuilder ${dracut_dir}