OpenQuality.ru

Качество программного обеспечения

Качество программного обеспечения: в главных ролях

Лента  Радар  Блог  Опыт  
Разум  Видео  Заметки  Эпизоды


VMware ESXi: управление виртуальными машинами из командной строки

Добрый день.

Этот скрипт не претендует на оригинальность. Он довольно простой, но, возможно, кто-то захочет не изобретать свой велосипед. Скрипт работает с виртуальными машинами 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

 
Всего доброго.

Отправить в Twitter, Facebook, ВКонтакте | Опубликовано 24.08.2018 в рубрике "Автоматизация"

Комментарии


Добавить комментарий

Пожалуйста, исправьте результат: дважды два равно



КРАТКОЕ СОДЕРЖАНИЕ

Что такое качество программного обеспечения и как его улучшить: теория и практика, задачи и решения, подводные камни и обходные пути.


ПУТЕВОДИТЕЛЬ

Проект был основан в 2008 году. За это время часть статей устарела, а некоторые из них вызывают улыбку, но пусть они останутся в том виде, в котором были написаны. Cписок всех статей с краткой аннотацией и разбивкой по рубрикам: открыть.

ПОДПИСКА

Доступ к самым интересным материалам по электропочте и RSS. Подробности.

ИЩЕЙКА