Skip to content

Commit

Permalink
Merge pull request kata-containers#1215 from jcvenegas/build-image-al…
Browse files Browse the repository at this point in the history
…l-time

ci: build the complete image
  • Loading branch information
chavafg authored Mar 6, 2019
2 parents 662b7a2 + 353648c commit 3c02251
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 113 deletions.
54 changes: 54 additions & 0 deletions .ci/ci_cache_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace

function handle_error {
local exit_code="${?}"
local line_number="${1:-}"
echo "Failed at $line_number: ${BASH_COMMAND}"
exit "${exit_code}"
}
trap 'handle_error $LINENO' ERR

WORKSPACE=${WORKSPACE:-$(pwd)}
kata_dir="/usr/share/kata-containers/"

cache_build() {
type="${1}"

if [ "${type}" == "image" ]; then
link="${kata_dir}/kata-containers.img"
else
link="${kata_dir}/kata-containers-${type}.img"
fi
path=$(readlink -f ${link})
echo $(basename "${path}") > "latest-${type}"
sudo cp "${path}" "${kata_dir}/osbuilder-${type}.yaml" .

sudo chown -R "${USER}:${USER}" ./

sha256sum "$(cat latest-${type})" > "sha256sum-${type}"
sha256sum -c "sha256sum-${type}"

tar -cJf "$(cat latest-${type}).tar.xz" "$(cat latest-${type})"

sha256sum "$(cat latest-${type}).tar.xz" > "sha256sum-${type}-tarball"
sha256sum -c "sha256sum-${type}-tarball"
rm "$(cat latest-${type})"
}

mkdir -p "${WORKSPACE}/artifacts"
pushd "${WORKSPACE}/artifacts"
cache_build image
cache_build initrd

ls -la "${WORKSPACE}/artifacts/"
popd
sync

253 changes: 140 additions & 113 deletions .ci/install_kata_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace

function handle_error() {
local exit_code="${?}"
local line_number="${1:-}"
echo "Failed at $line_number: ${BASH_COMMAND}"
exit "${exit_code}"
}
trap 'handle_error $LINENO' ERR

cidir=$(dirname "$0")
cidir=$(realpath "${cidir}")

source /etc/os-release || source /usr/lib/os-release
source "${cidir}/lib.sh"
Expand All @@ -19,151 +29,168 @@ ARCH="$(${cidir}/kata-arch.sh -d)"
AGENT_INIT=${AGENT_INIT:-no}
TEST_INITRD=${TEST_INITRD:-no}

TMP_DIR=
ROOTFS_DIR=
IMAGE_DIR="/usr/share/kata-containers"
IMG_LINK_NAME="kata-containers.img"
INITRD_LINK_NAME="kata-containers-initrd.img"

if [ "${TEST_INITRD}" == "no" ]; then
OSBUILDER_YAML_INSTALL_NAME="osbuilder-image.yaml"
LINK_PATH="${IMAGE_DIR}/${IMG_LINK_NAME}"
IMG_TYPE="image"
else
OSBUILDER_YAML_INSTALL_NAME="osbuilder-initrd.yaml"
LINK_PATH="${IMAGE_DIR}/${INITRD_LINK_NAME}"
IMG_TYPE="initrd"
fi

PACKAGED_IMAGE="kata-containers-image"
IMG_PATH="/usr/share/kata-containers"
IMG_NAME="kata-containers.img"
IMAGE_TYPE="assets.image.meta.image-type"
IMAGE_OS_KEY="assets.${IMG_TYPE}.architecture.$(uname -m).name"
IMAGE_OS_VERSION_KEY="assets.${IMG_TYPE}.architecture.$(uname -m).version"

agent_path="${GOPATH}/src/github.com/kata-containers/agent"

IMG_MOUNT_DIR=
LOOP_DEVICE=

# Build Kata agent
bash -f "${cidir}/install_agent.sh"
agent_commit=$(git --work-tree="${agent_path}" --git-dir="${agent_path}/.git" log --format=%h -1 HEAD)

