OVH Community, votre nouvel espace communautaire.

[SDK] Gestion des snapshots


hpppv2
07/07/2012, 09h51
Citation Envoyé par floiseau
Salut,
En effet,

Code:
my $VMViews  = Vim::find_entity_view('view_type'    => 'VirtualMachine',
                                       'begin_entity' => $DatacenterView ,
                                    );
doit être remplacé par
Code:
my $VMViews  = Vim::find_entity_views('view_type'    => 'VirtualMachine',
                                       'begin_entity' => $DatacenterView ,
                                    );
C'est la fonction "find_entity_views" qui va renvoyer un array. "find_entity_view" ne renverra qu'1 VM.

J'ai changé dans le code.

Merci,
Ok merci

floiseau
05/07/2012, 00h07
Salut,
En effet,

Code:
my $VMViews  = Vim::find_entity_view('view_type'    => 'VirtualMachine',
                                       'begin_entity' => $DatacenterView ,
                                    );
doit être remplacé par
Code:
my $VMViews  = Vim::find_entity_views('view_type'    => 'VirtualMachine',
                                       'begin_entity' => $DatacenterView ,
                                    );
C'est la fonction "find_entity_views" qui va renvoyer un array. "find_entity_view" ne renverra qu'1 VM.

J'ai changé dans le code.

Merci,

hpppv2
04/07/2012, 21h02
si je demande une vm en particulier pas de problème. bizarre

hpppv2
04/07/2012, 20h38
salut,

Moi je me prend un vieux : Not an ARRAY reference at ./test.pl line 42.
La ligne 42 c'est la première boucle foreach :
# Bouclons sur la liste des VMs
foreach my $VMView (@$VMViews)

Une idée?

Merci

floiseau
09/10/2011, 18h07
Le script de suppression du snapshot


Le bout de code ci-dessous affiche les opérations
effectuées sur le vCenter :

Code:
Connecting
Connected
Getting Datacenter view
Got Datacenter View
Getting VMView for my VM
Got VMView
Task to delete snapshot started for VM MaVM started
Waiting for task to finish on vcenter...
Waiting for task to finish on vcenter...
Ok
Disconnected

Les snapshots se gèrent en arbre. Comme pour le get du snapshot, je vais
passer par un fonction récursive pour retrouver le snapshot que l'on veut
supprimer. Ce qui nous donne :


Code:
##
# Supprimer un snapshot
##

print "Getting Datacenter view  \n";
my $DatacenterView  = Vim::find_entity_view(view_type => 'Datacenter', filter => {'name'=>'pcc-XXX-XXX-XXX-XXX_Datacenter1'} );
!$DatacenterView and die('Failed to get DatacenterView');
print "Got Datacenter View\n";

print "Getting VMView for my VM\n";
my $VMView  = Vim::find_entity_view('view_type'    => 'VirtualMachine',
                                    'begin_entity' => $DatacenterView ,
                                    'filter'       => {'name'  =>  'MaVM'}
);
!$VMView and die('Failed to get VMView');
print "Got VMView\n";

# Trouver récursivement le snapshot que l'on veut supprimer

my $ret = _findSnapshotMoRefFromSnapshotName('snapList' => $VMView->snapshot->rootSnapshotList , 'name' => 'Mon Snapshot' );
if (!$ret )
{
            die "Cannot find this snapshot";
}

my $SnapshotTreeView = $ret;

# Nous avons la view de l'arbre, on recupere le snap :
my $SnapshotView =  Vim::get_view('mo_ref' => $SnapshotTreeView->snapshot);

my $Task;
eval{$Task =  $SnapshotView->RemoveSnapshot_Task('removeChildren' => 'false' ); };
if ($@)
{
            Util::disconnect();
                die ("Error while deleting snapshot for VM : " , $@);
}
print 'Task to delete snapshot started for VM ' .$VMView->name . " started \n";

