#!/bin/bash # # Copyright (c) 2018 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 set -e die() { local msg="$*" echo "ERROR: ${msg}" >&2 exit 1 } OK() { local msg="$*" echo "[OK] ${msg}" >&2 } info() { local msg="$*" echo "INFO: ${msg}" } warning() { local msg="$*" echo "WARNING: ${msg}" } check_program() { type "$1" >/dev/null 2>&1 } check_root() { if [ "$(id -u)" != "0" ]; then echo "Root is needed" exit 1 fi } generate_dnf_config() { REPO_NAME=${REPO_NAME:-"base"} CACHE_DIR=${CACHE_DIR:-"/var/cache/dnf-${OS_NAME}"} cat > "${DNF_CONF}" << EOF [main] cachedir=${CACHE_DIR} logfile=${LOG_FILE} keepcache=0 debuglevel=2 exactarch=1 obsoletes=1 plugins=0 installonly_limit=3 reposdir=/root/mash retries=5 EOF if [ "$BASE_URL" != "" ]; then cat >> "${DNF_CONF}" << EOF [base] name=${OS_NAME}-${OS_VERSION} ${REPO_NAME} failovermethod=priority baseurl=${BASE_URL} enabled=1 EOF elif [ "$MIRROR_LIST" != "" ]; then cat >> "${DNF_CONF}" << EOF [base] name=${OS_NAME}-${OS_VERSION} ${REPO_NAME} mirrorlist=${MIRROR_LIST} enabled=1 EOF fi if [ -n "$GPG_KEY_URL" ]; then if [ ! -f "${CONFIG_DIR}/${GPG_KEY_FILE}" ]; then curl -L ${GPG_KEY_URL} -o ${CONFIG_DIR}/${GPG_KEY_FILE} fi cat >> "${DNF_CONF}" << EOF gpgcheck=1 gpgkey=file://${CONFIG_DIR}/${GPG_KEY_FILE} EOF fi if [ -n "$GPG_KEY_ARCH_URL" ]; then if [ ! -f "${CONFIG_DIR}/${GPG_KEY_ARCH_FILE}" ]; then curl -L ${GPG_KEY_ARCH_URL} -o ${CONFIG_DIR}/${GPG_KEY_ARCH_FILE} fi cat >> "${DNF_CONF}" << EOF file://${CONFIG_DIR}/${GPG_KEY_ARCH_FILE} EOF fi } build_rootfs() { # Mandatory local ROOTFS_DIR="$1" [ -z "$ROOTFS_DIR" ] && die "need rootfs" # In case of support EXTRA packages, use it to allow # users add more packages to the base rootfs local EXTRA_PKGS=${EXTRA_PKGS:-""} #PATH where files this script is placed #Use it to refer to files in the same directory #Exmaple: ${CONFIG_DIR}/foo #local CONFIG_DIR=${CONFIG_DIR} check_root if [ ! -f "${DNF_CONF}" ]; then DNF_CONF="./kata-${OS_NAME}-dnf.conf" generate_dnf_config fi mkdir -p "${ROOTFS_DIR}" if [ -n "${PKG_MANAGER}" ]; then info "DNF path provided by user: ${PKG_MANAGER}" elif check_program "dnf"; then PKG_MANAGER="dnf" elif check_program "yum" ; then PKG_MANAGER="yum" else die "neither yum nor dnf is installed" fi DNF="${PKG_MANAGER} --config=$DNF_CONF -y --installroot=${ROOTFS_DIR} --noplugins" $DNF install ${EXTRA_PKGS} ${PACKAGES} [ -n "${ROOTFS_DIR}" ] && rm -r "${ROOTFS_DIR}${CACHE_DIR}" } # Create a YAML metadata file inside the rootfs. # # This provides useful information about the rootfs than can be interrogated # once the rootfs has been converted into a image/initrd. create_summary_file() { local -r rootfs_dir="$1" [ -z "$rootfs_dir" ] && die "need rootfs" local -r file_dir="/var/lib/osbuilder" local -r dir="${rootfs_dir}${file_dir}" local -r filename="osbuilder.yaml" local file="${dir}/${filename}" local -r now=$(date '+%Y-%m-%dT%T.%N%zZ') # sanitise package lists PACKAGES=$(echo "$PACKAGES"|tr ' ' '\n'|sort -u|tr '\n' ' ') EXTRA_PKGS=$(echo "$EXTRA_PKGS"|tr ' ' '\n'|sort -u|tr '\n' ' ') local -r packages=$(for pkg in ${PACKAGES}; do echo " - \"${pkg}\""; done) local -r extra=$(for pkg in ${EXTRA_PKGS}; do echo " - \"${pkg}\""; done) mkdir -p "$dir" # Semantic version of the summary file format. # # XXX: Increment every time the format of the summary file changes! local -r format_version="0.0.2" local -r osbuilder_url="https://github.com/kata-containers/osbuilder" local agent="${AGENT_DEST}" [ "$AGENT_INIT" = yes ] && agent="${init}" local -r agent_version=$("$agent" --version|awk '{print $NF}') cat >"$file"<<-EOT --- osbuilder: url: "${osbuilder_url}" version: "${OSBUILDER_VERSION}" rootfs-creation-time: "${now}" description: "osbuilder rootfs" file-format-version: "${format_version}" architecture: "${ARCH}" base-distro: name: "${OS_NAME}" version: "${OS_VERSION}" packages: default: ${packages} extra: ${extra} agent: url: "https://${GO_AGENT_PKG}" name: "${AGENT_BIN}" version: "${agent_version}" agent-is-init-daemon: "${AGENT_INIT}" EOT local rootfs_file="${file_dir}/$(basename "${file}")" info "Created summary file '${rootfs_file}' inside rootfs" }