Bugs fixed

This commit is contained in:
Juan 2018-08-14 16:23:33 +02:00
parent d0022ba3ce
commit fee9a47f3f
7 changed files with 175 additions and 127 deletions

View File

@ -2,7 +2,7 @@
# Don't modify this file, copy it to config.my.pl and make your changes there.
# The log file path
log_file = '/var/log/vn-vmware.log',
log_file => '/var/log/vn-vmware.log',
# Hostname or IP address of vCenter host
hostname => 'vcenter',

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
vn-vmware (2.0.34) stable; urgency=low
vn-vmware (1.0.0) stable; urgency=low
* Initial Release.

2
debian/control vendored
View File

@ -1,7 +1,7 @@
Source: vn-vmware
Priority: optional
Maintainer: Juan Ferrer Toribio <juan@verdnatura.es>
Build-Depends: build-essential, debhelper
Build-Depends: devscripts
Standards-Version: 3.9.3
Section: misc
Homepage: https://verdnatura.es

2
debian/links vendored
View File

@ -1 +1 @@
usr/share/vn-vmware.pl usr/bin/vn-vmware.pl
usr/share/vn-vmware/vn-vmware.pl usr/bin/vn-vmware.pl

1
debian/rules vendored
View File

@ -2,4 +2,3 @@
%:
dh $@

12
deploy.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
pkg="vn-vmware_1.0.0"
debPkg="${pkg}_all.deb"
host="root@bacula"
debuild -us -uc -b
#scp ../$debPkg $host:/root
#ssh $host dpkg -i /root/$debPkg
#ssh $host rm /root/$debPkg
debian/rules clean
rm ../${pkg}*

View File

