first
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Fri, 25 Feb 2022 14:17:31 +0000 (01:17 +1100)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Fri, 25 Feb 2022 14:17:31 +0000 (01:17 +1100)
control [new file with mode: 0755]
startup [new file with mode: 0755]

diff --git a/control b/control
new file mode 100755 (executable)
index 0000000..28a4d2c
--- /dev/null
+++ b/control
@@ -0,0 +1,83 @@
+#!/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
diff --git a/startup b/startup
new file mode 100755 (executable)
index 0000000..c279cd5
--- /dev/null
+++ b/startup
@@ -0,0 +1,35 @@
+#!/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