* Created Get->kernel_release() that returns the current kernel release (version) in use on the host or on a remote system.

* Created DRBD->_initialize_drbd() to makes sure the DRBD kernel module can load and tries to build the module, if necessary. This is meant to provide support for clients that can't access needed internet resource (or the internet at all).

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 3 years ago
parent cc4c3bd3e3
commit 3346d31194
  1. 2
      Anvil/Tools.pm
  2. 113
      Anvil/Tools/DRBD.pm
  3. 89
      Anvil/Tools/Get.pm
  4. 1
      Anvil/Tools/System.pm
  5. 6
      share/words.xml
  6. 6
      tools/anvil-daemon

@ -1102,6 +1102,7 @@ sub _set_paths
units => "/usr/lib/systemd/system",
},
exe => {
akmods => "/usr/sbin/akmods",
'alteeve-repo-setup' => "/usr/sbin/alteeve-repo-setup",
'anvil-boot-server' => "/usr/sbin/anvil-boot-server",
'anvil-change-password' => "/usr/sbin/anvil-change-password",
@ -1197,6 +1198,7 @@ sub _set_paths
md5sum => "/usr/bin/md5sum",
'mkdir' => "/usr/bin/mkdir",
modifyrepo_c => "/usr/bin/modifyrepo_c",
modprobe => "/usr/sbin/modprobe",
mv => "/usr/bin/mv",
nmap => "/usr/bin/nmap",
nmcli => "/bin/nmcli",

@ -26,6 +26,7 @@ my $THIS_FILE = "DRBD.pm";
# reload_defaults
# resource_uuid
# update_global_common
# _initialize_kmod
#
=pod
@ -1835,6 +1836,7 @@ sub get_status
return(0);
}
=head2 manage_resource
This takes a task, C<< up >>, C<< down >>, C<< primary >>, or C<< secondary >> and a resource name and acts on the request.
@ -3029,3 +3031,114 @@ sub update_global_common
#############################################################################################################
# Private functions #
#############################################################################################################
=head2 _initialize_kmod
This checks to see if the C<< drbd >> kernel module can load. If not, a check is made to see if an RPM that matches the kernel exists. If so, it is installed. If not, C<< akmods >> is asked to build and install the drbd kernel module.
Returns C<< 0 >> is the module loads or is already loaded. C<< !!error!! >> if not.
=cut
sub _initialize_kmod
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "DRBD->_initialize_kmod()" }});
my $kernel_release = $anvil->Get->kernel_release({debug => $debug});
my $shell_call = $anvil->data->{path}{exe}{modprobe}." drbd";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
kernel_release => $kernel_release,
shell_call => $shell_call,
}});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
if (not $return_code)
{
# Loaded fine
return(0);
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0676"});
my $install = 0;
my $shell_call = $anvil->data->{path}{exe}{dnf}." -q search kmod-drbd-".$kernel_release;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /Name Exactly/)
{
# We can install.
$install = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { install => $install }});
last;
}
}
# Install or build?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { install => $install }});
if ($install)
{
### TODO: Should this be a background process?
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0677"});
my $shell_call = $anvil->data->{path}{exe}{dnf}." -y install kmod-drbd-".$kernel_release;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0678"});
my $shell_call = $anvil->data->{path}{exe}{akmods}." --force";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
}
# In either case, try again.
$output = undef;
$return_code = undef;
$shell_call = $anvil->data->{path}{exe}{modprobe}." drbd";
($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
if (not $return_code)
{
# Loaded fine
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0679"});
return(0);
}
else
{
# Failed
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0132"});
}
}
return('!!error!!');
}

