From 3674a47179c783b33a77110cba4acd9e1af3df01 Mon Sep 17 00:00:00 2001 From: Digimer Date: Mon, 16 Aug 2021 11:39:16 -0400 Subject: [PATCH] WIP - Working a tool to manually load updated server definition files. Signed-off-by: Digimer --- share/words.xml | 13 +++ tools/anvil-update-definition | 180 ++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100755 tools/anvil-update-definition diff --git a/share/words.xml b/share/words.xml index 6d61cb83..870417ef 100644 --- a/share/words.xml +++ b/share/words.xml @@ -434,6 +434,19 @@ The attempt to start the servers appears to have failed. The return code '0' was The Anvil! UUID: [#!variable!anvil_uuid!#] is not valid or was not found in the database. There are no Anvil! systems yet in the database, nothing to do. There are no servers yet in the database, nothing to do. + You need to specify the updated definition file with '--file /path/to/definition.xml'. + You definition file: [#!variable!file!#] doesn't exist or couldn't be read. + The server name was not found in the new definition file. + The server UUID was not found (or is not valid) in the new definition file. + +Failed to parse the XML in the new definition file. The error was: +==== +#!variable!error!# +==== + + Y'.]]> + The server UUID: [#!variable!server_uuid!#] in the definition file wasn't found in the database, unable to update. + The new definition has changed the server's name from: [#!variable!current_name!#] to: [#!variable!new_name!#]. Changing the server's name must be done with the 'anvil-rename-server' tool. diff --git a/tools/anvil-update-definition b/tools/anvil-update-definition new file mode 100755 index 00000000..8b255619 --- /dev/null +++ b/tools/anvil-update-definition @@ -0,0 +1,180 @@ +#!/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: +# + +use strict; +use warnings; +use Anvil::Tools; +require POSIX; +use Term::Cap; + +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->data->{switches}{file} = ""; +$anvil->Get->switches; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'switches::file' => $anvil->data->{switches}{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"}); + $anvil->nice_exit({exit_code => 1}); +} + +# Does the file exist? +if (not $anvil->data->{switches}{file}) +{ + # Not defined. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0323"}); + $anvil->nice_exit({exit_code => 1}); +} +elsif ((not -e $anvil->data->{switches}{file}) or (not -r $anvil->data->{switches}{file})) +{ + # Not found or can't be read. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0324", variables => { + file => $anvil->data->{switches}{file}, + }}); + $anvil->nice_exit({exit_code => 1}); +} + +validate_and_update($anvil); + +$anvil->nice_exit({exit_code => 0}); + + +############################################################################################################# +# Functions # +############################################################################################################# + +sub validate_and_update +{ + my ($anvil) = @_; + + # Can we parse the definition? + my $new_definition = $anvil->Storage->read_file({file => $anvil->data->{switches}{file}}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_definition => $new_definition }}); + + # Pull the server name and uuid out. + my $server_name = ""; + my $server_uuid = ""; + foreach my $line (split/\n/, $new_definition) + { + if ($line =~ /(.*?)<\/name>/) + { + $server_name = $1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_name => $server_name }}); + } + if ($line =~ /(.*?)<\/uuid>/) + { + $server_uuid = $1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_uuid => $server_uuid }}); + } + } + + # If I didn't find the server name or UUID, there's a problem. + if ($server_name eq "") + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0325"}); + $anvil->nice_exit({exit_code => 1}); + } + if (($server_uuid eq "") or (not $anvil->Validate->uuid({uuid => $server_uuid}))) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0326"}); + $anvil->nice_exit({exit_code => 1}); + } + + local $@; + my $dom = eval { XML::LibXML->load_xml(string => $new_definition); }; + if ($@) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0327", variables => { error => $@ }}); + $anvil->nice_exit({exit_code => 1}); + } + + # Find out how much memory being allocated. + my $memory = 0; + foreach my $memory ($dom->findnodes('/domain/memory')) + { + my $units = $memory->{unit}; + my $value = $memory->to_literal(); + $memory = $anvil->Convert->human_readable_to_bytes({size => $value, type => $units}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + units => $units, + value => $value, + memory => $memory." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $memory}).")", + }}); + } + if (not $memory) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0328"}); + $anvil->nice_exit({exit_code => 1}); + } + + # Do we know about this server yet? + $anvil->Database->get_servers(); + if (not exists $anvil->data->{servers}{server_uuid}{$server_uuid}) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0329", variables => { server_uuid => $server_uuid }}); + $anvil->nice_exit({exit_code => 1}); + } + + # We can't update the server name with this tool. + if ($server_name ne $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name}) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0330", variables => { + current_name => $current_name. + new_name => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name}, + }}); + $anvil->nice_exit({exit_code => 1}); + } + + # Still here? Update! Has the assigned RAM changed? + my $configured_ram = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_configured_ram}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + configured_ram => $configured_ram." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $configured_ram}).")", + }}); + if ($memory != $configured_ram) + { + # Update the configured RAM value. + + my $query = " +UPDATE + servers +SET + server_configured_ram = ".$anvil->Database->quote($memory).", + modified_date = ".$anvil->Database->quote($anvil->Database->refresh_timestamp)." +WHERE + server_uuid = ".$anvil->Database->quote($server_uuid).", +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__}); + } + + return(0); +} \ No newline at end of file