@ -23,18 +23,18 @@ use constant true => 1;
my %opts = (
operation => {
type => "=s",
help => "Operation to perform: backuping, cloning,rotate, backup, clone, snapshot, migrate",
help => "Operation to perform: backuping, cloning, rotate, backup, clone, snapshot, migrate",
required => true
},
job => {
type => "=s",
help => "The job name"
},
vmname => {
type => "=s",
variable => "vmname",
help => "Name of the virtual machine"
},
job => {
type => "=s",
help => "The job name"
},
rotation_days => {
type => "=i",
help => "Rotation days for backups",
@ -108,6 +108,11 @@ my %opts = (
help => "Whether to power on machine after operation",
default => 1
},
show_logs => {
type => "",
help => "Whether to redirect logs to stdout",
default => 0
},
snapshot_name => {
type => "=s",
help => "Name of the snapshot",
@ -124,9 +129,9 @@ Opts::add_options(%opts);
Opts::parse();
Opts::validate();
my $vmname = Opts::get_option('vmname');
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');
@ -143,46 +148,77 @@ 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 $log_fh;
my $vm;
my $remote_host;
my $vm_datastore;
my $time_pattern = '%Y-%m-%d_%H-%M';
my $local_backup_dir = %config{local_backup_dir};
my $backup_datastore = %config{backup_datastore};
my $vcenter_host = %config{hostname};
my $username = %config{user};
my %config;
my $config_files = (
'config.my.pl',
'config.pl',
my @config_files = (
'/etc/vn-vmware/config.my.pl',
'/etc/vn-vmware/config.pl'
'/etc/vn-vmware/config.pl',
'config.my.pl',
'config.pl'
);
foreach my $config_file (@$config_files) {
foreach my $config_file (@config_files) {
if (-e $config_file) {
%config = do $config_file;
last;
}
}
unless (%config) {
die "Configuration file not found";
}
my $vm;
my $remote_host;
my $vm_datastore;
my $log_fh;
my $time_pattern = '%Y-%m-%d_%H-%M';
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";
}
sub log_message {
my ($message) = @_;
if ($log_fh) {
log_to_file $message;
} else {
print "$message\n"
}
}
sub log_error {
my ($message) = @_;
print STDERR color("red").$message.color("reset");
if ($log_fh) {
log_to_file $message;
}
}
unless ($show_logs) {
open($log_fh, '>', $config{log_file});
}
eval {
&main();
main();
};
if (my $err = $@) {
print STDERR color("red").$err.color("reset");
log $err;
if ($@) {
log_error($@);
}
if ($log_fh) {
close $log_fh;
}
sub main {
$log_fh = STDOUT;
my $vcenter_host = $config{hostname};
my $username = $config{user};
VMware::VICredStore::init(filename => %config{credentials_file});
VMware::VICredStore::init(filename => $config{credentials_file});
my $password = VMware::VICredStore::get_password(server => $vcenter_host, username => $username);
my $url = "https://$vcenter_host/sdk/vimService";
@ -201,44 +237,41 @@ sub main {
die "Cannot connect to $vcenter_host";
}
log "Connected to $vcenter_host";
log_message "Connected to $vcenter_host";
eval {
given ($operation) {
when ('backuping') {
&open_log();
&backuping();
backup_job();
}
when ('cloning') {
&open_log();
&cloning();
clone_job();
}
when ('rotate') {
&rotate_backup();
rotate_backup();
}
when ('backup') {
&open_machine();
&backup_machine();
open_machine();
backup_machine();
}
when ('clone') {
&open_machine();
&clone_machine();
open_machine();
clone_machine();
}
when ('snapshot') {
&open_machine();
&snapshot_machine();
open_machine();
snapshot_machine();
}
when ('migrate') {
&open_machine();
&migrate_machine();
open_machine();
migrate_machine();
}
}
};
my $err = $@;
Vim::logout();
close $log_fh;
if ($err) {
die $err;
@ -247,53 +280,68 @@ sub main {
#--------------------------------- Operations
sub backuping() {
log "Backup job '$job' started";
my %schedule = %config{schedules}{$job};
my %rotation_cfg = %config{rotations}{%schedule{rotation}}
$rotation_count = %rotation_cfg{count};
$rotation_days = %rotation_cfg{days};
my @machines = %schedule{machines};
foreach $vmname (@$machines) {
&open_machine();
&backup_machine();
&rotate_backup();
sub backup_job() {
unless (exists $config{schedules}{$job}) {
die "Backup job '$job' doesn't exists";
}
log "Backup job '$job' finished";
log_message "Backup job '$job' started";
my $schedule = $config{schedules}{friday};
my $rotation_cfg = $config{rotations}{$schedule->{rotation}};
$rotation_count = $rotation_cfg->{count};
$rotation_days = $rotation_cfg->{days};
my @machines = $schedule->{machines};
foreach $vmname (@machines) {
eval {
print "$vmname\n";
#open_machine();
#backup_machine();
#rotate_backup();
};
if ($@) {
log_error($@);
}
}
log_message "Backup job '$job' finished";
}
sub cloning() {
log "Clone job '$job' started";
sub clone_job() {
unless (exists $config{clone}{$job}) {
die "Cloning job '$job' doesn't exists";
}
my %cfg = %config{clone}{$job};
log_message "Clone job '$job' started";
$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};
my $cfg = $config{clone}{$job};
&open_machine();
&clone_machine();
$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};
log "Clone job '$job' finished";
open_machine();
clone_machine();
log_message "Clone job '$job' finished";
}
sub backup_machine() {
log "Backup of '$vmname' started";
log_message "Backup of '$vmname' started";
my $time = Time::Piece->new;
my $timeMark = $time->strftime($time_pattern);
my $tmpDir = ".$timeMark";
my $backup_datastore = $config{backup_datastore};
my $dsBackupPath = "[$backup_datastore] $vmname/$tmpDir";
my $local_dir = "$local_backup_dir/$vmname";
my $localTmpDir = "$local_dir/$tmpDir";
@ -307,7 +355,7 @@ sub backup_machine() {
my $fileManager = Vim::get_view(mo_ref => $serviceContent->fileManager);
my $dc = Vim::find_entity_view(
view_type => "Datacenter",
filter => {'name' => $datacenter}
filter => {'name' => $config{datacenter}}
);
$fileManager->MakeDirectory(
@ -361,11 +409,11 @@ sub backup_machine() {
die $err;
}
log "Backup of '$vmname' successfully created";
log_message "Backup of '$vmname' successfully created";
}
sub rotate_backup() {
log "Rotating '$vmname' backups";
log_message "Rotating '$vmname' backups";
use List::Util qw[min];
@ -406,38 +454,38 @@ sub rotate_backup() {
splice(@deleteFiles, -min($rotation_count - $keptCount, $removeCount));
}
my $removeCount = scalar(@deleteFiles);
$removeCount = scalar(@deleteFiles);
if ($removeCount == $fileCount) {
die "Rotation aborted, because is trying to remove all backups";
}
foreach my $deleteFile (@deleteFiles) {
log "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;
}
if (scalar(@deleteFiles) == 0) {
log "No backups to clean";
log_message "No backups to clean";
} else {
log "$removeCount backups cleaned";
log_message "$removeCount backups cleaned";
}
closedir($dh);
}
sub clone_machine {
log "Cloning '$vmname' to '$dst_name'";
log_message "Cloning '$vmname' to '$dst_name'";
&check_datastore();
check_datastore();
my $vmOriginal = Vim::find_entity_view(
view_type => 'VirtualMachine',
filter => {'name' => $dst_name}
);
if ($vmOriginal) {
if ($overwrite) {
&set_power_state($vmOriginal, "poweredOff");
set_power_state($vmOriginal, "poweredOff");
sleep(20);
$vmOriginal->Destroy();
} else {
@ -549,7 +597,7 @@ 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 $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(
deviceChange => [$vm_dev_spec],
@ -574,15 +622,15 @@ sub clone_machine {
spec => $cloneSpec
);
log "Clone '$dst_name' of '$vmname' successfully created";
log_message "Clone '$dst_name' of '$vmname' successfully created";
}
sub snapshot_machine() {
log "Creating snapshot of '$vmname' with CBT $cbt";
log_message "Creating snapshot of '$vmname' with CBT $cbt";
if ($cbt) {
if ($vm->capability->changeTrackingSupported) {
&setCBT(true);
setCBT(true);
} else {
die "CBT not supported";
}
@ -613,46 +661,46 @@ sub snapshot_machine() {
my $vmFolder = "/vmfs/volumes/$vm_datastore/$vmname";
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 $fic_snap = 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);
my $tamano_snp = execute_ssh_command($command);
if (($tamano_snp + 0) >= $cbt_size) {
&set_power_state($vmbackup, "poweredOff");
set_power_state($vmbackup, "poweredOff");
$command = "scp -i /etc/ssh/ssh_host_dsa_key $vmFolder/$vmname.vmdk root@"."$dst_host:/vmfs/volumes/$dst_datastore/$vm_dst_datastore";
&execute_ssh_command($command);
execute_ssh_command($command);
&create_snapshot($vm);
&create_snapshot($vmbackup);
create_snapshot($vm);
create_snapshot($vmbackup);
my $fichero = "$vmname-".substr($fic_snap,0,length($fic_snap)-1)."*.vmdk";
log "Copying snapshot $fichero is less or equal than $cbt_size with a size of ".length($fic_snap)."";
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";
&execute_ssh_command($command);
execute_ssh_command($command);
# Deletes all snapshots
$vm->RemoveAllSnapshots();
&create_snapshot($vm);
create_snapshot($vm);
} else {
log "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 $vmname-$fic_snap-delta.vmdk is less than $cbt_size";
}
} else {
log "Creating first snapshot";
&create_snapshot($vm);
log_message "Creating first snapshot";
create_snapshot($vm);
}
} else {
&create_snapshot($vm);
create_snapshot($vm);
}
log "Snapshot of '$vmname' successfully created";
log_message "Snapshot of '$vmname' successfully created";
}
sub migrate_machine {
log "Migrating '$vmname' to $dst_host";
log_message "Migrating '$vmname' to $dst_host";
unless ($priority) {
$priority = "highPriority";
@ -687,7 +735,7 @@ sub migrate_machine {
);
$vm->PowerOnVM();
log "Migration of '$vmname' successfull";
log_message "Migration of '$vmname' successfull";
}
#--------------------------------- Utils
@ -711,18 +759,7 @@ sub open_machine() {
$vm_datastore = $_->{name};
}
log "Found machine '$vmname' at host $remote_host at datastore '$vm_datastore'";
}
sub open_log {
open($log_fh, '>', %config{log_file});
}
sub log {
my ($message) = @_;
my $time = Time::Piece->new;
my $timeMark = $time->strftime('%Y-%m-%d %H:%M:%S');
print $log_fh "$timeMark : $message\n";
log_message "Found machine '$vmname' at host $remote_host at datastore '$vm_datastore'";
}
sub setCBT {
@ -731,7 +768,7 @@ sub setCBT {
return;
}
eval {
log "Switching CBT to $enable";
log_message "Switching CBT to $enable";
my $spec = Vim::VirtualMachineConfigSpec->new(changeTrackingEnabled => $enable);
my $task = $vm->ReconfigVM_Task(spec => $spec);
};
@ -756,9 +793,9 @@ 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";
log "SSH: $remote_host: $command";
log_message "SSH: $remote_host: $command";
my $result = $ssh->capture($command);
log "SSH: Result: $result";
log_message "SSH: Result: $result";
$ssh->system('exit');
return substr($result, 0, 200);
}
@ -771,11 +808,11 @@ sub set_power_state {
given ($state) {
when ('poweredOff') {
$vmPower->ShutdownGuest();
log "Turning off ".$vmPower->name;
log_message "Turning off ".$vmPower->name;
}
when ('poweredOn') {
$vmPower->PowerOnVM();
log "Turning on ".$vmPower->name;
log_message "Turning on ".$vmPower->name;
}
}
sleep(50);