* Created the new anvil-join-anvil tool that will run on nodes and the DR host to pick up the job to join an Anvil! system.

* Finished the saving of a "run manifest" job menu. Included filtering out potential machines already in other Anvil! systems from the select box and updating the password fields to not trigger a browser to save/auto-complete the field.
* Fixed a bug in Database->get_hosts() caused by the attempt to immediately return with a 0 if it had been called before. Now a check is made in ->insert_or_update_manifests() where the recursive loop was possible.
* Updated the RPM spec to v.33 after releasing .32 after the last commit. Also added the core requirement for perl-Data-Validate-Domain.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent 22e7e8b03e
commit 613a7f0c58
  1. 1
      Anvil/Tools.pm
  2. 23
      Anvil/Tools/Database.pm
  3. 591
      cgi-bin/striker
  4. 26
      html/skins/alteeve/anvil.html
  5. 8
      rpm/SPECS/anvil.spec
  6. 10
      share/words.xml
  7. 51
      tools/anvil-join-anvil

@ -1115,6 +1115,7 @@ sub _set_paths
'anvil-daemon' => "/usr/sbin/anvil-daemon",
'anvil-download-file' => "/usr/sbin/anvil-download-file",
'anvil-file-details' => "/usr/sbin/anvil-file-details",
'anvil-join-anvil' => "/usr/sbin/anvil-join-anvil",
'anvil-maintenance-mode' => "/usr/sbin/anvil-maintenance-mode",
'anvil-manage-firewall' => "/usr/sbin/anvil-manage-firewall",
'anvil-manage-keys' => "/usr/sbin/anvil-manage-keys",

