--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2014 Martin Lucina. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# rumprun: "driver" script for running rumprun application stacks
+#
+
+err() {
+ echo rumprun: error: "$@" 1>&2
+ exit 1
+}
+
+usage() {
+ cat <<EOM
+usage: rumprun STACK [ -ipd ] [ -N NAME ] [ -M MEM ] [ -b BLKSPEC ] [ -n NETSPEC ] [ -- ] APP [ args ]
+ STACK is the rumprun stack to use. Only "xen" is currently supported
+ APP is the rumprun application to start
+ args will be passed to the application command line
+ -N NAME sets the domain's name to NAME, default is rumprun-APP
+ -M MEM sets the domain's memory to MEM, default is 16
+ -b BLKSPEC configures a block device as hostpath:mountpoint
+ -n NETSPEC configures a network interface, using one of:
+ inet:dhcp - IPv4 with DHCP
+ inet:static:ADDR/MASK[:GATEWAY] - IPv4 with static IP
+ -i attaches to domain console on startup
+ -p creates the domain but leaves it paused
+ -d destroys the domain on poweroff
+
+ When run without -i the local domain id is printed to standard output
+EOM
+ exit 1
+}
+
+# Detect the filesystem type of the image at $1.
+detect_fstype() {
+ ftype=$(file -b $1)
+ case $ftype in
+ "Unix Fast File system"*)
+ echo ffs
+ return 0
+ ;;
+ "ISO 9660"*)
+ echo cd9660
+ return 0
+ ;;
+ *)
+ echo unknown
+ return 1
+ ;;
+ esac
+}
+
+cidr2mask()
+{
+ # Number of args to shift, 255..255, first non-255 byte, zeroes
+ set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
+ [ $1 -gt 1 ] && shift $1 || shift
+ echo ${1-0}.${2-0}.${3-0}.${4-0}
+}
+
+parse_netspec() {
+ # Call ourselves recursively to split $@ on :
+ if [ "$IFS" != ":" ]; then
+ OLDIFS=$IFS
+ IFS=: parse_netspec "$@"
+ return $?
+ else
+ set -- $1
+ IFS=$OLDIFS
+ fi
+ [ $# -lt 2 ] && usage
+ iftype=$1
+ ifmethod=$2
+ [ "${iftype}" != "inet" ] && return 1
+ conf_vif="${conf_vif}'',"
+ case ${ifmethod} in
+ dhcp)
+ echo net/${nindex}/type inet >>${xenstore}
+ echo net/${nindex}/method dhcp >>${xenstore}
+ ;;
+ static)
+ ifaddr=${3%/*}
+ ifmask=$(cidr2mask ${3#*/})
+ ifgw=$4
+ echo net/${nindex}/type inet >>${xenstore}
+ echo net/${nindex}/method static >>${xenstore}
+ echo net/${nindex}/addr ${ifaddr} >>${xenstore}
+ echo net/${nindex}/netmask ${ifmask} >>${xenstore}
+ [ -n "${ifgw}" ] &&
+ echo net/${nindex}/gw ${ifgw} >>${xenstore}
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ return 0
+}
+
+# run_xen: Generate Xen configuration and run application stack.
+run_xen() {
+ conf=/tmp/xr.conf.$$
+ xenstore=/tmp/xr.store.$$
+ >${conf}
+ >${xenstore}
+ OPTIND=1
+ nindex=0
+ bindex=0
+ conf_disk=
+ conf_vif=
+ opt_pause=
+ opt_interactive=
+ opt_destroy='on_poweroff="preserve"'
+ opt_mem=16
+ opt_name=
+ while getopts "n:b:pidN:M:" opt; do
+ case "$opt" in
+ # -n: NETSPEC: type:method
+ n)
+ parse_netspec "${OPTARG}" || usage
+ nindex=$(expr $nindex + 1)
+ ;;
+ # -b: BLKSPEC: hostpath:mountpoint
+ b)
+ image=${OPTARG%:*}
+ mountpoint=${OPTARG#*:}
+ [ -n "$image" ] || usage
+ [ -n "$mountpoint" ] || usage
+ [ -f "$image" ] || err File $image does not exist
+ fstype=$(detect_fstype $image)
+ [ $? -ne 0 ] && err File $image: unknown fstype
+ vdev=hd$(echo $bindex | tr '[0-9]' '[a-j]')
+ conf_disk="${conf_disk}'file:$image,$vdev,rw',"
+ echo blk/${bindex}/type etfs >>${xenstore}
+ echo blk/${bindex}/fstype $fstype >>${xenstore}
+ echo blk/${bindex}/mountpoint $mountpoint\
+ >>${xenstore}
+ bindex=$(expr $bindex + 1)
+ ;;
+ # -p: Leave the domain paused after creation.
+ p)
+ opt_pause=1
+ ;;
+ # -i: Attach to domain console on startup.
+ i)
+ opt_interactive=1
+ ;;
+ # -d: Destroy domain on poweroff instead of preserving it.
+ d)
+ opt_destroy='on_poweroff="destroy"'
+ ;;
+ # -N: Override domain name.
+ N)
+ opt_name=${OPTARG}
+ ;;
+ # -M: Set domain memory.
+ M)
+ opt_mem=${OPTARG}
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ done
+ # Clean up vif and disk, xl does not like trailing commas.
+ conf_vif=$(echo ${conf_vif} | sed -e s/,\$//)
+ [ -n ${conf_vif} ] && conf_vif="vif=[${conf_vif}]"
+ conf_disk=$(echo ${conf_disk} | sed -e s/,\$//)
+ [ -n ${conf_disk} ] && conf_disk="disk=[${conf_disk}]"
+ # Remaining arguments belong to the application.
+ shift $((OPTIND-1))
+ [ "$1" = "--" ] && shift
+ name=${opt_name:-rumprun-$(basename $1)}
+ app=$(realpath $1)
+ shift
+ # Generate xl configuration file.
+ cat <<EOM >/tmp/xr.conf.$$
+kernel="${app}"
+name="${name}"
+vcpus=1
+memory=${opt_mem}
+on_crash="preserve"
+${opt_destroy}
+extra="$@"
+${conf_vif}
+${conf_disk}
+EOM
+ # Create the domain and leave it paused so that we can get its domid.
+ if ! xl create -p ${conf} >/dev/null; then
+ err xl create failed
+ fi
+ rm ${conf}
+ domid=$(xl domid ${name})
+ # Write provisioning information for domain to xenstore.
+ prefix=/local/domain/${domid}/rumprun
+ cat ${xenstore} | while read line; do
+ xenstore-write ${prefix}/${line}
+ done
+ rm ${xenstore}
+ # Go go go!
+ [ -z "$opt_pause" ] && xl unpause ${domid}
+ if [ -n "$opt_interactive" ]; then
+ exec xl console $domid
+ else
+ echo ${domid}
+ fi
+}
+
+if [ $# -lt 2 ]; then
+ usage
+fi
+if [ $(id -u) -ne 0 ]; then
+ err Must be root
+fi
+
+[ "$1" != "xen" ] && usage
+shift
+run_xen "$@"
+++ /dev/null
-#!/bin/sh
-#
-# Copyright (c) 2014 Martin Lucina. All Rights Reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-
-#
-# rumprun-xen: "driver" script for running rumprun-xen application stacks
-#
-
-err() {
- echo rumprun-xen: error: "$@" 1>&2
- exit 1
-}
-
-usage() {
- cat <<EOM
-usage: rumprun-xen [ -ipd ] [ -N NAME ] [ -M MEM ] [ -b BLKSPEC ] [ -n NETSPEC ] [ -- ] APP [ args ]
- APP is the rumprun-xen application to start
- args will be passed to the application command line
- -N NAME sets the domain's name to NAME, default is rumprun-APP
- -M MEM sets the domain's memory to MEM, default is 16
- -b BLKSPEC configures a block device as hostpath:mountpoint
- -n NETSPEC configures a network interface, using one of:
- inet:dhcp - IPv4 with DHCP
- inet:static:ADDR/MASK[:GATEWAY] - IPv4 with static IP
- -i attaches to domain console on startup
- -p creates the domain but leaves it paused
- -d destroys the domain on poweroff
-
- When run without -i the local domain id is printed to standard output
-EOM
- exit 1
-}
-
-# Detect the filesystem type of the image at $1.
-detect_fstype() {
- ftype=$(file -b $1)
- case $ftype in
- "Unix Fast File system"*)
- echo ffs
- return 0
- ;;
- "ISO 9660"*)
- echo cd9660
- return 0
- ;;
- *)
- echo unknown
- return 1
- ;;
- esac
-}
-
-cidr2mask()
-{
- # Number of args to shift, 255..255, first non-255 byte, zeroes
- set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
- [ $1 -gt 1 ] && shift $1 || shift
- echo ${1-0}.${2-0}.${3-0}.${4-0}
-}
-
-parse_netspec() {
- # Call ourselves recursively to split $@ on :
- if [ "$IFS" != ":" ]; then
- OLDIFS=$IFS
- IFS=: parse_netspec "$@"
- return $?
- else
- set -- $1
- IFS=$OLDIFS
- fi
- [ $# -lt 2 ] && usage
- iftype=$1
- ifmethod=$2
- [ "${iftype}" != "inet" ] && return 1
- conf_vif="${conf_vif}'',"
- case ${ifmethod} in
- dhcp)
- echo net/${nindex}/type inet >>${xenstore}
- echo net/${nindex}/method dhcp >>${xenstore}
- ;;
- static)
- ifaddr=${3%/*}
- ifmask=$(cidr2mask ${3#*/})
- ifgw=$4
- echo net/${nindex}/type inet >>${xenstore}
- echo net/${nindex}/method static >>${xenstore}
- echo net/${nindex}/addr ${ifaddr} >>${xenstore}
- echo net/${nindex}/netmask ${ifmask} >>${xenstore}
- [ -n "${ifgw}" ] &&
- echo net/${nindex}/gw ${ifgw} >>${xenstore}
- ;;
- *)
- return 1
- ;;
- esac
- return 0
-}
-
-# run: Generate configuration and run application stack.
-run() {
- conf=/tmp/xr.conf.$$
- xenstore=/tmp/xr.store.$$
- >${conf}
- >${xenstore}
- OPTIND=1
- nindex=0
- bindex=0
- conf_disk=
- conf_vif=
- opt_pause=
- opt_interactive=
- opt_destroy='on_poweroff="preserve"'
- opt_mem=16
- opt_name=
- while getopts "n:b:pidN:M:" opt; do
- case "$opt" in
- # -n: NETSPEC: type:method
- n)
- parse_netspec "${OPTARG}" || usage
- nindex=$(expr $nindex + 1)
- ;;
- # -b: BLKSPEC: hostpath:mountpoint
- b)
- image=${OPTARG%:*}
- mountpoint=${OPTARG#*:}
- [ -n "$image" ] || usage
- [ -n "$mountpoint" ] || usage
- [ -f "$image" ] || err File $image does not exist
- fstype=$(detect_fstype $image)
- [ $? -ne 0 ] && err File $image: unknown fstype
- vdev=hd$(echo $bindex | tr '[0-9]' '[a-j]')
- conf_disk="${conf_disk}'file:$image,$vdev,rw',"
- echo blk/${bindex}/type etfs >>${xenstore}
- echo blk/${bindex}/fstype $fstype >>${xenstore}
- echo blk/${bindex}/mountpoint $mountpoint\
- >>${xenstore}
- bindex=$(expr $bindex + 1)
- ;;
- # -p: Leave the domain paused after creation.
- p)
- opt_pause=1
- ;;
- # -i: Attach to domain console on startup.
- i)
- opt_interactive=1
- ;;
- # -d: Destroy domain on poweroff instead of preserving it.
- d)
- opt_destroy='on_poweroff="destroy"'
- ;;
- # -N: Override domain name.
- N)
- opt_name=${OPTARG}
- ;;
- # -M: Set domain memory.
- M)
- opt_mem=${OPTARG}
- ;;
- *)
- usage
- ;;
- esac
- done
- # Clean up vif and disk, xl does not like trailing commas.
- conf_vif=$(echo ${conf_vif} | sed -e s/,\$//)
- [ -n ${conf_vif} ] && conf_vif="vif=[${conf_vif}]"
- conf_disk=$(echo ${conf_disk} | sed -e s/,\$//)
- [ -n ${conf_disk} ] && conf_disk="disk=[${conf_disk}]"
- # Remaining arguments belong to the application.
- shift $((OPTIND-1))
- [ "$1" = "--" ] && shift
- name=${opt_name:-rumprun-$(basename $1)}
- app=$(realpath $1)
- shift
- # Generate xl configuration file.
- cat <<EOM >/tmp/xr.conf.$$
-kernel="${app}"
-name="${name}"
-vcpus=1
-memory=${opt_mem}
-on_crash="preserve"
-${opt_destroy}
-extra="$@"
-${conf_vif}
-${conf_disk}
-EOM
- # Create the domain and leave it paused so that we can get its domid.
- if ! xl create -p ${conf} >/dev/null; then
- err xl create failed
- fi
- rm ${conf}
- domid=$(xl domid ${name})
- # Write provisioning information for domain to xenstore.
- prefix=/local/domain/${domid}/rumprun
- cat ${xenstore} | while read line; do
- xenstore-write ${prefix}/${line}
- done
- rm ${xenstore}
- # Go go go!
- [ -z "$opt_pause" ] && xl unpause ${domid}
- if [ -n "$opt_interactive" ]; then
- exec xl console $domid
- else
- echo ${domid}
- fi
-}
-
-if [ $# -lt 1 ]; then
- usage
-fi
-if [ $(id -u) -ne 0 ]; then
- err Must be root
-fi
-
-run "$@"