diff options
author | Christophe Lyon <christophe.lyon@linaro.org> | 2017-01-27 13:24:19 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@linaro.org> | 2017-01-27 13:34:49 +0000 |
commit | b1e0f5737e72b654076410469af949931fd2ef7a (patch) | |
tree | bd7b785e8217d75fedb6fd5d577b95206e50f7f5 | |
parent | 927e3cfb59fdb7262ea30b1b2d6b6b66bda18db5 (diff) |
Add new scripts to start a container.
The 3 main scripts are:
start-container-none.sh
start-container-schroot.sh
start-container-docker.sh
and check-server.exp is a helper for start-container-docker.sh.
The 3 main scripts have the same calling convention:
start-container-${container_type}.sh arch flavour.
Currently, arch can be i386, amd, armhf or arm64,
and distro can be trusty or xenial.
If successful, the script outputs a few lines of shell
that should be executed in the calling script, which:
- install a trap handler to remove the container upon exit
- define the ${CONTAINER} variable, to be used as a prefix
for commands you want to execute in the container
- define ${session_host} and ${session_port} that can be
used by the parent script to interact with container (for
instance to help another (test)-container connect to the
newly created container.
The docker variant uses an helper expect script to make sure
the ssh server running in the docker instance is ready.
Change-Id: I2e2baf3ab606dd636fae87d0b0583a3102fb8f95
-rw-r--r-- | check-server.exp | 21 | ||||
-rwxr-xr-x | start-container-docker.sh | 97 | ||||
-rwxr-xr-x | start-container-none.sh | 36 | ||||
-rwxr-xr-x | start-container-schroot.sh | 39 |
4 files changed, 193 insertions, 0 deletions
diff --git a/check-server.exp b/check-server.exp new file mode 100644 index 00000000..83833fbd --- /dev/null +++ b/check-server.exp @@ -0,0 +1,21 @@ +#!/usr/bin/expect +set timeout 20 +set ip [lindex $argv 0] +set port [lindex $argv 1] + +spawn telnet $ip $port + +expect { + "SSH" + { + send_user "OK\n" + exit 0 + } + + "host: Connection refused" + { + send_user "ERROR: Connection refused!\n" + exit 1 + } +} + diff --git a/start-container-docker.sh b/start-container-docker.sh new file mode 100755 index 00000000..cc4ec58b --- /dev/null +++ b/start-container-docker.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# Start a local docker instance with the requested arch and distro + +# This script is meant to be executed from Jenkins jobs inside TCWG +# lab. It prints shell commands meant to be executed in the parent +# shell, consisting in: +# - a trap statement, to cleanup the container upon exit +# - definition of ${CONTAINER}, used to prefix commands that you want +# to run inside the container. +# - definition of ${session_host} and ${session_port}, can be used for +# a remote connexion to the container + +if [ $# -ne 2 ]; then + echo Usage: $0 arch flavour + echo " arch: architecture (eg: amd64, i386, arm64, armhf)" + echo " flavour: distribution (eg: trusty)" + exit 1 +fi + +# BUILD_NUMBER, JOB_NAME and WORKSPACE are set by Jenkins +if [ "x$BUILD_NUMBER" = "x" ]; then + echo "BUILD_NUMBER is not defined. Are you executing this from Jenkins ?" + exit 1 +fi +if [ "x$JOB_NAME" = "x" ]; then + echo "JOB_NAME is not defined. Are you executing this from Jenkins ?" + exit 1 +fi +if [ "x$WORKSPACE" = "x" ]; then + echo "WORKSPACE is not defined. Are you executing this from Jenkins ?" + exit 1 +fi + +container_arch=$1 +distro=$2 + +# Save stdout/stderr file descriptors +exec 3>&1 4>&2 + +# Make sure all output goes to stderr +exec 1>&2 + +session_host="$(hostname).tcwglab" +session_name=$(echo $BUILD_NUMBER-$JOB_NAME | sed -e "s#[/=,]#-#g") +session_id=$(ssh $session_host docker run --name $session_name -dtP \ + -v $HOME/snapshots-ref:$HOME/snapshots-ref:ro \ + -v $WORKSPACE:$WORKSPACE \ + --memory=7500M --pids-limit=5000 \ + linaro/${distro}-${container_arch}-tcwg) + +if [ x"$session_id" = x ]; then + exit 1 +fi + +# Remove the docker instance we have just created in case something +# goes wrong. +trap "docker -H $session_host:2375 rm -fv $session_id ; exec 1>&3 2>&4" EXIT + +session_port=$(ssh $session_host docker port $session_id 22 | cut -d: -f 2) + +rundir="$(pwd -P)" +mydir="$(dirname $0)" +cd "${mydir}" +mydir="$(pwd)" +cd ${rundir} + +# Wait until the ssh server is ready to serve connexions + +# Make sure connexion messages go to stderr, so that in case of +# success stdout contains only the connexion info expected by the +# caller. +count=20 +while [ $count -gt 0 ] +do + sleep 5 + expect ${mydir}/check-server.exp ${session_host} ${session_port} && break + echo SSH not ready, waiting..... + count=$((count - 1)) +done + +if [ $count -eq 0 ]; then + echo SSH server did not respond, exiting + exit 1 +fi + +# Do not remove the container upon exit: it is now ready +trap EXIT + +# Restore stdout/stderr +exec 1>&3 2>&4 + +cat <<EOF +trap "docker -H $session_host:2375 rm -fv $session_id" EXIT +CONTAINER="ssh -p $session_port -A $session_host" +session_host=${session_host} +session_port=${session_port} +EOF diff --git a/start-container-none.sh b/start-container-none.sh new file mode 100755 index 00000000..7315612c --- /dev/null +++ b/start-container-none.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Pretend to start a local container. Parameters are ignored but +# required to have the same interface as the other scripts in this +# directory. + +# This script is meant to be executed from Jenkins jobs inside TCWG +# lab. It prints shell commands meant to be executed in the parent +# shell, consisting in: +# - a trap statement, to cleanup the container upon exit +# - definition of ${CONTAINER}, used to prefix commands that you want +# to run inside the container. +# - definition of ${session_host} and ${session_port}, can be used for +# a remote connexion to the container + +if [ $# -ne 2 ]; then + echo Usage: $0 arch flavour + echo " arch: architecture (eg: amd64, i386, arm64, armhf)" + echo " flavour: distribution (eg: trusty)" + exit 1 +fi + +if [ x"$DOCKER_HOST" = x"" ]; then + session_host="$(hostname).tcwglab" + session_port="22" +else + session_host="$(echo $DOCKER_HOST | sed -e "s#^tcp://\(.*\):.*#\1#")" + session_port="$(ssh $session_host docker port $DOCKER_CONTAINER_ID 22)" + session_port="$(echo $session_port | cut -d: -f 2)" +fi + +cat <<EOF +ulimit -u 5000 +CONTAINER="bash -c" +session_host=${session_host} +session_port=${session_port} +EOF diff --git a/start-container-schroot.sh b/start-container-schroot.sh new file mode 100755 index 00000000..c95cae29 --- /dev/null +++ b/start-container-schroot.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Start a local schroot instance with the requested arch and distro + +# This script is meant to be executed from Jenkins jobs inside TCWG +# lab. It prints shell commands meant to be executed in the parent +# shell, consisting in: +# - a trap statement, to cleanup the container upon exit +# - definition of ${CONTAINER}, used to prefix commands that you want +# to run inside the container. +# - definition of ${session_host} and ${session_port}, can be used for +# a remote connexion to the container +if [ $# -ne 2 ]; then + echo Usage: $0 arch flavour + echo " arch: architecture (eg: amd64, i386, arm64, armhf)" + echo " flavour: distribution (eg: trusty)" + exit 1 +fi + +container_arch=$1 +distro=$2 + +session_host="$(hostname).tcwglab" +session_port=22 +schroot_image="tcwg-build-${container_arch}-${distro}" +session_id=$(schroot -b -c chroot:$schroot_image --preserve-environment) + +if [ x"$session_id" = x ]; then + exit 1 +fi + +cat <<EOF +ulimit -u 5000 +# Sometimes /dev/pts can't get unmounted on the first try. +# Workaround by retrying. +trap "{ schroot -f -e -c session:$session_id || { sleep 60 ; schroot -f -e -c session:$session_id; } || true; }" EXIT +CONTAINER="schroot -r -c session:$session_id --preserve-environment -- bash -c" +session_host=${session_host} +session_port=${session_port} +EOF |