forked from pool/virtualbox
f0824ee78b
Hi Larry, I finally put some effort in fixing the VM autostart mechanics, that are terminally broken in the current package (due to the way, systemd interacts with Sys-V init scripts, stop operations aren't executed most of the time, because it lost track of the state...). With these changes, I'm able to reliably start/stop all VMs on hosts ranging from 13.2 to 42.2. I'm confident, this will improve for all systemd based systems, i.o.w all those systems we care about.. It resembles pretty much the same scheme, vboxdrv is using already. Give it a try. - reorganize vbox autostart, coping with systemd: - add /usr/lib/virtualbox/vboxes.sh (based on /etc/init.d/vboxes) - add /usr/lib/systemd/system/vboxes.service - remove /etc/init.d/vboxes OBS-URL: https://build.opensuse.org/request/show/514488 OBS-URL: https://build.opensuse.org/package/show/Virtualization/virtualbox?expand=0&rev=357
228 lines
5.8 KiB
Bash
228 lines
5.8 KiB
Bash
#!/bin/sh
|
|
#
|
|
# 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
|
|
#
|
|
# Converted to standalone script for systemd environments
|
|
#
|
|
# By Hans-Peter jansen <hpj at urpla dot net> - July 2017
|
|
#
|
|
|
|
PRG=$(basename $0)
|
|
SERVICE="Virtualbox machines"
|
|
|
|
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
|
|
|
|
# read config file
|
|
[ -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 "Starting $SERVICE: no virtual machines configured"
|
|
else
|
|
|
|
N=1
|
|
echo "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 getent passwd ${VBOX_USER[$N]} &>/dev/null; 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 "$VBOXMGR_BIN 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
|
|
|
|
# start VM with VBoxManage in headless mode
|
|
# unlike VBoxHeadless, VBoxManage waits until VM is running
|
|
su ${VBOX_USER[$N]} -c "$VBOXMGR_BIN -q startvm "${VBOX_NAME[$N]}" -type headless" &> /tmp/$PRG.$$
|
|
RETVAL=$?
|
|
|
|
if [[ $RETVAL != 0 ]]; then
|
|
echo "Starting virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}) failed: "
|
|
cat /tmp/$PRG.$$
|
|
fi
|
|
|
|
rm /tmp/$PRG.$$
|
|
|
|
else
|
|
echo "Virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}) does not exist"
|
|
fi
|
|
|
|
else
|
|
echo "Virtual machine: ${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}) is already running"
|
|
fi
|
|
|
|
else
|
|
echo "Virtual machine: ${VBOX_NAME[$N]}, VBOX_USER: ${VBOX_USER[$N]} does not exist"
|
|
fi
|
|
|
|
else
|
|
echo "Virtual machine: ${VBOX_NAME[$N]}: VBOX_USER not configured"
|
|
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 "Shutting down $SERVICE: no virtual machines running."
|
|
else
|
|
|
|
echo "Shutting down $SERVICE: "
|
|
N=1
|
|
while [[ $N -le $VBOXES ]]; do
|
|
echo -n "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}): "
|
|
su ${VBOX_USER[$N]} -c "$VBOXMGR_BIN -q controlvm ${VBOX_NAME[$N]} savestate"
|
|
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 "$SERVICE: no virtual machines running."
|
|
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\n" "${VBOX_NAME[$N]} (user: ${VBOX_USER[$N]}):" "$STATE"
|
|
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
|