13 votes

Comment faire fonctionner une machine VirtualBox en tant que service sous Windows XP ?

J'ai une machine VirtualBox avec Windows XP sur un hôte Windows XP.

Comment puis-je démarrer VirtualBox en tant que service, afin d'obtenir une machine virtuelle sous le capot, et ne pas avoir à démarrer VirtualBox pour accéder à ma machine virtuelle (via VNC depuis le réseau) ?

J'ai trouvé que VirtualBox Manage pourrait être la solution, mais comme je suis un débutant dans ce domaine, je ne sais pas par où commencer.

Des idées ?

10voto

Deborah Dumont Points 1

Notez que la réponse actuellement acceptée (Molly7244) démarre en fait la VM lorsque vous vous connectez - et non lorsque vous démarrez la machine. Il ne s'agit pas, en d'autres termes, d'un service.

Pour un service réel qui s'exécute au démarrage de la machine, j'utilise deux scripts (à l'origine de aquí ) en conjonction avec cygwin (cygrunsrv). Utilise le mode VBoxHeadless comme mentionné ailleurs sur cette page.

Le premier script exécute votre VM via VBoxHeadless ; il obtient le nom de la bonne VM à exécuter (et d'autres infos comme votre répertoire d'origine VBOX) à partir de variables d'environnement. Le second script installe un service pour une VM particulière (en utilisant cygrunsrv pour appeler le premier script avec les bonnes variables d'environnement définies). Enfin, il y a un troisième fichier qui contient les fonctions communes. Si vous mettez tout cela dans un répertoire ensemble, vous pouvez installer une nouvelle vm comme ceci :

$ VBOX_USER_HOME="/path/to/.VirtualBox/" vboxd-install MyVMName 3333

Puis démarrez le service avec "net start vboxd-MyVMName" ou "cygrunsrv -S vboxd-MyVMName".

Voici le script d'exécution de la VM, "vboxd" :

#!/bin/bash
# from http://forums.virtualbox.org/viewtopic.php?f=1&t=23536

##
## Manages start / stop of VirtualBox virtual machines
##

## load common functions
basedir="$(readlink -f $(dirname $0))"
source "$basedir/.libcommon" || exit 1

## parse arguments
parseArg vmName "$1" "$VBOXD_VM_NAME"
parseArg vmPort "$2" "$VBOXD_VM_PORT"

VBOX_INSTALL_PATH="$(cygpath "$VBOX_MSI_INSTALL_PATH")"

## define signal handler
function onHalt {
    warn "Stopping virtual machine '$vmName'"
    "$VBOX_INSTALL_PATH/VBoxManage" controlvm "$vmName" savestate
    exit 0
}

## install signal handler; cygrunsrv uses SIGTERM by default
trap 'onHalt' TERM

## hardcode this path if you like; it's required for VBox* utils to
## find the correct VirtualBox.xml config file and is usually set
## during a call to vboxd-install.
#export VBOX_USER_HOME="$USERPROFILE\\.VirtualBox"

## default VBoxHeadless port specification
portSpec="-e \"TCP/Ports=$vmPort\""

## determine vm state
info "Querying virtual machine '$vmName' state"
vmState=$( \
    "$VBOX_INSTALL_PATH/VBoxManage" showvminfo "$vmName" \
    | grep '^State:' \
    | sed 's/State: *//' )
info "Virtual machine '$vmName' is $vmState"

## if vm state is saved, we can't specify port without an exception,
## as port spec requires modification of the (immutable) saved machine
## state. See http://www.virtualbox.de/ticket/3609
if  [ "${vmState##saved}" != "$vmState" ]; then
    ## state is saved; clear port specification
    warn "Port specification is not allowed for saved vms"
    portSpec=""
fi

## start the VM
info "Starting virtual machine '$vmName' on port $vmPort"
"$VBOX_INSTALL_PATH/VBoxHeadless" -s "$vmName" $portSpec &

## record pid of VBoxHeadless child process and wait on it
pid="$!"
info "Waiting on VBoxHeadless child process $pid"
wait "$pid"

Et voici l'installateur script, "vboxd-install" :

#!/bin/bash
# http://forums.virtualbox.org/viewtopic.php?f=1&t=23536

##
## Registers a VirtualBox virtual machine to start as a service via cygrunsrv
##

## load common functions
basedir="$(readlink -f $(dirname $0))"
source "$basedir/.libcommon" || exit 1

## test for presence of cygrunsrv utility
if [ ! -x "$(which cygrunsrv)" ]; then
    die "Utility 'cygrunsrv' is not in path"
fi

## test VirtualBox configuration
if [ -z "$VBOX_USER_HOME" ]; then
    die "Required environment variable 'VBOX_USER_HOME' is undefined. " \
     "Please ensure this variable is set to point to the directory " \
     "containing your VirtualBox.xml configuration file."
fi
configFile=$(cygpath -u "$VBOX_USER_HOME\\VirtualBox.xml")
if [ ! -e "$configFile" ]; then
    die "VirtualBox configuration file '$(cygpath -w $configFile)' not found"
fi