# Toujours, le petit bonus, attendre que la task se finnisse
my $TaskView = Vim::get_view('mo_ref' => $Task);


while (!defined $finished)
{
    $TaskView->ViewBase::update_view_data();
    my $Info = $TaskView->info;
    if ($Info->state->val eq 'success')
    {
        print "Ok \n";
        $finished = 1;
    }
    elsif ($Info->state->val eq 'error')
    {
        Util::disconnect();
        die "Stop waiting, so got an error";
    }
    else
    {
        print "Waiting for task to finish on vcenter...\n";
        sleep 3;
    }
}


Util::disconnect();
print "Disconnected \n";


# La fonction récursive :

sub _findSnapshotMoRefFromSnapshotName
{
    my %params    = @_;
    my $snapList  = $params{'snapList'};   # ARRAY REF
    my $snapName  = $params{'name'};


    foreach my $snap (@{$snapList})
    {
        if($snap->name eq $snapName)
        {
            return $snap;
        }
        else
        {
            my $ret = _findSnapshotMoRefFromSnapshotName('snapList' => $snap->childSnapshotList , 'name' => $snapName );
            if($ret)
            {
                return $ret;
            }
        }
    }
    return 0;
}

floiseau
07/10/2011, 18h32
Le script de prise du snapshot.

Le bout de code ci-dessous affiche les opérations
effectuées sur le vCenter :

Code:
Connecting
Connected
Getting Datacenter view
Got Datacenter View
Getting VMView for All VMs
Got VMView
Task to create snapshot started for VM MaVM started
Waiting for task to finish on vcenter...
Waiting for task to finish on vcenter...
Ok
Disconnected

Alors :

Code:
##
# Prendre un snapshot :
##

print "Getting Datacenter view  \n";
my $DatacenterView  = Vim::find_entity_view(view_type => 'Datacenter', filter => {'name'=>'pcc-XXX-XXX-XXX-XXX_Datacenter1'} );
!$DatacenterView and die('Failed to get DatacenterView');
print "Got Datacenter View\n";

# On récupère que la VM concernée
print "Getting VMView for my VM MaVM \n";
my $VMView  = Vim::find_entity_view('view_type'    => 'VirtualMachine',
                                    'begin_entity' => $DatacenterView ,
                                    'filter'       => {'name'  =>  'MaVM'}
                                    );
!$VMView and die('Failed to get VMView');
print "Got VMView\n";

my $Task;
eval{$Task = $VMView->CreateSnapshot_Task('name'        => "snap1",
                                          'description' => "Mise a jour logicielle",
                                          'memory'      => 'false',
                                          'quiesce'     => 'false'
                                        );
};
if ($@)
{
    Util::disconnect();
    die ("Error while creating snapshot for VM : " , $@);
}
print 'Task to create snapshot started for VM ' .$VMView->name . " started \n";

####
##  La partie creation est finie.
##  Bonus => on attend et on confirme que la task est bien terminiée sur le vCenter
####

my $finished;
# On récupère la View de la Task retournée par la création du snapshot
my $TaskView = Vim::get_view('mo_ref' => $Task);
while (!defined $finished)
{
    $TaskView->ViewBase::update_view_data();
    my $Info = $TaskView->info;
    if ($Info->state->val eq 'success')
    {
        print "Ok \n";
        $finished = 1;
    }
    elsif ($Info->state->val eq 'error')
    {
        Util::disconnect();
        die "Stop waiting, got an error";
    }
    else
    {
        print "Waiting for task to finish on vcenter...\n";
        sleep 3;
    }
}


Util::disconnect();
print "Disconnected \n";

floiseau
07/10/2011, 17h29
Bonjour,

Fonctionner avec des snapshots en tant que backup ou empiler X snapshots mensuels comme une solution de repli
en cas de problème n'est pas bon pour les performances de la VM et bloque certaines fonctionnalités (VMware 4.1)
comme le Storage vMotion.

