Добрый день.
Этот скрипт не претендует на оригинальность. Он довольно простой, но, возможно, кто-то захочет не изобретать свой велосипед. Скрипт работает с виртуальными машинами VMware ESXi и позволяет создавать снапшоты для нескольких машин одной командой, откатываться к нужному снапшоту, а также стартовать машины. Типичное применение: подготовка снапшота тестового окружения после выхода релизного билда и откат к нужному снапшоту при необходимости проверить хотфиксы. К скрипту можно легко добавить другие операции - например, удаление снапшота. Примечание: безусловно, все эти операции можно реализовать с помощью инструментов вендора: например, Power CLI. Назначение скрипта и подобных ему: быть встроенным в существующую инфраструктуру без добавления новых языков и инструментов. Ниже приведен код скрипта и примеры запуска.
Код:
#!perl use Getopt::Long; use strict; # Mode can be either dummy or force. Dummy is just to verify that everything is specified correctly (highly recommended!). Force is to do the job. # Operation can be stop, start, revert, create # Pattern means text pattern in machine or snapshot name (mpattern and spattern, respectively) # Snapshot name and description (sname and sdesc, respectively) are used when operation is create (snapshot) # Host, User, Password - ESXi credentials my ($mode, $operation, $mpattern, $spattern, $host, $user, $password, $sname, $sdesc); my ($command, @output, $string, $vmid, $machine, %machines, %snapshots); my $Sleep = 10; GetOptions( "mode:s" => \$mode, "operation:s" => \$operation, "mpattern:s" => \$mpattern, "spattern:s" => \$spattern, "sname:s" => \$sname, "sdesc:s" => \$sdesc, "host:s" => \$host, "user:s" => \$user, "password:s" => \$password ); # Default settings if some arguments were not specified $mode = "dummy" unless ($mode); $operation = "list" unless ($operation); $mpattern = "who watches watchers" unless ($mpattern); $spattern = "not defined" unless ($spattern); do { print "No ESXi creds specified...\n"; exit } unless ($host && $password && $user); my $plink = "plink.exe -batch ".$host." -l ".$user." -pw ".$password; my $dummy = "\nDummy mode: just for verification that machines are selected properly. Please use force mode to do the job, but be careful!\n"; my $force = "\nDo you really want force mode? Did you try dummy mode to make sure you select the right machines? \nType Y to continue, or any other input to quit:\n"; # Some caution wouldn't hurt print "\nMode: $mode, operation: $operation, machine pattern: $mpattern\n"; do { print "Wrong mode!\n";exit } unless ($mode =~ m/(dummy|force)/); do { print "Wrong operation!\n";exit } unless ($operation =~ m/(start|stop|revert|create)/); if ($operation eq "create") { do { print "Snapshot name and/or description are not defined!\n";exit } unless ($sname && $sdesc); } print "Snapshot pattern: $spattern\n" if $operation eq "revert"; print "Snapshot name: $sname, snapshot desc: $sdesc\n" if $operation eq "create"; if ($mode eq "force") { print $force; my $choice = <STDIN>; chomp $choice; exit if lc($choice) ne "y"; } print "\n"; # Getting the info about all machines on this host that match the pattern in their names $command = $plink." \"vim-cmd vmsvc/getallvms\""; @output = `$command`; # print join("\n", @output); foreach $string (@output) { if ($string =~ /^(\d+)\s+([^\s]+)\s+/) { # vmid, machine_name $vmid = $1; $machine = $2; if ($machine =~ /$mpattern/) { $machines{$vmid} = $machine; } } } print "The following machines are ready for ". $operation. " operation:\n\nID Name\n"; print "$_ $machines{$_}\n" for (keys %machines); # Time to execute the operation if (($operation eq "start") || ($operation eq "stop")) { my $op = ($operation eq "start")? "on": "off"; if ($mode eq "dummy") { print $dummy; } elsif ($mode eq "force") { for (keys %machines) { print "Machine: $machines{$_}\n"; $command = $plink." \"vim-cmd vmsvc/power.".$op." ".$_."\""; @output = `$command`; print join("\n", @output); print "\n\n"; sleep ($Sleep); } } } if ($operation eq "revert") { my ($snapshot_name, $snapshot_id, $machine_id, $machine_name); # For each machine that matches machine pattern, looking for the right snapshot that matches snapshot pattern for (keys %machines) { $machine_id = $_; $machine_name = $machines{$_}; $command = $plink." \"vim-cmd vmsvc/snapshot.get ".$_."\""; @output = `$command`; foreach $string (@output) { if ($string =~ /Snapshot Name\s+:\s+(.*)$/) { # snapshot name $snapshot_name = $1; } elsif ($string =~ /Snapshot Id\s+:\s+(.*)$/) { $snapshot_id = $1; if ($snapshot_name =~ /$spattern/) { $snapshots{$machine_id}[0] = $machine_name; $snapshots{$machine_id}[1] = $snapshot_id; $snapshots{$machine_id}[2] = $snapshot_name; last; } } } # foreach $string (@output) } # for (keys %machines) print "\n\nSnapshots to be used:\n\nVMID\tMachine\t\tSnapshotID\tSnapshotName\n"; print "$_\t$snapshots{$_}[0]\t$snapshots{$_}[1]\t$snapshots{$_}[2]\n" for (keys %snapshots); if ($mode eq "dummy") { print $dummy; } elsif ($mode eq "force") { for (keys %snapshots) { $machine_id = $_; $machine_name = $snapshots{$machine_id}[0]; $snapshot_id = $snapshots{$machine_id}[1]; print "Machine: $machine_name\n"; $command = $plink." \"vim-cmd vmsvc/snapshot.revert ".$machine_id." ".$snapshot_id."suppressPowerOff = 1\""; @output = `$command`; print join("\n", @output); print "\n\n"; sleep ($Sleep); } } # elsif ($mode eq "force") { } # if ($operation eq "revert") { if ($operation eq "create") { if ($mode eq "dummy") { print $dummy; } elsif ($mode eq "force") { for (keys %machines) { print "Machine: $machines{$_}\n"; $command = $plink." \"vim-cmd vmsvc/snapshot.create ".$_." \'".$sname."\' \'".$sdesc."\'\""; @output = `$command`; print join("\n", @output); print "\n\n"; sleep ($Sleep); } } }
Формат запуска:
Для машин, чьи названия начинаются с “disp”, создать снапшот с названием “385 release” и описанием “21.08.2018 2.97.385.0306″. Поскольку mode=dummy, команда выведет список машин, для которых предполагается сделать снапшот и предложит использовать режим force:
perl vm.pl –Host=10.30.33.175 –User=root –Password=yFawXFQX4sJ –mode=dummy –operation=create –mpattern=disp –sname=”385 release” –sdesc=”21.08.2018 2.97.385.0306″
——————————
Команда стартует машины, названия которых начинаются с “disp”. Указан режим force, поэтому после подтверждения операции команда будет выполнена:
perl vm.pl –Host=10.30.33.175 –User=root –Password=yFawXFQX4sJ –mode=force –operation=start –mpattern=disp
——————————
Для машин, чьи названия начинаются с “disp”, откатиться к снапшоту, в названии которого фигурирует “385″.
perl vm.pl –Host=10.30.33.175 –User=root –Password=yFawXFQX4sJ –mode=dummy –operation=revert –mpattern=disp –spattern=385
Всего доброго.
Что такое качество программного обеспечения и как его улучшить: теория и практика, задачи и решения, подводные камни и обходные пути.