Novell Home

Running a VMware Virtual Machine as a Service in OES Linux

Novell Cool Solutions: AppNote
By Andrew Grant

Digg This - Slashdot This

Posted: 15 Jun 2006
 

Virtualisation is something that has really taken off over the past few years. Here's a way to run virtual machine(s) in a similar way to a service using freely available software. The console of this virtual machine runs in its own X session.

Objectives:

  • Install VMware player on OES Linux
  • Setting up the VMware machine
  • Configure the init script to start and stop the virtual machine
  • Get the script to run at the right runlevels

Pre-requisites:

  • You already have a VMware machine ready to use (created with VMware Server Console)
  • The VMware machine is assumed to be Linux / Unix based with SSH installed
  • The VMware player .rpm (http://www.vmware.com/download/)
  • OES Linux machine to act as a host
  • Host OES machine has an X window system configured (i.e. You get a graphical login screen when the machine boots)

Contents:

Installing the VMware player on OES Linux

The VMware player will need to compile certain modules in order to work on OES Linux, this will require the kernel source being present.

  1. Run the YaST2 control centre and launch Software?'Install and Remove Software'
  2. Set the Filter to 'Selections' and ensure that 'C/C++Compiler and Tools' is ticked
  3. Change the filter to 'Search' and the search for 'Kernel'. Ensure that kernel source is ticked.
  1. Click 'Accept' and allow the software to install.

Once this is done, open red-carpet and ensure that the kernel source and other updates have been applied to the system. If the kernel has been updated along with the source, you will need to reboot the server before proceeding.

Now that the installation pre-requisites have installed, we can get on with installing the actual application.

Installing the VMware player:

  1. Open a terminal
  2. Change to the directory where the vmware-player is located
  3. Run 'rpm -i Vmware-player-1.0.1-19317.i386.rpm'
  4. Once this is installed, run '/usr/bin/vmware-config.pl'
  5. Accept the License agreement
  6. Use MIME icons default (/usr/share/icons)
  7. Use Default desktop menu entry directory (/usr/share/applications)
  8. Use Default icons directory (/usr/share/pixmaps)
  9. Enter yes when asked if you want the player to recompile modules
  10. Use Default kernel source directory (/usr/src/linux/include)
  11. Use Default C header files directory (/lib/modules/2.6.5-7.252-smp/build/include)
  12. Select 'yes' You definitely want networking for the VMPlayer (a bridge will be created)
  13. Choose whether you want NAT networking (yes)
  14. Select 'yes' to allow probing for an unused private subnet
  15. Select 'no' You probably only want to use one NAT network
  16. Select 'yes' to allow host only networking (gives you more options)
  17. Select 'yes' to allow probing for unused private subnet
  18. Select 'no' you don't want to configure another network
  19. The installer will do some compiling and configuring
  20. Decide whether you want to Google searchbar in the border of the VMplayer window
    All done! The installer will show you the path to the vmplayer executable.

Setting up the VMware machine

In this section we'll deal with getting a VMware machine into a state where it can be controlled from an init script. Because the VMware player can't given a command to shutdown the virtual machine cleanly, we'll use SSH to initiate a shutdown command on the virtual machine.

In this scenario the host machine is called Parrot and the virtual (parasite) machine is called Tapeworm :-)

To do this we'll need to set up a trust relationship between the host and virtual machine using SSH keys.

Creating the SSH keys on the host machine (Parrot):

As root, run "ssh-keygen -t dsa" This will create a set of keys that you can use to automatically run commands and log into the virtual machine.

Note: Leave the passwords blank!

Setting up the VMware machine and locking down its SSD daemon:

  1. Copy the contents of the VMware machine from where you created it (you can't have server and player on the same machine) to a local directory where you have enough space (I'm using /var, but /usr is also suitable).


  2. Log into X and open your virtual machine with the vmplayer. If you're not root, don't forget to set the file permissions on your virtual machine directory so that you can access it as a user.


  3. On the host machine as root: Change to the directory where you created your SSH keys (we used /root/.ssh)


  4. Create a copy of the public key by running "cp id_dsa.pub parrot.id_dsa.pub" as we don't want to get the keyfiles confused.
  1. Now scp the file to the virtual machine by running "scp parrot.id_dsa.pub root@tapeworm:/root". Use the name of your host machine instead of Parrot.


  2. Log into the virtual machine, we will finish with the SSH keys and then configure its SSH daemon.



  3. Append the contents of your public key to the authorized_keys files by running cat parrot.id_dsa.pub >> /root/.ssh/authorized_keys



  4. Now to configure and lock down the SSH daemon. Still on the Virtual Machine, Edit /etc/ssh/sshd_config, remove the comment before 'PermitRootLogin' and change the option to 'without-password'. This only allows SSH keys to log into root using SSH keys which are pretty secure.
    Note: Incidently, this should be the default setting for all SSH servers, the default of allowing direct password based root login is a bad idea!



  5. Restart the SSH daemon by running '/etc/rc.d/sshd restart'


  6. To test, as root from the host machine (Virtual Machine must still be running) and run the command "ssh root@tapeworm", you should be abe to log in without a password.
    Note: The test >has< to work otherwise the script won't be able to close your virtual machine.

Configure the init script to start and stop the virtual machine

Now that the host machine can SSH into the virtual machine without human interaction, we can implement the init script that will launch and cleanly shutdown the virtual machine as needed.

Attempts have been made to script bullet resistent the script by making it be able to handle scenarios involving the VMware machine crashing or being killed and the host machine being reset etc. The script also produces the right error messages if the script is fired before the virtual machines SSH daemon is operational.