Il est donc pertinent de savoir combien de snapshots on a sur une VM et de quand ils datent.

On peut scripter toutes ces opération.
Les snapshots se gèrent en arbre. Je vais passer par une fonciton récursive.

Le bout de code ci-dessous affiche la liste des VMs dans un hash, qui contient un array de hash de snapshots
Bref :

Code:
Connecting
Connected
Getting Datacenter exchange view
Got Datacenter View
Getting VMView for All VMs
Got VMViews
$VAR1 = {
          'MaVM' => [
                   {
                     'desc' => 'test',
                     'date' => 1317970514,
                     'name' => 'test'
                   },
                   {
                     'desc' => 'test',
                     'date' => 1317970543,
                     'name' => 'test2'
                   },
                   {
                     'desc' => 'test',
                     'date' => 1317970616,
                     'name' => 'test4'
                   },
                   {
                     'desc' => 'test',
                     'date' => 1317970583,
                     'name' => 'test3'
                   },
                   {
                     'desc' => 'test',
                     'date' => 1317970713,
                     'name' => 'test5'
                   }
                 ]
        };
Disconnected

Ce qui nous donne :

Code:
##
# Recupérer la liste des snapshots d'une VM
##

# On récupère la view de notre Datacenter :
print "Getting Datacenter view\n";

my $DatacenterView  = Vim::find_entity_view(view_type => 'Datacenter', filter => {'name'=>'pcc-XXX-XXX-XXX-XXX_Datacenter1'} );
!$DatacenterView and die('Failed to get DatacenterView');

print "Got Datacenter View\n";

# On va ici récupèrer la list de toutes les VMs du datacenter :
print "Getting VMView for All VMs \n";
my $VMViews  = Vim::find_entity_views('view_type'    => 'VirtualMachine',
                                       'begin_entity' => $DatacenterView ,
                                    );
!$VMViews and die('Failed to get VMViews');
print "Got VMViews\n";

my $listVm;
my $snapshots;
my $ret;
# Bouclons sur la liste des VMs
foreach my $VMView (@$VMViews)
{
    # Si la VM a au moins 1 snap
    if ($VMView->snapshot)
    {
        foreach my $snap (@{$VMView->snapshot->rootSnapshotList})
        {
            # On appelle la fonction récursive
            $ret = _getAllSnapshots( 'snap' => $snap , 'snapshots' => $snapshots );
            !$ret and die $ret;
            $listVm->{$VMView->name} = $ret;
        }
    }
}

print Dumper $listVm;

Util::disconnect();
print "Disconnected \n";


# Sub récursive qui liste les snaps
sub _getAllSnapshots
{
    my %params    = @_;
    my $snap      = $params{'snap'};
    my $snapshots = $params{'snapshots'};

    # J'ai choisis la date en timestamp :
    my ($date1,$date2)= split /T/, $snap->createTime;
    my ($year,$mon,$day) = split /-/, $date1;
    my ($hrs,$min,$sec ) = split /:/, $date2;
    my $createdTime = timegm($sec, $min, $hrs, $day, $mon-1, $year-1900);

    # On remplis le hash
    my $snapHash = {
        'name' => $snap->name ,
        'date' => $createdTime,
        'desc' => $snap->description
    };
    push @$snapshots , $snapHash;

    # Et on tourne
    if ($snap->childSnapshotList)
    {
        foreach my $snapChild (@{$snap->childSnapshotList})
        {
            my $ret = _getAllSnapshots('snap' => $snapChild , 'snapshots' => $snapshots);
            !$ret and warn $ret;
        }
    }
    return $snapshots;
}
Si vous voulez le faire sur une seule VM, changez le début :

Code:
my $VMViews  = Vim::find_entity_views('view_type'    => 'VirtualMachine',
                                       'begin_entity' => $DatacenterView ,
                                       'filter' => { 'name' => 'MaVM' } ,
                                    );

Merci,

--
Francois Loiseau
OVH