## parse arguments
parseArg vmName "$1"
parseArg vmPort "$2"
parseArg vmUser "$3" "SYSTEM"

## if vmUser is not SYSTEM, update userSpec
userSpec="--interactive"
if [ "$vmUser" != "SYSTEM" ]; then
    ## "interactive" option disallowed when user is specified
    userSpec="--user \"$vmUser\""
fi

## install the service
cygrunsrv \
    --install "vboxd-$vmName" \
    --path "$basedir/vboxd" \
    --env "VBOXD_VM_NAME=$vmName" \
    --env "VBOXD_VM_PORT=$vmPort" \
    --env "VBOX_USER_HOME=$VBOX_USER_HOME" \
    --desc "VirtualBox virtual machine '$vmName' on port $vmPort" \
    $userSpec \
    --type auto \
    --termsig TERM \
    --shutsig TERM \
    --neverexits \
    --preshutdown \
    || die "Failed to install service"

Et, enfin, voici le script ".libcommon" référencé par les deux :

# -*-shell-script-*-
# from http://forums.virtualbox.org/viewtopic.php?f=1&t=23536

SCRIPT="$(basename $0)"
BASEDIR="$(readlink -f $(dirname $0))"
[ -z "$LOGLEVEL" ] && LOGLEVEL=2
[ -z "$LOGDATEFORMAT" ] && LOGDATEFORMAT="%Y-%m-%d %H:%M:%S "

function log {
    local now=""
    [ -n "$LOGDATEFORMAT" ] && now=$(date +"$LOGDATEFORMAT")
    echo "$SCRIPT $now$@" >&2
}

function debug {
    [ "$LOGLEVEL" -lt 3 ] && return
    log "[DEBUG] $@"
}

function info {
    [ "$LOGLEVEL" -lt 2 ] && return
    log "[INFO]  $@"
}

function warn {
    [ "$LOGLEVEL" -lt 1 ] && return
    log "[WARN]  $@"
}

function error {
    log "[ERROR] $@"
}

function die {
    error "$@"
    exit 1
}

function parseArg {
    local _name="$1"
    local _value="$2"
    local _default="$3"
    if [ -z "$_value" ]; then
        if [ -z "$_default" ]; then
            die "Required argument '$_name' is undefined"
        fi
     if [ "$_default" = "*EMPTY*" ]; then
         _value=""
     else
            _value="$_default"
     fi
    fi
    debug "$_name=\"$_value\""
    eval "$_name=\"$_value\""
}

Cette solution fonctionne très bien pour moi ; j'espère que vous aurez la même chance.

8voto

Tao Points 848

On dirait que la réponse la plus simple à ce stade est Service VBoxVMS . Je n'ai pas encore essayé, mais j'essaierai de me rappeler de venir ici et de mettre à jour la réponse si/quand je le fais.

4voto

RooiWillie Points 141

D'accord sur VBoxVMService. Il est très facile à mettre en place et semble bien fonctionner. Vous pouvez trouver un mode d'emploi sur sa mise en place ici :

http://www.Windows-noob.com/forums/index.php?/topic/4931-have-virtualbox-vms-start-as-a-service-on-a-Windows-host/

****EDIT**** Conformément à la demande ci-dessous, un résumé du lien. Bien que la solution ait fonctionné pour moi, le mérite en revient à Peter Upfold. http://peter.upfold.org.uk/

  • Installez Virtualbox et configurez la VM pour qu'elle accepte les sessions RDP.
  • Téléchargez et installez VBoxVmService en C:\vms. Il suffit de chercher VBoxVmService sur Google pour obtenir un lien de téléchargement (désolé, pas assez de représentants pour poster plus de 2 liens).
  • Modifier le fichier ini de VBoxVmService sous C:\vms :

[Paramètres]

ServiceName=VBoxVmService

VBOX_USER_HOME= C:\Users\Administrator.VirtualBox

RunAsUser=. \Administrator

UserPassword=enteryourpasswordhere

RunWebService=no

PauseShutdown=5000

[Vm0] VmName=nom du vm dans VirtualBox

ShutdownMethod=savestate

AutoStart=yes

  • Remplacez le VBOX_USER_HOME par le dossier .VirtualBox dans le répertoire personnel de l'utilisateur correct, ainsi que les directives RunAsUser et UserPassword, et définissez le nom de la machine virtuelle cible dans l'application VirtualBox dans VmName. Vous pouvez également ajouter des sections [Vmx] supplémentaires après [Vm0] avec d'autres machines virtuelles à démarrer lorsque la machine démarre.

  • Lorsque vous êtes satisfait de votre configuration, à partir d'une invite de commande accessible par l'administrateur, exécutez la commande suivante pour installer le service. Une fois le service installé, vous pouvez supprimer votre mot de passe utilisateur du fichier INI, car il est enregistré dans la configuration du service :

C:\vms\VmServiceControl.exe -i

  • Maintenant, vous devez redémarrer l'ordinateur avant d'essayer de lancer le service pour la première fois, ou il sera incapable de localiser les VMs.

  • Au redémarrage, le service devrait démarrer (sous réserve du délai 'Automatic (Delayed Start)') et vos VMs seront démarrées au démarrage.