cleanup() {
[ -d "${ROOTFS_DIR}" ] && [[ "${ROOTFS_DIR}" = *"rootfs"* ]] && sudo rm -rf "${ROOTFS_DIR}"
[ -d "${TMP_DIR}" ] && rm -rf "${TMP_DIR}"
if [ -n "${IMG_MOUNT_DIR}" ] && mount | grep -q "${IMG_MOUNT_DIR}"; then
sudo umount "${IMG_MOUNT_DIR}"
osbuilder_repo="github.com/kata-containers/osbuilder"
osbuilder_path="${GOPATH}/src/${osbuilder_repo}"
latest_build_url="http://jenkins.katacontainers.io/job/image-nightly-$(uname -m)/lastSuccessfulBuild/artifact/artifacts"

install_ci_cache_image() {
type=${1}
check_not_empty "$type" "image type not provided"
info "Install pre-built ${type}"
local image_name=$(curl -fsL "${latest_build_url}/latest-${type}")
sudo mkdir -p "${IMAGE_DIR}"
pushd "${IMAGE_DIR}" >/dev/null
local image_path=$(readlink -f "${IMAGE_DIR}/${image_name}")

sudo -E curl -fsOL "${latest_build_url}/sha256sum-${type}-tarball"
sudo -E curl -fsL "${latest_build_url}/${image_name}.tar.xz" -o "${image_path}.tar.xz"
sudo sha256sum -c "sha256sum-${type}-tarball"

sudo -E curl -fsOL "${latest_build_url}/sha256sum-${type}"
sudo tar xfv "${image_path}.tar.xz"
sudo sha256sum -c "sha256sum-${type}"

sudo -E ln -sf "${image_path}" "${LINK_PATH}"
sudo -E curl -fsL "${latest_build_url}/${OSBUILDER_YAML_INSTALL_NAME}" -o "${IMAGE_DIR}/${OSBUILDER_YAML_INSTALL_NAME}"

popd >/dev/null

if [ ! -L "${LINK_PATH}" ]; then
echo "Link path not installed: ${LINK_PATH}"
false
fi
if [ -d "${IMG_MOUNT_DIR}" ]; then
rm -rf "${IMG_MOUNT_DIR}"
fi
if [ -n "${LOOP_DEVICE}" ]; then
sudo losetup -d "${LOOP_DEVICE}"
fi
}

trap cleanup EXIT

get_packaged_agent_version() {
version=$(ls "$IMG_PATH" | grep "$PACKAGED_IMAGE" | cut -d'_' -f4 | cut -d'.' -f1)
echo "$version"
if [ ! -f "$(readlink ${LINK_PATH})" ]; then
echo "Link to ${LINK_PATH} is broken"
false
fi
}

install_packaged_image() {
rc=0
if [ "$ID" == "ubuntu" ] || [ "$ID" == "debian" ]; then
chronic sudo -E apt install -y "$PACKAGED_IMAGE" || rc=1
elif [ "$ID" == "fedora" ]; then
chronic sudo -E dnf install -y "$PACKAGED_IMAGE" || rc=1
elif [ "$ID" == "centos" ]; then
chronic sudo -E yum install -y "$PACKAGED_IMAGE" || rc=1
elif [[ "$ID" =~ ^opensuse.*$ ]]; then
chronic sudo -E zypper -n install "$PACKAGED_IMAGE" || rc=1
else
die "Linux distribution not supported"
check_not_empty() {
value=${1:-}
msg=${2:-}
if [ -z "${value}" ]; then
echo "${msg}"
false
fi

return "$rc"
}

update_agent() {
pushd "$agent_path"

LOOP_DEVICE=$(sudo losetup -f --show "${IMG_PATH}/${IMG_NAME}")
IMG_MOUNT_DIR=$(mktemp -d -t kata-image-mount.XXXXXXXXXX)
sudo partprobe "$LOOP_DEVICE"
sudo mount "${LOOP_DEVICE}p1" "$IMG_MOUNT_DIR"

echo "Old agent version:"
"${IMG_MOUNT_DIR}/usr/bin/kata-agent" --version
build_image() {
image_output=${1}
distro=${2}
os_version=${3}
agent_commit=${4}

echo "Install new agent"
sudo -E PATH="$PATH" bash -c "make install DESTDIR=$IMG_MOUNT_DIR"
installed_version=$("${IMG_MOUNT_DIR}/usr/bin/kata-agent" --version)
echo "New agent version: $installed_version"
check_not_empty "$image_output" "Missing image"
check_not_empty "$distro" "Missing distro"
check_not_empty "$os_version" "Missing os version"
check_not_empty "$agent_commit" "Missing agent commit"

popd
installed_version=${installed_version##k*-}
[[ "${installed_version}" == *"${current_version}"* ]]
}
pushd "${osbuilder_path}" >/dev/null

build_image() {
TMP_DIR=$(mktemp -d -t kata-image-install.XXXXXXXXXX)
readonly ROOTFS_DIR="${TMP_DIR}/rootfs"
readonly ROOTFS_DIR="${PWD}/rootfs"
export ROOTFS_DIR
sudo rm -rf "${ROOTFS_DIR}"

image_type=$(get_version "${IMAGE_TYPE}")
OSBUILDER_DISTRO=${OSBUILDER_DISTRO:-$image_type}
osbuilder_repo="github.com/kata-containers/osbuilder"

# Clone os-builder repository
go get -d "${osbuilder_repo}" || true

# Make sure runc is default runtime.
# The image builder with USER_DOCKER=true will not work otherwise.
# See https://github.com/clearcontainers/osbuilder/issues/8
"${cidir}/../cmd/container-manager/manage_ctr_mgr.sh" docker configure -r runc -f
echo "Set runtime as default runtime to build the image"
bash "${cidir}/../cmd/container-manager/manage_ctr_mgr.sh" docker configure -r runc -f

(cd "${GOPATH}/src/${osbuilder_repo}/rootfs-builder" && \
sudo -E AGENT_INIT="${AGENT_INIT}" AGENT_VERSION="${agent_commit}" \
GOPATH="$GOPATH" USE_DOCKER=true ./rootfs.sh "${OSBUILDER_DISTRO}")
sudo -E AGENT_INIT="${AGENT_INIT}" AGENT_VERSION="${agent_commit}" \
GOPATH="$GOPATH" USE_DOCKER=true OS_VERSION=${os_version} ./rootfs-builder/rootfs.sh "${distro}"

# Build the image
if [ x"${TEST_INITRD}" == x"yes" ]; then
pushd "${GOPATH}/src/${osbuilder_repo}/initrd-builder"
sudo -E AGENT_INIT="${AGENT_INIT}" USE_DOCKER=true ./initrd_builder.sh "$ROOTFS_DIR"
image_name="kata-containers-initrd.img"
if [ "${TEST_INITRD}" == "no" ]; then
sudo -E AGENT_INIT="${AGENT_INIT}" USE_DOCKER=true ./image-builder/image_builder.sh "$ROOTFS_DIR"
local image_name="kata-containers.img"

else
pushd "${GOPATH}/src/${osbuilder_repo}/image-builder"
sudo -E AGENT_INIT="${AGENT_INIT}" USE_DOCKER=true ./image_builder.sh "$ROOTFS_DIR"
image_name="kata-containers.img"
sudo -E AGENT_INIT="${AGENT_INIT}" USE_DOCKER=true ./initrd-builder/initrd_builder.sh "$ROOTFS_DIR"
local image_name="kata-containers-initrd.img"
fi

# Install the image
commit=$(git log --format=%h -1 HEAD)
date=$(date +%Y-%m-%d-%T.%N%z)
image="kata-containers-${date}-osbuilder-${commit}-agent-${agent_commit}"

sudo install -o root -g root -m 0640 -D ${image_name} "/usr/share/kata-containers/${image}"
(cd /usr/share/kata-containers && sudo ln -sf "$image" ${image_name})
sudo install -o root -g root -m 0640 -D ${image_name} "${IMAGE_DIR}/${image_output}"
sudo install -o root -g root -m 0640 -D "${ROOTFS_DIR}/var/lib/osbuilder/osbuilder.yaml" "${IMAGE_DIR}/${OSBUILDER_YAML_INSTALL_NAME}"
(cd /usr/share/kata-containers && sudo ln -sf "${IMAGE_DIR}/${image_output}" "${LINK_PATH}")

popd
popd >/dev/null
}

#Load specific configure file
if [ -f "${cidir}/${ARCH}/lib_kata_image_${ARCH}.sh" ]; then
source "${cidir}/${ARCH}/lib_kata_image_${ARCH}.sh"
fi

get_dependencies() {
info "Pull and install agent on host"
bash -f "${cidir}/install_agent.sh"
go get -d "${osbuilder_repo}" || true
}

main() {
if [ x"${TEST_INITRD}" == x"yes" ]; then
build_image
get_dependencies
local os_version=$(get_version "${IMAGE_OS_VERSION_KEY}")
local osbuilder_distro=$(get_version "${IMAGE_OS_KEY}")

if [ "${osbuilder_distro}" == "clearlinux" ] && [ "${os_version}" == "latest" ]; then
os_version=$(curl -fLs https://download.clearlinux.org/latest)
fi

local agent_commit=$(git --work-tree="${agent_path}" --git-dir="${agent_path}/.git" log --format=%h -1 HEAD)
local osbuilder_commit=$(git --work-tree="${osbuilder_path}" --git-dir="${osbuilder_path}/.git" log --format=%h -1 HEAD)

image_output="kata-containers-${osbuilder_distro}-${os_version}-osbuilder-${osbuilder_commit}-agent-${agent_commit}"

if [ "${TEST_INITRD}" == "no" ]; then
image_output="${image_output}.img"
type="image"
else
# If installing packaged image from OBS fails,
# then build and install it from sources.
rc=0
install_packaged_image || rc=1
if [ "$rc" == "1" ]; then
build_image && exit
fi
packaged_version=$(get_packaged_agent_version)
if [ -z "$packaged_version" ]; then
build_image
else
current_version=${agent_commit}
if [ "$packaged_version" != "$current_version" ]; then
update_agent || build_image
fi
image_output="${image_output}.initrd"
type="initrd"
fi

latest_file="latest-${type}"
info "Image to generate: ${image_output}"

last_build_image_version=$(curl -fsL "${latest_build_url}/${latest_file}") ||
last_build_image_version="error-latest-cached-imaget-not-found"

info "Latest cached image: ${last_build_image_version}"

if [ "$image_output" == "$last_build_image_version" ]; then
info "Cached image is same to be generated"
if ! install_ci_cache_image "${type}"; then
info "failed to install cached image, trying to build from source"
build_image "${image_output}" "${osbuilder_distro}" "${os_version}" "${agent_commit}"
fi
else
build_image "${image_output}" "${osbuilder_distro}" "${os_version}" "${agent_commit}"
fi

if [ ! -L "${LINK_PATH}" ]; then
die "Link path not installed: ${LINK_PATH}"
fi

if [ ! -f "$(readlink ${LINK_PATH})" ]; then
die "Link to ${LINK_PATH} is broken"
fi
}

main
main $@

0 comments on commit 3c02251

Please sign in to comment.