* Got more work done on System->configure_ipmi(). It should now configure the IP address, subnet mask and default gateway using information from the manifest and anvil-join-anvil data.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 1fa63d2ea3
commit dcfdf1127c
  1. 205
      Anvil/Tools/System.pm
  2. 6
      share/words.xml
  3. 47
      tools/anvil-join-anvil
  4. 6
      tools/test.pl

@ -1189,7 +1189,13 @@ If a BMC is found and configured, the C<< fence_ipmilan >> call used to check th
B<< NOTE >>: The password used to set the IPMI BMC access is included both in the database table and the returned string. B<< NOTE >>: The password used to set the IPMI BMC access is included both in the database table and the returned string.
This method takes no parameters. Parameters;
=head3 manifest_uuid (Optional, default sys::manifest_uuid)
The C<< manifests >> -> C<< manifest_uuid >> used to pull out configuration data. This is required, but in most cases, it can be determined if not passed.
If not passed, C<< sys::manifest_uuid >> is checked. If this is set, it is used. If this isn't set either, the call will fail.
=cut =cut
sub configure_ipmi sub configure_ipmi
@ -1200,8 +1206,27 @@ sub configure_ipmi
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->configure_ipmi()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->configure_ipmi()" }});
my $manifest_uuid = defined $parameter->{manifest_uuid} ? $parameter->{manifest_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
manifest_uuid => $manifest_uuid,
}});
if ((not $manifest_uuid) && (exists $anvil->data->{sys}{manifest_uuid}) && ($anvil->data->{sys}{manifest_uuid}))
{
$manifest_uuid = $anvil->data->{sys}{manifest_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { manifest_uuid => $manifest_uuid }});
}
if (not $manifest_uuid)
{
# Nothing more we can do.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Systeme->configure_ipmi()", parameter => "manifest_uuid" }});
return(0);
}
# Is this host in an Anvil!? # Is this host in an Anvil!?
$anvil->Database->get_hosts(); $anvil->Database->get_hosts();
$anvil->Database->get_anvils();
my $anvil_uuid = ""; my $anvil_uuid = "";
my $host_uuid = $anvil->Get->host_uuid; my $host_uuid = $anvil->Get->host_uuid;
if ((exists $anvil->data->{hosts}{host_uuid}{$host_uuid}) && ($anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_uuid})) if ((exists $anvil->data->{hosts}{host_uuid}{$host_uuid}) && ($anvil->data->{hosts}{host_uuid}{$host_uuid}{anvil_uuid}))
@ -1217,6 +1242,123 @@ sub configure_ipmi
return(0); return(0);
} }
# Look for a job for 'anvil-join-anvil' for this host. With it, we'll figure out the password and
# which machine we are.
my $query = "
SELECT
job_uuid,
job_data
FROM
jobs
WHERE
job_command LIKE '\%anvil-join-anvil'
AND
job_host_uuid = ".$anvil->Database->quote($host_uuid)."
ORDER BY
modified_date DESC
LIMIT 1
;"
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
my $job_uuid = defined $results->[0]->[0] ? $results->[0]->[0] : "";
my $job_data = defined $results->[0]->[1] ? $results->[0]->[1] : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
job_uuid => $job_uuid,
job_data => $anvil->Log->is_secure($job_data),
}});
if (not $job_uuid)
{
# Unable to proceed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0501"});
return(0);
}
my ($machine, $manifest_uuid, $anvil_uuid) = ($anvil->data->{jobs}{job_data} =~ /as_machine=(.*?),manifest_uuid=(.*?),anvil_uuid=(.*?)$/);
$machine = "" if not defined $machine;
$manifest_uuid = "" if not defined $manifest_uuid;
$anvil_uuid = "" if not defined $anvil_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
machine => $machine,
manifest_uuid => $manifest_uuid,
anvil_uuid => $anvil_uuid,
}});
# Load the manifest.
my $problem = $anvil->Striker->load_manifest({
debug => 2,
manifest_uuid => $manifest_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
{
# The load_manifest method would log the details.
return(0);
}
# Make sure the IPMI IP, subnet mask and password are available.
my $password = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_password};
my $ip_address = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{ipmi_ip};
my $subnet_mask = "";
my $gateway = "";
my $in_network = "";
# Find the subnet the IPMI IP is in.
foreach my $network_type ("bcn", "ifn", "sn")
{
my $count = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{count}{$network_type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_type => $network_type,
count => $count,
}});
foreach my $i (1..$count)
{
my $network_name = $network_type.$i;
my $network = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{$network_name}{network};
my $this_subnet_mask = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{$network_name}{subnet};
my $this_gateway = $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{networks}{$network_name}{gateway};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
network_name => $network_name,
network => $network,
this_subnet_mask => $this_subnet_mask,
this_gateway => $this_gateway,
}});
my $match = $anvil->Network->is_ip_in_network({
network => $network,
subnet_mask => $this_subnet_mask,
ip => $ip_address,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_name => $match}});
if ($match)
{
$subnet_mask = $this_subnet_mask;
$gateway = $this_gateway;
$in_network = $network_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
subnet_mask => $subnet_mask,
gateway => $gateway,
in_network => $in_network,
}});
last;
}
}
}
# If we didn't find a network, we're done.
if (not $subnet_mask)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0502", variables => {
ip_address => $ip_address,
manifest_uuid => $manifest_uuid,
}});
return(0);
}
# Call dmidecode to see if there even is an IPMI BMC on this host. # Call dmidecode to see if there even is an IPMI BMC on this host.
my $host_ipmi = ""; my $host_ipmi = "";
my $has_ipmi = 0; my $has_ipmi = 0;
@ -1345,21 +1487,64 @@ sub configure_ipmi
} }
# If we didn't find a LAN channel, we can't proceed. # If we didn't find a LAN channel, we can't proceed.
if (not $lan_channel) if ($lan_channel eq 99)
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0499"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0499"});
return(0); return(0);
} }
### TODO: Left off here. # Is the desired values different from the current network?
# What values do we want? if ($current_network_type eq "dhcp")
=cut {
# Change to static.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0503"});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ipmitool}." lan set ".$lan_channel." ipsrc static"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
}
if ((($ip_address) && ($ip_address ne $current_ip_address))
{
# Update the IP
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0504", variables => {
old => $current_ip_address,
new => $ip_address,
}});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ipmitool}." lan set ".$lan_channel." ipaddr ".$ip_address});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
}
if (($subnet_mask) && ($subnet_mask ne $current_subnet_mask))
{
# Update the subnet mask
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0505", variables => {
old => $current_ip_address,
new => $ip_address,
}});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ipmitool}." lan set ".$lan_channel." netmask ".$subnet_mask});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
}
if (($gateway) && ($gateway ne $current_gateway))
{
# Update the gateway
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "log_0506", variables => {
old => $current_ip_address,
new => $ip_address,
}});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ipmitool}." lan set ".$lan_channel." defgw ipaddr ".$gateway});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
}
ipmitool lan print {1..x} =cut
ipmitool lan set 2 ipsrc static
ipmitool lan set 2 ipaddr 10.20.51.1
ipmitool lan set 2 netmask 255.255.0.0
ipmitool lan set 2 defgw ipaddr 10.20.255.254
ipmitool user list 2 ipmitool user list 2
=cut =cut

