Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.2 KiB

#!/usr/bin/perl
#
# This keeps an eye on the network configuration and ensures the firewall is configured appropriately. What
# exactly that means depends on why kind of machine the local host is.
#
# Exit codes;
# 0 = Normal exit.
# 1 = Failed to unlink an unneeded file.
# 2 = Failed to write or update a file.
#
# TODO:
#
# # Allow routing/masq'ing through the IFN1 (provide net access to the BCN)
# firewall-cmd --zone=IFN1 --add-masquerade
# # Check
# firewall-cmd --zone=IFN1 --query-masquerade
# #[yes|no]
# # Disable
# # NOTE: Doesn't break existing connections
# firewall-cmd --zone=IFN1 --remove-masquerade
#
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use Text::Diff;
# Disable buffering
$| = 1;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
my $anvil = Anvil::Tools->new();
# If the user has disabled auto-management of the firewall, exit.
if (not $anvil->data->{sys}{manage}{firewall})
{
# Do nothing.
$anvil->nice_exit({exit_code => 0});
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches
$anvil->data->{switches}{'job-uuid'} = "";
$anvil->data->{switches}{server} = "";
$anvil->Get->switches;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'},
'switches::server' => $anvil->data->{switches}{server},
}});
# Log our start.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "message_0134"});
# If we've been passed a job UUID, pick up the details.
if ($anvil->data->{switches}{'job-uuid'})
{
$anvil->Job->clear();
$anvil->Job->get_job_details();
$anvil->Job->update_progress({
progress => 1,
job_picked_up_by => $$,
job_picked_up_at => time,
message => "message_0134",
});
if ($anvil->data->{jobs}{job_data} =~ /server=(.*)$/)
{
$anvil->data->{switches}{server} = $1 if not $anvil->data->{switches}{server};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'switches::server' => $anvil->data->{switches}{server},
}});
wait_for_server($anvil);
}
}
# This used to do all the work, but that's now moved to the method below. So all we do here now is call it.
$anvil->Network->manage_firewall();
if ($anvil->data->{switches}{'job-uuid'})
{
$anvil->Job->update_progress({
progress => 100,
message => "job_0281",
});
}
# We're done
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Private functions. #
#############################################################################################################
# This simple watches 'virsh list' until the named server appears.
sub wait_for_server
{
($anvil) = @_;
$anvil->Job->update_progress({
progress => 25,
message => "job_0401,!!server!".$anvil->data->{switches}{server}."!!",
});
my $wait_until = time + 60;
my $waiting = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
wait_until => $wait_until,
}});
while($waiting)
{
my $shell_call = $anvil->data->{path}{exe}{virsh}." list --name";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
's1:output' => $output,
's2:return_code' => $return_code,
}});
foreach my $server (split/\n/, $output)
{
$server = $anvil->Words->clean_spaces({string => $server});
next if not $server;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server => $server }});
if ($server eq $anvil->data->{switches}{server})
{
# Found it.
$waiting = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { waiting => $waiting }});
}
}
if ($waiting)
{
if (time > $wait_until)
{
# timed out
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "err", key => "job_0402", variables => { server => $anvil->data->{switches}{server} }});
$anvil->Job->update_progress({
progress => 75,
message => "job_0402,!!server!".$anvil->data->{switches}{server}."!!",
});
}
else
{
sleep 3;
my $time_left = $wait_until - time;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "job_0403", variables => {
server => $anvil->data->{switches}{server},
time_left => $time_left,
}});
$anvil->Job->update_progress({
progress => 50,
message => "job_0403,!!server!".$anvil->data->{switches}{server}."!!,!!time_left!".$time_left."!!",
});
}
}
}
return(0);
}