@ -31,6 +31,7 @@ my $THIS_FILE = "Get.pm";
# host_uuid_from_name
# host_type
# host_uuid
# kernel_release
# md5sum
# os_type
# server_uuid_from_name
@ -1777,6 +1778,94 @@ sub host_uuid
return($anvil->{HOST}{UUID});
}
=head2 kernel_release
This returns the kernel release (same output as C<<uname -r>>) on the local or remote host. If there is a problem, C<< !!error!! >> is returned.
Parameters;
=head3 password (optional)
This is the password to use when connecting to a remote machine. If not set, but C<< target >> is, an attempt to connect without a password will be made.
=head3 port (optional)
This is the TCP port to use when connecting to a remote machine. If not set, but C<< target >> is, C<< 22 >> will be used.
=head3 remote_user (optional, default root)
If C<< target >> is set, this will be the user we connect to the remote machine as.
=head3 target (optional)
This is the IP or host name of the machine to read the kernel release. If this is not set, the local system's kernel release is checked.
=cut
sub kernel_release
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->kernel_release()" }});
my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $port = defined $parameter->{port} ? $parameter->{port} : "";
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $target = defined $parameter->{target} ? $parameter->{target} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
target => $target,
port => $port,
remote_user => $remote_user,
password => $anvil->Log->is_secure($password),
}});
my $kernel_release = "";
my $return_code = "";
my $shell_call = $anvil->data->{path}{exe}{uname}." --kernel-release";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
if ($anvil->Network->is_local({host => $target}))
{
# Local call
($kernel_release, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
kernel_release => $kernel_release,
return_code => $return_code,
}});
}
else
{
# Remote call
($kernel_release, my $error, $return_code) = $anvil->Remote->call({
debug => $debug,
shell_call => $shell_call,
target => $target,
port => $port,
password => $password,
remote_user => $remote_user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
kernel_release => $kernel_release,
error => $error,
return_code => $return_code,
}});
if ($return_code)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "error_0356", variables => {
target => $target,
output => $kernel_release,
return_code => $return_code,
}});
$kernel_release = "!!error!!";
}
}
return($kernel_release);
}
=head2 md5sum
This returns the C<< md5sum >> of a given file.

@ -3152,6 +3152,7 @@ sub host_name
return($host_name, $descriptive);
}
=head2 maintenance_mode
This sets, clears or checks if the local system is in maintenance mode. Any system in maintenance mode will not be used by normal Anvil! tasks.

@ -501,6 +501,7 @@ The output, if any, was;
====
</key>
<key name="error_0355">Failed to load the database file: [#!variable!file!#]. Deleting it so it's not considered in the next load attempt.</key>
<key name="error_0356">Failed to read the kernel release on the host: [#!variable!target!#]. The return code was: [#!variable!return_code!#] (expected '0') and the release output, if any, was: [#!variable!output!#].</key>
<!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -2066,6 +2067,10 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0673">The host: [#!variable!host_name!#] has good power and temperature readings. Booting it back up now.</key>
<key name="log_0674">The resync has completed in: [#!variable!took!#] second(s).</key>
<key name="log_0675"><![CDATA[[ Error ] - There was a database handle error while preparing the database query: [#!variable!query!#] on: [#!variable!server!#]. The eval error was: [#!variable!eval_error!#]. Note that if the query reports '--', the query was listed as containing sensitive data and '$anvil->Log->secure' is not set. ]]></key>
<key name="log_0676">[ Note ] - The DRBD kernel module failed to load. It is possible the kernel was updated. We will check to see if we can install a pre-built RPM, or if we need to build one ourselves.</key>
<key name="log_0677">Found an installable DRBD kernel module RPM that matches the current kernel. Installing it now.</key>
<key name="log_0678">[ Note ] - We need to build the DRBD kernel module. This can take a few minutes, please be patient! Use 'journalctl -f' to monitor the build process.</key>
<key name="log_0679">Successfully built and installed the new DRBD kernel module!</key>
<!-- 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>
@ -3091,6 +3096,7 @@ We will sleep a bit and try again.
</key>
<key name="warning_0130">[ Warning ] - The storage group: [#!variable!storage_group_name!#] had the host: [#!variable!host_name!#] as a member. This host is not a member (anymore?) of the Anvil!: [#!variable!anvil_name!#]. Removing it from the storage group now.</key>
<key name="warning_0131">[ Warning ] - The postgresql server is not installed yet. Sleeping for a bit, then will check again.</key>
<key name="warning_0132">[ Warning ] - Failed to build or install the DRBD kernel module! It is very likely that this machine will be able to run any servers until this is fixed.</key>
<!-- The entries below here are not sequential, but use a key to find the entry. -->
<!-- Run 'striker-parse-os-list to find new entries. -->

@ -1126,11 +1126,12 @@ sub handle_special_cases
{
my ($anvil) = @_;
# RHBZ #1961562 - https://bugzilla.redhat.com/show_bug.cgi?id=1961562#c16
my $host_type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if ($host_type ne "striker")
{
### TODO: Test that this is fixed. The bug is now ERRATA
# RHBZ #1961562 - https://bugzilla.redhat.com/show_bug.cgi?id=1961562#c16
# We're a node or DR host. We need to touch this file.
my $work_around_file = "/etc/qemu/firmware/50-edk2-ovmf-cc.json";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { work_around_file => $work_around_file }});
@ -1147,6 +1148,9 @@ sub handle_special_cases
group => "root",
});
}
# Make sure DRBD compiled after a kernel upgrade.
$anvil->DRBD->_initialize_kmod({debug => 2});
}
return(0);

Loading…
Cancel
Save