2voto

Aaron Copley Points 468

C'est juste une autre option :

Utilisez la commande Windows intégrée 'sc' pour créer un service. En combinant cette commande avec 'vboxheadless', vous arriverez à vos fins.

Non testé avec vboxheadless spécifiquement, mais j'ai créé un service de test qui exécute calc.exe. Vous devriez faire quelque chose comme ça :

sc create servicenamehere start= auto binPath= "C:\path\to\vboxheadless.exe --startvm name"

Reportez-vous à la documentation de sc pour plus d'informations. Remarque : les espaces après le signe égal sont intentionnels.

1voto

Aaron Miller Points 9509

Si les scripts de vboxd vous posent autant de problèmes qu'à moi, vous pouvez essayer ceci ; c'est une solution plutôt simple, implémentée en Perl, qui fournit la même fonctionnalité. Plus précisément, la VM démarre avec le système (en supposant que le service est configuré pour démarrer automatiquement, ce qui est le cas par défaut), et s'arrête proprement lorsque le service est arrêté.

Les principales différences par rapport à la solution vboxd, outre le fait qu'elle est considérablement plus simple à gérer selon mon expérience, sont que ce script ne passe pas un paramètre de port VRDE à VBoxHeadless, et que l'arrêt de la VM est géré via "acpipowerbutton" plutôt que "savestate".

Si cela ne vous convient pas, il est assez facile de le modifier ; dans le premier cas, ajoutez '-e "TCP/Ports=[,port...]"' à la chaîne de la ligne de commande VBoxHeadless ($cmd), et dans le second cas, remplacez simplement "acpipowerbutton" par "savestate" dans le gestionnaire SIGTERM.

Voici le script en Perl :

 #!/usr/bin/perl
 # Service wrapper for VirtualBox VM.

 use strict;

 # Windows-style path pointing to your VirtualBox home directory
 # (i.e., where your VirtualBox.xml lives)
 my $vboxhome = 'c:\\Documents and Settings\\Aaron\\.VirtualBox';

 # Cygwin path pointing to the VirtualBox install directory
 my $vboxpath = '/cygdrive/c/Program Files/Oracle/VirtualBox';

 # Name or UUID of your virtual machine
 my $vmname = '{83dfb4b1-4243-4a07-9d37-9df5573792d8}';

 $ENV{'VBOX_USER_HOME'} = $vboxhome;

 my $exit_handler = sub {
    print "Caught SIGTERM; shutting down VM.\n";
    exec("'$vboxpath/VBoxManage.exe' controlvm $vmname acpipowerbutton");
 };

 $SIG{TERM} = $exit_handler;

 print "[debug] pid $$\n";

 # Command line for VBoxHeadless - add your VRDE port here if you want one
 my $cmd = "'$vboxpath/VBoxHeadless.exe' --startvm $vmname 2>&1 1>/dev/null";
 print "[debug] $cmd\n";
 system($cmd);

 print "VM died unexpectedly; exiting.\n";

Et voici la ligne de commande cygrunsrv que j'ai utilisée pour installer le service Windows :

 cygrunsrv --install '<service-name>' --desc '<description>' \
  --path '/usr/bin/perl' --args '<full-path-to-service-script>' \
  --chdir '<path-to-service-script-dir>' --termsig TERM --shutsig TERM \
  --preshutdown --interactive

A partir de là, il devrait juste être question de lancer 'sc start <service-name>', et vous devriez être prêt à partir -- rappelez-vous que, par défaut, les services cygrunsrv enregistrent dans /var/log/<service-name>.log, donc si quelque chose se comporte mal, c'est le premier endroit où chercher la raison.

Une chose à garder à l'esprit est que, lorsque vous exécutez la VM de cette façon, elle sera exécutée sous le compte SYSTEM intégré, plutôt que sous votre propre compte. Ceci étant, vous ne pourrez pas administrer la VM via la console VirtualBox pendant qu'elle fonctionne comme un service ; elle semblera être dans l'état "Powered off", et vous ne pourrez pas accéder à ses paramètres. (Essayer de mettre en marche la VM alors qu'elle fonctionne comme un service est non recommandé -- Je ne sais pas ce qui se passera, mais au mieux, ce sera un no-op, et au pire, ça hose votre VM). Si vous avez besoin de modifier les paramètres de la VM ou d'accéder à la console, arrêtez d'abord le service (et attendez que VBoxHeadless.exe se termine), puis configurez-le ou allumez-le dans la console VirtualBox comme vous le feriez normalement.

Vous pourriez probablement résoudre ce problème en installant un deuxième service interactif pour exécuter la console VirtualBox ; puisque cela exécuterait la console sous le compte SYSTEM également, il serait très probablement en mesure de voir et de gérer la VM en cours d'exécution. Je n'ai pas eu besoin de faire cela moi-même, donc je ne suis pas sûr que cela fonctionnerait, mais je ne vois pas pourquoi cela ne fonctionnerait pas. (Si vous essayez, j'apprécierais un commentaire à cette réponse, me faisant savoir comment cela a fonctionné pour vous. Merci)

J'espère que cela vous aidera !

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X