Schlagwort-Archive: Perl

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

policyd-weight: warning: child: err: Undefined subroutine &main::dn_expand called

Örks – nach dem letzten Neustart hatte einer meiner Mailserver etwas Schluckauf an den Tag gelegt: Mails wurden nicht mehr angenommen, im Log zeigte sich policyd-weight als Verursacher:

warning: child: err: Undefined subroutine &main::dn_expand called at /usr/libexec/postfix/policyd-weight line 3591, ...

Ursache ist offenbar ein veralteter Aufruf der Library Net::DNS dieses Perl-Monsters. Ein passender Patch ist bei Debian zu finden, mit 3 geänderten Zeilen ist der Fehler erledigt und die Software wieder lauffähig.

+++ policyd-weight
72 -use Net::DNS::Packet qw(dn_expand);
3591 -            my ($dn, $offset) = dn_expand(\$qb, 0);
3591 +	    my ($decoded, $offset) = decode Net::DNS::DomainName(\$qb);
3592 +            my $dn = $decoded->name;

 

[Gentoo] Slot-Conflice durch Perl-Updates

Schon etwas älter, aber ab und zu stoße ich trotzdem drauf: Durch Perl kommt es bei Updates zu einem Slot-Conflice / Blocked Packages. Die Lösung wird z.T. gleich mitgeliefert:


* Remove all perl-core packages from your world file
* emerge --deselect --ask $(qlist -IC 'perl-core/*')
* Update all the installed Perl virtuals
* emerge -uD1a $(qlist -IC 'virtual/perl-*')
* Afterwards re-run perl-cleaner
perl-cleaner --reallyall

wget 1.14 & Perl 5.18.x: Expected text after =item, not a number

Beim Kompilieren eines OpenWRT machte eben wget-ssl dicke Backen: „Expected text after =item, not a number“ im Dokumentationsordner ließ die letzte Meldung verlauten. Grund sind striktere Syntaxchecks in Perl ab Version 5.18. Im Wget-Upstream ist das Problem bereits erledigt (0102e0e7e503c4fcd70a14eba4ffe357c84de3bb), für 1.14 gibts einen passenden Patch von Javier Vasquez, bei OpenWRT schwirrt auch etwas passendes von Jonathan McCrohan herum, hat es aber noch nicht in den Trunk geschafft.

Wer dem ganzen Problem ausweichen möchte: Seit Januar ist wget 1.15 verfügbar, hierzu einfach in feeds/packages/net/wget/Makefile folgende Änderungen vornehmen:


11c11
< PKG_VERSION:=1.14 --- > PKG_VERSION:=1.15
16c16
< PKG_MD5SUM:=316f6f59292c9098ad81fd54f658c579 --- > PKG_MD5SUM:=7a279d5ac5594919124d5526e7143e28

Gentoo-Upgrade: XML::Parser perl module is required for intltool

Uff… Updates schleifen lassen ist bei Rolling-Release-Distros ja immer ein Problem. Heute im Angebot: Das Gentoo-Upgrade eines Systems, welches etwa 4 Monate stand, verabschiedet sich bei nahezu allen Paketen mit folgender Meldung während „configure“:

XML::Parser perl module is required for intltool

Eine Neuinstallation von Perl und dem genannten XML-Modul brachte keine Besserung, auch unter @preserved… oder revdep-rebuild zeigte sich nichts passendes. Die Lösung ist einfacher als befürchtet: Der Befehl

perl-cleaner --reallyall

sucht alle betroffenen Pakete, welche noch Verweise auf ein altes Perl enthalten, und baut sie über portage neu. Bei mir kam es noch zu einer Kollision durch veraltete glib und qt-Pakete, da der emerge-Befehl aber bereits fertig zum kopieren bereitstand war die nötige Ergänzung kein wirkliches Problem – knapp 190 Pakete später funktioniert’s dann auch wieder mit dem Update.