@ -1838,9 +1838,6 @@ sub get_hosts
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_hosts()" }});
# This prevents some recursive loops, like when Database->insert_or_update_anvils() is called.
return(0) if $anvil->data->{hosts}{loaded};
# Load anvils. If a host is registered with an Anvil!, we'll note it.
$anvil->Database->get_anvils({debug => $debug});
@ -1908,8 +1905,6 @@ FROM
}});
}
$anvil->data->{hosts}{loaded} = 1;
my $return_count = @{$return};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { return_count => $return_count }});
return($return);
@ -3008,7 +3003,7 @@ WHERE
}
# Make sure that, if any host_uuid's are passed, that they're valid.
$anvil->Database->get_hosts({debug => $debug}) if not $anvil->data->{hosts}{loaded};
$anvil->Database->get_hosts({debug => $debug}) if ref($anvil->data->{hosts}{host_uuid}) ne "HASH";
if (($anvil_node1_host_uuid) && (not $anvil->data->{hosts}{host_uuid}{$anvil_node1_host_uuid}{host_name}))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0128", variables => { uuid => $anvil_node1_host_uuid, column => "anvil_node1_host_uuid" }});
@ -3374,7 +3369,7 @@ WHERE
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -3740,7 +3735,7 @@ WHERE
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -4215,7 +4210,7 @@ AND
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -4458,7 +4453,7 @@ WHERE
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -5195,7 +5190,7 @@ WHERE
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -5578,7 +5573,7 @@ AND
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -8074,7 +8069,7 @@ AND
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
@ -8565,7 +8560,7 @@ WHERE
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $hosts = $anvil->Database->get_hosts({debug => $debug});
my $found = 0;
foreach my $hash_ref (@{$hosts})
{

@ -1630,262 +1630,423 @@ sub run_manifest
$anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value};
if ($anvil->data->{cgi}{confirm}{value})
{
# Save the jobs!
}
else
{
# Ask the user to choose the targets and confirm the manifest settings.
my $nodes = [];
my $dr_hosts = [];
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
# Make sure the passwords match.
my $problem = 0;
if (not $anvil->data->{cgi}{password1}{value})
{
# Didn't set a password
$problem = 1;
$anvil->data->{cgi}{password1}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0047!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::password1::alert" => $anvil->data->{cgi}{password1}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
elsif (not $anvil->data->{cgi}{password2}{value})
{
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $host_anvil = "";
if ((exists $anvil->data->{hosts}{host_uuid}{$host_uuid}) && ($anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_name} ne $anvil_name))
{
$host_anvil = $anvil_name;
}
# Missing both passwords
$problem = 1;
$anvil->data->{cgi}{password2}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0048!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
host_anvil => $host_anvil,
problem => $problem,
"cgi::password2::alert" => $anvil->data->{cgi}{password2}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
elsif ($anvil->data->{cgi}{password1}{value} ne $anvil->data->{cgi}{password2}{value})
{
$problem = 1;
$anvil->data->{cgi}{password1}{alert} = 1;
$anvil->data->{cgi}{password2}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => "#!string!warning_0049!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::password1::alert" => $anvil->data->{cgi}{password1}{alert},
"cgi::password2::alert" => $anvil->data->{cgi}{password2}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
# Does this host belong to another Anvil! already?
if (($host_anvil) && ($host_anvil ne $anvil_name))
# Check that the machines selected didn't get added to another anvil while looking.
my $node1_host_name = $anvil->data->{cgi}{node1_host}{value};
my $node1_host_uuid = $anvil->data->{sys}{hosts}{by_name}{$node1_host_name};
my $node1_anvil = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{anvil_name};
my $node2_host_name = $anvil->data->{cgi}{node2_host}{value};
my $node2_host_uuid = $anvil->data->{sys}{hosts}{by_name}{$node2_host_name};
my $node2_anvil = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{anvil_name};
my $dr1_host_name = $anvil->data->{cgi}{dr1_host}{value};
my $dr1_host_uuid = $dr1_host_name ? $anvil->data->{sys}{hosts}{by_name}{$dr1_host_name} : "";
my $dr1_anvil = $dr1_host_name ? $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{anvil_name} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
node1_host_name => $node1_host_name,
node1_host_uuid => $node1_host_uuid,
node1_anvil => $node1_anvil,
node2_host_name => $node2_host_name,
node2_host_uuid => $node2_host_uuid,
node2_anvil => $node2_anvil,
dr1_host_name => $dr1_host_name,
dr1_host_uuid => $dr1_host_uuid,
dr1_anvil => $dr1_anvil,
}});
if (($node1_anvil) && ($node1_anvil ne $anvil_name))
{
# The server belongs to another Anvil! system.
my $message = $anvil->Words->string({key => "warning_0050", variables => {
machine => $node1_host_name,
anvil => $anvil_name,
}});
$problem = 1;
$anvil->data->{cgi}{node1_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::node1_host::alert" => $anvil->data->{cgi}{node1_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
if (($node2_anvil) && ($node2_anvil ne $anvil_name))
{
# The server belongs to another Anvil! system.
my $message = $anvil->Words->string({key => "warning_0050", variables => {
machine => $node2_host_name,
anvil => $anvil_name,
}});
$problem = 1;
$anvil->data->{cgi}{node2_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::node2_host::alert" => $anvil->data->{cgi}{node2_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
if ($anvil->data->{cgi}{dr1_host}{value})
{
if (($dr1_anvil) && ($dr1_anvil ne $anvil_name))
{
# yup, ignore it.
next;
# The server belongs to another Anvil! system.
my $message = $anvil->Words->string({key => "warning_0050", variables => {
machine => $dr1_host_name,
anvil => $anvil_name,
}});
$problem = 1;
$anvil->data->{cgi}{dr1_host}{alert} = 1;
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $message }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
problem => $problem,
"cgi::dr1_host::alert" => $anvil->data->{cgi}{dr1_host}{alert},
"form::error_massage" => $anvil->data->{form}{error_massage},
}});
}
}
if ($host_type eq "node")
{
push @{$nodes}, $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
if (not $problem)
{
# Save the jobs!
my ($node1_job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $node1_host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'},
job_data => "as_machine=node1,manifest_uuid=".$manifest_uuid,
job_name => "join_anvil::node1",
job_title => "job_0072",
job_description => "job_0073",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node1_job_uuid => $node1_job_uuid }});
if ((not defined $anvil->data->{cgi}{node1_host}{value}) && ($host_name eq $node1_name))
{
$anvil->data->{cgi}{node1_host}{value} = $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node1_host::value" => $anvil->data->{cgi}{node1_host}{value} }});
}
elsif ((not defined $anvil->data->{cgi}{node2_host}{value}) && ($host_name eq $node2_name))
{
$anvil->data->{cgi}{node2_host}{value} = $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node2_host::value" => $anvil->data->{cgi}{node2_host}{value} }});
}
}
elsif ($host_type eq "dr")
my ($node2_job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $node2_host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'},
job_data => "as_machine=node2,manifest_uuid=".$manifest_uuid,
job_name => "join_anvil::node2",
job_title => "job_0072",
job_description => "job_0073",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node2_job_uuid => $node2_job_uuid }});
if ($anvil->data->{cgi}{dr1_host}{value})
{
push @{$dr_hosts}, $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
if ((not defined $anvil->data->{cgi}{dr1_host}{value}) && ($host_name eq $dr1_name))
{
$anvil->data->{cgi}{dr1_host}{value} = $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dr1_host::value" => $anvil->data->{cgi}{dr1_host}{value} }});
}
my ($dr1_job_uuid) = $anvil->Database->insert_or_update_jobs({
debug => 2,
file => $THIS_FILE,
line => __LINE__,
job_host_uuid => $dr1_host_uuid,
job_command => $anvil->data->{path}{exe}{'anvil-join-anvil'},
job_data => "as_machine=dr1,manifest_uuid=".$manifest_uuid,
job_name => "join_anvil::dr1",
job_title => "job_0072",
job_description => "job_0073",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { dr1_job_uuid => $dr1_job_uuid }});
}
}
# We're going to need three selects; one for each node and one for DR. The DR is allowed to
# be unselected so it has an empty entry.
my $select_node1 = $anvil->Template->select_form({
name => "node1_host",
options => $nodes,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{node1_host}{value},
class => $anvil->data->{cgi}{node1_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
# Tell them we're done and send them back to the main page.
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => "#!string!ok_0011!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "form::ok_message" => $anvil->data->{form}{ok_message} }});
process_create($anvil);
my $select_node2 = $anvil->Template->select_form({
name => "node2_host",
options => $nodes,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{node2_host}{value},
class => $anvil->data->{cgi}{node2_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
return(0);
}
}
my $select_dr1 = $anvil->Template->select_form({
name => "dr_host",
options => $dr_hosts,
blank => 1,
'sort' => 1,
selected => $anvil->data->{cgi}{dr1_host}{value},
class => $anvil->data->{cgi}{dr1_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
# Ask the user to choose the targets and confirm the manifest settings.
my $nodes = [];
my $dr_hosts = [];
foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}})
{
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
my $host_type = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type};
my $host_anvil = "";
if ((exists $anvil->data->{hosts}{host_uuid}{$host_uuid}) && ($anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_name} ne $anvil_name))
{
$host_anvil = $anvil_name;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
host_type => $host_type,
host_anvil => $host_anvil,
}});
# Show the networks.
my $networks = "";
my $default_seen = 0;
foreach my $network ("bcn", "sn", "ifn")
# Does this host belong to another Anvil! already?
if (($host_anvil) && ($host_anvil ne $anvil_name))
{
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count => $count,
}});
foreach my $i (1..$count)
{
my $network_name = $network.$i;
my $network_range = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{network};
my $subnet = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{subnet};
my $gateway = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{gateway};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_name => $network_name,
network_range => $network_range,
subnet => $subnet,
gateway => $gateway,
}});
# yup, ignore it.
next;
}
my $say_default = "";
if (($network eq "ifn") && (not $default_seen) && ($gateway))
{
$default_seen = 1;
$say_default = "(#!string!striker_0249!#)";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
default_seen => $default_seen,
say_default => $say_default,
}});
}
if ($host_type eq "node")
{
push @{$nodes}, $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
my $network_key = "header_0036";
if ($network eq "sn") { $network_key = "header_0037"; }
elsif ($network eq "ifn") { $network_key = "header_0038"; }
$networks .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-network", variables => {
name => $anvil->Words->string({key => $network_key, variables => { number => $i }}),
network => $network_range,
subnet => $subnet,
gateway => $gateway ? $gateway : "--",
'default' => $say_default,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
if ((not defined $anvil->data->{cgi}{node1_host}{value}) && ($host_name eq $node1_name))
{
$anvil->data->{cgi}{node1_host}{value} = $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node1_host::value" => $anvil->data->{cgi}{node1_host}{value} }});
}
elsif ((not defined $anvil->data->{cgi}{node2_host}{value}) && ($host_name eq $node2_name))
{
$anvil->data->{cgi}{node2_host}{value} = $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::node2_host::value" => $anvil->data->{cgi}{node2_host}{value} }});
}
}
# Pull out the IPs that will be assigned to servers.
my $machine_ips = "";
foreach my $network ("bcn", "sn", "ifn")
elsif ($host_type eq "dr")
{
if ($network eq "sn")
push @{$dr_hosts}, $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }});
if ((not defined $anvil->data->{cgi}{dr1_host}{value}) && ($host_name eq $dr1_name))
{
# Inject the IPMI data.
my $node1_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ipmi_ip};
my $node2_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{ipmi_ip};
my $dr1_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{ipmi_ip};
$machine_ips .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ip", variables => {
name => "#!string!striker_0258!#",
node1 => $node1_ipmi_ip ? $node1_ipmi_ip : "--",
node2 => $node2_ipmi_ip ? $node2_ipmi_ip : "--",
dr1 => $dr1_ipmi_ip ? $dr1_ipmi_ip : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
$anvil->data->{cgi}{dr1_host}{value} = $host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "cgi::dr1_host::value" => $anvil->data->{cgi}{dr1_host}{value} }});
}
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network};
}
}
# We're going to need three selects; one for each node and one for DR. The DR is allowed to
# be unselected so it has an empty entry.
my $select_node1 = $anvil->Template->select_form({
name => "node1_host",
options => $nodes,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{node1_host}{value},
class => $anvil->data->{cgi}{node1_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
my $select_node2 = $anvil->Template->select_form({
name => "node2_host",
options => $nodes,
blank => 0,
'sort' => 1,
selected => $anvil->data->{cgi}{node2_host}{value},
class => $anvil->data->{cgi}{node2_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
my $select_dr1 = $anvil->Template->select_form({
name => "dr1_host",
options => $dr_hosts,
blank => 1,
'sort' => 1,
selected => $anvil->data->{cgi}{dr1_host}{value},
class => $anvil->data->{cgi}{dr1_host}{alert} ? "input_alert" : "input_clear",
style => "",
});
# Show the networks.
my $networks = "";
my $default_seen = 0;
foreach my $network ("bcn", "sn", "ifn")
{
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count => $count,
}});
foreach my $i (1..$count)
{
my $network_name = $network.$i;
my $network_range = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{network};
my $subnet = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{subnet};
my $gateway = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{name}{$network_name}{gateway};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count => $count,
network_name => $network_name,
network_range => $network_range,
subnet => $subnet,
gateway => $gateway,
}});
foreach my $i (1..$count)
my $say_default = "";
if (($network eq "ifn") && (not $default_seen) && ($gateway))
{
my $network_name = $network.$i;
my $node1_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{network}{$network_name}{ip};
my $node2_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{network}{$network_name}{ip};
my $dr1_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{network}{$network_name}{ip};
$default_seen = 1;
$say_default = "(#!string!striker_0249!#)";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_name => $network_name,
node1_ip => $node1_ip,
node2_ip => $node2_ip,
dr1_ip => $dr1_ip,
default_seen => $default_seen,
say_default => $say_default,
}});
my $network_key = "header_0036";
if ($network eq "sn") { $network_key = "header_0037"; }
elsif ($network eq "ifn") { $network_key = "header_0038"; }
$machine_ips .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ip", variables => {
name => $anvil->Words->string({key => $network_key, variables => { number => $i }}),
node1 => $node1_ip ? $node1_ip : "--",
node2 => $node2_ip ? $node2_ip : "--",
dr1 => $dr1_ip ? $dr1_ip : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
}
=cut
manifests::manifest_uuid::<manifest_uuid>::parsed::upses::<ups_name>::uuid = <upses -> ups_uuid of named UPS>
manifests::manifest_uuid::<manifest_uuid>::parsed::fences::<fence_name>::uuid = <fences -> fence_uuid of named fence device>
manifests::manifest_uuid::<manifest_uuid>::parsed::networks::name::<network_name>::network = <base network ip, ie: 10.255.0.0>
manifests::manifest_uuid::<manifest_uuid>::parsed::machine::<machine>::name = <host name>
manifests::manifest_uuid::<manifest_uuid>::parsed::machine::<machine>::ups::<ups_name>::used = <1 if powered by USB, 0 if not>
=cut
my $dns = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{dns};
my $ntp = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{ntp};
my $mtu = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{mtu};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
dns => $dns,
ntp => $ntp,
mtu => $mtu,
}});
my $fences = "";
foreach my $fence_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{fence}})
{
my $node1_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{fence}{$fence_name}{port};
my $node2_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{fence}{$fence_name}{port};
my $dr1_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{fence}{$fence_name}{port};
$fences .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-fence", variables => {
name => $fence_name,
node1 => $node1_port ? $node1_port : "--",
node2 => $node2_port ? $node2_port : "--",
dr1 => $dr1_port ? $dr1_port : "--",
my $network_key = "header_0036";
if ($network eq "sn") { $network_key = "header_0037"; }
elsif ($network eq "ifn") { $network_key = "header_0038"; }
$networks .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-network", variables => {
name => $anvil->Words->string({key => $network_key, variables => { number => $i }}),
network => $network_range,
subnet => $subnet,
gateway => $gateway ? $gateway : "--",
'default' => $say_default,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
}
my $upses = "";
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ups}})
# Pull out the IPs that will be assigned to servers.
my $machine_ips = "";
foreach my $network ("bcn", "sn", "ifn")
{
if ($network eq "sn")
{
# Inject the IPMI data.
my $node1_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ipmi_ip};
my $node2_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{ipmi_ip};
my $dr1_ipmi_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{ipmi_ip};
$machine_ips .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ip", variables => {
name => "#!string!striker_0258!#",
node1 => $node1_ipmi_ip ? $node1_ipmi_ip : "--",
node2 => $node2_ipmi_ip ? $node2_ipmi_ip : "--",
dr1 => $dr1_ipmi_ip ? $dr1_ipmi_ip : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network => $network,
count => $count,
}});
foreach my $i (1..$count)
{
my $node1_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ups}{$ups_name}{used};
my $node2_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{ups}{$ups_name}{used};
my $dr1_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{ups}{$ups_name}{used};
$upses .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ups", variables => {
name => $ups_name,
node1 => $node1_uses ? '<span class="available">#!string!unit_0001!#</span>' : '<span class="unavailable">#!string!unit_0002!#</span>',
node2 => $node2_uses ? '<span class="available">#!string!unit_0001!#</span>' : '<span class="unavailable">#!string!unit_0002!#</span>',
dr1 => $dr1_uses ? '<span class="available">#!string!unit_0001!#</span>' : '<span class="unavailable">#!string!unit_0002!#</span>',
my $network_name = $network.$i;
my $node1_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{network}{$network_name}{ip};
my $node2_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{network}{$network_name}{ip};
my $dr1_ip = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{network}{$network_name}{ip};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_name => $network_name,
node1_ip => $node1_ip,
node2_ip => $node2_ip,
dr1_ip => $dr1_ip,
}});
my $network_key = "header_0036";
if ($network eq "sn") { $network_key = "header_0037"; }
elsif ($network eq "ifn") { $network_key = "header_0038"; }
$machine_ips .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ip", variables => {
name => $anvil->Words->string({key => $network_key, variables => { number => $i }}),
node1 => $node1_ip ? $node1_ip : "--",
node2 => $node2_ip ? $node2_ip : "--",
dr1 => $dr1_ip ? $dr1_ip : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
}
$anvil->data->{form}{back_link} = "?anvil=true&task=create";
$anvil->data->{form}{refresh_link} = "?anvil=true&task=manifests&run=true&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "run-manifest", variables => {
debug => 2,
title => $anvil->Words->string({key => "striker_0270", variables => { name => $anvil_name }}),
password => $anvil->data->{cgi}{password}{value},
password_class => $anvil->data->{cgi}{password}{alert} ? "input_alert" : "",
fences => $fences,
upses => $upses,
networks => $networks,
dns => $dns ? $dns : "8.8.8.8,8.8.4.4",
ntp => $ntp ? $ntp : "--",
mtu => $mtu ? $mtu : "1500",
select_node1 => $select_node1,
select_node2 => $select_node2,
select_dr1 => $select_dr1,
machine_ips => $machine_ips,
my $dns = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{dns};
my $ntp = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{ntp};
my $mtu = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{mtu};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
dns => $dns,
ntp => $ntp,
mtu => $mtu,
}});
my $fences = "";
foreach my $fence_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{fence}})
{
my $node1_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{fence}{$fence_name}{port};
my $node2_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{fence}{$fence_name}{port};
my $dr1_port = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{fence}{$fence_name}{port};
$fences .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-fence", variables => {
name => $fence_name,
node1 => $node1_port ? $node1_port : "--",
node2 => $node2_port ? $node2_port : "--",
dr1 => $dr1_port ? $dr1_port : "--",
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
my $upses = "";
foreach my $ups_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ups}})
{
my $node1_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node1}{ups}{$ups_name}{used};
my $node2_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{node2}{ups}{$ups_name}{used};
my $dr1_uses = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{dr1}{ups}{$ups_name}{used};
$upses .= $anvil->Template->get({file => "anvil.html", name => "run-manifest-ups", variables => {
name => $ups_name,
node1 => $node1_uses ? '<span class="available">#!string!unit_0001!#</span>' : '<span class="unavailable">#!string!unit_0002!#</span>',
node2 => $node2_uses ? '<span class="available">#!string!unit_0001!#</span>' : '<span class="unavailable">#!string!unit_0002!#</span>',
dr1 => $dr1_uses ? '<span class="available">#!string!unit_0001!#</span>' : '<span class="unavailable">#!string!unit_0002!#</span>',
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { networks => $networks }});
}
$anvil->data->{form}{back_link} = "?anvil=true&task=create";
$anvil->data->{form}{refresh_link} = "?anvil=true&task=manifests&run=true&manifest_uuid=".$anvil->data->{cgi}{manifest_uuid}{value};
$anvil->data->{form}{body} = $anvil->Template->get({file => "anvil.html", name => "run-manifest", variables => {
debug => 2,
title => $anvil->Words->string({key => "striker_0270", variables => { name => $anvil_name }}),
password => $anvil->data->{cgi}{password}{value},
password_class => $anvil->data->{cgi}{password}{alert} ? "input_alert" : "",
fences => $fences,
upses => $upses,
networks => $networks,
dns => $dns ? $dns : "8.8.8.8,8.8.4.4",
ntp => $ntp ? $ntp : "--",
mtu => $mtu ? $mtu : "1500",
select_node1 => $select_node1,
select_node2 => $select_node2,
select_dr1 => $select_dr1,
hostname_node1 => $node1_name,
hostname_node2 => $node2_name,
hostname_dr1 => $dr1_name,
machine_ips => $machine_ips,
}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'form::body' => $anvil->data->{form}{body} }});
return(0);
}

