How can I start VirtualBox with a non root user

Hello,

I want to start VB in headless mode. It is possibe to tell VB to run the VM with a useraccount, but i will asked after his password.
So it is not possible to run it in runnlevel 2 and 3.
Any ideas?

Regards

Krodon

You cannot run VirtualBox at runlevel 2 and 3 because it’s a GUI application and Xorg doesn’t normally run at those runlevels (unless you are on Ubuntu). To run VirtualBox as a user, you have to add this user to the vboxusers group.

Hello Nicolas,

it is possibe to run the VM"s in runnlevel 2 & 3. The GUI is only nessesary to install the OS. It make sense not to run the runnlevel 5 when a Server is running in the VM because more RAM can be used from the VM.
I have added the users to the group vboxusers. When I reboot the host, no VM will be started. If I try to do this manually with voxes start I will be asked for the passwords of this users. That"s why they will not be started during booting.

Regards

Krodon

All right. So you want to start a VM from the command line with:
VBoxHeadless --startvm vmname
You don’t need to provide a password for that. Or do you want to do it without having to login ?

If that’s what you want, create the file /etc/init.d/after.local with the following content:

#! /bin/sh
VBoxHeadless --startvm *vmname* &
  • replace vmname with the name of your VM.

make the file executable:
chmod 755 /etc/init.d/after.local

Your VM will be started automatically when the system boots. You won’t have to login or provide a password (if that’s what you want).

Hi,

after installing VirtualBox there is a script in /etc/init.d/vboxes wich is controlled by the Runnleveleditor.
This script I want to use. It reads the file vbox in /etc/sysconfig and has two variables, the VM Name and the username. Where do I have to modify it. This is the script:

#!/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[li]}
[/li]
  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[li]}
[/li]
  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[li]}
[/li]
  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


Regards

krodon

That script parses the variable VBOX_AUTOSTART (probably defined in /etc/sysconfig/vbox). This variable might have several values separated by spaces (I guess). Each value includes the VM Name and username separated by “;” (without spaces). If the username is not defined, the variable VBOX_USER is empty and then … it gets complicated… as far as I can tell from reading that script. I don’t have such a script though (in the PUEL version I’m using). It must come with the OSE version.

However if you turn off that service and run/usr/lib/virtualbox/VBoxHeadless (the command defined in VBOXMGR_BIN in the script ) from /etc/init.d/after.local, it might work.

Hello,

the file /etc/init.d/after.local do no exist on my machine, you are right i am using the ose version.

That script parses the variable VBOX_AUTOSTART (probably defined in /etc/sysconfig/vbox). This variable might have several values separated by spaces (I guess). Each value includes the VM Name and username separated by “;” (without spaces). If the username is not defined, the variable VBOX_USER is empty and then … it gets complicated… as far as I can tell from reading that script. I don’t have such a script though (in the PUEL version I’m using). It must come with the OSE version.

That is my vbox : VBOX_AUTOSTART=“xyz;root” that works if I modify it to: VBOX_AUTOSTART=“xyz;vm” it is not working. vm is in the group vboxusers.
Couls you please post your script.

Regards

Krodon

I don’t have such a script. I’m just discovering it in your post. The one I have (/etc/init.d/vboxdrv) serves another purpose (starting/recompiling the vboxdrv kernel module).

Well , the script (yours) look for the username in /etc/passwd. Of course this user has to exist. Then it runs the commands as “su thatUser”. Basically all you need is to be able to su without password. You can try to add the user to the wheel group and add the following line in /etc/pam.d/su:

auth sufficient pam_wheel.so trust use_uid

Be aware that it won’t make your system more secure.

  • I haven’t tested this solution. So you’ll tell me if it works.

Hello,

that is what I thoght the script is doing. I am not so safe in reading scripts.

Basically all you need is to be able to su without password. You can try to add the user to the wheel group and add the following line in /etc/pam.d/su:

auth sufficient pam_wheel.so trust use_uid

Be aware that it won’t make your system more secure.

I think you are right, it should be safer to run this machines with root, a su without password is very unsecure.

Regards

Krodon

I think something is wrong with the script /usr/sbin/rcvboxes. I’ve followed the set-up steps mentioned before and can start the vm from the command line with rcvboxes start. But the vm doesn’t come up during boot. I have added a sleep 5; instruction in the script where it starts the vm and this seems to have cured the problem. Instead of

su ${VBOX_USER$N]} -c "$VBOXHeadLess_BIN --startvm "${VBOX_NAME$N]}"" > /tmp/$PRG.$$ 2>&1 &

my line now looks like this:

su ${VBOX_USER$N]} -c "sleep 5; $VBOXHeadLess_BIN --startvm "${VBOX_NAME$N]}"" > /tmp/$PRG.$$ 2>&1 &