Seite 1 von 1

VMware Backup Skript mit Perl

Verfasst: 12.01.2007, 14:05
von dremke
Hallo zusammen,

für interessierte hier mein Skript zum sichern der Images mit Perl:

Code: Alles auswählen

#!/usr/bin/perl

BEGIN {
   if ($^O eq "MSWin32") {
      @INC = ("./5.00503/lib",
           "./5.00503/lib/MSWin32-x86/auto",
           "./5.00503/lib/MSWin32-x86",
           "./site/5.00503/lib",
           "./site/5.00503/lib/MSWin32-x86/auto",
           "./site/5.00503/lib/MSWin32-x86");
   } else {
      push(@INC,
          ("/usr/lib/perl5/site_perl/5.005/i386-linux",
           "/usr/lib/perl5/5.00503",
           "."));
   }
}

use VMware::Control;
use VMware::Control::Server;
use VMware::Control::VM;
use Time::HiRes qw(gettimeofday);
use warnings;

# Setzen der Variablen:
my $port = 902;
my $op = "suspend_to_disk";
my $ziel = "/export/vmware";
my $passwordfile = "/root/vmware.pw";
my $user = "root";
use vars qw($passwd @wakeup $cfg_path $vm $server $errorNumber $errorString);
my $i = 0;

sub usage() {
        print STDERR "Aufruf: vmware-backup.pl Servername\n";
exit(1);

}
usage() unless (scalar(@ARGV) == 1);
my $serverName = $ARGV[0];


# gespeichertes Passwort aus Datei auslesen:
unless (open (FILE, "$passwordfile")) {
        die "Fehler: Kann $passwordfile nicht öffnen: $!\n";
        }
        else {
                $passwd = <FILE>; # erste zeile einlesen
                close (FILE); # zeilenumbruch am ende bei bedarf abschneiden
                chomp($passwd);
        }

        # Eine Verbindung zum Server wird aufgebaut:
        &aufbau;

        # Holt eine Liste mit allen registrierten VMware-Images auf dem Server:
        my @list = $server->enumerate();

        # ...nur zum debugen:       #print "\nListe der Images auf $serverName:\n\n";
        #print "$_\n" foreach (@list);
        #print "\n...\n\n";

        foreach (@list) {
                $cfg_path=$_;

                &verbinden;

                # Der aktuelle Status des Images wird ermittelt:
                my $curState = $vm->get("Status.power");
                if ($curState eq "stuck") {
                        print STDERR "Die Virtuelle Maschine $cfg_path wartet auf eine Eingabe. Abbruch...\n";
                        exit(0);
                }

                # ...ermitteln des Status geht weiter:
                if (!$curState) {
                my ($errorNumber, $errorString) = $vm->get_last_error();
                die  "Fehler ermitteln des Status von Image $vm $errorNumber: $errorString\n";
                }

                # ...zum debugen:
                # print "$cfg_path hat den Status: $curState\n";

                # Ab hier beginnt der eigentliche Backup-Teil:
                # Ist das Image aktiv, muss es zuerst mal gestoppt werden:
                if ($curState eq "on") {
                        print "\n$cfg_path wird heruntergefahren...\n\n";

                        # Alle laufenden Images werden zum spaeteren starten in ein array gespeichert:
                        $wakeup[$i] = $cfg_path;

                        # zu dedug zwecken.
                        # print "$wakeup[$i]\n\n";
                        $i++;

                        # Das Image wird in den Suspend-Modus geschickt:
                        # *(1)* sorgt für Nachdruck, bei *(0)* würden nur Images mit aktuellen VMware-Tools herunterfahren:
                        my $ok = $vm->$op(1);

                        unless ($ok) {
                        my ($err, $errstr) = $vm->get_last_error();
                        cleanup();
                        print STDERR "Fehler beim trennen: ($err): $errstr\n";
                        }
                }
}

$server->disconnect();

# Hier wird der Kopiervorgang fuer das Image gestartet:
my $vor = gettimeofday();


system("echo kopiere...");
if (system("rsync -a --delete --password-file=$passwordfile $serverName:\:vmware $ziel/$serverName")) {
               warn "Fehler beim kopieren der Images: $!\n";
}

print "\n\nKopieren ist abgschlossen.\n\n";
my $nach = gettimeofday() - $vor;
$nach = $nach/60;
my $diff = sprintf("%.2f", $nach);
print "\nDas kopieren hat $diff Minuten gedauert.\n\n";

