From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id E26906DE01D0 for ; Tue, 16 Aug 2016 14:15:22 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: 0.229 X-Spam-Level: X-Spam-Status: No, score=0.229 tagged_above=-999 required=5 tests=[AWL=0.238, HEADER_FROM_DIFFERENT_DOMAINS=0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 53uTBg0t8v8G for ; Tue, 16 Aug 2016 14:15:21 -0700 (PDT) X-Greylist: delayed 424 seconds by postgrey-1.35 at arlo; Tue, 16 Aug 2016 14:15:21 PDT Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34]) by arlo.cworth.org (Postfix) with ESMTP id 127A06DE0134 for ; Tue, 16 Aug 2016 14:15:21 -0700 (PDT) Received: by guru.guru-group.fi (Postfix, from userid 501) id B063C1000B3; Wed, 17 Aug 2016 00:07:52 +0300 (EEST) From: Tomi Ollila To: notmuch@notmuchmail.org Cc: tomi.ollila@iki.fi Subject: [RFC PATCH] test: add devel/test-in-docker.sh Date: Wed, 17 Aug 2016 00:07:51 +0300 Message-Id: <1471381671-21134-1-git-send-email-tomi.ollila@iki.fi> X-Mailer: git-send-email 2.8.2 X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Aug 2016 21:15:23 -0000 With this user can try and test notmuch in docker container, in fixed environment where it should compile and tests should pass... Currently provided container environments are Debian 8.5 and Ubuntu 16.04 based. Host OS could be any Linux environment with modern enough docker; Perhaps this works on macOS (with docker 1.12+) too (in Windows this script probably fails). --- Currently quite a few tests FAIL -- due to missing prerequisite tests. It would be easy to add some packages, like gdb, emacs(-nox), dtach, but I left those out just to tease you >;) devel/test-in-docker.sh | 193 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100755 devel/test-in-docker.sh diff --git a/devel/test-in-docker.sh b/devel/test-in-docker.sh new file mode 100755 index 000000000000..f9537c177ad9 --- /dev/null +++ b/devel/test-in-docker.sh @@ -0,0 +1,193 @@ +#!/bin/sh +# -*- mode: shell-script; sh-basic-offset: 8; tab-width: 8 -*- + +case ${BASH_VERSION-} in *.*) PATH=/ shopt -s xpg_echo; esac +case ${ZSH_VERSION-} in *.*) PATH=/ emulate ksh; esac + +set -u # expanding unset variable makes non-interactive shell exit immediately +set -f # disable pathname expansion by default -- makes e.g. eval more robust +set -e # exit on error -- know potential false negatives and positives ! +#et -x # s/#/s/ may help debugging (or run /bin/sh -x ... on command line) + +LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8; export LANG LC_ALL + +#PATH='/sbin:/usr/sbin:/bin:/usr/bin'; export PATH + +# XXX If bash finds *this* script by searching PATH... +case $0 in */*) ;; *) + echo "'$0' does not contain '/'s. try './$0'" >&2; exit 1 +esac + +saved_IFS=$IFS; readonly saved_IFS + +warn () { for l; do echo "$l"; done; } >&2 +die () { for l; do echo "$l"; done; exit 1; } >&2 + +x () { echo + "$@" >&2; "$@"; } +x_env () { echo + "$@" >&2; env "$@"; } +x_eval () { echo + "$*" >&2; eval "$*"; } +x_exec () { echo + "$@" >&2; exec "$@"; die "exec '$*' failed"; } + +test $# -gt 0 || { + exec >&2; echo + echo Usage: $0 '(debian8|ubuntu1604)' + echo + echo After everything set up a user shell to the given container + echo is started "(cwd='$HOME'; X11 should work)." + echo + echo If container is already running, new shell is started. + echo If container exists but is not running it is restarted. + echo If image exists but no container, new container is created. + echo If image does not exist. It is built. + echo Build files are stored in /root/.docker-setup/ in the container. + echo + exit 1 +} + +case $1 +in debian|debian8) + shift; set debian8 "$@" + name='debian8-notmuch' +;; ubuntu|ubuntu16|ubuntu1604) + shift; set ubuntu1604 "$@" + name='ubuntu1604-notmuch' +;; *) + die "'$1': unsupported container name" +esac + +if status=`exec docker inspect -f '{{.State.Status}}' $name 2>&1` +then + if test "$status" = running + then x_exec docker exec -it "$name" /bin/bash --login + else x_exec docker start -i "$name" + fi +fi + +run () +{ + test -d /tmp/.X11-unix && + xv='-v /tmp/.X11-unix:/tmp/.X11-unix:ro' || xv= + + x_exec docker run -it -e DISPLAY -e _USER="$USER" --name "$name" \ + -h "$name" -v $HOME:/home/$USER ${v:+-v "$v"} --ipc=host "$name" +} + +case $status in *parsing*error*.State.Status*) run; esac + +# Here if above docker inspect -f '{{.State.Status}}' did not match above, but +# Error: No such image or container: ... + +case $1 +in debian8) + FROM_HASH=1b01529cc499d51767c62f9fc8083043610546b4e050898809ec54e00dbb1a34 + FROM_REF=debian:8.5 +;; ubuntu1604) + FROM_HASH=42118e3df429f09ca581a9deb3df274601930e428e452f7e4e9f1833c56a100a + FROM_REF=ubuntu:16.04 +esac + +TRUNC_HASH=${FROM_HASH%????????????????????????????????????????????????????} + +rmtmps () { rm -rf _docker_wip; trap - 0; } +rmtmps +mkdir _docker_wip + +# outcomment next line when debugging build +trap rmtmps 0 INT HUP TERM +exec 3>&1 > _docker_wip/Dockerfile.gen + +cat < /etc/default/locale \ + && apt-get install -y -q build-essential git libxapian-dev libgmime-2.6-dev libtalloc-dev zlib1g-dev \ + && apt-get -y autoremove && apt-get -y clean # rm -rf /var/lib/apt/lists/ + +EOF + +esac + +# all containers (more may be added...) + +cat <<'EOF' +RUN set -xeu \ + && chmod 755 /root \ + && exec 3>&1 >>/root/.bash_profile && echo \ + && echo 'test ! -f /root/.docker-setup/bash-as-user.sh ||' \ + && echo ' . /root/.docker-setup/bash-as-user.sh' \ + && exec >>/etc/bash.bashrc && echo \ + && echo '# emulate zsh printexitvalue (written from Dockerfile)' \ + && echo 'trap '\''echo -n bash: exit $? \\ \\ ; fc -nl -1 -1'\'' ERR' \ + && exec 1>&3 3>&- \ + && umask 077 \ + && mkdir -p /etc/sudoers.d \ + && echo '%root ALL= NOPASSWD: ALL' >/etc/sudoers.d/55-wheel-allmighty + +ADD bash-as-user.sh Dockerfile.gen /root/.docker-setup/ + +CMD ["/bin/bash", "--login" ] + +EOF + +exec >&3 3>&- + +cat >_docker_wip/bash-as-user.sh <<'EOF' +# This file is supposed to be loaded from /root/.bash_profile +# when bash is started as login shell (-l or --login). + +user=${_USER-} +unset _USER + +if test "$user" && test -d /home/"$user" +then + case $user in *[!-a-z0-9_]*) exit 1; esac + grep -q "^$user:" /etc/passwd || { + duid=`exec stat -c %u /home/"$user"` + useradd -d /home/"$user" -M -u $duid -U -G 0 -s /bin/bash \ + -c "user $user" "$user" 2>/dev/null || : + } +fi + +# Simple change user which may work as well as gosu(1) if not (better). +test -z "$user" || exec perl -e ' + my @user = getpwnam $ARGV[0]; + chdir $user[7]; + $ENV{HOME} = $user[7]; + $ENV{USER} = $ARGV[0]; + $( = $) = "$user[3] $user[3] 0"; + $< = $> = $user[2]; die "setting uids: $!\n" if $!; + exec qw"/bin/bash --login";' "$user" +unset user +EOF + +( cd _docker_wip + # TIME is used by (GNU) /usr/bin/time (TIMEFORMAT by bash builtin) + export TIME='%Us user, %Ss system, %P cpu, %E total (max resident mem %Mk)' + export SHELL=/bin/sh + x command time docker build -f Dockerfile.gen -t $name . + x_exec docker history $name ) + +rmtmps +# run() does exec; auto-eliminating traps +run -- 2.8.2