Create a file in /etc/init.d and call it vmware-virtual.machine.name (i.e. Mine is called vmware-tapeworm). You will need to customise the variables VMMachine, VMDir, VMFile, VMDisplay, VMTerminal, VMDns and VMShutdownTimer to your setup. The meaning of each variable is given in the comment section at the top of the file.

Download the file here: vmware-tapeworm

Use this script:

#! /bin/bash
#
# Author: Andrew Grant
# Date: 12/06/2006
#
### BEGIN INIT INFO
# Provides:       vmware-player
# Required-Start: $network VMware xdm
# Required-Stop: $network VMware
# Default-Start:  5
# Default-Stop:   0 1 2 6
# Description:    Run a VMware machine as a service
### END INIT INFO

# Variable explanations:
# VMMachine = Friendly name of virtual machine
# VMDir = Directory path of Virtual Machine
# VMFile = Virtual Machine Configuration File (.vmx file)
# VMDisplay = Virtual Machine Display (start with 1)
# VMTerminal = Virtual Machine Terminal to use (start with 8)
# VMDns = DNS name assigned to the Virtual Machine
# VMShutdownTimer = Time to wait for VM shutdown (in seconds)
# 5 Minutes is normally more than adequate
#
# Each virtual machine must have its own X display and terminal. 
# Assuming a standard installation that runs X on display 0 and 
# vt7, your first virtual machine will use:
# X display 1 and vt 8
# The second:
# X Display 2 and vt 9
# and so on.

# Set this to what you need
VMMachine="tapeworm"
VMDir="/var/vmserver/Novell Open Enterprise Server"
VMFile="SUSE Linux Enterprise Server.vmx"
VMDisplay="1"
VMTerminal="8"
VMDnsName="tapeworm.ru.ac.za"
VMShutdownTimer="300"

# These shouldn't need to be changed
VMFullName="$VMDir/$VMFile"
VMBin="/usr/lib/vmware/bin/vmplayer"
PID_FILE="/var/run/vmware-$VMMachine.pid"

# Set paths
export PATH=/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/opt/gnome/bin:/usr/lib/java/bin

. /etc/rc.status
rc_reset

case "$1" in
      start)
            echo -n "Starting Virtual Machine ${VMMachine}"
            if [ ! -f "${VMFullName}" ]; then
                  echo -n >&2 "Virtual Machine not found, ${VMFile} does not exist. "
                  rc_status -s
                  exit 6
            fi
            checkproc -p ${PID_FILE} ${VMBin}
            case "$?" in
                  0) echo "- Warning: daemon already running. " ;;
                  1) echo "- Warning: ${PID_FILE} exists. " ;;
            esac
            if [ -f "/tmp/.X${VMDisplay}-lock" ]; then
                  echo "Stale X lock for display ${VMDisplay} found, removing..."
                  rm "/tmp/.X${VMDisplay}-lock"
            fi
            startproc -p ${PID_FILE} /usr/X11R6/bin/xinit /usr/bin/vmplayer "${VMFullName}" -- :${VMDisplay} vt${VMTerminal} > /dev/null &
            rc_status -v
            ;;
      stop)
            checkproc -p ${PID_FILE} ${VMBin}
            VMStatus=${?}
                case "$VMStatus" in
                        1) 
                    echo "- Warning: Virtual Machine ${VMMachine} not running but ${PID_FILE} exists. "
                    exit 1
                    ;;
                        3) 
                    echo "- Warning: Virtual Machine ${VMMachine} not running. "
                    exit 1
                    ;;
                esac
            echo -n "Shutting down Virtual Machine ${VMMachine} - this will take a moment..."
            /usr/bin/ssh root@${VMDnsName} '/sbin/shutdown -h now'
            if [ "$?" = 1 ] ; then
                  echo "- Warning: Unable to contact Virtual Machine ${VMMachine} "
                  exit 1
            fi
            timer=0
            while [ $? != 3 ]
            do
                  /bin/sleep 1      
                  let timer=timer+1
                  if [ "$timer" = "$VMShutdownTimer" ] ; then
                        echo "- Warning: Shutdown of Virtual Machine ${VMMachine} failed (took too long)"
                        exit 1
                  fi
            checkproc -p ${PID_FILE} ${VMBin}
            done
            echo "Shutdown of ${VMMachine} complete."
            rc_status -v
            ;;
      restart)
            $0 stop
            $0 start
            rc_status
            ;;
      status)
            echo -n "Checking for Virtual Machine ${VMMachine}"
            checkproc -p ${PID_FILE} ${VMBin}
            rc_status -v
            ;;
      *)
            echo "Usage: $0 {start|stop|status|restart}"
            exit 1
            ;;
esac
rc_exit
 

Once you have your script you need to make it executable. Run "chmod +x /etc/init.d/vmware-tapeworm" (change the name of the file to whatever you called yours!).

Testing your script:

If all goes well you should be able to start, stop and get status of your virtual machine like any other service. It should open up in its own X display and everything should close when a shutdown is initiated. When you start the Virtual Machine you will get some output from the X server.

Note: If you try and shutdown your virtual machine before its SSH daemon is operational, it will tell you that it's unavailable.

Get the script to run at the right runlevels

Now that we have a manageable virtual machine and a way to easily control it we now need to get the host machine to handle it. Order is important here, but fortunately the init script contains info that will get it started and stopped at the right place.

  1. On the host machine (parrot), open a terminal as root.
  2. We now run insserv to configure the start and stop options for us. This is done by running "insserv -v /etc/init.d/vmware-tapeworm

The Virtual Machine should now start and stop as the server does.

On the todo list — comments and contributions welcome

Make the shutdown mechanism OS independent (on the virtual machine). There has to be a way to send a ACPI power off command to the player, this would remove the dependence on SSH. Each virtual machine requires its own init script. There are plans to change it to use only one and source the settings from small easy to edit files located elsewhere.

References:


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell