forked from pool/virtualbox
23e21a1790
OBS-URL: https://build.opensuse.org/package/show/Virtualization/virtualbox?expand=0&rev=1
308 lines
8.7 KiB
Bash
308 lines
8.7 KiB
Bash
#!/bin/sh
|
|
#
|
|
# chkconfig: - 91 35
|
|
# description: Starts and stops vbox autostart VMs.
|
|
# Based on
|
|
# http://www.amiryan.org/2009/11/04/virtualbox-init-d-service-autostart-scriptu
|
|
#
|
|
# By Richard Bos <rbos at opensuse dot org> - May 2010
|
|
|
|
### BEGIN INIT INFO
|
|
# Provides: vboxes
|
|
# Required-Start: $network vboxdrv $ALL
|
|
# Required-Stop: $network $named
|
|
# Default-Start: 3 5
|
|
# Default-Stop: 0 1 2 3 4 5 6
|
|
# Short-Description: Autostart Virtual Box VMs
|
|
# Description: Autostart Virtual Box VMs that are mentioned in /etc/sysconfig/vbox file
|
|
### END INIT INFO
|
|
|
|
# Shell functions sourced from /etc/rc.status:
|
|
# rc_check check and set local and overall rc status
|
|
# rc_status check and set local and overall rc status
|
|
# rc_status -v be verbose in local rc status and clear it afterwards
|
|
# rc_status -v -r ditto and clear both the local and overall rc status
|
|
# rc_status -s display "skipped" and exit with status 3
|
|
# rc_status -u display "unused" and exit with status 3
|
|
# rc_failed set local and overall rc status to failed
|
|
# rc_failed <num> set local and overall rc status to <num>
|
|
# rc_reset clear both the local and overall rc status
|
|
# rc_exit exit appropriate to overall rc status
|
|
# rc_active checks whether a service is activated by symlinks
|
|
. /etc/rc.status
|
|
|
|
# Reset status of this service
|
|
rc_reset
|
|
|
|
# Return values acc. to LSB for all commands but status:
|
|
# 0 - success
|
|
# 1 - generic or unspecified error
|
|
# 2 - invalid or excess argument(s)
|
|
# 3 - unimplemented feature (e.g. "reload")
|
|
# 4 - user had insufficient privileges
|
|
# 5 - program is not installed
|
|
# 6 - program is not configured
|
|
# 7 - program is not running
|
|
# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
|
|
#
|
|
# Note that starting an already running service, stopping
|
|
# or restarting a not-running service as well as the restart
|
|
# with force-reload (in case signaling is not supported) are
|
|
# considered a success.
|
|
|
|
VBOXMGR_BIN=/usr/lib/virtualbox/VBoxManage
|
|
if [[ ! -x $VBOXMGR_BIN ]]; then
|
|
echo "$VBOXMGR_BIN does not exist"
|
|
if [ "$1" = "stop" ]; then
|
|
exit 0;
|
|
else
|
|
exit 6
|
|
fi;
|
|
fi
|
|
|
|
VBOXHeadLess_BIN=/usr/lib/virtualbox/VBoxHeadless
|
|
if [[ ! -x $VBOXHeadLess_BIN ]]; then
|
|
echo "$VBOXHeadLess_BIN does not exist"
|
|
if [ "$1" = "start" ]; then
|
|
exit 6;
|
|
else
|
|
exit 0
|
|
fi;
|
|
fi
|
|
|
|
PRG=$(basename $0)
|
|
SERVICE="Virtualbox machines"
|
|
|
|
[ -r /etc/sysconfig/vbox ] && . /etc/sysconfig/vbox
|
|
|
|
start() {
|
|
|
|
N=1
|
|
for VBOX in $VBOX_AUTOSTART; do
|
|
|
|
if grep -q \; <<< "$VBOX"; then
|
|
VBOX_NAME[$N]=$(cut -d\; -f1 <<< "$VBOX")
|
|
VBOX_USER[$N]=$(cut -d\; -f2 <<< "$VBOX")
|
|
else
|
|
VBOX_NAME[$N]="$VBOX"
|
|
VBOX_USER[$N]=""
|
|
fi
|
|
N=$(($N+1))
|
|
done
|
|
|
|
VBOXES=${#VBOX_NAME[*]}
|
|
|
|
if [ $VBOXES -eq 0 ]; then
|
|
# The virtual machines have to be configured in /etc/sysconfig/vbox
|
|
echo -n "Starting $SERVICE: no virtual machines configured"
|
|
rc_status -u
|
|
else
|
|
|
|
N=1
|
|
echo -n "Starting $SERVICE: "
|
|
while [[ $N -le $VBOXES ]]; do
|
|
if [[ $N -lt $VBOXES ]]; then
|
|
echo -n "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}), "
|
|
else
|
|
echo "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]})"
|
|
fi
|
|
N=$(($N+1))
|
|
done
|
|
|
|
N=1
|
|
while [[ $N -le $VBOXES ]]; do
|
|
|
|
if [[ -n "${VBOX_USER[$N]}" ]]; then
|
|
|
|
if grep --quiet --word-regexp ${VBOX_USER[$N]} /etc/passwd; then
|
|
|
|
# The tag "Name:" occurs in multiple sections. Require at least 7 blanks
|
|
# with an additional flexible amount of spaces. At the moment of writing
|
|
# 13 spaces are needed.
|
|
VBOX_RUNNING=$(su ${VBOX_USER[$N]} -c "VBoxManage list --long runningvms" |
|
|
sed -n 's/^Name:[[:blank:]]\{7\} *//p' | grep -w "${VBOX_NAME[$N]}")
|
|
|
|
if [[ -z "$VBOX_RUNNING" ]]; then
|
|
|
|
VBOX_PRESENT=$(su ${VBOX_USER[$N]} -c "$VBOXMGR_BIN list --long vms" |
|
|
sed -n 's/^Name:[[:blank:]]\{7\} *//p' | grep -w "${VBOX_NAME[$N]}")
|
|
|
|
if [[ -n "$VBOX_PRESENT" ]]; then
|
|
|
|
# VBoxManage startvm does not result in a VM with working networking
|
|
# su ${VBOX_USER[$N]} -c "$VBOXMGR_BIN -q startvm "${VBOX_NAME[$N]}" -type headless" > /tmp/$PRG.$$ 2>&1
|
|
# Start virtualbox in Headless mode
|
|
su ${VBOX_USER[$N]} -c "$VBOXHeadLess_BIN --startvm "${VBOX_NAME[$N]}"" > /tmp/$PRG.$$ 2>&1 &
|
|
RETVAL=$?
|
|
|
|
if [[ $RETVAL == 0 ]]; then
|
|
echo -n " Starting virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]})"
|
|
rc_status -v -r
|
|
else
|
|
echo -n " Starting virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}) failed with the following output: "
|
|
rc_failed; rc_status -v -r
|
|
# Give the VBOXHeadLess_BIN some time to write the output file
|
|
sleep 2
|
|
cat /tmp/$PRG.$$
|
|
fi
|
|
|
|
rm /tmp/$PRG.$$
|
|
|
|
else
|
|
echo -n " Virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}) does not exist"
|
|
rc_status -s -r
|
|
fi
|
|
|
|
else
|
|
echo -n " Virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}) is already running"
|
|
rc_status -v -r
|
|
fi
|
|
|
|
else
|
|
echo -n " Virtual machine: ${VBOX_NAME[$N]}, VBOX_USER: ${VBOX_USER[$N]} does not exist"
|
|
rc_status -s -r
|
|
fi
|
|
|
|
else
|
|
echo -n " Virtual machine: ${VBOX_NAME[$N]}: VBOX_USER not configured"
|
|
rc_status -s -r
|
|
fi
|
|
|
|
N=$(($N+1))
|
|
done
|
|
fi
|
|
}
|
|
|
|
stop() {
|
|
|
|
for VBOX in $VBOX_AUTOSTART; do
|
|
|
|
if grep -q \; <<< "$VBOX"; then
|
|
VBOX_USER=$(cut -d\; -f2 <<< "$VBOX")
|
|
|
|
# Only add the user to the list, if not present yet
|
|
if ! grep -qw "$VBOX_USER" <<< "$VBOX_USERS"; then
|
|
VBOX_USERS="$VBOX_USERS $VBOX_USER"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
N=1
|
|
for VBOX_USER in $VBOX_USERS; do
|
|
VBOX_RUNNING=$(su $VBOX_USER -c "$VBOXMGR_BIN list --long runningvms" |
|
|
sed -n 's/^Name:[[:blank:]]\{7\} *//p')
|
|
for VBOX in $VBOX_RUNNING; do
|
|
VBOX_NAME[$N]="$VBOX"
|
|
VBOX_USER[$N]="$VBOX_USER"
|
|
N=$(($N+1))
|
|
done
|
|
done
|
|
|
|
VBOXES=${#VBOX_NAME[*]}
|
|
|
|
if [[ $VBOXES -eq 0 ]]; then
|
|
echo -n "Shutting down $SERVICE: no virtual machines running."
|
|
rc_status -s -r
|
|
else
|
|
|
|
echo -n "Shutting down $SERVICE: "
|
|
N=1
|
|
while [[ $N -le $VBOXES ]]; do
|
|
if [[ $N -lt $VBOXES ]]; then
|
|
echo -n "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}), "
|
|
else
|
|
echo "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]})"
|
|
fi
|
|
N=$(($N+1))
|
|
done
|
|
|
|
N=1
|
|
while [[ $N -le $VBOXES ]]; do
|
|
|
|
echo -n " ${VBOX_NAME[$N]}: "
|
|
su ${VBOX_USER[$N]} -c "$VBOXMGR_BIN -q controlvm "${VBOX_NAME[$N]}" savestate"
|
|
RETVAL=$?
|
|
|
|
echo -n " Shutting down virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]})"
|
|
if [[ $RETVAL == $? ]]; then
|
|
rc_status -v -r
|
|
else
|
|
rc_failed; rc_status -v -r
|
|
fi
|
|
N=$(($N+1))
|
|
done
|
|
fi
|
|
}
|
|
|
|
status() {
|
|
|
|
for VBOX in $VBOX_AUTOSTART; do
|
|
|
|
if grep -q \; <<< "$VBOX"; then
|
|
VBOX_USER=$(cut -d\; -f2 <<< "$VBOX")
|
|
|
|
# Only add the user to the list, if not present yet
|
|
if ! grep -qw "$VBOX_USER" <<< "$VBOX_USERS"; then
|
|
VBOX_USERS="$VBOX_USERS $VBOX_USER"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
N=1
|
|
for VBOX_USER in $VBOX_USERS; do
|
|
# The tag "Name:" occurs in multiple sections. Require at least 7 blanks
|
|
# with an additional flexible amount of spaces. At the moment of writing
|
|
# 13 spaces are needed.
|
|
VBOX_RUNNING=$(su $VBOX_USER -c "$VBOXMGR_BIN list --long runningvms" |
|
|
sed -n 's/^Name:[[:blank:]]\{7\} *//p')
|
|
for VBOX in $VBOX_RUNNING; do
|
|
VBOX_NAME[$N]="$VBOX"
|
|
VBOX_USER[$N]="$VBOX_USER"
|
|
N=$(($N+1))
|
|
done
|
|
done
|
|
|
|
VBOXES=${#VBOX_NAME[*]}
|
|
|
|
if [[ $VBOXES -eq 0 ]]; then
|
|
echo -n "$SERVICE: no virtual machines running."
|
|
rc_status -s -r
|
|
else
|
|
N=1
|
|
while [[ $N -le $VBOXES ]]; do
|
|
# The long sed line changes the output from:
|
|
# running (since 2010-04-25T14:51:57.373000000)
|
|
# to:
|
|
# running (since 2010-04-25 14:51:57)
|
|
#
|
|
STATE=$(su ${VBOX_USER[$N]} -c "$VBOXMGR_BIN showvminfo "${VBOX_NAME[$N]}"" |
|
|
sed -n 's/State: *//p' |
|
|
sed 's/\([0-9][0-9]\)\.[0-9]\{9\}/\1/;s/\([0-9][0-9]\)T\([0-9][0-9]\)/\1 \2/')
|
|
printf " %-56s %s" "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}):" "$STATE"
|
|
rc_status -v
|
|
N=$(($N+1))
|
|
done
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
start
|
|
;;
|
|
stop)
|
|
stop
|
|
;;
|
|
restart|force-reload)
|
|
stop
|
|
start
|
|
;;
|
|
status)
|
|
status
|
|
;;
|
|
*)
|
|
echo "Usage: $PRG {start|stop|restart|force-reload|status}" >&2
|
|
exit 3
|
|
;;
|
|
esac
|
|
|