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