--- /dev/null
+#!/bin/bash
+#
+# Control program for bespoke arbitrary services through unshared sub-hosts
+#
+# $1 = the command: start or stop
+# $2 = the sub-host to start or stop
+# $3... = the optional chroot-ed command (/startup by default)
+
+SCRIPT=$0
+CMD=$1
+NAME=$2
+shift 2
+
+usage() {
+ echo "$SCRIPT (start|stop) <subhost>" >&2
+ exit 1
+}
+
+[ -z "$NAME" ] && usage
+
+: ${ATTIC=/opt/srv}
+: ${BRIDGE=srv_br}
+: ${TARGET=/srv/$NAME}
+: ${LOWER=$ATTIC/daedalus.fs}
+: ${IMAGE=$ATTIC/$NAME/$NAME.img}
+: ${UPPER=$ATTIC/$NAME/root}
+: ${WORK=$ATTIC/$NAME/work}
+: ${MOUNT=$ATTIC/$NAME/mnt}
+: ${NSNAME=$NAME}
+: ${NETH=1}
+
+create_subhost() {
+ mkdir -p $TARGET $MOUNT $UPPER $WORK
+}
+
+setup_network() {
+ if [ -n "$BRIDGE" ] ; then
+ brctl show $BRIDGE >& /dev/null || brctl addbr $BRIDGE
+ fi
+
+ E=0
+ ip netns add $NSNAME
+ for I in $(eval echo "{1..$NETH}") ; do
+ IF=$NAME$E
+ ip link add $IF type veth peer name eth$E netns $NSNAME
+ ip link set $IF up
+ [ -n "$BRIDGE" ] && brctl addif $BRIDGE $IF
+ E=$((E+1))
+ done
+}
+
+setup_rootfs() {
+ if [ -e "$IMAGE" ] ; then
+ mount $IMAGE $MOUNT || exit 1
+ LOWER=$MOUNT/root
+ WORK=$MOUNT/work
+ fi
+ mount -t overlay $NAME -olowerdir=$LOWER,upperdir=$UPPER,workdir=$WORK \
+ $TARGET
+}
+
+case "$CMD" in
+ start)
+ cd "$ATTIC" || exit 1
+ [ -e "/run/netns/$NSNAME" ] || setup_network
+ [ -d "$MOUNT" ] || create_subhost
+ grep -q "^$NAME $TARGET overlay" /proc/mounts || setup_rootfs
+ START=/bin/bash
+ [ -x $TARGET/startup ] && START=/startup
+ exec ip netns exec $NSNAME unshare \
+ --fork --pid --mount-proc --kill-child \
+ --uts --ipc --mount --cgroup \
+ "--root=$TARGET" $START
+ ;;
+ stop)
+ umount $TARGET
+ [ -e $IMAGE ] && umount $MOUNT
+ ip netns del $NSNAME
+ ;;
+ *)
+ usage
+ ;;
+esac
--- /dev/null
+#!/bin/bash
+#
+# This is a script to run at startup of a bespoke sub-host
+
+NOW=$(date +"%Y%m%d-%H%M%S")
+
+{
+ echo "Startup at $NOW"
+ set -x
+
+ mkdir -p /dev/pts /dev/shm /run
+ if ! grep "^none /run tmpfs" /proc/mounts ; then
+ mount -t tmpfs -osize=80M none /run
+ mount -t tmpfs -osize=20M none /dev/shm
+ mount -t devpts none /dev/pts
+ mount -t sysfs none /sys
+ mkdir -p /run/lock /run/user
+ fi
+
+ # Restart auto interfaces
+ for IF in $(grep "^auto" /etc/network/interfaces) ; do
+ [ "$IF" = auto ] && continue
+ ifdown $IF
+ ifup $IF
+ done
+
+ # Restart services
+ SERVICES=( )
+ for S in ${SERVICES[@]} ; do
+ service $S restart
+ done
+
+} >& /var/log/startup-$NOW.log
+
+exec /bin/bash