I am beating my head over this. It has been 2 days I feel I have tried at least a half dozen combinations in the attempts to finish this sub routine.
The problem:
The subroutine is functional, but as seen in the hash output under the key “nas” there should be 2 disks listed but only one is showing up, I have verified that the disk is actually listed in the file and I am about 98% sure my regex has the ability to match the second disk which is named “nas_1.vmdk”. The first one is called “nas.vmdk” for reference.
This is what my output looks like;
$VAR1 = {
'server02' => {
'nas' => {
'SCSI0' => {
'Disk1' => 'nas.vmdk'
}
}
},
'server01' => {
'NS02' => {
'SCSI0' => {
'Disk0' => 'NS02.vmdk'
}
},
'MX01' => {
'SCSI0' => {
'Disk0' => 'MX01.vmdk'
}
},
'NS01' => {
'SCSI0' => {
'Disk0' => 'NS01.vmdk'
}
},
'SQL01' => {
'SCSI0' => {
'Disk0' => 'SQL01.vmdk'
}
}
}
};
Like I said the VM “nas” should have a disk0 and a disk1 but only disk1 is showing up, this leads me to believe that the values for disk0 are getting overwritten by the values for disk1 before they can be written out to the hash, but I am not sure where it is going wrong.
My code:
sub discovery_find_snapshots {
foreach my $server_label (keys %virtual_machines) {
# Set the current server address to esx_host
my $esx_host = $config_file{$server_label}{address};
# Create a hash for storing the options needed by Net::OpenSSH
my %ssh_options = (
port => $config_file{$server_label}{port},
user => $config_file{$server_label}{user},
password => $config_file{$server_label}{password}
);
# Print the name of the server currently being discovered
print "Discovering snapshots for $esx_host\n";
# Create a new Net::OpenSSH object
my $ssh = Net::OpenSSH->new($esx_host, %ssh_options);
foreach my $vm (keys %{$virtual_machines{$server_label}}) {
# Create new scalars for ide port, ide disk, vmdk file and vmdk location
my $snapshot0_adapter_number;
my $snapshot0_disk_number;
my $snapshot0_file;
my $vmsd_source = $ssh->capture("cat $virtual_machines{$server_label}{$vm}{VMSD}");
if (! $vmsd_source eq '') {
while ($vmsd_source =~ m/^snapshot0\.disk([0-9]|1[0-5])\.node\s+=\s+"scsi(?<ADAPTER>[0-3])\:(?<DISK>([0-9]|1[0-5]))"/xmg) {
$snapshot0_adapter_number = "$+{ADAPTER}";
$snapshot0_disk_number = "$+{DISK}";
if ($vmsd_source =~ m/^snapshot0\.disk([0-9|1[0-5])\.fileName\s+=\s+"(?<VMDK_FILE>[^"]+?\.vmdk)"/xm) {
$snapshot0_file = "$+{VMDK_FILE}";
}
$vmsd_disks{$server_label}{$vm}{"SCSI$snapshot0_adapter_number"}{"Disk$snapshot0_disk_number"} = "$snapshot0_file";
}
} else {
print "$vm, no snapshot metadata found\n";
}
}
}
debug();
}
The subroutine “debug” is just an extra subroutine I made to allow me to centralise the use of Data::Dumper.
Oh yeah, I almost forgot. This is the information that I am trying to match against.
snapshot.lastUID = "1"
snapshot.numSnapshots = "1"
snapshot.current = "1"
snapshot0.uid = "1"
snapshot0.filename = "nas-Snapshot1.vmsn"
snapshot0.displayName = "Milestone - Test"
snapshot0.description = "Test for my script"
snapshot0.type = "1"
snapshot0.createTimeHigh = "301769"
snapshot0.createTimeLow = "-826832731"
snapshot0.numDisks = "2"
snapshot0.disk0.fileName = "nas.vmdk"
snapshot0.disk0.node = "scsi0:0"
snapshot0.disk1.fileName = "nas_1.vmdk"
snapshot0.disk1.node = "scsi0:1"
In the while loop, keep the disk number in a variable and reuse it in the following regex (in the if), like :