commit
4976ba251a
52 changed files with 3303 additions and 1399 deletions
@ -0,0 +1,57 @@ |
||||
.\" Manpage for the Anvil! server boot program |
||||
.\" Contact mkelly@alteeve.com to report issues, concerns or suggestions. |
||||
.TH anvil-manage-host "8" "Octobober 12 2023" "Anvil! Intelligent Availability™ Platform" |
||||
.SH NAME |
||||
anvil-manage-host \- Tool used to check or set various configuration options for a host. |
||||
.SH SYNOPSIS |
||||
.B anvil-manage-host |
||||
\fI\,<command> \/\fR[\fI\,options\/\fR] |
||||
.SH DESCRIPTION |
||||
|
||||
.TP |
||||
.SH OPTIONS |
||||
.TP |
||||
\-?, \-h, \fB\-\-help\fR |
||||
Show this man page. |
||||
.TP |
||||
\fB\-\-log-secure\fR |
||||
When logging, record sensitive data, like passwords. |
||||
.TP |
||||
\-v, \-vv, \-vvv |
||||
Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data. |
||||
.SS "Commands:" |
||||
.TP |
||||
\fB\-\-age\-out\-database\fR |
||||
This requests the database check for records that are too old and purge them. |
||||
.TP |
||||
\fB\-\-check\-configured\fR |
||||
Check to see if the host is marked as configured or yet. |
||||
.TP |
||||
\fB\-\-check\-database\fR |
||||
This checks to see if the database is enabled or not. |
||||
.TP |
||||
\fB\-\-check\-network\-mapping\fR |
||||
This reports if the host is currently in network mapping (this disables several features and watches the network states much more frequently) |
||||
.TP |
||||
\fB\-\-database\-active\fR |
||||
This enables the database on the local Striker dashboard. |
||||
.TP |
||||
\fB\-\-database\-inactive\fR |
||||
This disables the database on the local Striker dashboard. |
||||
.TP |
||||
\fB\-\-disable\-network\-mapping\fR |
||||
This disables the network mapping mode. |
||||
.TP |
||||
\fB\-\-enable\-network\-mapping\fR |
||||
This enables the network mapping mode. |
||||
.TP |
||||
\fB\-\-mark\-configured\fR |
||||
This marks the host as having been configured. |
||||
.TP |
||||
\fB\-\-resync\-database\fR |
||||
This forces a database resync if two or more strikers are online. |
||||
.IP |
||||
.SH AUTHOR |
||||
Written by Madison Kelly, Alteeve staff and the Anvil! project contributors. |
||||
.SH "REPORTING BUGS" |
||||
Report bugs to users@clusterlabs.org |
@ -0,0 +1,39 @@ |
||||
.\" Manpage for the Anvil! server system manager |
||||
.\" Contact mkelly@alteeve.com to report issues, concerns or suggestions. |
||||
.TH anvil-manage-server-system "8" "August 30 2023" "Anvil! Intelligent Availability™ Platform" |
||||
.SH NAME |
||||
anvil-manage-server-system \- Tool used to manage the system configuration of a hosted server. |
||||
.SH SYNOPSIS |
||||
.B anvil-manage-server-system |
||||
\fI\,<command> \/\fR[\fI\,options\/\fR] |
||||
.SH DESCRIPTION |
||||
anvil-manage-server-system \- This tool is used to manage various system configuration components of hosted servers. Storage is NOT managed here, see 'anvil-manage-server-storage' for that. |
||||
.TP |
||||
When called without switches, the list of servers than can be worked on will be displayed. |
||||
.TP |
||||
.SH OPTIONS |
||||
.TP |
||||
\-?, \-h, \fB\-\-help\fR |
||||
Show this man page. |
||||
.TP |
||||
\fB\-\-log-secure\fR |
||||
When logging, record sensitive data, like passwords. |
||||
.TP |
||||
\-v, \-vv, \-vvv |
||||
Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data. |
||||
.SS "Commands:" |
||||
.TP |
||||
\fB\-\-boot\-menu\fR <yes,no> |
||||
.TP |
||||
When called without a value, it shows if the boot menu is enabled or not. If called with 'yes', it enables the boot menu. If called with 'no', the boot meny is disabled. |
||||
.TP |
||||
\fB\-\-job\-uuid\fR |
||||
This is the jobs -> job_uuid to execute. Generally this is only used by other programs. |
||||
.TP |
||||
\fB\-\-\fR |
||||
|
||||
.IP |
||||
.SH AUTHOR |
||||
Written by Madison Kelly, Alteeve staff and the Anvil! project contributors. |
||||
.SH "REPORTING BUGS" |
||||
Report bugs to users@clusterlabs.org |
@ -0,0 +1,38 @@ |
||||
.\" Manpage for the Anvil! server boot program |
||||
.\" Contact mkelly@alteeve.com to report issues, concerns or suggestions. |
||||
.TH striker-boot-machine "8" "October 12 2023" "Anvil! Intelligent Availability™ Platform" |
||||
.SH NAME |
||||
striker-boot-machine \- Tool used to boot physical machines that have IPMI configuration information. |
||||
.SH SYNOPSIS |
||||
.B striker-boot-machine |
||||
\fI\,<command> \/\fR[\fI\,options\/\fR] |
||||
.SH DESCRIPTION |
||||
This tool is used to power up any machine in the cluster with IPMI configuration in the database. Typically this is subnodes and DR hosts, but could also be Striker dashboards if they have an IPMI BMC. If the server is found to already be om, it will NOT be booted again. |
||||
.TP |
||||
.SH OPTIONS |
||||
.TP |
||||
\-?, \-h, \fB\-\-help\fR |
||||
Show this man page. |
||||
.TP |
||||
\fB\-\-log-secure\fR |
||||
When logging, record sensitive data, like passwords. |
||||
.TP |
||||
\-v, \-vv, \-vvv |
||||
Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data. |
||||
.SS "Commands:" |
||||
.TP |
||||
\fB\-\-host\fR <name, UUID or 'all'> |
||||
This is the host name or UUID of the server to power on. If this is set to 'all', all machines that have IPMI configuration information will be checked, and if it's found to be off, it will be booted. |
||||
.TP |
||||
\fB\-\-host-uuid\fR <UUID> |
||||
This is effectively the same as \fB\-\-host\fR, but provides backwards compatibility. It's use is discouraged. |
||||
.TP |
||||
\fB\-\-job\-uuid\fR <uuid> |
||||
If this is set, the job will be processed. |
||||
.TP |
||||
Be aware that when this is used, if a server fails to boot, no further servers will be started. |
||||
.IP |
||||
.SH AUTHOR |
||||
Written by Madison Kelly, Alteeve staff and the Anvil! project contributors. |
||||
.SH "REPORTING BUGS" |
||||
Report bugs to users@clusterlabs.org |
@ -0,0 +1,37 @@ |
||||
.\" Manpage for the Anvil! server boot program |
||||
.\" Contact mkelly@alteeve.com to report issues, concerns or suggestions. |
||||
.TH striker-show-jobs "8" "October 18 2023" "Anvil! Intelligent Availability™ Platform" |
||||
.SH NAME |
||||
striker-show-jobs \- This shows the queued, running and (recently) completed jobs. |
||||
.SH SYNOPSIS |
||||
.B striker-show-jobs |
||||
\fI\,<command> \/\fR[\fI\,options\/\fR] |
||||
.SH DESCRIPTION |
||||
This shows information about jobs that are queued, running or completed within a set amount of time on the command line. |
||||
.TP |
||||
.SH OPTIONS |
||||
.TP |
||||
\-?, \-h, \fB\-\-help\fR |
||||
Show this man page. |
||||
.TP |
||||
\fB\-\-log-secure\fR |
||||
When logging, record sensitive data, like passwords. |
||||
.TP |
||||
\-v, \-vv, \-vvv |
||||
Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data. |
||||
.SS "Commands:" |
||||
.TP |
||||
\fB\-\-ended\-within\fR <seconds> |
||||
This allows viewing jobs that have already completed. This is the number of seconds (default '300') back in time that you want to see completed jobs. Jobs that completed more than this amount of time ago will be ignored. |
||||
.TP |
||||
\fB\-\-host\fR <name, UUID or 'all'> |
||||
This is the host name or UUID that you want to see jobs from. The default is 'all' and shows all machines in the Anvil! cluster. |
||||
.TP |
||||
Setting this to '0' will hide completed jobs. |
||||
\fB\-\-job\-uuid\fR <uuid> |
||||
This allows showing the details of only one specific job. |
||||
.IP |
||||
.SH AUTHOR |
||||
Written by Madison Kelly, Alteeve staff and the Anvil! project contributors. |
||||
.SH "REPORTING BUGS" |
||||
Report bugs to users@clusterlabs.org |
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,688 @@ |
||||
#!/usr/bin/perl |
||||
# |
||||
# This program will manage servers; Changing RAM, CPU cores, Growing virtual disks, adding virtual disks, |
||||
# inserting and ejecting ISO images into virtual optical media. |
||||
# |
||||
# Exit codes; |
||||
# 0 = Normal exit. |
||||
# 1 = No database connection. |
||||
# |
||||
# TODO: |
||||
# |
||||
# USAGE: |
||||
# - Show |
||||
# - anvil-manage-server-storage --server srv01-fs37 |
||||
# |
||||
|
||||
use strict; |
||||
use warnings; |
||||
use Anvil::Tools; |
||||
require POSIX; |
||||
use Term::Cap; |
||||
use Text::Diff; |
||||
use Data::Dumper; |
||||
use Sys::Virt; |
||||
|
||||
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; |
||||
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; |
||||
if (($running_directory =~ /^\./) && ($ENV{PWD})) |
||||
{ |
||||
$running_directory =~ s/^\./$ENV{PWD}/; |
||||
} |
||||
|
||||
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete. |
||||
$| = 1; |
||||
|
||||
my $anvil = Anvil::Tools->new(); |
||||
|
||||
# Read switches (target ([user@]host[:port]) and the file with the target's password. |
||||
$anvil->Get->switches({list => [ |
||||
"add", |
||||
"anvil", |
||||
"boot", |
||||
"boot-menu", |
||||
"confirm", |
||||
"disk", |
||||
"eject", |
||||
"job-uuid", |
||||
"grow", |
||||
"insert", |
||||
"optical", |
||||
"server", |
||||
"storage-group", |
||||
], man => $THIS_FILE}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }}); |
||||
|
||||
# Connect to the database(s). If we have no connections, we'll proceed anyway as one of the 'run_once' tasks |
||||
# is to setup the database server. |
||||
$anvil->Database->connect(); |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"}); |
||||
if (not $anvil->data->{sys}{database}{connections}) |
||||
{ |
||||
# No databases, update the job, sleep for a bit and then exit. The daemon will pick it up and try |
||||
# again after we exit. |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0305"}); |
||||
sleep 10; |
||||
$anvil->nice_exit({exit_code => 1}); |
||||
} |
||||
|
||||
if ($anvil->data->{switches}{'job-uuid'}) |
||||
{ |
||||
load_job($anvil); |
||||
} |
||||
|
||||
$anvil->Database->get_hosts(); |
||||
$anvil->Database->get_anvils(); |
||||
$anvil->Database->get_servers(); |
||||
|
||||
if ($anvil->data->{switches}{anvil}) |
||||
{ |
||||
# Make sure they asked for a real anvil. |
||||
$anvil->Get->anvil_from_switch({string => $anvil->data->{switches}{anvil}}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"switches::anvil_name" => $anvil->data->{switches}{anvil_name}, |
||||
"switches::anvil_uuid" => $anvil->data->{switches}{anvil_uuid}, |
||||
}}); |
||||
} |
||||
|
||||
if (not $anvil->data->{switches}{server}) |
||||
{ |
||||
# Show the list of servers. |
||||
show_server_list($anvil); |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0456"}); |
||||
$anvil->Job->update_progress({ |
||||
progress => 100, |
||||
message => "error_0456", |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
$anvil->nice_exit({exit_code => 0}); |
||||
} |
||||
|
||||
validate_server($anvil); |
||||
|
||||
if ($anvil->data->{switches}{cpu}) |
||||
{ |
||||
#manage_cpu($anvil); |
||||
} |
||||
elsif ($anvil->data->{switches}{ram}) |
||||
{ |
||||
#manage_ram($anvil); |
||||
} |
||||
elsif ($anvil->data->{switches}{boot}) |
||||
{ |
||||
#manage_boot($anvil); |
||||
} |
||||
elsif ($anvil->data->{switches}{'boot-menu'}) |
||||
{ |
||||
manage_boot_menu($anvil); |
||||
} |
||||
else |
||||
{ |
||||
show_server_details($anvil, 1); |
||||
} |
||||
|
||||
|
||||
$anvil->Job->update_progress({ |
||||
progress => 100, |
||||
message => "job_0281", |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
$anvil->nice_exit({exit_code => 0}); |
||||
|
||||
|
||||
############################################################################################################# |
||||
# Functions # |
||||
############################################################################################################# |
||||
|
||||
sub connect_to_libvirt |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
my $short_host_name = $anvil->Get->short_host_name; |
||||
my $host_uuid = $anvil->Get->host_uuid; |
||||
my $server_name = $anvil->data->{switches}{server_name}; |
||||
my $server_uuid = $anvil->data->{switches}{server_uuid}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
's1:short_host_name' => $short_host_name, |
||||
's2:host_uuid' => $host_uuid, |
||||
's3:server_name' => $server_name, |
||||
's4:server_uuid' => $server_uuid, |
||||
}}); |
||||
|
||||
my $from_source = get_definition_source($anvil); |
||||
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
from_source => $from_source, |
||||
server_state => $server_state, |
||||
}}); |
||||
|
||||
# We'll make changes to the DB and on-disk definitions if the server isn't running. If it is, we'll |
||||
# update the live system as well. |
||||
my $uri = ""; |
||||
if ($server_state eq "running") |
||||
{ |
||||
if ($server_uuid eq $anvil->Get->host_uuid) |
||||
{ |
||||
### NOTE: Don't use 'localhost', Sys::Virt translates it to '::1' which Net::OpenSSH |
||||
### breaks on. |
||||
# Connect to the local libvirtd API, and handle problems if not. |
||||
$uri = "qemu+ssh://".$short_host_name."/system"; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }}); |
||||
} |
||||
else |
||||
{ |
||||
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; |
||||
my $server_host_name = $anvil->Database->get_host_from_uuid({ |
||||
short => 1, |
||||
host_uuid => $server_host_uuid, |
||||
}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }}); |
||||
|
||||
my $target_ip = $anvil->Network->find_target_ip({ |
||||
debug => 2, |
||||
host_uuid => $server_host_uuid, |
||||
test_access => 1, |
||||
networks => "bcn,mn,sn,ifn,any", |
||||
}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_ip => $target_ip }}); |
||||
if ($target_ip) |
||||
{ |
||||
# Connect using this URI |
||||
$uri = "qemu+ssh://".$target_ip."/system"; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }}); |
||||
} |
||||
} |
||||
} |
||||
|
||||
my $connection = ""; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }}); |
||||
eval { $connection = Sys::Virt->new(uri => $uri); }; |
||||
if ($@) |
||||
{ |
||||
# Throw an error, then clear the URI so that we just update the DB/on-disk definitions. |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0162", variables => { |
||||
host_name => $short_host_name, |
||||
uri => $uri, |
||||
error => $@, |
||||
}}); |
||||
return(1); |
||||
} |
||||
|
||||
my $domain = ""; |
||||
my @domains = $connection->list_all_domains(); |
||||
foreach my $domain_handle (@domains) |
||||
{ |
||||
my $this_server_name = $domain_handle->get_name; |
||||
next if $this_server_name ne $server_name; |
||||
|
||||
$domain = $domain_handle; |
||||
last; |
||||
} |
||||
|
||||
return($domain); |
||||
} |
||||
|
||||
sub manage_boot_menu |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
my $short_host_name = $anvil->Get->short_host_name; |
||||
my $host_uuid = $anvil->Get->host_uuid; |
||||
my $server_name = $anvil->data->{switches}{server_name}; |
||||
my $server_uuid = $anvil->data->{switches}{server_uuid}; |
||||
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
's1:short_host_name' => $short_host_name, |
||||
's2:host_uuid' => $host_uuid, |
||||
's3:server_name' => $server_name, |
||||
's4:server_uuid' => $server_uuid, |
||||
's5:server_host_uuid' => $server_host_uuid, |
||||
}}); |
||||
|
||||
my $domain_handle = connect_to_libvirt($anvil); |
||||
my $from_source = get_definition_source($anvil); |
||||
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
domain_handle => $domain_handle, |
||||
from_source => $from_source, |
||||
server_state => $server_state, |
||||
}}); |
||||
if ($server_state eq "running") |
||||
{ |
||||
my $server_host_name = $anvil->Database->get_host_from_uuid({ |
||||
short => 1, |
||||
host_uuid => $server_host_uuid, |
||||
}); |
||||
} |
||||
|
||||
my $say_yes = $anvil->Words->string({key => 'unit_0001'}); |
||||
my $say_no = $anvil->Words->string({key => 'unit_0002'}); |
||||
my $current_boot_menu = lc($anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{info}{boot_menu}); |
||||
my $say_old_boot_menu = $current_boot_menu eq "yes" ? $say_yes : $say_no; |
||||
my $new_boot_menu = $anvil->data->{switches}{'boot-menu'}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
current_boot_menu => $current_boot_menu, |
||||
say_old_boot_menu => $say_old_boot_menu, |
||||
new_boot_menu => $new_boot_menu, |
||||
}}); |
||||
|
||||
if (($anvil->data->{switches}{'boot-menu'} eq "yes") or ($anvil->data->{switches}{'boot-menu'} eq "no")) |
||||
{ |
||||
# We need to rewrite the boot menu manually. |
||||
my $new_definition = ""; |
||||
my $in_os = 0; |
||||
my $bootmenu_seen = 0; |
||||
foreach my $line (split/\n/, $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}) |
||||
{ |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); |
||||
if ($line =~ /<os>/) |
||||
{ |
||||
$in_os = 1; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_os => $in_os }}); |
||||
} |
||||
if ($in_os) |
||||
{ |
||||
if ($line =~ /<bootmenu enable='(.*?)'\/>/) |
||||
{ |
||||
my $old_value = $1; |
||||
$bootmenu_seen = 1; |
||||
$line =~ s/<bootmenu enable='.*?'\/>/<bootmenu enable='$new_boot_menu'\/>/; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
old_value => $old_value, |
||||
bootmenu_seen => $bootmenu_seen, |
||||
line => $line, |
||||
}}); |
||||
} |
||||
if ($line =~ /<\/os>/) |
||||
{ |
||||
$in_os = 0; |
||||
if (not $bootmenu_seen) |
||||
{ |
||||
# Insert it |
||||
$new_definition .= " <bootmenu enable='".$new_boot_menu."'\/>\n"; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_definition => $new_definition }}); |
||||
} |
||||
} |
||||
} |
||||
$new_definition .= $line."\n"; |
||||
} |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_definition => $new_definition }}); |
||||
|
||||
# Always call this, as a previous run may have only updated some definitions. |
||||
my $problem = $anvil->Server->update_definition({ |
||||
debug => 2, |
||||
server => $server_uuid, |
||||
new_definition_xml => $new_definition, |
||||
}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); |
||||
} |
||||
else |
||||
{ |
||||
print "Boot Menu enabled: [".$say_old_boot_menu."]\n"; |
||||
print "- You can change this using '--boot-menu off' or '--boot-menu on'.\n"; |
||||
} |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
sub show_server_details |
||||
{ |
||||
my ($anvil, $show_nodes) = @_; |
||||
|
||||
my $short_host_name = $anvil->Get->short_host_name; |
||||
my $host_uuid = $anvil->Get->host_uuid; |
||||
my $server_name = $anvil->data->{switches}{server_name}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
's1:short_host_name' => $short_host_name, |
||||
's2:host_uuid' => $host_uuid, |
||||
's3:server_name' => $server_name, |
||||
's4:show_nodes' => $show_nodes, |
||||
}}); |
||||
|
||||
# Words we'll use. |
||||
my $say_yes = $anvil->Words->string({key => 'unit_0001'}); |
||||
my $say_no = $anvil->Words->string({key => 'unit_0002'}); |
||||
my $say_disk = $anvil->Words->string({key => 'header_0068'}); |
||||
my $say_optical = $anvil->Words->string({key => 'header_0111'}); |
||||
my $say_ejected = $anvil->Words->string({key => 'unit_0049'}); |
||||
|
||||
my $from_source = get_definition_source($anvil); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); |
||||
|
||||
# Boot stuff |
||||
my $say_boot_menu = lc($anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{info}{boot_menu}) eq "yes" ? $say_yes : $say_no; |
||||
my $say_boot_device = lc($anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{1}{device_type}) eq "cdrom" ? $say_optical : $say_disk; |
||||
my $boot_device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{1}{device_target}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
say_boot_menu => $say_boot_menu, |
||||
say_boot_device => $say_boot_device, |
||||
boot_device => $boot_device, |
||||
}}); |
||||
my $boot_order = []; |
||||
foreach my $sequence (sort {$a <=> $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}}) |
||||
{ |
||||
my $this_device_type = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$sequence}{device_type}; |
||||
my $say_this_boot_device = lc($this_device_type) eq "cdrom" ? $say_optical : $say_disk; |
||||
my $this_boot_device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$sequence}{device_target}; |
||||
my $device_path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$this_device_type}{target}{$this_boot_device}{path} // ""; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
sequence => $sequence, |
||||
say_this_boot_device => $say_this_boot_device, |
||||
this_boot_device => $this_boot_device, |
||||
device_path => $device_path, |
||||
}}); |
||||
if ((not $device_path) && (lc($this_device_type) eq "cdrom")) |
||||
{ |
||||
$device_path = $say_ejected; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { device_path => $device_path }}); |
||||
} |
||||
|
||||
push @{$boot_order}, $sequence."; ".$this_boot_device.", type: [".$say_this_boot_device."], path: [".$device_path."]"; |
||||
} |
||||
|
||||
print "Boot Menu enabled: [".$say_boot_menu."]\n"; |
||||
print "Boot device:\n"; |
||||
foreach my $say_other_boot (@{$boot_order}) |
||||
{ |
||||
print "- ".$say_other_boot."\n"; |
||||
} |
||||
|
||||
# CPU |
||||
my $cpu_sockets = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{sockets}; |
||||
my $cpu_cores = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{cpu}{cores}; |
||||
my $cpu_total_cores = $cpu_sockets * $cpu_cores; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
cpu_sockets => $cpu_sockets, |
||||
cpu_cores => $cpu_cores, |
||||
cpu_total_cores => $cpu_total_cores, |
||||
}}); |
||||
print "CPU Total: [".$cpu_total_cores."]; Sockets: [".$cpu_sockets."], Cores per Socket: [".$cpu_cores."]\n"; |
||||
|
||||
# RAM |
||||
my $ram = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{memory}; |
||||
print "RAM: [".$anvil->Convert->bytes_to_human_readable({'bytes' => $ram})."] (".$anvil->Convert->add_commas({number => $ram})." Bytes)\n"; |
||||
|
||||
|
||||
return(0); |
||||
} |
||||
|
||||
sub get_definition_source |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
my $short_host_name = $anvil->Get->short_host_name; |
||||
my $server_name = $anvil->data->{switches}{server_name}; |
||||
my $server_uuid = $anvil->data->{switches}{server_uuid}; |
||||
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
||||
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; |
||||
my $from_source = ""; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
short_host_name => $short_host_name, |
||||
server_name => $server_name, |
||||
server_uuid => $server_uuid, |
||||
server_state => $server_state, |
||||
from_source => $from_source, |
||||
}}); |
||||
|
||||
$anvil->data->{server}{$short_host_name}{$server_name}{from_virsh} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}; |
||||
$anvil->data->{server}{$short_host_name}{$server_name}{from_disk} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}; |
||||
$anvil->data->{server}{$short_host_name}{$server_name}{from_db} = "" if not exists $anvil->data->{server}{$short_host_name}{$server_name}{from_db}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"server::${short_host_name}::${server_name}::from_virsh" => $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}, |
||||
"server::${short_host_name}::${server_name}::from_disk" => $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}, |
||||
"server::${short_host_name}::${server_name}::from_db" => $anvil->data->{server}{$short_host_name}{$server_name}{from_db}, |
||||
}}); |
||||
|
||||
if (($server_state eq "running") && |
||||
($server_host_uuid eq $anvil->Get->host_uuid()) && |
||||
(exists $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh})) |
||||
{ |
||||
$from_source = "from_virsh"; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); |
||||
} |
||||
elsif (exists $anvil->data->{server}{$short_host_name}{$server_name}{from_disk}) |
||||
{ |
||||
$from_source = "from_disk"; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); |
||||
} |
||||
else |
||||
{ |
||||
$from_source = "from_db"; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { from_source => $from_source }}); |
||||
} |
||||
|
||||
return($from_source); |
||||
} |
||||
|
||||
sub show_server_list |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
# Loop through all Anvil! nodes, then all server in that Anvil! |
||||
foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_name}}) |
||||
{ |
||||
my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid}; |
||||
my $anvil_description = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
anvil_name => $anvil_name, |
||||
anvil_uuid => $anvil_uuid, |
||||
anvil_description => $anvil_description, |
||||
}}); |
||||
if (($anvil->data->{switches}{anvil_uuid}) && ($anvil->data->{switches}{anvil_uuid} ne $anvil_uuid)) |
||||
{ |
||||
next; |
||||
} |
||||
print "\n".$anvil->Words->string({key => "message_0343", variables => { |
||||
anvil_name => $anvil_name, |
||||
anvil_uuid => $anvil_uuid, |
||||
anvil_description => $anvil_description, |
||||
}})."\n"; |
||||
|
||||
my $server_count = 0; |
||||
if (exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}) |
||||
{ |
||||
$server_count = keys %{$anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_count => $server_count }}); |
||||
} |
||||
if (not $server_count) |
||||
{ |
||||
print $anvil->Words->string({key => "message_0344"})."\n"; |
||||
} |
||||
else |
||||
{ |
||||
foreach my $server_name (sort {$a cmp $b} keys %{$anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}}) |
||||
{ |
||||
my $server_uuid = $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid}; |
||||
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
server_name => $server_name, |
||||
server_uuid => $server_uuid, |
||||
server_state => $server_state, |
||||
}}); |
||||
next if $server_state eq "DELETED"; |
||||
print $anvil->Words->string({key => "message_0345", variables => { |
||||
server_name => $server_name, |
||||
server_uuid => $server_uuid, |
||||
}})."\n"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
sub validate_server |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
$anvil->Get->server_from_switch({ |
||||
debug => 2, |
||||
string => $anvil->data->{switches}{server}, |
||||
anvil_uuid => $anvil->data->{switches}{anvil_uuid}, |
||||
}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"switches::server_name" => $anvil->data->{switches}{server_name}, |
||||
"switches::server_uuid" => $anvil->data->{switches}{server_uuid}, |
||||
}}); |
||||
|
||||
if (not $anvil->data->{switches}{server_uuid}) |
||||
{ |
||||
show_server_list($anvil); |
||||
my $variables = { |
||||
server => $anvil->data->{switches}{server}, |
||||
anvil => $anvil->data->{switches}{anvil_name}, |
||||
}; |
||||
if ($anvil->data->{switches}{anvil_uuid}) |
||||
{ |
||||
# Not found on the requested Anvil! node. |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0451", variables => $variables}); |
||||
$anvil->Job->update_progress({ |
||||
progress => 100, |
||||
message => "error_0451", |
||||
variables => $variables, |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
} |
||||
else |
||||
{ |
||||
# Not found at all. |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0452", variables => $variables}); |
||||
$anvil->Job->update_progress({ |
||||
progress => 100, |
||||
message => "error_0452", |
||||
variables => $variables, |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
} |
||||
$anvil->nice_exit({exit_code => 1}); |
||||
} |
||||
|
||||
my $variables = { |
||||
server_name => $anvil->data->{switches}{server_name}, |
||||
server_uuid => $anvil->data->{switches}{server_uuid}, |
||||
}; |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0802", variables => $variables}); |
||||
$anvil->Job->update_progress({ |
||||
progress => 2, |
||||
message => "log_0802", |
||||
variables => $variables, |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
my $short_host_name = $anvil->Get->short_host_name; |
||||
my $server_name = $anvil->data->{switches}{server_name}; |
||||
my $server_uuid = $anvil->data->{switches}{server_uuid}; |
||||
my $server_definition = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml}; |
||||
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid}; |
||||
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; |
||||
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
's1:short_host_name' => $short_host_name, |
||||
's2:server_name' => $server_name, |
||||
's3:server_uuid' => $server_uuid, |
||||
's4:server_definition' => $server_definition, |
||||
's5:server_host_uuid' => $server_host_uuid, |
||||
's6:server_state' => $server_state, |
||||
's7:anvil_uuid' => $anvil_uuid, |
||||
}}); |
||||
if (not $anvil->data->{switches}{anvil_uuid}) |
||||
{ |
||||
$anvil->data->{switches}{anvil_uuid} = $anvil_uuid; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
's1:switches::anvil_uuid' => $anvil->data->{switches}{anvil_uuid}, |
||||
}}); |
||||
} |
||||
|
||||
if ($server_state eq "DELETED") |
||||
{ |
||||
# The server has been deleted |
||||
my $variables = { server => $server_name }; |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0453", variables => $variables}); |
||||
$anvil->Job->update_progress({ |
||||
progress => 100, |
||||
message => "error_0453", |
||||
variables => $variables, |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
$anvil->nice_exit({exit_code => 1}); |
||||
} |
||||
|
||||
# Parse the definition. |
||||
$anvil->Server->parse_definition({ |
||||
debug => 3, |
||||
host => $short_host_name, |
||||
server => $server_name, |
||||
source => "from_db", |
||||
definition => $server_definition, |
||||
}); |
||||
|
||||
# Can we read the XML definition? |
||||
$anvil->Server->get_status({ |
||||
debug => 2, |
||||
server => $server_name, |
||||
host => $short_host_name, |
||||
}); |
||||
|
||||
if (not $anvil->data->{server}{$short_host_name}{$server_name}{from_virsh}{xml}) |
||||
{ |
||||
# The server isn't actually running... Not here anyway. |
||||
if ($server_state eq "running") |
||||
{ |
||||
my $server_host_name = $anvil->Database->get_host_from_uuid({ |
||||
short => 1, |
||||
host_uuid => $server_host_uuid, |
||||
}); |
||||
|
||||
my $variables = { |
||||
server => $server_name, |
||||
host_name => $server_host_name, |
||||
}; |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0454", variables => $variables}); |
||||
$anvil->Job->update_progress({ |
||||
progress => 100, |
||||
message => "error_0454", |
||||
variables => $variables, |
||||
}) if $anvil->data->{switches}{'job-uuid'}; |
||||
$anvil->nice_exit({exit_code => 1}); |
||||
} |
||||
} |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
sub load_job |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
$anvil->Job->clear({ |
||||
debug => 2, |
||||
job_uuid => $anvil->data->{switches}{'job-uuid'}, |
||||
}); |
||||
$anvil->Job->get_job_details({ |
||||
debug => 2, |
||||
job_uuid => $anvil->data->{switches}{'job-uuid'}, |
||||
}); |
||||
|
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
'jobs::job_data' => $anvil->data->{jobs}{job_data}, |
||||
}}); |
||||
foreach my $line (split/\n/, $anvil->data->{jobs}{job_data}) |
||||
{ |
||||
my ($variable, $value) = ($line =~ /^(.*)=(.*)$/); |
||||
$value =~ s/^"(.*)\"/$1/; |
||||
$value =~ s/^'(.*)\'/$1/; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
's1:line' => $line, |
||||
's2:variable' => $variable, |
||||
's3:value' => $value, |
||||
}}); |
||||
|
||||
$anvil->data->{switches}{$variable} = $value; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"switches::${variable}" => $anvil->data->{switches}{$variable}, |
||||
}}); |
||||
} |
||||
|
||||
$anvil->Job->update_progress({ |
||||
progress => 1, |
||||
job_picked_up_by => $$, |
||||
job_picked_up_at => time, |
||||
message => "message_0350", |
||||
}); |
||||
|
||||
return(0); |
||||
} |
@ -0,0 +1,287 @@ |
||||
#!/usr/bin/perl |
||||
# |
||||
# This program will boot a target machine using either it's IPMI interface, if available, or one of the |
||||
# (non-PDU) fence methods, if the target is in an Anvil! and we have a manifest for it. |
||||
# |
||||
# Exit codes; |
||||
# 0 = Normal exit. |
||||
# 1 = No database connection. |
||||
# |
||||
# TODO: |
||||
# |
||||
|
||||
use strict; |
||||
use warnings; |
||||
use Anvil::Tools; |
||||
|
||||
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; |
||||
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; |
||||
if (($running_directory =~ /^\./) && ($ENV{PWD})) |
||||
{ |
||||
$running_directory =~ s/^\./$ENV{PWD}/; |
||||
} |
||||
|
||||
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete. |
||||
$| = 1; |
||||
|
||||
my $anvil = Anvil::Tools->new(); |
||||
|
||||
$anvil->Get->switches({list => [ |
||||
"ended-within", |
||||
"host", |
||||
"job-uuid"], man => $THIS_FILE}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}}); |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); |
||||
|
||||
# Make sure we've got a |
||||
if (($anvil->data->{switches}{'ended-within'} eq "") or ($anvil->data->{switches}{'ended-within'} !~ /^\d+$/)) |
||||
{ |
||||
$anvil->data->{switches}{'ended-within'} = 300; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"switches::ended-within" => $anvil->data->{switches}{'ended-within'}, |
||||
}}); |
||||
} |
||||
|
||||
$anvil->data->{show}{host_uuid} = ""; |
||||
if (($anvil->data->{switches}{host}) && ($anvil->data->{switches}{host} ne "all")) |
||||
{ |
||||
# Get the host_uuid |
||||
$anvil->data->{show}{host_uuid} = $anvil->Database->get_host_uuid_from_string({debug => 2, string => $anvil->data->{switches}{host}}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"show::host_uuid" => $anvil->data->{show}{host_uuid}, |
||||
}}); |
||||
} |
||||
|
||||
$anvil->Database->connect(); |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"}); |
||||
if (not $anvil->data->{sys}{database}{connections}) |
||||
{ |
||||
# No databases, update the job, sleep for a bit and then exit. The daemon will pick it up and try |
||||
# again after we exit. |
||||
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0075"}); |
||||
sleep 10; |
||||
$anvil->nice_exit({exit_code => 1}); |
||||
} |
||||
|
||||
show_jobs($anvil); |
||||
|
||||
$anvil->nice_exit({exit_code => 0}); |
||||
|
||||
|
||||
############################################################################################################# |
||||
# Functions # |
||||
############################################################################################################# |
||||
|
||||
sub show_jobs |
||||
{ |
||||
my ($anvil) = @_; |
||||
|
||||
$anvil->Database->get_hosts({debug => 3}); |
||||
$anvil->Database->get_jobs({ |
||||
debug => 2, |
||||
job_host_uuid => $anvil->data->{show}{host_uuid} // "all", |
||||
ended_within => $anvil->data->{switches}{'ended-within'}, |
||||
}); |
||||
|
||||
# Sort them into hosts, and then sort them by picked-up time (if we sorted by modified date, the |
||||
# display would jump all over the place) |
||||
# NOTE: Yes, I know, sorting on job_uuid doesn't make much sense but it means repeated runs are |
||||
# at least consistent in the logss. |
||||
my $jobs_found = 0; |
||||
foreach my $job_uuid (sort {$a cmp $b} keys %{$anvil->data->{jobs}{running}}) |
||||
{ |
||||
if (($anvil->data->{switches}{'job-uuid'}) && ($anvil->data->{switches}{'job-uuid'} ne $job_uuid)) |
||||
{ |
||||
next; |
||||
} |
||||
$jobs_found++; |
||||
my $job_command = $anvil->data->{jobs}{running}{$job_uuid}{job_command}; |
||||
my $job_data = $anvil->data->{jobs}{running}{$job_uuid}{job_data}; |
||||
my $job_picked_up_by = $anvil->data->{jobs}{running}{$job_uuid}{job_picked_up_by}; |
||||
my $job_picked_up_at = $anvil->data->{jobs}{running}{$job_uuid}{job_picked_up_at}; |
||||
my $job_updated = $anvil->data->{jobs}{running}{$job_uuid}{job_updated}; |
||||
my $job_name = $anvil->data->{jobs}{running}{$job_uuid}{job_name}; |
||||
my $job_progress = $anvil->data->{jobs}{running}{$job_uuid}{job_progress}; |
||||
my $job_title = $anvil->data->{jobs}{running}{$job_uuid}{job_title}; |
||||
my $job_description = $anvil->data->{jobs}{running}{$job_uuid}{job_description}; |
||||
my $job_status = $anvil->data->{jobs}{running}{$job_uuid}{job_status}; |
||||
my $job_host_uuid = $anvil->data->{jobs}{running}{$job_uuid}{job_host_uuid}; |
||||
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$job_host_uuid}{short_host_name} // ""; |
||||
my $modified_date = $anvil->data->{jobs}{running}{$job_uuid}{modified_date}; |
||||
my $modified_date_unix = $anvil->data->{jobs}{running}{$job_uuid}{modified_date_unix}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
jobs_found => $jobs_found, |
||||
job_command => $job_command, |
||||
job_data => $job_data, |
||||
job_picked_up_by => $job_picked_up_by, |
||||
job_picked_up_at => $job_picked_up_at, |
||||
job_updated => $job_updated, |
||||
job_name => $job_name, |
||||
job_progress => $job_progress, |
||||
job_title => $job_title, |
||||
job_description => $job_description, |
||||
job_status => $job_status, |
||||
job_host_uuid => $job_host_uuid, |
||||
short_host_name => $short_host_name, |
||||
modified_date => $modified_date, |
||||
modified_date_unix => $modified_date_unix, |
||||
}}); |
||||
|
||||
# Turn the time stamps into strings and translate the job_title, job_description, and job_status |
||||
my $say_job_picked_up_at = $anvil->Get->date_and_time({use_time => $job_picked_up_at}); |
||||
my $say_job_updated = $anvil->Get->date_and_time({use_time => $job_updated}); |
||||
my $say_job_title = $anvil->Words->parse_banged_string({debug => 2, key_string => $job_title}); |
||||
my $say_job_description = $anvil->Words->parse_banged_string({debug => 2, key_string => $job_description}); |
||||
my $say_job_status = $anvil->Words->parse_banged_string({debug => 2, key_string => $job_status}); |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
say_job_picked_up_at => $say_job_picked_up_at, |
||||
say_job_updated => $say_job_updated, |
||||
say_job_title => $say_job_title, |
||||
say_job_description => $say_job_description, |
||||
say_job_status => $say_job_status, |
||||
}}); |
||||
|
||||
my $sort_key = "queued"; |
||||
if ($job_progress == 100) |
||||
{ |
||||
# Finished |
||||
$sort_key = "completed"; |
||||
} |
||||
elsif ($job_progress) |
||||
{ |
||||
# Picked up |
||||
$sort_key = "in_progress"; |
||||
} |
||||
|
||||
if (not exists $anvil->data->{count}{$short_host_name}{$sort_key}) |
||||
{ |
||||
$anvil->data->{count}{$short_host_name}{$sort_key} = 1; |
||||
} |
||||
else |
||||
{ |
||||
$anvil->data->{count}{$short_host_name}{$sort_key}++; |
||||
} |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"count::${short_host_name}::${sort_key}" => $anvil->data->{count}{$short_host_name}{$sort_key}, |
||||
}}); |
||||
|
||||
# Store |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_uuid} = $job_uuid; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_command} = $job_command; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_data} = $job_data; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_picked_up_by} = $job_picked_up_by; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_updated} = $say_job_updated; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_picked_up_at} = $say_job_picked_up_at; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_name} = $job_name; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_progress} = $job_progress; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_title} = $say_job_title; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_description} = $say_job_description; |
||||
$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_status} = $say_job_status; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_uuid" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_uuid}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_command" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_command}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_data" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_data}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_picked_up_by" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_picked_up_by}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_updated" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_updated}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_picked_up_at" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_picked_up_at}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_name" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_name}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_progress" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_progress}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_title" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_title}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_description" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_description}, |
||||
"sorted_jobs::${short_host_name}::${sort_key}::${job_picked_up_at}::job_status" => $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_status}, |
||||
}}); |
||||
} |
||||
|
||||
if (($anvil->data->{switches}{'job-uuid'}) && (not $jobs_found)) |
||||
{ |
||||
print "The job: [".$anvil->data->{switches}{'job-uuid'}."] was not found.\n"; |
||||
$anvil->nice_exit({exit_code => 1}); |
||||
} |
||||
|
||||
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{sorted_jobs}}) |
||||
{ |
||||
print "-=] Jobs on ".$short_host_name." [=------------------------------------------------\n"; |
||||
foreach my $sort_key ("queued", "in_progress", "completed") |
||||
{ |
||||
my $count = exists $anvil->data->{count}{$short_host_name}{$sort_key} // 0; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
sort_key => $sort_key, |
||||
count => $count, |
||||
}}); |
||||
next if not $count; |
||||
|
||||
my $say_header = ""; |
||||
if ($sort_key eq "queued") |
||||
{ |
||||
$say_header = $anvil->Words->string({key => 'header_0112'}); |
||||
} |
||||
elsif ($sort_key eq "in_progress") |
||||
{ |
||||
$say_header = $anvil->Words->string({key => 'header_0113'}); |
||||
} |
||||
elsif ($sort_key eq "completed") |
||||
{ |
||||
$say_header = $anvil->Words->string({key => 'header_0114'}); |
||||
} |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_header => $say_header }}); |
||||
print "- ".$say_header."\n"; |
||||
foreach my $job_picked_up_at (sort {$a cmp $b} keys %{$anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}}) |
||||
{ |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_picked_up_at => $job_picked_up_at }}); |
||||
my $job_uuid = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_uuid}; |
||||
my $job_command = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_command}; |
||||
my $job_data = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_data}; |
||||
my $job_picked_up_by = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_picked_up_by}; |
||||
my $say_job_updated = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_updated}; |
||||
my $say_job_picked_up_at = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_picked_up_at}; |
||||
my $job_name = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_name}; |
||||
my $job_progress = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_progress}; |
||||
my $say_job_title = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_title}; |
||||
my $say_job_description = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_description}; |
||||
my $say_job_status = $anvil->data->{sorted_jobs}{$short_host_name}{$sort_key}{$job_picked_up_at}{job_status}; |
||||
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||
job_uuid => $job_uuid, |
||||
job_command => $job_command, |
||||
job_data => $job_data, |
||||
job_picked_up_by => $job_picked_up_by, |
||||
say_job_updated => $say_job_updated, |
||||
say_job_picked_up_at => $say_job_picked_up_at, |
||||
job_name => $job_name, |
||||
job_progress => $job_progress, |
||||
say_job_title => $say_job_title, |
||||
say_job_description => $say_job_description, |
||||
say_job_status => $say_job_status, |
||||
}}); |
||||
print "Job Name: [".$job_name."], UUID: [".$job_uuid."]\n"; |
||||
if ($sort_key eq "queued") |
||||
{ |
||||
print "- Command: [".$job_command."], <queued>\n"; |
||||
} |
||||
elsif ($sort_key eq "completed") |
||||
{ |
||||
print "- Command: [".$job_command."], Picked up at: [".$say_job_picked_up_at."], last updated: [".$say_job_updated."]\n"; |
||||
} |
||||
else |
||||
{ |
||||
print "- Command: [".$job_command."], Progress: [".$job_progress."\%] Picked up at: [".$say_job_picked_up_at."], last updated: [".$say_job_updated."], PID: [".$job_picked_up_by."]\n"; |
||||
} |
||||
my $job_data_lines = (split/\n/, $job_data); |
||||
if ($job_data_lines > 1) |
||||
{ |
||||
print "---] Job Data:\n"; |
||||
print $job_data."\n"; |
||||
print "----------------\n"; |
||||
} |
||||
else |
||||
{ |
||||
print "- Job Data: [".$job_data."]\n"; |
||||
} |
||||
print "---] Job Status:\n"; |
||||
print $say_job_status."\n"; |
||||
print "--------------------------------------------------------------------------------\n"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return(0); |
||||
} |
Loading…
Reference in new issue