print "Die folgenden Images werden wieder gestartet:\n";
print "$_\n" foreach (@wakeup);
print "\n\n";

foreach (@wakeup) {
        $cfg_path=$_;
        &verbinden;
        my $ok = $vm->start(1);

        unless ($ok) {
        my ($err, $errstr) = $vm->get_last_error();
        cleanup();
        print STDERR "Fehler beim starten des Images $_ ($err): $errstr\n";
        }
}


if ($@) {
        print "Es ist ein Fehler aufgetreten: $@";
        } else {
                 print "Backup abgeschlossen!\n\n";
}

# Beendet die Verbindung zum Server:
$server->disconnect();

sub aufbau {
        # Ein neues Objekt *VMware::Control::Server* wird für die Verbindung zum Server erstellt:
        $server = VMware::Control::Server::new($serverName,$port,$user,$passwd);

        # Eine Verbindung zum Remote-Server wird aufgebaut:
        if (!$server->connect()) {
        ($errorNumber, $errorString) = $server->get_last_error();
        die "Keine Verbindung zum Server: Fehler $errorNumber: $errorString\n";
        }
}

sub verbinden {
        # Das Objekt *VMware::Control::VM* wird für die Virtuelle Maschine *cfg_path* erstellt:
        $vm = VMware::Control::VM::new($server, $cfg_path);
                if (!$vm->connect()) {
                        ($errorNumber, $errorString ) = $vm->get_last_error();
                die  "Keine Verbindung zum Image: Fehler $errorNumber: $errorString\n";
        }
}

# Trennt alle verbunden Objekte:
sub cleanup {
        if ($vm) {
                $vm->disconnect();}
        if ($server) {
                $server->disconnect();
        }
}


Gruß,
Daniel

Verfasst: 17.01.2007, 10:56
von heinzelrumpel
Hi,

eine Beschreibung zu dem Skript wäre noch ganz hilfreich, also ob z.B das Skript die Guests automatisch herunterfährt etc.

Gruß

Verfasst: 17.01.2007, 11:26
von dremke
Steht eigentlich alles in den Kommentaren. Die Images werden supended(wenn sie laufen) und dann mit rsync auf in das Zielverzeichnis kopiert.

Gruß,
Daniel

schaut sehr gut aus

Verfasst: 13.04.2007, 09:44
von sven.xxxxxx
Hallo Daniel,

das Skript schaut sehr gut aus, ich will es in den nächsten Tagen ausprobieren.
Was muss den genau in die Passwort-File rein, wahrscheinlich "nur" das Root-Passwort.
Funktioniert das Skript bei dir soweit problemlos?

Bin noch relativ neu in Perl, dewegen.

Wenn das gehen würde, wäre das eine echte Hilfe und ein super Skript!

Grüße
Sven

Verfasst: 18.04.2007, 10:25
von sven.xxxxxx
hehe

Verfasst: 18.04.2007, 14:54
von dremke
Hallo Sven,

Was muss den genau in die Passwort-File rein, wahrscheinlich "nur" das Root-Passwort.


in der Datei steht das Passwort für den rsync Daemon. Der Benutzername und das Passwort zum suspenden der Image wird dem Skript übergeben(siehe unten).

Funktioniert das Skript bei dir soweit problemlos?


Bei mir läuft es Problemlos. Ich sichere so die Images von allen meinen VMware Servern(Windows und Linux). Voreraussetzung ist halt das auf allen Maschine der rsync Daemon läuft.

Gruß,
Daniel

Code: Alles auswählen

#!/usr/bin/perl

BEGIN {
   if ($^O eq "MSWin32") {
      @INC = ("./5.00503/lib",
           "./5.00503/lib/MSWin32-x86/auto",
           "./5.00503/lib/MSWin32-x86",
           "./site/5.00503/lib",
           "./site/5.00503/lib/MSWin32-x86/auto",
           "./site/5.00503/lib/MSWin32-x86");
   } else {
      push(@INC,
          ("/usr/lib/perl5/site_perl/5.005/i386-linux",
           "/usr/lib/perl5/5.00503",
           "."));
   }
}

use VMware::Control;
use VMware::Control::Server;
use VMware::Control::VM;
use Time::HiRes qw(gettimeofday);
use warnings;

# Setzen der Variablen:
my $port = 902;
my $op = "suspend_to_disk";
my $ziel = "/export/vmware";
my $passwordfile = "/root/vmware.pw";
use vars qw(@wakeup $cfg_path $vm $server $errorNumber $errorString);
my $i = 0;

