From: Ralph Ronnquist Date: Sun, 20 Mar 2022 05:53:39 +0000 (+1100) Subject: initial X-Git-Tag: deb_0.1~29 X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=df3ccb2170beff852f8ec7d421709c5e85bafc7d;p=rrq%2Foverlay-boot.git initial --- diff --git a/functions b/functions new file mode 100644 index 0000000..1d52d74 --- /dev/null +++ b/functions @@ -0,0 +1,84 @@ +# This file implements common functions for all boot methods + +die() { + echo "$*" >&2 + exit 1 +} + +# grab and set a configuration variable +# $1 = variable, [ $2 = default .. error otherwise ] +config() { + eval $1="$(sed "/^$1=.*/{s|^$1=||;b};d" $CONFIG)" + [ -z "$(eval echo "\$$1")" ] || return 0 + [ $# -lt 2 ] && die "Missing $1=... in $CONFIG" + eval $1="'$2'" + eval echo "$1=\$$1" +} + +# Unless the subhost already has a private /etc/network/interfaces, +# install an "empty" one +setup_networking() { + [ -r $UPPER/etc/network/interfaces ] && return 0 + [ "$UPPER/etc/network" = "/etc/network" ] && exit 1 + mkdir -p $UPPER/etc/network + cat < $UPPER/etc/network/interfaces +# Generated for $NAME subhost +auto lo +iface lo inet loopback +EOF + return 1 +} + +# Setup the network namespace for the given $CABLES +# $1=netns ( $2="br=mac" .. ) +setup_veth_cables() { + local NETNS BR IF MAC C i ADD + NETNS="$1" + shift 1 + i=0 + ADD=false + setup_networking || ADD=true + for C in "$@" ; do + IF=$NETNS$i + MAC="${C#*=}" + [ -z "$MAC" ] || MAC="address $MAC" + ip link add $IF type veth peer name eth$i $MAC netns $NETNS + ip link set $IF up + $ADD && cat <> $UPPER/etc/network/interfaces + +auto eth$i +iface eth$i inet manual +EOF + BR="${C%=*}" + [ -z "$BR" ] || brctl addif $BR $IF + i=$((i+1)) + done +} + +REAPER=$(dirname $(realpath $0))/reaper/reaper +# (name live system root work) +# Set up an overlay fmr $name on $live, with a new tmpfs on its /run, +# and "install" a "reaper" as the upcoming pid 1 +setup_overlay() { + set -x + mkdir -p $4/run + mount -t tmpfs -osize=100M tmpfs $4/run + mkdir -p $4/run/lock + grep -q "$1 $2" /proc/mounts || \ + mount -t overlay -olowerdir=$3,upperdir=$4,workdir=$5 $1 $2 || \ + die "Cannot set up the overlay mount $2" + mount --bind $4/run $2/run + cp $REAPER $LIVE/.reaper +} + + +# Check if $SRV is "live" ; will +is_live() { + pgrep -f ".reaper $SRV" > /dev/null +} + +start_services() { + for S in "$@" ; do + service $S start + done +} diff --git a/olle/olle.conf b/olle/olle.conf new file mode 100644 index 0000000..71b86ef --- /dev/null +++ b/olle/olle.conf @@ -0,0 +1,10 @@ +NAME=olle +BASE=olle +CABLES=homenet= +#LOG=/tmp/oly-olle.log +#LIVE=olle/live +#UPPER=olle/root" +#WORK=olle/work" +LOWER=/ +#START=networking ssh +#SUBSHELL=/bin/sh diff --git a/overlay-boot b/overlay-boot new file mode 100755 index 0000000..239ae1c --- /dev/null +++ b/overlay-boot @@ -0,0 +1,60 @@ +#!/bin/sh +# +# This boot method runs a service subhost with a root filesystem that +# is an overlay of the subhost's root and an OS root. The service +# subhost is defined by a configuration file named on teh command line + +[ $(id -u) = 0 ] || exec sudo $0 $@ + +. $(dirname $(realpath $0))/functions + +CONFIG="$1" +[ -r "$CONFIG" ] || die "Missing configuration $CONFIG" + +config NAME $(basename $1 .${1##*.}) +config LOG /tmp/oly-$NAME.log + +if [ -z "$UNSHARED" ] ; then + # Pre-unsharing: + # + # Create the network namespace for the subhost, then trigger + # detached re-run with unshared mount namespace + [ -r /run/netns/$NAME ] || ip netns add $NAME + exec env UNSHARED=yes unshare -m $0 $@ > $LOG 2>&1 & + echo "Logging to $LOG" >&2 + exit 0 +fi + +config BASE +config LIVE "$BASE/live" +config UPPER "$BASE/root" +config WORK "$BASE/work" +config LOWER "/" +config CABLES "" +config START "networking ssh" +config SUBSHELL /bin/sh +config STOP "" + +# Setup virtual cabling and subhost's /etc/network/interfaces +setup_veth_cables $NAME $CABLES + +# Set up the mount for this subhost, including a new tmpfs on its /run +echo setup_overlay "$NAME" "$LIVE" "$LOWER" "$UPPER" "$WORK" +setup_overlay "$NAME" "$LIVE" "$LOWER" "$UPPER" "$WORK" + +exithandler() { + ip netns del $NAME + umount -R "$LIVE" +} +trap "exithandler" 0 + +CMD="unshare -fp --mount-proc ip netns exec $NAME chroot $LIVE /bin/sh" +echo "$CMD" +cat <