@ -227,7 +227,8 @@
#!string!header_0030!#:
</td>
<td colspan="5">
<input type="password" name="password1" id="password1" value="#!variable!password!#" placeholder="#!string!striker_0271!#" class="#!variable!password_class!#"/>
<!-- This combination of input type text, disk characters and autocomplete=off prevents browsers from pre-filling password and offering to save passwords. -->
<input type="text" name="password1" id="password1" value="#!variable!password1!#" autocomplete="off" placeholder="#!string!striker_0271!#" class="#!variable!password_class!#" style="text-security:disc; -webkit-text-security:disc;" />
</td>
</tr>
<tr>
@ -236,7 +237,7 @@
#!string!header_0031!#:
</td>
<td colspan="5">
<input type="password" name="password2" id="password2" value="#!variable!password!#" placeholder="#!string!header_0031!#" class="#!variable!password_class!#"/>
<input type="text" name="password2" id="password2" value="#!variable!password2!#" autocomplete="off" placeholder="#!string!header_0031!#" class="#!variable!password_class!#" style="text-security:disc; -webkit-text-security:disc;" />
</td>
</tr>
<tr>
@ -288,6 +289,27 @@
#!variable!select_dr1!#
</td>
</tr>
<tr>
<td class="column_header">
<!-- New Hostname -->
#!string!header_0039!#:
</td>
<td class="column_row_value_fixed">
#!variable!hostname_node1!#
</td>
<td>
&nbsp;
</td>
<td class="column_row_value_fixed">
#!variable!hostname_node2!#
</td>
<td>
&nbsp;
</td>
<td class="column_row_value_fixed">
#!variable!hostname_dr1!#
</td>
</tr>
#!variable!machine_ips!#
<tr>
<td colspan="6">