sub usage() {
   print STDERR "Aufruf: vmware-backup.pl Servername Benutzer Passwort\n";
exit(1);

}
usage() unless (scalar(@ARGV) == 3);
my $serverName = $ARGV[0];
my $user = $ARGV[1];
my $passwd = $ARGV[2];


# Eine Verbindung zum Server wird aufgebaut:
&aufbau;

   # Holt eine Liste mit allen registrierten VMware-Images auf dem Server:
   my @list = $server->enumerate();

   # ...nur zum debugen:
   #print "\nListe der Images auf $serverName:\n\n";
   #print "$_\n" foreach (@list);
   #print "\n...\n\n";

   foreach (@list) {
      $cfg_path=$_;

      &verbinden;

      # Der aktuelle Status des Images wird ermittelt:
      my $curState = $vm->get("Status.power");
      if ($curState eq "stuck") {
         print STDERR "Die Virtuelle Maschine $cfg_path wartet auf eine Eingabe. Abbruch...\n";
         exit(0);
      }

      # ...ermitteln des Status geht weiter:
      if (!$curState) {
         my ($errorNumber, $errorString) = $vm->get_last_error();
         die  "Fehler ermitteln des Status von Image $vm $errorNumber: $errorString\n";
      }

      # ...zum debugen:
      # print "$cfg_path hat den Status: $curState\n";

      # Ab hier beginnt der eigentliche Backup-Teil:
      # Ist das Image aktiv, muss es zuerst mal gestoppt werden:
      if ($curState eq "on") {
         print "$cfg_path wird heruntergefahren...\n";

         # Alle laufenden Images werden zum spaeteren starten in ein array gespeichert:
         $wakeup[$i] = $cfg_path;

         # zu dedug zwecken.
         # print "$wakeup[$i]\n\n";
         $i++;

         # Das Image wird in den Suspend-Modus geschickt:
         # *(1)* sorgt für Nachdruck, bei *(0)* würden nur Images mit aktuellen VMware-Tools herunterfahren:
         my $ok = $vm->$op(1);

         unless ($ok) {
            my ($err, $errstr) = $vm->get_last_error();
            cleanup();
            print STDERR "Fehler beim trennen: ($err): $errstr\n";
         }
      }
}

$server->disconnect();

# Hier wird der Kopiervorgang fuer das Image gestartet:
my $vor = gettimeofday();
system("echo kopiere...");
if (system("rsync -a --delete --password-file=$passwordfile root\@$serverName:\:vmware $ziel/$serverName")) {
      warn "Fehler beim kopieren der Images: $!\n";
}

print "\n\nKopieren ist abgschlossen.\n\n";
my $nach = gettimeofday() - $vor;
$nach = $nach/60;
my $diff = sprintf("%.2f", $nach);
print "\nDas kopieren hat $diff Minuten gedauert.\n\n";

print "Die folgenden Images werden wieder gestartet:\n";
print "$_\n" foreach (@wakeup);
print "\n\n";

foreach (@wakeup) {
   $cfg_path=$_;
   &verbinden;
   my $ok = $vm->start(1);

   unless ($ok) {
   my ($err, $errstr) = $vm->get_last_error();
      cleanup();
        print STDERR "Fehler beim starten des Images $_ ($err): $errstr\n";
      }
}


if ($@) {
   print "Es ist ein Fehler aufgetreten: $@";
   } else {
       print "Backup abgeschlossen!\n\n";
}

# Beendet die Verbindung zum Server:
$server->disconnect();

sub aufbau {
   # Ein neues Objekt *VMware::Control::Server* wird für die Verbindung zum Server erstellt:
   $server = VMware::Control::Server::new($serverName,$port,$user,$passwd);

   # Eine Verbindung zum Remote-Server wird aufgebaut:
   if (!$server->connect()) {
      ($errorNumber, $errorString) = $server->get_last_error();
      die "Keine Verbindung zum Server: Fehler $errorNumber: $errorString\n";
   }
}

sub verbinden {
   # Das Objekt *VMware::Control::VM* wird für die Virtuelle Maschine *cfg_path* erstellt:
   $vm = VMware::Control::VM::new($server, $cfg_path);
      if (!$vm->connect()) {
         ($errorNumber, $errorString ) = $vm->get_last_error();
      die  "Keine Verbindung zum Image: Fehler $errorNumber: $errorString\n";
   }
}
# Trennt alle verbunden Objekte:
sub cleanup {
   if ($vm) {
      $vm->disconnect();
   }
   if ($server) {
      $server->disconnect();
   }
}