Blame tools/run-container

Packit bc9a3a
#!/bin/bash
Packit bc9a3a
# This file is part of cloud-init. See LICENSE file for license information.
Packit bc9a3a
#
Packit bc9a3a
# shellcheck disable=2015,2016,2039,2162,2166
Packit bc9a3a
Packit bc9a3a
set -u
Packit bc9a3a
Packit bc9a3a
VERBOSITY=0
Packit bc9a3a
KEEP=false
Packit bc9a3a
CONTAINER=""
Packit bc9a3a
DEFAULT_WAIT_MAX=30
Packit bc9a3a
Packit bc9a3a
error() { echo "$@" 1>&2; }
Packit bc9a3a
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
Packit bc9a3a
errorrc() { local r=$?; error "$@" "ret=$r"; return $r; }
Packit bc9a3a
Packit bc9a3a
Usage() {
Packit bc9a3a
    cat <
Packit bc9a3a
Usage: ${0##*/} [ options ] [images:]image-ref
Packit bc9a3a
Packit bc9a3a
    This utility can makes it easier to run tests, build rpm and source rpm
Packit bc9a3a
        generation inside a LXC of the specified version of CentOS.
Packit bc9a3a
Packit bc9a3a
    To see images available, run 'lxc image list images:'
Packit bc9a3a
    Example input:
Packit bc9a3a
       centos/7
Packit bc9a3a
       opensuse/42.3
Packit bc9a3a
       debian/10
Packit bc9a3a
Packit bc9a3a
    options:
Packit bc9a3a
      -a | --artifacts DIR   copy build artifacts out to DIR.
Packit bc9a3a
                             by default artifacts are not copied out.
Packit bc9a3a
           --dirty           apply local changes before running tests.
Packit bc9a3a
                             If not provided, a clean checkout of branch is
Packit bc9a3a
                             tested.  Inside container, changes are in
Packit bc9a3a
                             local-changes.diff.
Packit bc9a3a
      -k | --keep            keep container after tests
Packit bc9a3a
           --pyexe V         python version to use.  Default=auto.
Packit bc9a3a
                             Should be name of an executable.
Packit bc9a3a
                             ('python2' or 'python3')
Packit bc9a3a
      -p | --package         build a binary package (.deb or .rpm)
Packit bc9a3a
      -s | --source-package  build source package (debuild -S or srpm)
Packit bc9a3a
      -u | --unittest        run unit tests
Packit bc9a3a
Packit bc9a3a
    Example:
Packit bc9a3a
      * ${0##*/} --package --source-package --unittest centos/6
Packit bc9a3a
EOF
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
Packit bc9a3a
cleanup() {
Packit bc9a3a
    if [ -n "$CONTAINER" ]; then
Packit bc9a3a
        if [ "$KEEP" = "true" ]; then
Packit bc9a3a
            error "not deleting container '$CONTAINER' due to --keep"
Packit bc9a3a
        else
Packit bc9a3a
            delete_container "$CONTAINER"
Packit bc9a3a
        fi
Packit bc9a3a
    fi
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
debug() {
Packit bc9a3a
    local level=${1}; shift;
Packit bc9a3a
    [ "${level}" -gt "${VERBOSITY}" ] && return
Packit bc9a3a
    error "${@}"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
Packit bc9a3a
inside_as() {
Packit bc9a3a
    # inside_as(container_name, user, cmd[, args])
Packit bc9a3a
    # executes cmd with args inside container as user in users home dir.
Packit bc9a3a
    local name="$1" user="$2"
Packit bc9a3a
    shift 2
Packit bc9a3a
    if [ "$user" = "root" ]; then
Packit bc9a3a
        inside "$name" "$@"
Packit bc9a3a
        return
Packit bc9a3a
    fi
Packit bc9a3a
    local stuffed="" b64=""
Packit bc9a3a
    stuffed=$(getopt --shell sh --options "" -- -- "$@")
Packit bc9a3a
    stuffed=${stuffed# -- }
Packit bc9a3a
    b64=$(printf "%s\n" "$stuffed" | base64 --wrap=0)
Packit bc9a3a
    inside "$name" su "$user" -c \
Packit bc9a3a
        'cd; eval set -- "$(echo '"$b64"' | base64 --decode)" && exec "$@"';
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
inside_as_cd() {
Packit bc9a3a
    local name="$1" user="$2" dir="$3"
Packit bc9a3a
    shift 3
Packit bc9a3a
    inside_as "$name" "$user" sh -c 'cd "$0" && exec "$@"' "$dir" "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
inside() {
Packit bc9a3a
    local name="$1"
Packit bc9a3a
    shift
Packit bc9a3a
    lxc exec "$name" -- "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
inject_cloud_init(){
Packit bc9a3a
    # take current cloud-init git dir and put it inside $name at
Packit bc9a3a
    # ~$user/cloud-init.
Packit bc9a3a
    local name="$1" user="$2" dirty="$3"
Packit bc9a3a
    local dname="cloud-init" gitdir="" commitish=""
Packit bc9a3a
    gitdir=$(git rev-parse --git-dir) || {
Packit bc9a3a
        errorrc "Failed to get git dir in $PWD";
Packit bc9a3a
        return
Packit bc9a3a
    }
Packit bc9a3a
    local t=${gitdir%/*}
Packit bc9a3a
    case "$t" in
Packit bc9a3a
        */worktrees) 
Packit bc9a3a
            if [ -f "${t%worktrees}/config" ]; then
Packit bc9a3a
                gitdir="${t%worktrees}"
Packit bc9a3a
            fi
Packit bc9a3a
    esac
Packit bc9a3a
Packit bc9a3a
    # attempt to get branch name.
Packit bc9a3a
    commitish=$(git rev-parse --abbrev-ref HEAD) || {
Packit bc9a3a
        errorrc "Failed git rev-parse --abbrev-ref HEAD"
Packit bc9a3a
        return
Packit bc9a3a
    }
Packit bc9a3a
    if [ "$commitish" = "HEAD" ]; then
Packit bc9a3a
        # detached head
Packit bc9a3a
        commitish=$(git rev-parse HEAD) || {
Packit bc9a3a
            errorrc "failed git rev-parse HEAD"
Packit bc9a3a
            return
Packit bc9a3a
        }
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    local local_changes=false
Packit bc9a3a
    if ! git diff --quiet "$commitish"; then
Packit bc9a3a
        # there are local changes not committed.
Packit bc9a3a
        local_changes=true
Packit bc9a3a
        if [ "$dirty" = "false" ]; then
Packit bc9a3a
            error "WARNING: You had uncommitted changes.  Those changes will "
Packit bc9a3a
            error "be put into 'local-changes.diff' inside the container. "
Packit bc9a3a
            error "To test these changes you must pass --dirty."
Packit bc9a3a
        fi
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    debug 1 "collecting ${gitdir} ($dname) into user $user in $name."
Packit bc9a3a
    tar -C "${gitdir}" -cpf - . |
Packit bc9a3a
        inside_as "$name" "$user" sh -ec '
Packit bc9a3a
            dname=$1
Packit bc9a3a
            commitish=$2
Packit bc9a3a
            rm -Rf "$dname"
Packit bc9a3a
            mkdir -p $dname/.git
Packit bc9a3a
            cd $dname/.git
Packit bc9a3a
            tar -xpf -
Packit bc9a3a
            cd ..
Packit bc9a3a
            git config core.bare false
Packit bc9a3a
            out=$(git checkout $commitish 2>&1) ||
Packit bc9a3a
                { echo "failed git checkout $commitish: $out" 1>&2; exit 1; }
Packit bc9a3a
            out=$(git checkout . 2>&1) ||
Packit bc9a3a
                { echo "failed git checkout .: $out" 1>&2; exit 1; }
Packit bc9a3a
            ' extract "$dname" "$commitish"
Packit bc9a3a
    [ "${PIPESTATUS[*]}" = "0 0" ] || {
Packit bc9a3a
        error "Failed to push tarball of '$gitdir' into $name" \
Packit bc9a3a
            " for user $user (dname=$dname)"
Packit bc9a3a
        return 1
Packit bc9a3a
    }
Packit bc9a3a
Packit bc9a3a
    echo "local_changes=$local_changes dirty=$dirty"
Packit bc9a3a
    if [ "$local_changes" = "true" ]; then
Packit bc9a3a
        git diff "$commitish" |
Packit bc9a3a
            inside_as "$name" "$user" sh -exc '
Packit bc9a3a
                cd "$1"
Packit bc9a3a
                if [ "$2" = "true" ]; then
Packit bc9a3a
                    git apply
Packit bc9a3a
                else
Packit bc9a3a
                    cat > local-changes.diff
Packit bc9a3a
                fi
Packit bc9a3a
                ' insert_changes "$dname" "$dirty"
Packit bc9a3a
        [ "${PIPESTATUS[*]}" = "0 0" ] || {
Packit bc9a3a
            error "Failed to apply local changes."
Packit bc9a3a
            return 1
Packit bc9a3a
        }
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    return 0
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
get_os_info_in() {
Packit bc9a3a
    # prep the container (install very basic dependencies)
Packit bc9a3a
    [ -n "${OS_VERSION:-}" -a -n "${OS_NAME:-}" ] && return 0
Packit bc9a3a
    data=$(run_self_inside "$name" os_info) ||
Packit bc9a3a
        { errorrc "Failed to get os-info in container $name"; return; }
Packit bc9a3a
    eval "$data" && [ -n "${OS_VERSION:-}" -a -n "${OS_NAME:-}" ] || return
Packit bc9a3a
    debug 1 "determined $name is $OS_NAME/$OS_VERSION"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
os_info() {
Packit bc9a3a
    get_os_info || return
Packit bc9a3a
    echo "OS_NAME=$OS_NAME"
Packit bc9a3a
    echo "OS_VERSION=$OS_VERSION"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
get_os_info() {
Packit bc9a3a
    # run inside container, set OS_NAME, OS_VERSION
Packit bc9a3a
    # example OS_NAME are centos, debian, opensuse
Packit bc9a3a
    [ -n "${OS_NAME:-}" -a -n "${OS_VERSION:-}" ] && return 0
Packit bc9a3a
    if [ -f /etc/os-release ]; then
Packit bc9a3a
        OS_NAME=$(sh -c '. /etc/os-release; echo $ID')
Packit bc9a3a
        OS_VERSION=$(sh -c '. /etc/os-release; echo $VERSION_ID')
Packit bc9a3a
        if [ -z "$OS_VERSION" ]; then
Packit bc9a3a
            local pname=""
Packit bc9a3a
            pname=$(sh -c '. /etc/os-release; echo $PRETTY_NAME')
Packit bc9a3a
            case "$pname" in
Packit bc9a3a
                *buster*) OS_VERSION=10;;
Packit bc9a3a
                *sid*) OS_VERSION="sid";;
Packit bc9a3a
            esac
Packit bc9a3a
        fi
Packit bc9a3a
    elif [ -f /etc/centos-release ]; then
Packit bc9a3a
        local line=""
Packit bc9a3a
        read line < /etc/centos-release
Packit bc9a3a
        case "$line" in
Packit bc9a3a
            CentOS\ *\ 6.*) OS_VERSION="6"; OS_NAME="centos";;
Packit bc9a3a
        esac
Packit bc9a3a
    fi
Packit bc9a3a
    [ -n "${OS_NAME:-}" -a -n "${OS_VERSION:-}" ] ||
Packit bc9a3a
        { error "Unable to determine OS_NAME/OS_VERSION"; return 1; }
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
yum_install() {
Packit bc9a3a
    local n=0 max=10 ret
Packit bc9a3a
    bcmd="yum install --downloadonly --assumeyes --setopt=keepcache=1"
Packit bc9a3a
    while n=$((n+1)); do
Packit bc9a3a
       error ":: running $bcmd $* [$n/$max]"
Packit bc9a3a
       $bcmd "$@"
Packit bc9a3a
       ret=$?
Packit bc9a3a
       [ $ret -eq 0 ] && break
Packit bc9a3a
       [ $n -ge $max ] && { error "gave up on $bcmd"; exit $ret; }
Packit bc9a3a
       nap=$((n*5))
Packit bc9a3a
       error ":: failed [$ret] ($n/$max). sleeping $nap."
Packit bc9a3a
       sleep $nap
Packit bc9a3a
    done
Packit bc9a3a
    error ":: running yum install --cacheonly --assumeyes $*"
Packit bc9a3a
    yum install --cacheonly --assumeyes "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
zypper_install() {
Packit bc9a3a
    local pkgs="$*"
Packit bc9a3a
    set -- zypper --non-interactive --gpg-auto-import-keys install \
Packit bc9a3a
        --auto-agree-with-licenses "$@"
Packit bc9a3a
    debug 1 ":: installing $pkgs with zypper: $*"
Packit bc9a3a
    "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
apt_install() {
Packit bc9a3a
    apt-get update -q && apt-get install --no-install-recommends "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
install_packages() {
Packit bc9a3a
    get_os_info || return
Packit bc9a3a
    case "$OS_NAME" in
Packit bc9a3a
        centos) yum_install "$@";;
Packit bc9a3a
        opensuse) zypper_install "$@";;
Packit bc9a3a
        debian|ubuntu) apt_install "$@";;
Packit bc9a3a
        *) error "Do not know how to install packages on ${OS_NAME}";
Packit bc9a3a
           return 1;;
Packit bc9a3a
    esac
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
prep() {
Packit bc9a3a
    # we need some very basic things not present in the container.
Packit bc9a3a
    #  - git
Packit bc9a3a
    #  - tar (CentOS 6 lxc container does not have it)
Packit bc9a3a
    #  - python-argparse (or python3)
Packit bc9a3a
    local needed="" pair="" pkg="" cmd="" needed=""
Packit bc9a3a
    local pairs="tar:tar git:git"
Packit bc9a3a
    local pyexe="$1"
Packit bc9a3a
    get_os_info
Packit bc9a3a
    local py2pkg="python2" py3pkg="python3"
Packit bc9a3a
    case "$OS_NAME" in
Packit bc9a3a
        opensuse)
Packit bc9a3a
            py2pkg="python-base"
Packit bc9a3a
            py3pkg="python3-base";;
Packit bc9a3a
    esac
Packit bc9a3a
Packit bc9a3a
    case "$pyexe" in
Packit bc9a3a
        python2) pairs="$pairs python2:$py2pkg";;
Packit bc9a3a
        python3) pairs="$pairs python3:$py3pkg";;
Packit bc9a3a
    esac
Packit bc9a3a
Packit bc9a3a
    for pair in $pairs; do
Packit bc9a3a
        pkg=${pair#*:}
Packit bc9a3a
        cmd=${pair%%:*}
Packit bc9a3a
        command -v "$cmd" >/dev/null 2>&1 || needed="${needed} $pkg"
Packit bc9a3a
    done
Packit bc9a3a
    if [ "$OS_NAME" = "centos" -a "$pyexe" = "python2" ]; then
Packit bc9a3a
        python -c "import argparse" >/dev/null 2>&1 ||
Packit bc9a3a
            needed="${needed} python-argparse"
Packit bc9a3a
    fi
Packit bc9a3a
    needed=${needed# }
Packit bc9a3a
    if [ -z "$needed" ]; then
Packit bc9a3a
        error "No prep packages needed"
Packit bc9a3a
        return 0
Packit bc9a3a
    fi
Packit bc9a3a
    error "Installing prep packages: ${needed}"
Packit bc9a3a
    # shellcheck disable=SC2086
Packit bc9a3a
    set -- $needed
Packit bc9a3a
    install_packages "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
nose() {
Packit bc9a3a
    local pyexe="$1" cmd=""
Packit bc9a3a
    shift
Packit bc9a3a
    get_os_info
Packit bc9a3a
    if [ "$OS_NAME/$OS_VERSION" = "centos/6" ]; then
Packit bc9a3a
        cmd="nosetests"
Packit bc9a3a
    else
Packit bc9a3a
        cmd="$pyexe -m nose"
Packit bc9a3a
    fi
Packit bc9a3a
    ${cmd} "$@"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
is_done_cloudinit() {
Packit bc9a3a
    [ -e "/run/cloud-init/result.json" ]
Packit bc9a3a
    _RET=""
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
is_done_systemd() {
Packit bc9a3a
    local s="" num="$1"
Packit bc9a3a
    s=$(systemctl is-system-running 2>&1;;
Packit bc9a3a
    _RET="$? $s"
Packit bc9a3a
    case "$s" in
Packit bc9a3a
        initializing|starting) return 1;;
Packit bc9a3a
        *[Ff]ailed*connect*bus*)
Packit bc9a3a
            # warn if not the first run.
Packit bc9a3a
            [ "$num" -lt 5 ] ||
Packit bc9a3a
                error "Failed to connect to systemd bus [${_RET%% *}]";
Packit bc9a3a
            return 1;;
Packit bc9a3a
    esac
Packit bc9a3a
    return 0
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
is_done_other() {
Packit bc9a3a
    local out=""
Packit bc9a3a
    out=$(getent hosts ubuntu.com 2>&1)
Packit bc9a3a
    return
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
wait_inside() {
Packit bc9a3a
    local name="$1" max="${2:-${DEFAULT_WAIT_MAX}}" debug=${3:-0}
Packit bc9a3a
    local i=0 check="is_done_other";
Packit bc9a3a
    if [ -e /run/systemd ]; then
Packit bc9a3a
        check=is_done_systemd
Packit bc9a3a
    elif [ -x /usr/bin/cloud-init ]; then
Packit bc9a3a
        check=is_done_cloudinit
Packit bc9a3a
    fi
Packit bc9a3a
    [ "$debug" != "0" ] && debug 1 "check=$check"
Packit bc9a3a
    while ! $check $i && i=$((i+1)); do
Packit bc9a3a
        [ "$i" -ge "$max" ] && exit 1
Packit bc9a3a
        [ "$debug" = "0" ] || echo -n .
Packit bc9a3a
        sleep 1
Packit bc9a3a
    done
Packit bc9a3a
    if [ "$debug" != "0" ]; then
Packit bc9a3a
        read up _ 
Packit bc9a3a
        debug 1 "[$name ${i:+done after $i }up=$up${_RET:+ ${_RET}}]"
Packit bc9a3a
    fi
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
wait_for_boot() {
Packit bc9a3a
    local name="$1"
Packit bc9a3a
    local out="" ret="" wtime=$DEFAULT_WAIT_MAX
Packit bc9a3a
    get_os_info_in "$name"
Packit bc9a3a
    [ "$OS_NAME" = "debian" ] && wtime=300 &&
Packit bc9a3a
        debug 1 "on debian we wait for ${wtime}s"
Packit bc9a3a
    debug 1 "waiting for boot of $name"
Packit bc9a3a
    run_self_inside "$name" wait_inside "$name" "$wtime" "$VERBOSITY" ||
Packit bc9a3a
        { errorrc "wait inside $name failed."; return; }
Packit bc9a3a
Packit bc9a3a
    if [ ! -z "${http_proxy-}" ]; then
Packit bc9a3a
        if [ "$OS_NAME" = "centos" ]; then
Packit bc9a3a
            debug 1 "configuring proxy ${http_proxy}"
Packit bc9a3a
            inside "$name" sh -c "echo proxy=$http_proxy >> /etc/yum.conf"
Packit bc9a3a
            inside "$name" sed -i s/enabled=1/enabled=0/ \
Packit bc9a3a
                /etc/yum/pluginconf.d/fastestmirror.conf
Packit bc9a3a
            inside "$name" sh -c "sed -i '/^#baseurl=/s/#// ; s/^mirrorlist/#mirrorlist/' /etc/yum.repos.d/*.repo"
Packit bc9a3a
        else
Packit bc9a3a
            debug 1 "do not know how to configure proxy on $OS_NAME"
Packit bc9a3a
        fi
Packit bc9a3a
    fi
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
start_container() {
Packit bc9a3a
    local src="$1" name="$2"
Packit bc9a3a
    debug 1 "starting container $name from '$src'"
Packit bc9a3a
    lxc launch "$src" "$name" || {
Packit bc9a3a
        errorrc "Failed to start container '$name' from '$src'";
Packit bc9a3a
        return
Packit bc9a3a
    }
Packit bc9a3a
    CONTAINER=$name
Packit bc9a3a
    wait_for_boot "$name"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
delete_container() {
Packit bc9a3a
    debug 1 "removing container $1 [--keep to keep]"
Packit bc9a3a
    lxc delete --force "$1"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
run_self_inside() {
Packit bc9a3a
    # run_self_inside(container, args)
Packit bc9a3a
    local name="$1"
Packit bc9a3a
    shift
Packit bc9a3a
    inside "$name" bash -s "$@" <"$0"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
run_self_inside_as_cd() {
Packit bc9a3a
    local name="$1" user="$2" dir="$3"
Packit bc9a3a
    shift 3
Packit bc9a3a
    inside_as_cd "$name" "$user" "$dir" bash -s "$@" <"$0"
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
main() {
Packit bc9a3a
    local short_opts="a:hknpsuv"
Packit bc9a3a
    local long_opts="artifacts:,dirty,help,keep,name:,pyexe:,package,source-package,unittest,verbose"
Packit bc9a3a
    local getopt_out=""
Packit bc9a3a
    getopt_out=$(getopt --name "${0##*/}" \
Packit bc9a3a
        --options "${short_opts}" --long "${long_opts}" -- "$@") &&
Packit bc9a3a
        eval set -- "${getopt_out}" ||
Packit bc9a3a
        { bad_Usage; return; }
Packit bc9a3a
Packit bc9a3a
    local cur="" next=""
Packit bc9a3a
    local package=false srcpackage=false unittest="" name=""
Packit bc9a3a
    local dirty=false pyexe="auto" artifact_d="."
Packit bc9a3a
Packit bc9a3a
    while [ $# -ne 0 ]; do
Packit bc9a3a
        cur="${1:-}"; next="${2:-}";
Packit bc9a3a
        case "$cur" in
Packit bc9a3a
            -a|--artifacts) artifact_d="$next";;
Packit bc9a3a
               --dirty) dirty=true;;
Packit bc9a3a
            -h|--help) Usage ; exit 0;;
Packit bc9a3a
            -k|--keep) KEEP=true;;
Packit bc9a3a
            -n|--name) name="$next"; shift;;
Packit bc9a3a
               --pyexe) pyexe=$next; shift;;
Packit bc9a3a
            -p|--package) package=true;;
Packit bc9a3a
            -s|--source-package) srcpackage=true;;
Packit bc9a3a
            -u|--unittest) unittest=1;;
Packit bc9a3a
            -v|--verbose) VERBOSITY=$((VERBOSITY+1));;
Packit bc9a3a
            --) shift; break;;
Packit bc9a3a
        esac
Packit bc9a3a
        shift;
Packit bc9a3a
    done
Packit bc9a3a
Packit bc9a3a
    [ $# -eq 1 ] || { bad_Usage "Expected 1 arg, got $# ($*)"; return; }
Packit bc9a3a
    local img_ref_in="$1"
Packit bc9a3a
    case "${img_ref_in}" in
Packit bc9a3a
        *:*) img_ref="${img_ref_in}";;
Packit bc9a3a
        *) img_ref="images:${img_ref_in}";;
Packit bc9a3a
    esac
Packit bc9a3a
Packit bc9a3a
    # program starts here
Packit bc9a3a
    local out="" user="ci-test" cdir="" home=""
Packit bc9a3a
    home="/home/$user"
Packit bc9a3a
    cdir="$home/cloud-init"
Packit bc9a3a
    if [ -z "$name" ]; then
Packit bc9a3a
        if out=$(petname 2>&1;; then
Packit bc9a3a
            name="ci-${out}"
Packit bc9a3a
        elif out=$(uuidgen -t 2>&1;; then
Packit bc9a3a
            name="ci-${out%%-*}"
Packit bc9a3a
        else
Packit bc9a3a
            error "Must provide name or have petname or uuidgen"
Packit bc9a3a
            return 1
Packit bc9a3a
        fi
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    trap cleanup EXIT
Packit bc9a3a
Packit bc9a3a
    start_container "$img_ref" "$name" ||
Packit bc9a3a
        { errorrc "Failed to start container for $img_ref"; return; }
Packit bc9a3a
Packit bc9a3a
    get_os_info_in "$name" ||
Packit bc9a3a
        { errorrc "failed to get os_info in $name"; return; }
Packit bc9a3a
Packit bc9a3a
    if [ "$pyexe" = "auto" ]; then
Packit bc9a3a
        case "$OS_NAME/$OS_VERSION" in
Packit bc9a3a
            centos/*|opensuse/*) pyexe=python2;;
Packit bc9a3a
            *) pyexe=python3;;
Packit bc9a3a
        esac
Packit bc9a3a
        debug 1 "set pyexe=$pyexe for $OS_NAME/$OS_VERSION"
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    # prep the container (install very basic dependencies)
Packit bc9a3a
    run_self_inside "$name" prep "$pyexe" ||
Packit bc9a3a
        { errorrc "Failed to prep container $name"; return; }
Packit bc9a3a
Packit bc9a3a
    # add the user
Packit bc9a3a
    inside "$name" useradd "$user" --create-home "--home-dir=$home" ||
Packit bc9a3a
        { errorrc "Failed to add user '$user' in '$name'"; return 1; }
Packit bc9a3a
Packit bc9a3a
    debug 1 "inserting cloud-init"
Packit bc9a3a
    inject_cloud_init "$name" "$user" "$dirty" || {
Packit bc9a3a
        errorrc "FAIL: injecting cloud-init into $name failed."
Packit bc9a3a
        return
Packit bc9a3a
    }
Packit bc9a3a
Packit bc9a3a
    inside_as_cd "$name" root "$cdir" \
Packit bc9a3a
        $pyexe ./tools/read-dependencies "--distro=${OS_NAME}" \
Packit bc9a3a
            --test-distro || {
Packit bc9a3a
        errorrc "FAIL: failed to install dependencies with read-dependencies"
Packit bc9a3a
        return
Packit bc9a3a
    }
Packit bc9a3a
Packit bc9a3a
    local errors=( )
Packit bc9a3a
    inside_as_cd "$name" "$user" "$cdir" git status || {
Packit bc9a3a
        errorrc "git checkout failed."
Packit bc9a3a
        errors[${#errors[@]}]="git checkout";
Packit bc9a3a
    }
Packit bc9a3a
Packit bc9a3a
    if [ -n "$unittest" ]; then
Packit bc9a3a
        debug 1 "running unit tests."
Packit bc9a3a
        run_self_inside_as_cd "$name" "$user" "$cdir" nose "$pyexe" \
Packit bc9a3a
            tests/unittests cloudinit/ || {
Packit bc9a3a
                errorrc "nosetests failed.";
Packit bc9a3a
                errors[${#errors[@]}]="nosetests"
Packit bc9a3a
            }
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    local build_pkg="" build_srcpkg="" pkg_ext="" distflag=""
Packit bc9a3a
    case "$OS_NAME" in
Packit bc9a3a
        centos) distflag="--distro=redhat";;
Packit bc9a3a
        opensuse) distflag="--distro=suse";;
Packit bc9a3a
    esac
Packit bc9a3a
Packit bc9a3a
    case "$OS_NAME" in
Packit bc9a3a
        debian|ubuntu)
Packit bc9a3a
            build_pkg="./packages/bddeb -d" 
Packit bc9a3a
            build_srcpkg="./packages/bddeb -S -d"
Packit bc9a3a
            pkg_ext=".deb";;
Packit bc9a3a
        centos|opensuse)
Packit bc9a3a
            build_pkg="./packages/brpm $distflag"
Packit bc9a3a
            build_srcpkg="./packages/brpm $distflag --srpm"
Packit bc9a3a
            pkg_ext=".rpm";;
Packit bc9a3a
    esac
Packit bc9a3a
    if [ "$srcpackage" = "true" ]; then
Packit bc9a3a
        [ -n "$build_srcpkg" ] || {
Packit bc9a3a
            error "Unknown package command for $OS_NAME"
Packit bc9a3a
            return 1
Packit bc9a3a
        }
Packit bc9a3a
        debug 1 "building source package with $build_srcpkg."
Packit bc9a3a
        # shellcheck disable=SC2086
Packit bc9a3a
        inside_as_cd "$name" "$user" "$cdir" $pyexe $build_srcpkg || {
Packit bc9a3a
            errorrc "failed: $build_srcpkg";
Packit bc9a3a
            errors[${#errors[@]}]="source package"
Packit bc9a3a
        }
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    if [ "$package" = "true" ]; then
Packit bc9a3a
        [ -n "$build_pkg" ] || {
Packit bc9a3a
            error "Unknown build source command for $OS_NAME"
Packit bc9a3a
            return 1
Packit bc9a3a
        }
Packit bc9a3a
        debug 1 "building binary package with $build_pkg."
Packit bc9a3a
        # shellcheck disable=SC2086
Packit bc9a3a
        inside_as_cd "$name" "$user" "$cdir" $pyexe $build_pkg || {
Packit bc9a3a
            errorrc "failed: $build_pkg";
Packit bc9a3a
            errors[${#errors[@]}]="binary package"
Packit bc9a3a
        }
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    if [ -n "$artifact_d" ] &&
Packit bc9a3a
        [ "$package" = "true" -o "$srcpackage" = "true" ]; then
Packit bc9a3a
        local art=""
Packit bc9a3a
        artifact_d="${artifact_d%/}/"
Packit bc9a3a
        [ -d "${artifact_d}" ] || mkdir -p "$artifact_d" || {
Packit bc9a3a
            errorrc "failed to create artifact dir '$artifact_d'"
Packit bc9a3a
            return
Packit bc9a3a
        }
Packit bc9a3a
Packit bc9a3a
        for art in $(inside "$name" sh -c "echo $cdir/*${pkg_ext}"); do
Packit bc9a3a
            lxc file pull "$name/$art" "$artifact_d" || {
Packit bc9a3a
                errorrc "Failed to pull '$name/$art' to ${artifact_d}"
Packit bc9a3a
                errors[${#errors[@]}]="artifact copy: $art"
Packit bc9a3a
            }
Packit bc9a3a
            debug 1 "wrote ${artifact_d}${art##*/}"
Packit bc9a3a
        done
Packit bc9a3a
    fi
Packit bc9a3a
Packit bc9a3a
    if [ "${#errors[@]}" != "0" ]; then
Packit bc9a3a
        local e=""
Packit bc9a3a
        error "there were ${#errors[@]} errors."
Packit bc9a3a
        for e in "${errors[@]}"; do
Packit bc9a3a
            error "  $e"
Packit bc9a3a
        done
Packit bc9a3a
        return 1
Packit bc9a3a
    fi
Packit bc9a3a
    return 0
Packit bc9a3a
}
Packit bc9a3a
Packit bc9a3a
case "${1:-}" in
Packit bc9a3a
    prep|os_info|wait_inside|nose) _n=$1; shift; "$_n" "$@";;
Packit bc9a3a
    *) main "$@";;
Packit bc9a3a
esac
Packit bc9a3a
Packit bc9a3a
# vi: ts=4 expandtab