#!/usr/bin/perl use strict; use warnings; use Anvil::Tools; use Data::Dumper; use Text::Diff; use Term::Cap; use Time::Local; $| = 1; my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; if (($running_directory =~ /^\./) && ($ENV{PWD})) { $running_directory =~ s/^\./$ENV{PWD}/; } my $anvil = Anvil::Tools->new(); # Get a list of all interfaces with IP addresses. $anvil->Get->switches({debug => 2, list => ["watch"]}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); our $t = Term::Cap->Tgetent; # One shot or continuous? $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { 'switches::watch' => $anvil->data->{switches}{watch}, }}); if ($anvil->data->{switches}{watch}) { # Do we have an interval? my $interval = 2; if ($anvil->data->{switches}{watch} =~ /^\d+$/) { $interval = $anvil->data->{switches}{watch}; } $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { interval => $interval }}); # Loop until terminated. while(1) { show_status($anvil); sleep $interval; } } else { # Once and exit. show_status($anvil); } $anvil->nice_exit({exit_code => 0}); sub show_status { my ($anvil) = @_; if ($anvil->data->{switches}{watch}) { system('clear'); print $t->Tgoto("cm", 0, 0); } if ($anvil->data->{switches}{watch}) { my $date = $anvil->Get->date_and_time(); print "-=] Updated: ".$date." - Press ' + ' to exit\n"; } my $vms = {}; my $longest_resource = 3; # Res my $longest_connection = 2; # To my $longest_volume = 3; # Vol my $total_transfer = 0; my $root_directory = $anvil->data->{path}{directories}{resource_status}; local(*DIRECTORY); opendir(DIRECTORY, $root_directory); while(my $file = readdir(DIRECTORY)) { next if $file eq "."; next if $file eq ".."; my $full_path = $root_directory."/".$file; if (-d $full_path) { my $resource = $file; if (length($resource) > $longest_resource) { $longest_resource = length($resource); } $vms->{resource}{$resource} = {}; #print "Resource found: [".$resource."]\n"; } } closedir(DIRECTORY); foreach my $resource (sort {$a cmp $b} keys %{$vms->{resource}}) { my $directory = $root_directory."/".$resource."/connections"; local(*DIRECTORY); opendir(DIRECTORY, $directory); while(my $file = readdir(DIRECTORY)) { next if $file eq "."; next if $file eq ".."; my $full_path = $directory."/".$file; if (-d $full_path) { my $connection = $file; if (length($connection) > $longest_connection) { $longest_connection = length($connection); } #print "Found connection: [".$resource."] -> [".$connection."]\n"; $vms->{resource}{$resource}{connection}{$connection} = {}; } } closedir(DIRECTORY); foreach my $connection (sort {$a cmp $b} keys %{$vms->{resource}{$resource}{connection}}) { my $directory = $root_directory."/".$resource."/connections/".$connection; local(*DIRECTORY); opendir(DIRECTORY, $directory); while(my $file = readdir(DIRECTORY)) { next if $file eq "."; next if $file eq ".."; my $full_path = $directory."/".$file."/proc_drbd"; if (-r $full_path) { my $volume = $file; if (length($volume) > $longest_volume) { $longest_volume = length($volume); } #print "Found volume: [".$resource."] -> [".$connection."] -> [".$volume."]\n"; $vms->{resource}{$resource}{connection}{$connection}{volume}{$volume}{proc_drbd} = $full_path; } } closedir(DIRECTORY); } } print "Sync progress:\n"; print " ".sprintf("%-${longest_resource}s", "Res")." ".sprintf("%-${longest_connection}s", "To")." Vol\n"; foreach my $resource (sort {$a cmp $b} keys %{$vms->{resource}}) { foreach my $connection (sort {$a cmp $b} keys %{$vms->{resource}{$resource}{connection}}) { foreach my $volume (sort {$a cmp $b} keys %{$vms->{resource}{$resource}{connection}{$connection}{volume}}) { my $local_role = ""; my $peer_role = ""; my $local_disk = ""; my $peer_disk = ""; my $proc_file = $vms->{resource}{$resource}{connection}{$connection}{volume}{$volume}{proc_drbd}; my $progress = ""; open (my $file_handle, "<", $proc_file) or die "Failed to read: [".$proc_file."], error: $!\n"; while(<$file_handle>) { chomp; my $line = $_; if ($line =~ /ds:(.*?)\/(.*?) /) { $local_disk = $1; $peer_disk = $2; if (($local_disk eq "UpToDate") && ($peer_disk eq "UpToDate")) { $progress = "(UpToDate)"; } } if ($line =~ /ro:(.*?)\/(.*?) /) { $local_role = $1; $peer_role = $2; if ($peer_role eq "Unknown") { $progress = "(Disconnected)"; } } if ($line =~ /(\[.*?\])/) { $progress = $1." "; } if ($line =~ /sync'ed: (.*?\%)/) { $progress .= $1." "; } if ($line =~ /speed: (.*?) \(/) { my $speed = $1; $progress .= $speed." KiB/Sec "; $speed =~ s/\D//g; $total_transfer += $speed; } if ($line =~ /finish: (.*?) speed/) { $progress .= "(ETA ".$1.")"; } } close $file_handle; my $say_resource = sprintf("%-${longest_resource}s", $resource); my $say_connection = sprintf("%${longest_connection}s", $connection); my $say_volume = sprintf("%${longest_volume}s", $volume); print "- ".$say_resource." -> ".$say_connection." -> ".$say_volume.": ".$progress." // ds:".$local_disk."/".$peer_disk.", ro:".$local_role."/".$peer_role."\n"; } } } my $say_speed = $total_transfer / 1024; $say_speed =~ s/^(\d+\.\d{3})\d+/$1/; print "* Total transfer speed is about: [".$say_speed." MiB/sec]\n"; }