#!/bin/sh # vblade-persist: this script sets up a permanent vblade instance under # runit supervision # Author: Daniel Kahn Gillmor # Copyright: November 2007 # License: GPLv3 or later VDIR=/var/lib/vblade-persist/vblades SDIR=/usr/share/vblade-persist usage() { echo "usage: vblade-persist setup SHELF SLOT NETIF SOURCE" echo " vblade-persist ls" echo " vblade-persist start|stop|restart|auto|noauto SHELF SLOT" echo " vblade-persist start|stop|restart|auto|noauto all" } error() { echo "vblade-persist: $1" >&2 } fatal() { error "$1" exit ${2:-'1'} } require_sv() { [ -x /usr/bin/sv ] || fatal "/usr/bin/sv not available. Please install runit." } # FIXME: make this test a little more robust. verify_vblade_persist_path() { [ -d "$1" ] } # shelf identifiers should be integers: # FIXME: check that they're in a certain range? verify_shelf() { expr match "$1" '[0-9][0-9]*' >/dev/null } # slot identifiers should be integers: # FIXME: check that they're in a certain range? verify_slot() { expr match "$1" '[0-9][0-9]*' >/dev/null } # FIXME: if there's no ip and no ifconfig, what do we do? verify_interface() { if [ -x /bin/ip ] ; then /bin/ip link show "$1" >/dev/null elif [ -x /sbin/ifconfig ] ; then /sbin/ifconfig -s "$1" > /dev/null else error "Don't know how to test interface. Assuming '$1' is acceptable." true fi } # make sure that the device is either a block device or a link to a # block device: verify_source() { [ -b `readlink -f "$1"` ] } setup() { SHELF="$1" SLOT="$2" NETIF="$3" SOURCE="$4" verify_shelf "$SHELF" || fatal "not a valid shelf: '$SHELF'" verify_slot "$SLOT" || fatal "not a valid shelf: '$SLOT'" verify_interface "$NETIF" || fatal "not a valid interface: '$NETIF'" verify_source "$SOURCE" || fatal "not a valid source: '$SOURCE'" DNAME="e$SHELF.$SLOT" mkdir "$VDIR/$DNAME" || fatal "Could not create directory '$VDIR/$DNAME'" mkdir "$VDIR/$DNAME/env" mkdir "$VDIR/$DNAME/log" mkdir "$VDIR/$DNAME/macs" # start it off idle (so that the admin can decide when to start): touch "$VDIR/$DNAME/down" ln -s "$SDIR/vblade-run" "$VDIR/$DNAME/run" ln -s "$SDIR/vblade-finish" "$VDIR/$DNAME/finish" ln -s "$SDIR/vblade-logrun" "$VDIR/$DNAME/log/run" echo "$SHELF" > "$VDIR/$DNAME/env/SHELF" echo "$SLOT" > "$VDIR/$DNAME/env/SLOT" echo "$NETIF" > "$VDIR/$DNAME/env/NETIF" echo "$SOURCE" > "$VDIR/$DNAME/env/SOURCE" # tell runit to supervise this vblade: ln -s "$VDIR/$DNAME" "/var/service/vblade-$DNAME" || fatal "Could not set up supervision for this vblade" } list() { echo -e '#shelf slot netif source auto stat' for dev in `ls "$VDIR"` ; do echo $(cat "$VDIR/$dev/env/SHELF" "$VDIR/$dev/env/SLOT" "$VDIR/$dev/env/NETIF" "$VDIR/$dev/env/SOURCE") $( [ -e "$VDIR/$dev/down" ] && echo 'no')auto $(cat "$VDIR/$dev/supervise/stat") done } svcommand() { require_sv CMD="$1" SVDIR="$2" verify_vblade_persist_path "$SVDIR" || fatal "This is not a vblade-persist path" sv "$CMD" "$SVDIR" } auto() { verify_vblade_persist_path "$2" || fatal "This is not a vblade-persist path" if [ "$1" == "auto" ] ; then rm -f "$2/down" else touch "$2/down" fi } autoall() { AUTO="$1" for dev in `ls "$VDIR"` ; do auto "$AUTO" "$VDIR/$dev" done } svall() { require_sv CMD="$1" for dev in `ls "$VDIR"` ; do svcommand "$CMD" "$VDIR/$dev" done } case "$1" in setup) setup "$2" "$3" "$4" "$5" ;; l*) list ;; start|stop|restart) if [ "all" == "$2" ] ; then svall "$1" else verify_shelf "$2" || fatal "Not a valid shelf: '$2'" verify_slot "$3" || fatal "Not a valid slot: '$3'" svcommand "$1" "$VDIR/e$2.$3" fi ;; auto|noauto) if [ "all" == "$2" ] ; then autoall "$1" else verify_shelf "$2" || fatal "Not a valid shelf: '$2'" verify_slot "$3" || fatal "Not a valid slot: '$3'" auto "$1" "$VDIR/e$2.$3" fi ;; *) usage exit 1 ;; esac