first
[rrq/subhost.git] / control
1 #!/bin/bash
2 #
3 # Control program for bespoke arbitrary services through unshared sub-hosts
4 #
5 # $1 = the command: start or stop
6 # $2 = the sub-host to start or stop
7 # $3... = the optional chroot-ed command (/startup by default)
8
9 SCRIPT=$0
10 CMD=$1
11 NAME=$2
12 shift 2
13
14 usage() {
15     echo "$SCRIPT (start|stop) <subhost>" >&2
16     exit 1
17 }
18
19 [ -z "$NAME" ] && usage
20
21 : ${ATTIC=/opt/srv}
22 : ${BRIDGE=srv_br}
23 : ${TARGET=/srv/$NAME}
24 : ${LOWER=$ATTIC/daedalus.fs}
25 : ${IMAGE=$ATTIC/$NAME/$NAME.img}
26 : ${UPPER=$ATTIC/$NAME/root}
27 : ${WORK=$ATTIC/$NAME/work}
28 : ${MOUNT=$ATTIC/$NAME/mnt}
29 : ${NSNAME=$NAME}
30 : ${NETH=1}
31
32 create_subhost() {
33     mkdir -p $TARGET $MOUNT $UPPER $WORK
34 }
35
36 setup_network() {
37     if [ -n "$BRIDGE" ] ; then
38         brctl show $BRIDGE >& /dev/null || brctl addbr $BRIDGE
39     fi
40
41     E=0
42     ip netns add $NSNAME
43     for I in $(eval echo "{1..$NETH}") ; do
44         IF=$NAME$E
45         ip link add $IF type veth peer name eth$E netns $NSNAME
46         ip link set $IF up
47         [ -n "$BRIDGE" ] && brctl addif $BRIDGE $IF
48         E=$((E+1))
49     done
50 }
51
52 setup_rootfs() {
53     if [ -e "$IMAGE" ] ; then
54         mount $IMAGE $MOUNT || exit 1
55         LOWER=$MOUNT/root
56         WORK=$MOUNT/work
57     fi
58     mount -t overlay $NAME -olowerdir=$LOWER,upperdir=$UPPER,workdir=$WORK \
59           $TARGET
60 }
61
62 case "$CMD" in
63     start)
64         cd "$ATTIC" || exit 1
65         [ -e "/run/netns/$NSNAME" ] || setup_network
66         [ -d "$MOUNT" ] || create_subhost
67         grep -q "^$NAME $TARGET overlay" /proc/mounts || setup_rootfs
68         START=/bin/bash
69         [ -x $TARGET/startup ] && START=/startup
70         exec ip netns exec $NSNAME unshare \
71              --fork --pid --mount-proc --kill-child \
72              --uts --ipc --mount --cgroup \
73              "--root=$TARGET" $START
74         ;;
75     stop)
76         umount $TARGET
77         [ -e $IMAGE ] && umount $MOUNT
78         ip netns del $NSNAME
79         ;;
80     *)
81         usage
82         ;;
83 esac