@ -933,6 +933,12 @@ If the targets are unique, did you copy the full database directory? A unique id
<key name="log_0498">This machine is not in an #!string!brand_0002!#, not configuring IPMI.</key> <key name="log_0498">This machine is not in an #!string!brand_0002!#, not configuring IPMI.</key>
<key name="log_0499">This machine does not appear to have an IPMI BMC (no BMC reported by 'dmidecode'). Not attempting to configure IPMI.</key> <key name="log_0499">This machine does not appear to have an IPMI BMC (no BMC reported by 'dmidecode'). Not attempting to configure IPMI.</key>
<key name="log_0500">This machine appears to have an IPMI BMC, but the LAN channel (used to configure the BMC's network) wasn't found. Channels 0 to 9 were checked.</key> <key name="log_0500">This machine appears to have an IPMI BMC, but the LAN channel (used to configure the BMC's network) wasn't found. Channels 0 to 9 were checked.</key>
<key name="log_0501">Configuring the local IPMI is dependent on knowing what #!string!brand_0002!# this host is a member of. This involves looking for a 'job' for this host to be run by 'anvil-join-anvil' (used to determine the IPMI password to set and to know which machine we are in the #!string!brand_0002!#). No job was found, so unable to configure IPMI at this time.</key>
<key name="log_0502">The IPMI BMC is configured to be set to: [#!variable!ip_address!#], but this doesn't match any of the networks in the install manifest with the UUID: [#!variable!manifest_uuid!#].</key>
<key name="log_0503">The IPMI BMC was set to DHCP, changing to static.</key>
<key name="log_0504">The IPMI BMC currently has the IP address: [#!variable!old!#], changing it to: [#!variable!new!#].</key>
<key name="log_0505">The IPMI BMC currently has the subnet mask of: [#!variable!old!#], changing it to: [#!variable!new!#].</key>
<key name="log_0506">The IPMI BMC currently has the default gateway of: [#!variable!old!#], changing it to: [#!variable!new!#].</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. --> <!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key> <key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>

@ -1343,11 +1343,27 @@ sub load_job
}}); }});
# Load in the manifest # Load in the manifest
load_manifest($anvil); $anvil->Database->get_hosts();
my $problem = $anvil->Striker->load_manifest({
debug => 2,
manifest_uuid => $anvil->data->{sys}{manifest_uuid},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
manifest_uuid => $anvil->data->{sys}{manifest_uuid},
problem => $problem,
}});
$anvil->Database->get_anvils(); if ($problem)
{
# Something went wrong
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "warning_0046", variables => { uuid => $anvil->data->{sys}{manifest_uuid} }});
update_progress($anvil, 0, "job_0076");
sleep 2;
$anvil->nice_exit({exit_code => 2});
}
# Load the manifest and anvil data. # Load the manifest and anvil data.
$anvil->Database->get_anvils();
if ((not exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}) or (not exists $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid})) if ((not exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}) or (not exists $anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}))
{ {
# Terminate the job entirely, it's likely an unrecoverable problem. # Terminate the job entirely, it's likely an unrecoverable problem.
@ -1370,33 +1386,6 @@ sub load_job
return(0); return(0);
} }
# Load in the manifest
sub load_manifest
{
my ($anvil) = @_;
$anvil->Database->get_hosts();
my $problem = $anvil->Striker->load_manifest({
debug => 2,
manifest_uuid => $anvil->data->{sys}{manifest_uuid},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
manifest_uuid => $anvil->data->{sys}{manifest_uuid},
problem => $problem,
}});
if ($problem)
{
# Something went wrong
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "warning_0046", variables => { uuid => $anvil->data->{sys}{manifest_uuid} }});
update_progress($anvil, 0, "job_0076");
sleep 2;
$anvil->nice_exit({exit_code => 2});
}
return(0);
}
# If this is being called as a job, this will allow the progress to be updated. # If this is being called as a job, this will allow the progress to be updated.
sub update_progress sub update_progress
{ {

@ -25,4 +25,8 @@ $anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0132"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0132"});
$anvil->Get->switches; $anvil->Get->switches;
$anvil->System->configure_ipmi({debug => 2}); $anvil->System->configure_ipmi({
debug => 2,
machine => $anvil->data->{switches}{machine},
manifest_uuid => "6115d040-bdc4-4c76-9514-15870d88fb43",
});

Loading…
Cancel
Save