unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [RFC PATCH] test: add devel/test-in-docker.sh
@ 2016-08-16 21:07 Tomi Ollila
  2016-08-19 13:50 ` Tomi Ollila
  0 siblings, 1 reply; 3+ messages in thread
From: Tomi Ollila @ 2016-08-16 21:07 UTC (permalink / raw)
  To: notmuch; +Cc: tomi.ollila

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 <<EOF
+
+# Ensure that FROM_REF & FROM_HASH are in sync; hash wins if not...
+#FROM $FROM_REF (is $TRUNC_HASH...)
+FROM $FROM_HASH
+
+# Note: The result of docker build with this Dockerfile is not entirely
+#       reproducable as packages installed from remote sources may get
+#       updated...
+
+ENV LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
+
+EOF
+
+case $1 in debian*|ubuntu*)
+
+cat <<'EOF'
+# Set locale in a way that is both ubuntu and debian compatible
+RUN set -xeu \
+ && export DEBIAN_FRONTEND=noninteractive \
+ && apt-get update && apt-get install -y -q locales \
+ && if test -f /etc/locale.gen; then \
+       sed -i '/en_US.UTF-8/ s/^. *//' /etc/locale.gen; fi \
+ && locale-gen en_US.UTF-8 \
+ && echo 'LANG="en_US.UTF-8"' > /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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-08-19 14:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-16 21:07 [RFC PATCH] test: add devel/test-in-docker.sh Tomi Ollila
2016-08-19 13:50 ` Tomi Ollila
2016-08-19 14:03   ` Philipp Ittershagen

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).