@ -3,7 +3,7 @@
%define anvilgroup admin
Name: anvil
Version: 3.0
Release: 32%{?dist}
Release: 33%{?dist}
Summary: Alteeve Anvil! complete package.
License: GPLv2+
@ -41,6 +41,7 @@ Requires: mailx
Requires: mlocate
Requires: perl-Capture-Tiny
Requires: perl-Data-Dumper
Requires: perl-Data-Validate-Domain
Requires: perl-DBD-Pg
Requires: perl-DBI
Requires: perl-Data-Validate-Domain
@ -360,7 +361,10 @@ fi
%changelog
* tbd Madison Kelly <mkelly@alteeve.ca> 3.0-32
* tbd Madison Kelly <mkelly@alteeve.ca> 3.0-33
- Updated source.
* Tue May 26 2020 Madison Kelly <mkelly@alteeve.ca> 3.0-32
- Updated source.
* Mon Jan 6 2020 Madison Kelly <mkelly@alteeve.ca> 3.0-31

@ -227,6 +227,7 @@ The error was:
<key name="header_0036">BCN link #!variable!number!#</key>
<key name="header_0037">SN link #!variable!number!#</key>
<key name="header_0038">IFN link #!variable!number!#</key>
<key name="header_0039">New Hostname</key>
<!-- Strings used by jobs -->
<key name="job_0001">Configure Network</key>
@ -304,6 +305,8 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec
<key name="job_0069">Unable to find a matching network, skipping this database.</key>
<key name="job_0070">Something went wrong adding this database. Please see: [#!data!path::log::main!#] for details.</key>
<key name="job_0071">The network configuration will be updated based on the variables stored in the database. When complete, the system will reboot.</key>
<key name="job_0072">Join this machine to an #!string!brand_0006!#.</key>
<key name="job_0073">This machine will join an #!string!brand_0006!# as a node or DR host. The role and #!string!brand_0006!# will be determined by the associated Install Manifest UUID.</key>
<!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key>
@ -1048,7 +1051,7 @@ NOTE: Please be patient!
<key name="message_0114"><![CDATA[Completed successfully, exiting.]]></key>
<!-- Above here are strings used in the kickstart scripts. Be sure to test kickstart installation after changing / translation between 'message_0103' and 'message_0114'. -->
<key name="message_0115">Striker Dashboard</key>
<key name="message_0116">#!string!brand_0006!# Node</key>
<key name="message_0116">#!string!brand_0002!# Node</key>
<key name="message_0117">Disaster Recovery (DR) Host</key>
<key name="message_0118">Regenerating the source repository metadata.</key>
<key name="message_0119">[ Error ] - The comps.xml file: [#!variable!comps_xml!#] was not found. This provides package group information required for Install Target guests. Is the 'anvil-striker-extra' package installed?</key>
@ -1116,6 +1119,7 @@ About to try to download aproximately: [#!variable!packages!#] packages needed t
<key name="ok_0008">The UPS: [#!variable!name!#] has been successfully deleted!</key>
<key name="ok_0009">The install manifest: [#!variable!name!#] has been successfully saved!</key>
<key name="ok_0010">The install manifest: [#!variable!name!#] has been successfully deleted!</key>
<key name="ok_0011">The install manifest job has be initiated! Target machines should start configuring momentarily!</key>
<!-- String prefixes -->
<key name="prefix_0001">[ Error ] - </key>
@ -1575,6 +1579,10 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st
<key name="warning_0044">[ Warning ] - The install manifest: [#!variable!name!#] with the UUID: [#!variable!uuid!#] has already been deleted.</key>
<key name="warning_0045">[ Warning ] - The install manifest: [#!variable!name!#] with the UUID: [#!variable!uuid!#] was NOT deleted. The reason may be in the: [#!data!path::log::main!#] log file on this host.</key>
<key name="warning_0046">[ Warning ] - The Install Manifest with the UUID: [#!variable!uuid!#] was not found.</key>
<key name="warning_0047">[ Warning ] - The password to set for this #!string!brand_0006!# was not set.</key>
<key name="warning_0048">[ Warning ] - The password verification was not set.</key>
<key name="warning_0049">[ Warning ] - The passwords do not match.</key>
<key name="warning_0050">[ Warning ] - The host: [#!variable!host!#] now belongs to the #!string!brand_0006!#, it can't be used here anymore.</key>
</language>
<!-- 日本語 -->

@ -0,0 +1,51 @@
#!/usr/bin/perl
#
# This adds a node (or gets a node to join to a new/rebuilt peer or added DR) to an Anvil!.
#
# Exit codes;
# 0 = Normal exit.
#
# 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->Log->level({set => 2});
$anvil->Log->secure({set => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches (target ([user@]host[:port]) and the file with the target's password. If the password is
# passed directly, it will be used. Otherwise, the password will be read from the database.
$anvil->Get->switches;
$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_0077"});
sleep 10;
$anvil->nice_exit({exit_code => 1});
}
$anvil->nice_exit({code => 0});
#############################################################################################################
# Functions #
#############################################################################################################
Loading…
Cancel
Save