Schlagwort-Archive: Scriptinging

VMWare vMotion auf VMA per CLI auslösen

Kleines Script zwischendurch: Über dieses Perl-Konstrukt kann man auf einem vSphere Management Assistant eine vMotion auf der Konsole auslösen. So lassen sich recht einfach eventgesteuerte vMotion-Aktionen umsetzen. Ich nutze es z.B. um zeitgesteuert VMs an Standorte mit höherer erwarteter Hitrate zu verlegen oder bei Störungen kritische VMs automatisiert auf „sicherere“ Hosts zu migrieren. Das Original stammt von William Lam, ich habe einige Punkte etwas umgebaut um Storage-vMotion auszuklammern. Üblicher Disclaimer: Proof of concept, keine Garantie, nicht-Programmierer-versucht-sich-an Perl, Works for me.

#!/usr/bin/perl -w

# Reworked for standard vmotion: Florian Knodt - https://www.adlerweb.info

# Original for distinct storage: William Lam - http://blogs.vmware.com/vsphere/automation

use strict;

use warnings;

use VMware::VILib;

use VMware::VIRuntime;

use Data::Dumper;

my %opts = (

    vmname => {

        type => "=s",

          help => "Name of Virtual Machine to migrate",

        required => 1,

    },

    vihost => {

          type => "=s",

          help => "Name of ESXi host to migrate to",

          required => 1,

     },

    priority => {

        type => "=s",

          help => "Migration priority [high|low]",

          required => 0,

        default => 'high',

    },

);

Opts::add_options(%opts);

Opts::parse();

Opts::validate();

Util::connect();

my $vmname = Opts::get_option('vmname');

my $vihost = Opts::get_option('vihost');

my $priority = Opts::get_option('priority');

if(Vim::get_service_content()->about->apiVersion lt "5.1") {

    &seeya("Script requires vCenter Server >5.1\n");

}

# define priority enums

my %priorityConstants = ('high' => 'highPriority', 'low' => 'lowPriority');

# retrieve VM

my $vm_view = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'name' => $vmname}, properties => ['name']);

if(!defined($vm_view)) {

    &seeya("Unable to find VM: " . $vmname . "\n")

}

# retrieve host

my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => {'name' => $vihost}, properties => ['name']);

if(!defined($host_view)) {

    my $test = Vim::find_entity_view(view_type => 'HostSystem', properties => ['name']);

    print Dumper($test);

    &seeya("Unable to find ESXi host: " . $vihost . "\n");

}

# in case bad input

if($priority ne "low" || $priority ne "high") {

    $priority = "high";

}

$priority .= "Priority";

my ($task,$message);

eval {

    # call migrate API

    print "Migrating " . $vmname . " to ESXi Host: " . $vihost . "...\n";

    $task = $vm_view->MigrateVM_Task(host => $host_view, priority => VirtualMachineMovePriority->new($priority));

    $message = "Successfully migrated " . $vmname . "!\n";

    &getStatus($task,$message);

};

if($@) {

    print "Error: " . $@ . "\n";

}

Util::disconnect();

sub getStatus {

     my ($taskRef,$message) = @_;

     my $task_view = Vim::get_view(mo_ref => $taskRef);

     my $taskinfo = $task_view->info->state->val;

     my $continue = 1;

     while ($continue) {

        my $info = $task_view->info;

        if ($info->state->val eq 'success') {

                print $message,"\n";

                return $info->result;

                $continue = 0;

        } elsif ($info->state->val eq 'error') {

                my $soap_fault = SoapFault->new;

                $soap_fault->name($info->error->fault);

                $soap_fault->detail($info->error->fault);

                $soap_fault->fault_string($info->error->localizedMessage);

                die "$soap_fault\n";

        }

        sleep 5;

        $task_view->ViewBase::update_view_data();

     }

}

sub seeya {

    my ($message) = @_;

    print $message;

    Util::disconnect();

    exit 1;

}

Aufruf:

./scriptname.pl --server vcenter.domain.local --username admin --password admin --vmname MyVM --vihost esxihost2.domain.local