Bugs fixed
This commit is contained in:
parent
fee9a47f3f
commit
849554c340
24
config.pl
24
config.pl
|
@ -22,40 +22,32 @@ backup_datastore => 'backups',
|
||||||
# The local directory where backups datastore folder is mounted
|
# The local directory where backups datastore folder is mounted
|
||||||
local_backup_dir => '/mnt/vm-backups',
|
local_backup_dir => '/mnt/vm-backups',
|
||||||
|
|
||||||
# Backup schedules
|
# Backup jobs
|
||||||
schedules => {
|
backup_jobs => {
|
||||||
schedule1 => {
|
schedule1 => {
|
||||||
machines => ['machine1', 'machine2'],
|
machines => ['test'],
|
||||||
rotation => 'weekly'
|
|
||||||
},
|
|
||||||
schedule2 => {
|
|
||||||
machines => ['machine3', 'machine4'],
|
|
||||||
rotation => 'daily'
|
rotation => 'daily'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
# Backup rotation configuration
|
# Backup rotation configuration
|
||||||
rotations => {
|
rotations => {
|
||||||
weekly => {
|
|
||||||
days => 21,
|
|
||||||
count => 4
|
|
||||||
},
|
|
||||||
daily => {
|
daily => {
|
||||||
days => 31,
|
days => 31,
|
||||||
count => 31
|
count => 31
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
# Cloning configuration
|
# Clone jobs
|
||||||
clone => {
|
clone_jobs => {
|
||||||
machine => {
|
machine => {
|
||||||
vm => 'src-machine',
|
vm => 'test',
|
||||||
dst_name => 'dst-machine',
|
dst_name => 'test-clone',
|
||||||
dst_host => '127.0.0.1',
|
dst_host => '127.0.0.1',
|
||||||
dst_datastore => 'datastore1',
|
dst_datastore => 'datastore1',
|
||||||
memory => 4084,
|
memory => 4084,
|
||||||
num_cpus => 2,
|
num_cpus => 2,
|
||||||
mac => '00:00:00:00:00:01',
|
mac => '00:50:56:BF:01:01',
|
||||||
poweron => 1,
|
poweron => 1,
|
||||||
overwrite => 1
|
overwrite => 1
|
||||||
}
|
}
|
||||||
|
|
406
vn-vmware.pl
406
vn-vmware.pl
|
@ -21,104 +21,104 @@ use constant false => 0;
|
||||||
use constant true => 1;
|
use constant true => 1;
|
||||||
|
|
||||||
my %opts = (
|
my %opts = (
|
||||||
operation => {
|
'operation' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Operation to perform: backuping, cloning, rotate, backup, clone, snapshot, migrate",
|
help => "Operation to perform: backup-job, clone-job, backup, rotate, clone, snapshot, migrate",
|
||||||
required => true
|
required => true
|
||||||
},
|
},
|
||||||
job => {
|
'job' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "The job name"
|
help => "The job name"
|
||||||
},
|
},
|
||||||
vmname => {
|
'vm-name' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
variable => "vmname",
|
variable => "vm_name",
|
||||||
help => "Name of the virtual machine"
|
help => "Name of the virtual machine"
|
||||||
},
|
},
|
||||||
rotation_days => {
|
'rotation-days' => {
|
||||||
type => "=i",
|
type => "=i",
|
||||||
help => "Rotation days for backups",
|
help => "Rotation days for backups",
|
||||||
default => 0
|
default => 0
|
||||||
},
|
},
|
||||||
rotation_count => {
|
'rotation-count' => {
|
||||||
type => "=i",
|
type => "=i",
|
||||||
help => "Number of backups to keep despite the rotation",
|
help => "Number of backups to keep despite the rotation",
|
||||||
default => 5
|
default => 5
|
||||||
},
|
},
|
||||||
dst_name => {
|
'dst-name' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Name of the new virtual machine"
|
help => "Name of the new virtual machine"
|
||||||
},
|
},
|
||||||
dst_host => {
|
'dst-host' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Name of the target host"
|
help => "Name of the target host"
|
||||||
},
|
},
|
||||||
dst_datastore => {
|
'dst-datastore' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Destination datastore"
|
help => "Destination datastore"
|
||||||
},
|
},
|
||||||
memory => {
|
'memory' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Memory amount in MB"
|
help => "Memory amount in MB"
|
||||||
},
|
},
|
||||||
num_cpus => {
|
'num-cpus' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Number of cores",
|
help => "Number of cores",
|
||||||
default => 1
|
default => 1
|
||||||
},
|
},
|
||||||
mac => {
|
'mac' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "MAC address"
|
help => "MAC address"
|
||||||
},
|
},
|
||||||
vnic => {
|
'vnic' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "NIC index",
|
help => "NIC index",
|
||||||
default => 1
|
default => 1
|
||||||
},
|
},
|
||||||
priority => {
|
'priority' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Operation priority: highpriority, slowpriority, defaultpriority",
|
help => "Operation priority: highpriority, slowpriority, defaultpriority",
|
||||||
default => 'defaultpriority'
|
default => 'defaultpriority'
|
||||||
},
|
},
|
||||||
cpu_reservation => {
|
'cpu-reservation' => {
|
||||||
type => "=i",
|
type => "=i",
|
||||||
help => "CPU Reservation in Mhz",
|
help => "CPU Reservation in Mhz",
|
||||||
default => 0
|
default => 0
|
||||||
},
|
},
|
||||||
mem_reservation => {
|
'mem-reservation' => {
|
||||||
type => "=i",
|
type => "=i",
|
||||||
help => "Memory reservation",
|
help => "Memory reservation",
|
||||||
default => 0
|
default => 0
|
||||||
},
|
},
|
||||||
cbt_size => {
|
'cbt-size' => {
|
||||||
type => "=i",
|
type => "=i",
|
||||||
help => "CBT size"
|
help => "CBT size"
|
||||||
},
|
},
|
||||||
cbt => {
|
'cbt' => {
|
||||||
type => "",
|
type => "",
|
||||||
help => "Whether to enable CBT"
|
help => "Whether to enable CBT"
|
||||||
},
|
},
|
||||||
overwrite => {
|
'overwrite' => {
|
||||||
type => "",
|
type => "",
|
||||||
help => "Whether to remove the virtual machine if there is one with the same name",
|
help => "Whether to remove the virtual machine if there is one with the same name",
|
||||||
default => 0
|
default => 0
|
||||||
},
|
},
|
||||||
poweron => {
|
'poweron' => {
|
||||||
type => "",
|
type => "",
|
||||||
help => "Whether to power on machine after operation",
|
help => "Whether to power on machine after operation",
|
||||||
default => 1
|
default => 1
|
||||||
},
|
},
|
||||||
show_logs => {
|
'show-logs' => {
|
||||||
type => "",
|
type => "",
|
||||||
help => "Whether to redirect logs to stdout",
|
help => "Whether to redirect logs to stdout",
|
||||||
default => 0
|
default => 0
|
||||||
},
|
},
|
||||||
snapshot_name => {
|
'snapshot-name' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Name of the snapshot",
|
help => "Name of the snapshot",
|
||||||
default => "snapshot"
|
default => "snapshot"
|
||||||
},
|
},
|
||||||
snapshot_desc => {
|
'snapshot-desc' => {
|
||||||
type => "=s",
|
type => "=s",
|
||||||
help => "Snapshot description",
|
help => "Snapshot description",
|
||||||
default => "Snapshot"
|
default => "Snapshot"
|
||||||
|
@ -131,26 +131,26 @@ Opts::validate();
|
||||||
|
|
||||||
my $operation = Opts::get_option('operation');
|
my $operation = Opts::get_option('operation');
|
||||||
my $job = Opts::get_option('job');
|
my $job = Opts::get_option('job');
|
||||||
my $vmname = Opts::get_option('vmname');
|
my $vm_name = Opts::get_option('vm-name');
|
||||||
my $rotation_days = Opts::get_option('rotation_days');
|
my $rotation_days = Opts::get_option('rotation-days');
|
||||||
my $rotation_count = Opts::get_option('rotation_count');
|
my $rotation_count = Opts::get_option('rotation-count');
|
||||||
my $dst_name = Opts::get_option('dst_name');
|
my $dst_name = Opts::get_option('dst-name');
|
||||||
my $dst_host = Opts::get_option('dst_host');
|
my $dst_host = Opts::get_option('dst-host');
|
||||||
my $dst_datastore = Opts::get_option('dst_datastore');
|
my $dst_datastore = Opts::get_option('dst-datastore');
|
||||||
my $memory = Opts::get_option('memory');
|
my $memory = Opts::get_option('memory');
|
||||||
my $num_cpus = Opts::get_option('num_cpus');
|
my $num_cpus = Opts::get_option('num-cpus');
|
||||||
my $mac = Opts::get_option('mac');
|
my $mac = Opts::get_option('mac');
|
||||||
my $vnic = Opts::get_option('vnic');
|
my $vnic = Opts::get_option('vnic');
|
||||||
my $priority = Opts::get_option('priority');
|
my $priority = Opts::get_option('priority');
|
||||||
my $mem_reservation = Opts::get_option('mem_reservation');
|
my $mem_reservation = Opts::get_option('mem-reservation');
|
||||||
my $cpu_reservation = Opts::get_option('cpu_reservation');
|
my $cpu_reservation = Opts::get_option('cpu-reservation');
|
||||||
my $cbt_size = Opts::get_option('cbt_size');
|
my $cbt_size = Opts::get_option('cbt-size');
|
||||||
my $cbt = Opts::option_is_set('cbt');
|
my $cbt = Opts::option_is_set('cbt');
|
||||||
my $overwrite = Opts::option_is_set('overwrite');
|
my $overwrite = Opts::option_is_set('overwrite');
|
||||||
my $poweron = Opts::option_is_set('poweron');
|
my $poweron = Opts::option_is_set('poweron');
|
||||||
my $show_logs = Opts::option_is_set('show_logs');
|
my $show_logs = Opts::option_is_set('show-logs');
|
||||||
my $snapshot_name = Opts::get_option('snapshot_name');
|
my $snapshot_name = Opts::get_option('snapshot-name');
|
||||||
my $snapshot_desc = Opts::get_option('snapshot_desc');
|
my $snapshot_desc = Opts::get_option('snapshot-desc');
|
||||||
|
|
||||||
my %config;
|
my %config;
|
||||||
my @config_files = (
|
my @config_files = (
|
||||||
|
@ -167,7 +167,7 @@ foreach my $config_file (@config_files) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unless (%config) {
|
unless (%config) {
|
||||||
die "Configuration file not found";
|
die "Configuration file not found.";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $vm;
|
my $vm;
|
||||||
|
@ -180,34 +180,43 @@ my $local_backup_dir = $config{local_backup_dir};
|
||||||
sub log_to_file {
|
sub log_to_file {
|
||||||
my ($message) = @_;
|
my ($message) = @_;
|
||||||
my $time = Time::Piece->new;
|
my $time = Time::Piece->new;
|
||||||
my $timeMark = $time->strftime('%Y-%m-%d %H:%M:%S');
|
my $time_mark = $time->strftime('%Y-%m-%d %H:%M:%S');
|
||||||
print $log_fh "$timeMark : $message\n";
|
print $log_fh "$time_mark > $message";
|
||||||
}
|
}
|
||||||
sub log_message {
|
sub log_message {
|
||||||
my ($message) = @_;
|
my ($message) = @_;
|
||||||
|
|
||||||
if ($log_fh) {
|
if ($log_fh) {
|
||||||
log_to_file $message;
|
log_to_file "MSG: $message\n";
|
||||||
} else {
|
} else {
|
||||||
print "$message\n"
|
print "$message\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sub log_error {
|
sub log_error {
|
||||||
my ($message) = @_;
|
my ($error) = @_;
|
||||||
print STDERR color("red").$message.color("reset");
|
|
||||||
|
if ($error->isa('SOAP::Fault')) {
|
||||||
|
$error = $error->faultcode.": ".$error->faultString;
|
||||||
|
}
|
||||||
|
|
||||||
|
print color('red');
|
||||||
|
print $error;
|
||||||
|
print color('reset');
|
||||||
|
|
||||||
if ($log_fh) {
|
if ($log_fh) {
|
||||||
log_to_file $message;
|
log_to_file "ERR: $error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unless ($show_logs) {
|
unless ($show_logs) {
|
||||||
open($log_fh, '>', $config{log_file});
|
open($log_fh, '>>', $config{log_file});
|
||||||
}
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
main();
|
main();
|
||||||
};
|
};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
log_error($@);
|
log_error $@;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($log_fh) {
|
if ($log_fh) {
|
||||||
|
@ -223,7 +232,7 @@ sub main {
|
||||||
my $url = "https://$vcenter_host/sdk/vimService";
|
my $url = "https://$vcenter_host/sdk/vimService";
|
||||||
|
|
||||||
unless (defined ($password)) {
|
unless (defined ($password)) {
|
||||||
die "Password not found $vcenter_host";
|
die "Password not found $vcenter_host.";
|
||||||
}
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
|
@ -234,27 +243,26 @@ sub main {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
die "Cannot connect to $vcenter_host";
|
die "Cannot connect to $vcenter_host.";
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Connected to $vcenter_host";
|
log_message "Connected to $vcenter_host.";
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
|
|
||||||
given ($operation) {
|
given ($operation) {
|
||||||
when ('backuping') {
|
when ('backup-job') {
|
||||||
backup_job();
|
backup_job();
|
||||||
}
|
}
|
||||||
when ('cloning') {
|
when ('clone-job') {
|
||||||
clone_job();
|
clone_job();
|
||||||
}
|
}
|
||||||
when ('rotate') {
|
|
||||||
rotate_backup();
|
|
||||||
}
|
|
||||||
when ('backup') {
|
when ('backup') {
|
||||||
open_machine();
|
open_machine();
|
||||||
backup_machine();
|
backup_machine();
|
||||||
}
|
}
|
||||||
|
when ('rotate') {
|
||||||
|
rotate_backup();
|
||||||
|
}
|
||||||
when ('clone') {
|
when ('clone') {
|
||||||
open_machine();
|
open_machine();
|
||||||
clone_machine();
|
clone_machine();
|
||||||
|
@ -267,6 +275,9 @@ sub main {
|
||||||
open_machine();
|
open_machine();
|
||||||
migrate_machine();
|
migrate_machine();
|
||||||
}
|
}
|
||||||
|
default {
|
||||||
|
die "Unknown operation '$operation'.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
my $err = $@;
|
my $err = $@;
|
||||||
|
@ -281,98 +292,108 @@ sub main {
|
||||||
#--------------------------------- Operations
|
#--------------------------------- Operations
|
||||||
|
|
||||||
sub backup_job() {
|
sub backup_job() {
|
||||||
unless (exists $config{schedules}{$job}) {
|
unless ($job) {
|
||||||
die "Backup job '$job' doesn't exists";
|
die "Job not defined.";
|
||||||
|
}
|
||||||
|
unless (exists $config{backup_jobs}{$job}) {
|
||||||
|
die "Backup job '$job' doesn't exists.";
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Backup job '$job' started";
|
log_message "Backup job '$job' started.";
|
||||||
|
|
||||||
my $schedule = $config{schedules}{friday};
|
my $backup_job = $config{backup_jobs}{$job};
|
||||||
|
|
||||||
my $rotation_cfg = $config{rotations}{$schedule->{rotation}};
|
my $rotation_cfg = $config{rotations}{$backup_job->{rotation}};
|
||||||
$rotation_count = $rotation_cfg->{count};
|
$rotation_count = $rotation_cfg->{count};
|
||||||
$rotation_days = $rotation_cfg->{days};
|
$rotation_days = $rotation_cfg->{days};
|
||||||
|
|
||||||
my @machines = $schedule->{machines};
|
my @machines = @{$backup_job->{machines}};
|
||||||
|
|
||||||
foreach $vmname (@machines) {
|
foreach my $machine (@machines) {
|
||||||
eval {
|
eval {
|
||||||
print "$vmname\n";
|
$vm_name = $machine;
|
||||||
#open_machine();
|
&open_machine();
|
||||||
#backup_machine();
|
backup_machine();
|
||||||
#rotate_backup();
|
rotate_backup();
|
||||||
};
|
};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
log_error($@);
|
log_error $@;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Backup job '$job' finished";
|
log_message "Backup job '$job' finished.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub clone_job() {
|
sub clone_job() {
|
||||||
unless (exists $config{clone}{$job}) {
|
unless ($job) {
|
||||||
die "Cloning job '$job' doesn't exists";
|
die "Job not defined.";
|
||||||
|
}
|
||||||
|
unless (exists $config{clone_jobs}{$job}) {
|
||||||
|
die "Clone job '$job' doesn't exists.";
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Clone job '$job' started";
|
log_message "Clone job '$job' started.";
|
||||||
|
|
||||||
my $cfg = $config{clone}{$job};
|
my $clone_job = $config{clone_jobs}{$job};
|
||||||
|
|
||||||
$vmname = $cfg->{vm};
|
$vm_name = $clone_job->{vm};
|
||||||
$dst_name = $cfg->{dst_name};
|
$dst_name = $clone_job->{dst_name};
|
||||||
$dst_host = $cfg->{dst_host};
|
$dst_host = $clone_job->{dst_host};
|
||||||
$dst_datastore = $cfg->{dst_datastore};
|
$dst_datastore = $clone_job->{dst_datastore};
|
||||||
$memory = $cfg->{memory};
|
$memory = $clone_job->{memory};
|
||||||
$num_cpus = $cfg->{num_cpus};
|
$num_cpus = $clone_job->{num_cpus};
|
||||||
$mac = $cfg->{mac};
|
$mac = $clone_job->{mac};
|
||||||
$poweron = $cfg->{poweron};
|
$poweron = $clone_job->{poweron};
|
||||||
$overwrite = $cfg->{overwrite};
|
$overwrite = $clone_job->{overwrite};
|
||||||
|
|
||||||
open_machine();
|
open_machine();
|
||||||
clone_machine();
|
clone_machine();
|
||||||
|
|
||||||
log_message "Clone job '$job' finished";
|
log_message "Clone job '$job' finished.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub backup_machine() {
|
sub backup_machine() {
|
||||||
log_message "Backup of '$vmname' started";
|
log_message "Backup of '$vm_name' started.";
|
||||||
|
|
||||||
my $time = Time::Piece->new;
|
my $time = Time::Piece->new;
|
||||||
my $timeMark = $time->strftime($time_pattern);
|
my $time_mark = $time->strftime($time_pattern);
|
||||||
my $tmpDir = ".$timeMark";
|
my $tmpDir = ".$time_mark";
|
||||||
my $backup_datastore = $config{backup_datastore};
|
my $backup_datastore = $config{backup_datastore};
|
||||||
my $dsBackupPath = "[$backup_datastore] $vmname/$tmpDir";
|
my $ds_tmp_dir = "[$backup_datastore] $vm_name/$tmpDir";
|
||||||
my $local_dir = "$local_backup_dir/$vmname";
|
my $local_dir = "$local_backup_dir/$vm_name";
|
||||||
my $localTmpDir = "$local_dir/$tmpDir";
|
my $local_tmp_dir = "$local_dir/$tmpDir";
|
||||||
my $tarFile = "$local_dir/$vmname-$timeMark.tar.gz";
|
my $tar_file = "$local_dir/${vm_name}_$time_mark.tar.gz";
|
||||||
|
|
||||||
if (-e $localTmpDir) {
|
if (-e $local_tmp_dir) {
|
||||||
die "Backup directory already exists: $localTmpDir";
|
die "Temporary backup directory already exists: $local_tmp_dir";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $serviceContent = Vim::get_service_content();
|
my $service_content = Vim::get_service_content();
|
||||||
my $fileManager = Vim::get_view(mo_ref => $serviceContent->fileManager);
|
my $file_manager = Vim::get_view(mo_ref => $service_content->fileManager);
|
||||||
my $dc = Vim::find_entity_view(
|
my $dc = Vim::find_entity_view(
|
||||||
view_type => "Datacenter",
|
view_type => "Datacenter",
|
||||||
filter => {'name' => $config{datacenter}}
|
filter => {'name' => $config{datacenter}}
|
||||||
);
|
);
|
||||||
|
|
||||||
$fileManager->MakeDirectory(
|
log_message "Creating temporary backup directory: $ds_tmp_dir";
|
||||||
name => $dsBackupPath,
|
$file_manager->MakeDirectory(
|
||||||
|
name => $ds_tmp_dir,
|
||||||
datacenter => $dc,
|
datacenter => $dc,
|
||||||
createParentDirectories => true
|
createParentDirectories => true
|
||||||
);
|
);
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$fileManager->CopyDatastoreFile(
|
my $vm_path_name = $vm->config->files->vmPathName;
|
||||||
sourceName => $vm->config->files->vmPathName,
|
log_message "Copying machine configuration file: $vm_path_name";
|
||||||
|
|
||||||
|
$file_manager->CopyDatastoreFile(
|
||||||
|
sourceName => $vm_path_name,
|
||||||
sourceDatacenter => $dc,
|
sourceDatacenter => $dc,
|
||||||
destinationName => "$dsBackupPath/$vmname.vmx",
|
destinationName => "$ds_tmp_dir/$vm_name.vmx",
|
||||||
destinationDatacenter => $dc
|
destinationDatacenter => $dc
|
||||||
);
|
);
|
||||||
|
|
||||||
my $vdm = Vim::get_view(mo_ref => $serviceContent->virtualDiskManager);
|
my $vdm = Vim::get_view(mo_ref => $service_content->virtualDiskManager);
|
||||||
my $devices = $vm->config->hardware->device;
|
my $devices = $vm->config->hardware->device;
|
||||||
|
|
||||||
$vm->RemoveAllSnapshots();
|
$vm->RemoveAllSnapshots();
|
||||||
|
@ -385,13 +406,14 @@ sub backup_machine() {
|
||||||
|
|
||||||
foreach my $device (@$devices) {
|
foreach my $device (@$devices) {
|
||||||
if ($device->isa('VirtualDisk')) {
|
if ($device->isa('VirtualDisk')) {
|
||||||
my $diskPath = $device->backing->fileName;
|
my $disk_path = $device->backing->fileName;
|
||||||
my $diskFile = basename($diskPath);
|
my $disk_file = basename($disk_path);
|
||||||
|
log_message "Copying virtual disk file: $disk_path";
|
||||||
|
|
||||||
$vdm->CopyVirtualDisk(
|
$vdm->CopyVirtualDisk(
|
||||||
sourceName => $diskPath,
|
sourceName => $disk_path,
|
||||||
sourceDatacenter => $dc,
|
sourceDatacenter => $dc,
|
||||||
destName => "$dsBackupPath/$diskFile",
|
destName => "$ds_tmp_dir/$disk_file",
|
||||||
destDatacenter => $dc
|
destDatacenter => $dc
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -399,34 +421,40 @@ sub backup_machine() {
|
||||||
|
|
||||||
$vm->RemoveAllSnapshots();
|
$vm->RemoveAllSnapshots();
|
||||||
|
|
||||||
system("tar -I pigz -cf $tarFile -C $localTmpDir .");
|
log_message "Compressing to TAR file: $tar_file";
|
||||||
|
system("tar -I pigz -cf $tar_file -C $local_tmp_dir .");
|
||||||
};
|
};
|
||||||
my $err = $@;
|
my $err = $@;
|
||||||
|
|
||||||
rmtree($localTmpDir);
|
if ($err) {
|
||||||
|
log_error "An error ocurred during '$vm_name' backup, aborting."
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "Removing temporary directory: $local_tmp_dir";
|
||||||
|
rmtree($local_tmp_dir);
|
||||||
|
|
||||||
if ($err) {
|
if ($err) {
|
||||||
die $err;
|
die $err;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Backup of '$vmname' successfully created";
|
log_message "Backup of '$vm_name' successfully created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rotate_backup() {
|
sub rotate_backup() {
|
||||||
log_message "Rotating '$vmname' backups";
|
log_message "Rotating '$vm_name' backups.";
|
||||||
|
|
||||||
use List::Util qw[min];
|
use List::Util qw[min];
|
||||||
|
|
||||||
my $local_dir = "$local_backup_dir/$vmname";
|
my $local_dir = "$local_backup_dir/$vm_name";
|
||||||
|
|
||||||
if ($rotation_days == 0 && $rotation_count == 0) {
|
if ($rotation_days == 0 && $rotation_count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $regex = qr/\Q$vmname\E_(\d{4}-\d{2}-\d{2}_\d{2}-\d{2})\.tar\.gz$/;
|
my $regex = qr/\Q$vm_name\E_(\d{4}-\d{2}-\d{2}_\d{2}-\d{2})\.tar\.gz$/;
|
||||||
|
|
||||||
my @deleteFiles;
|
my @delete_files;
|
||||||
my $fileCount = 0;
|
my $file_count = 0;
|
||||||
|
|
||||||
my $rotateTime = Time::Piece->new();
|
my $rotateTime = Time::Piece->new();
|
||||||
$rotateTime -= ONE_DAY * $rotation_days;
|
$rotateTime -= ONE_DAY * $rotation_days;
|
||||||
|
@ -437,57 +465,57 @@ sub rotate_backup() {
|
||||||
unless (@reResult = $file =~ $regex) {
|
unless (@reResult = $file =~ $regex) {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
$fileCount++;
|
$file_count++;
|
||||||
my ($fileMatch) = @reResult;
|
my ($fileMatch) = @reResult;
|
||||||
my $fileTime = Time::Piece->strptime($fileMatch, $time_pattern);
|
my $fileTime = Time::Piece->strptime($fileMatch, $time_pattern);
|
||||||
|
|
||||||
if ($fileTime < $rotateTime) {
|
if ($fileTime < $rotateTime) {
|
||||||
push(@deleteFiles, $file);
|
push(@delete_files, $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $removeCount = scalar(@deleteFiles);
|
my $delete_count = scalar(@delete_files);
|
||||||
my $keptCount = $fileCount - $removeCount;
|
my $kept_count = $file_count - $delete_count;
|
||||||
|
|
||||||
if ($keptCount < $rotation_count) {
|
if ($kept_count < $rotation_count) {
|
||||||
@deleteFiles = sort @deleteFiles;
|
@delete_files = sort @delete_files;
|
||||||
splice(@deleteFiles, -min($rotation_count - $keptCount, $removeCount));
|
splice(@delete_files, -min($rotation_count - $kept_count, $delete_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
$removeCount = scalar(@deleteFiles);
|
$delete_count = scalar(@delete_files);
|
||||||
|
|
||||||
if ($removeCount == $fileCount) {
|
if ($delete_count == $file_count) {
|
||||||
die "Rotation aborted, because is trying to remove all backups";
|
die "Rotation aborted, because is trying to remove all backups.";
|
||||||
}
|
}
|
||||||
foreach my $deleteFile (@deleteFiles) {
|
foreach my $deleteFile (@delete_files) {
|
||||||
log_message "Removing $deleteFile (Not done until script is tested for a while)";
|
log_message "Removing $deleteFile (Not done until script is tested for a while).";
|
||||||
#unlink $deleteFile;
|
#unlink $deleteFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scalar(@deleteFiles) == 0) {
|
if (scalar(@delete_files) == 0) {
|
||||||
log_message "No backups to clean";
|
log_message "No backups to clean.";
|
||||||
} else {
|
} else {
|
||||||
log_message "$removeCount backups cleaned";
|
log_message "$delete_count backups cleaned.";
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir($dh);
|
closedir($dh);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub clone_machine {
|
sub clone_machine {
|
||||||
log_message "Cloning '$vmname' to '$dst_name'";
|
log_message "Cloning '$vm_name' to '$dst_name'.";
|
||||||
|
|
||||||
check_datastore();
|
check_datastore();
|
||||||
|
|
||||||
my $vmOriginal = Vim::find_entity_view(
|
my $original_vm = Vim::find_entity_view(
|
||||||
view_type => 'VirtualMachine',
|
view_type => 'VirtualMachine',
|
||||||
filter => {'name' => $dst_name}
|
filter => {'name' => $dst_name}
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($vmOriginal) {
|
if ($original_vm) {
|
||||||
if ($overwrite) {
|
if ($overwrite) {
|
||||||
set_power_state($vmOriginal, "poweredOff");
|
set_power_state($original_vm, "poweredOff");
|
||||||
sleep(20);
|
sleep(20);
|
||||||
$vmOriginal->Destroy();
|
$original_vm->Destroy();
|
||||||
} else {
|
} else {
|
||||||
die "Machine with same name exists"
|
die "Machine with same name exists"
|
||||||
}
|
}
|
||||||
|
@ -509,12 +537,12 @@ sub clone_machine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $relocateSpec;
|
my $relocate_spec;
|
||||||
my $macType = "Generated";
|
my $mac_type = "Generated";
|
||||||
my $host_view = $vm->summary->runtime->host;
|
my $host_view = $vm->summary->runtime->host;
|
||||||
|
|
||||||
if (defined($mac)) {
|
if (defined($mac)) {
|
||||||
$macType = "Manual"
|
$mac_type = "Manual"
|
||||||
}
|
}
|
||||||
if (defined ($dst_host)) {
|
if (defined ($dst_host)) {
|
||||||
$host_view = Vim::find_entity_view(
|
$host_view = Vim::find_entity_view(
|
||||||
|
@ -531,13 +559,13 @@ sub clone_machine {
|
||||||
filter => {'name' => $dst_datastore},
|
filter => {'name' => $dst_datastore},
|
||||||
properties => ['name']
|
properties => ['name']
|
||||||
);
|
);
|
||||||
$relocateSpec = VirtualMachineRelocateSpec->new(
|
$relocate_spec = VirtualMachineRelocateSpec->new(
|
||||||
pool => $comp_res_view->resourcePool,
|
pool => $comp_res_view->resourcePool,
|
||||||
host => $host_view,
|
host => $host_view,
|
||||||
datastore => $ds_new
|
datastore => $ds_new
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$relocateSpec = VirtualMachineRelocateSpec->new(
|
$relocate_spec = VirtualMachineRelocateSpec->new(
|
||||||
pool => $comp_res_view->resourcePool,
|
pool => $comp_res_view->resourcePool,
|
||||||
host => $host_view
|
host => $host_view
|
||||||
);
|
);
|
||||||
|
@ -553,31 +581,31 @@ sub clone_machine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $currMac = $vnic_device->macAddress;
|
my $curr_mac = $vnic_device->macAddress;
|
||||||
my $network = Vim::get_view(mo_ref => $vnic_device->backing->network, properties => ['name']);
|
my $network = Vim::get_view(mo_ref => $vnic_device->backing->network, properties => ['name']);
|
||||||
|
|
||||||
my $config_spec_operation = VirtualDeviceConfigSpecOperation->new('edit');
|
my $config_spec_operation = VirtualDeviceConfigSpecOperation->new('edit');
|
||||||
my $backing_info = VirtualEthernetCardNetworkBackingInfo->new(deviceName => $network->{'name'});
|
my $backing_info = VirtualEthernetCardNetworkBackingInfo->new(deviceName => $network->{'name'});
|
||||||
|
|
||||||
my $nicType = ref($vnic_device);
|
my $nic_type = ref($vnic_device);
|
||||||
my @nicClasses = (
|
my @nic_classes = (
|
||||||
'VirtualE1000',
|
'VirtualE1000',
|
||||||
'VirtualPCNet32',
|
'VirtualPCNet32',
|
||||||
'VirtualVmxnet2',
|
'VirtualVmxnet2',
|
||||||
'VirtualVmxnet3'
|
'VirtualVmxnet3'
|
||||||
);
|
);
|
||||||
|
|
||||||
if (not($nicType ~~ @nicClasses)) {
|
if (not($nic_type ~~ @nic_classes)) {
|
||||||
Util::disconnect();
|
Util::disconnect();
|
||||||
die "Unable to retrieve NIC type";
|
die "Unable to retrieve NIC type.";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $newNetworkDevice = $nicType->new(
|
my $new_network_device = $nic_type->new(
|
||||||
key => $vnic_device->key,
|
key => $vnic_device->key,
|
||||||
unitNumber => $vnic_device->unitNumber,
|
unitNumber => $vnic_device->unitNumber,
|
||||||
controllerKey => $vnic_device->controllerKey,
|
controllerKey => $vnic_device->controllerKey,
|
||||||
backing => $backing_info,
|
backing => $backing_info,
|
||||||
addressType => $macType,
|
addressType => $mac_type,
|
||||||
macAddress => $mac
|
macAddress => $mac
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -596,10 +624,10 @@ sub clone_machine {
|
||||||
);
|
);
|
||||||
|
|
||||||
my $guest_id = ($vm->guest->guestId =~ m/^other/) ? "debian6_64Guest" : $vm->guest->guestId;
|
my $guest_id = ($vm->guest->guestId =~ m/^other/) ? "debian6_64Guest" : $vm->guest->guestId;
|
||||||
my $vm_dev_spec = VirtualDeviceConfigSpec->new(device => $newNetworkDevice, operation => $config_spec_operation);
|
my $vm_dev_spec = VirtualDeviceConfigSpec->new(device => $new_network_device, operation => $config_spec_operation);
|
||||||
my $extra_conf = OptionValue->new(key => "guestinfo.hostname", value => $dst_name);
|
my $extra_conf = OptionValue->new(key => "guestinfo.hostname", value => $dst_name);
|
||||||
|
|
||||||
my $changeSpec = VirtualMachineConfigSpec->new(
|
my $change_spec = VirtualMachineConfigSpec->new(
|
||||||
deviceChange => [$vm_dev_spec],
|
deviceChange => [$vm_dev_spec],
|
||||||
name => $dst_name,
|
name => $dst_name,
|
||||||
memoryMB => $memory,
|
memoryMB => $memory,
|
||||||
|
@ -609,37 +637,37 @@ sub clone_machine {
|
||||||
memoryAllocation => $mem_res,
|
memoryAllocation => $mem_res,
|
||||||
extraConfig => [$extra_conf]
|
extraConfig => [$extra_conf]
|
||||||
);
|
);
|
||||||
my $cloneSpec = VirtualMachineCloneSpec->new(
|
my $clone_spec = VirtualMachineCloneSpec->new(
|
||||||
powerOn => $poweron,
|
powerOn => $poweron,
|
||||||
template => 0,
|
template => 0,
|
||||||
location => $relocateSpec,
|
location => $relocate_spec,
|
||||||
config => $changeSpec
|
config => $change_spec
|
||||||
);
|
);
|
||||||
|
|
||||||
$vm->CloneVM(
|
$vm->CloneVM(
|
||||||
folder => $vm->parent,
|
folder => $vm->parent,
|
||||||
name => $dst_name,
|
name => $dst_name,
|
||||||
spec => $cloneSpec
|
spec => $clone_spec
|
||||||
);
|
);
|
||||||
|
|
||||||
log_message "Clone '$dst_name' of '$vmname' successfully created";
|
log_message "Clone '$dst_name' of '$vm_name' successfully created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub snapshot_machine() {
|
sub snapshot_machine() {
|
||||||
log_message "Creating snapshot of '$vmname' with CBT $cbt";
|
log_message "Creating snapshot of '$vm_name' with CBT $cbt.";
|
||||||
|
|
||||||
if ($cbt) {
|
if ($cbt) {
|
||||||
if ($vm->capability->changeTrackingSupported) {
|
if ($vm->capability->changeTrackingSupported) {
|
||||||
setCBT(true);
|
setCBT(true);
|
||||||
} else {
|
} else {
|
||||||
die "CBT not supported";
|
die "CBT not supported.";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $vmbackup = Vim::find_entity_view(
|
my $vm_backup = Vim::find_entity_view(
|
||||||
view_type => 'VirtualMachine',
|
view_type => 'VirtualMachine',
|
||||||
filter => {'name' => $dst_name}
|
filter => {'name' => $dst_name}
|
||||||
);
|
);
|
||||||
my $devices = $vmbackup->config->hardware->device;
|
my $devices = $vm_backup->config->hardware->device;
|
||||||
my $vm_dst_datastore;
|
my $vm_dst_datastore;
|
||||||
|
|
||||||
foreach (@$devices) {
|
foreach (@$devices) {
|
||||||
|
@ -658,27 +686,27 @@ sub snapshot_machine() {
|
||||||
my $vm_ds = Vim::get_views(mo_ref_array => $vm->get_property('datastore'));
|
my $vm_ds = Vim::get_views(mo_ref_array => $vm->get_property('datastore'));
|
||||||
$vm_datastore = join(',', map($_->get_property('name'), @{$vm_ds}));
|
$vm_datastore = join(',', map($_->get_property('name'), @{$vm_ds}));
|
||||||
|
|
||||||
my $vmFolder = "/vmfs/volumes/$vm_datastore/$vmname";
|
my $vm_folder = "/vmfs/volumes/$vm_datastore/$vm_name";
|
||||||
|
|
||||||
my $command = "cd $vmFolder && ".q[ls -lhr *-0*-ctk.vmdk|head -n1 |awk '{print $9}' |cut -c].(length($vmname)+2)."-".(length($vmname)+7);
|
my $command = "cd $vm_folder && ".q[ls -lhr *-0*-ctk.vmdk|head -n1 |awk '{print $9}' |cut -c].(length($vm_name)+2)."-".(length($vm_name)+7);
|
||||||
my $fic_snap = execute_ssh_command($command);
|
my $snap_file = execute_ssh_command($command);
|
||||||
|
|
||||||
if (length($fic_snap) > 0) {
|
if (length($snap_file) > 0) {
|
||||||
$command = "cd $vmFolder && ".q[ls -lhr *-0*-delta.vmdk|head -n1 |awk '{print $5}' | sed '$s/...$//'];
|
$command = "cd $vm_folder && ".q[ls -lhr *-0*-delta.vmdk|head -n1 |awk '{print $5}' | sed '$s/...$//'];
|
||||||
my $tamano_snp = execute_ssh_command($command);
|
my $snp_size = execute_ssh_command($command);
|
||||||
|
|
||||||
if (($tamano_snp + 0) >= $cbt_size) {
|
if (($snp_size + 0) >= $cbt_size) {
|
||||||
set_power_state($vmbackup, "poweredOff");
|
set_power_state($vm_backup, "poweredOff");
|
||||||
|
|
||||||
$command = "scp -i /etc/ssh/ssh_host_dsa_key $vmFolder/$vmname.vmdk root@"."$dst_host:/vmfs/volumes/$dst_datastore/$vm_dst_datastore";
|
$command = "scp -i /etc/ssh/ssh_host_dsa_key $vm_folder/$vm_name.vmdk root@"."$dst_host:/vmfs/volumes/$dst_datastore/$vm_dst_datastore";
|
||||||
execute_ssh_command($command);
|
execute_ssh_command($command);
|
||||||
|
|
||||||
create_snapshot($vm);
|
create_snapshot($vm);
|
||||||
create_snapshot($vmbackup);
|
create_snapshot($vm_backup);
|
||||||
|
|
||||||
my $fichero = "$vmname-".substr($fic_snap,0,length($fic_snap)-1)."*.vmdk";
|
my $vmdk_file = "$vm_name-".substr($snap_file,0,length($snap_file)-1)."*.vmdk";
|
||||||
log_message "Copying snapshot $fichero is less or equal than $cbt_size with a size of ".length($fic_snap)."";
|
log_message "Copying snapshot $vmdk_file is less or equal than $cbt_size with a size of ".length($snap_file).".";
|
||||||
$command = "scp -i /etc/ssh/ssh_host_dsa_key $vmFolder/$fichero root@"."$dst_host:/vmfs/volumes/$dst_datastore/$vm_dst_datastore";
|
$command = "scp -i /etc/ssh/ssh_host_dsa_key $vm_folder/$vmdk_file root@"."$dst_host:/vmfs/volumes/$dst_datastore/$vm_dst_datastore";
|
||||||
execute_ssh_command($command);
|
execute_ssh_command($command);
|
||||||
|
|
||||||
# Deletes all snapshots
|
# Deletes all snapshots
|
||||||
|
@ -686,7 +714,7 @@ sub snapshot_machine() {
|
||||||
$vm->RemoveAllSnapshots();
|
$vm->RemoveAllSnapshots();
|
||||||
create_snapshot($vm);
|
create_snapshot($vm);
|
||||||
} else {
|
} else {
|
||||||
log_message "No snapshot is made since the size of $vmname-$fic_snap-delta.vmdk is less than $cbt_size";
|
log_message "No snapshot is made since the size of $vm_name-$snap_file-delta.vmdk is less than $cbt_size.";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_message "Creating first snapshot";
|
log_message "Creating first snapshot";
|
||||||
|
@ -696,11 +724,11 @@ sub snapshot_machine() {
|
||||||
create_snapshot($vm);
|
create_snapshot($vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Snapshot of '$vmname' successfully created";
|
log_message "Snapshot of '$vm_name' successfully created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub migrate_machine {
|
sub migrate_machine {
|
||||||
log_message "Migrating '$vmname' to $dst_host";
|
log_message "Migrating '$vm_name' to $dst_host.";
|
||||||
|
|
||||||
unless ($priority) {
|
unless ($priority) {
|
||||||
$priority = "highPriority";
|
$priority = "highPriority";
|
||||||
|
@ -735,19 +763,23 @@ sub migrate_machine {
|
||||||
);
|
);
|
||||||
$vm->PowerOnVM();
|
$vm->PowerOnVM();
|
||||||
|
|
||||||
log_message "Migration of '$vmname' successfull";
|
log_message "Migration of '$vm_name' successfull.";
|
||||||
}
|
}
|
||||||
|
|
||||||
#--------------------------------- Utils
|
#--------------------------------- Utils
|
||||||
|
|
||||||
sub open_machine() {
|
sub open_machine() {
|
||||||
|
unless ($vm_name) {
|
||||||
|
die "Machine name not set.";
|
||||||
|
}
|
||||||
|
|
||||||
$vm = Vim::find_entity_view(
|
$vm = Vim::find_entity_view(
|
||||||
view_type => 'VirtualMachine',
|
view_type => 'VirtualMachine',
|
||||||
filter => {name => $vmname}
|
filter => {name => $vm_name}
|
||||||
);
|
);
|
||||||
|
|
||||||
unless ($vm) {
|
unless ($vm) {
|
||||||
die "Machine '$vmname' not found";
|
die "Machine '$vm_name' not found.";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $vm_remote_host = $vm->runtime->host;
|
my $vm_remote_host = $vm->runtime->host;
|
||||||
|
@ -759,7 +791,7 @@ sub open_machine() {
|
||||||
$vm_datastore = $_->{name};
|
$vm_datastore = $_->{name};
|
||||||
}
|
}
|
||||||
|
|
||||||
log_message "Found machine '$vmname' at host $remote_host at datastore '$vm_datastore'";
|
log_message "Found machine '$vm_name' at host $remote_host at datastore '$vm_datastore'.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub setCBT {
|
sub setCBT {
|
||||||
|
@ -768,7 +800,7 @@ sub setCBT {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eval {
|
eval {
|
||||||
log_message "Switching CBT to $enable";
|
log_message "Switching CBT to $enable.";
|
||||||
my $spec = Vim::VirtualMachineConfigSpec->new(changeTrackingEnabled => $enable);
|
my $spec = Vim::VirtualMachineConfigSpec->new(changeTrackingEnabled => $enable);
|
||||||
my $task = $vm->ReconfigVM_Task(spec => $spec);
|
my $task = $vm->ReconfigVM_Task(spec => $spec);
|
||||||
};
|
};
|
||||||
|
@ -776,12 +808,12 @@ sub setCBT {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub create_snapshot {
|
sub create_snapshot {
|
||||||
my ($vmsnapshot) = @_;
|
my ($vm_snapshot) = @_;
|
||||||
|
|
||||||
my $spec = VirtualMachineConfigSpec->new(changeTrackingEnabled => $cbt);
|
my $spec = VirtualMachineConfigSpec->new(changeTrackingEnabled => $cbt);
|
||||||
$vmsnapshot->ReconfigVM_Task(spec => $spec);
|
$vm_snapshot->ReconfigVM_Task(spec => $spec);
|
||||||
|
|
||||||
$vmsnapshot->CreateSnapshot(
|
$vm_snapshot->CreateSnapshot(
|
||||||
name => $snapshot_name,
|
name => $snapshot_name,
|
||||||
description => $snapshot_desc,
|
description => $snapshot_desc,
|
||||||
memory => 0,
|
memory => 0,
|
||||||
|
@ -791,8 +823,8 @@ sub create_snapshot {
|
||||||
|
|
||||||
sub execute_ssh_command {
|
sub execute_ssh_command {
|
||||||
my ($command) = @_;
|
my ($command) = @_;
|
||||||
my $promptEnd = '/\w+[\$\%\#\>]\s{0,1}$/o';
|
my $prompt_end = '/\w+[\$\%\#\>]\s{0,1}$/o';
|
||||||
my $ssh = Net::OpenSSH->new($remote_host) or die "Cannot connect to $dst_host via SSH";
|
my $ssh = Net::OpenSSH->new($remote_host) or die "Cannot connect to $dst_host via SSH.";
|
||||||
log_message "SSH: $remote_host: $command";
|
log_message "SSH: $remote_host: $command";
|
||||||
my $result = $ssh->capture($command);
|
my $result = $ssh->capture($command);
|
||||||
log_message "SSH: Result: $result";
|
log_message "SSH: Result: $result";
|
||||||
|
@ -801,18 +833,18 @@ sub execute_ssh_command {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub set_power_state {
|
sub set_power_state {
|
||||||
my ($vmPower, $state) = @_;
|
my ($vm_power, $state) = @_;
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
if ($vmPower->runtime->powerState->val ne $state) {
|
if ($vm_power->runtime->powerState->val ne $state) {
|
||||||
given ($state) {
|
given ($state) {
|
||||||
when ('poweredOff') {
|
when ('poweredOff') {
|
||||||
$vmPower->ShutdownGuest();
|
$vm_power->ShutdownGuest();
|
||||||
log_message "Turning off ".$vmPower->name;
|
log_message "Turning off ".$vm_power->name;
|
||||||
}
|
}
|
||||||
when ('poweredOn') {
|
when ('poweredOn') {
|
||||||
$vmPower->PowerOnVM();
|
$vm_power->PowerOnVM();
|
||||||
log_message "Turning on ".$vmPower->name;
|
log_message "Turning on ".$vm_power->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sleep(50);
|
sleep(50);
|
||||||
|
@ -837,5 +869,5 @@ sub check_datastore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
die "Datastore '$dst_datastore' does not exist";
|
die "Datastore '$dst_datastore' does not exist.";
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue