From 4401f48a0d9671d823c39b4ce30b2678b5abe607 Mon Sep 17 00:00:00 2001 From: James Adams Date: Thu, 25 Oct 2018 16:20:08 +0100 Subject: [PATCH] ncm-network: Add support for CAF::Service actions after changes Largely transcribed from ncm-metaconfig. Requires #1335. Resolves #1071. --- .../main/pan/components/network/schema.pan | 6 +++ ncm-network/src/main/perl/network.pm | 35 +++++++++++++++ ncm-network/src/test/perl/actions.t | 43 +++++++++++++++++++ ncm-network/src/test/resources/actions.pan | 14 ++++++ 4 files changed, 98 insertions(+) create mode 100644 ncm-network/src/test/perl/actions.t create mode 100644 ncm-network/src/test/resources/actions.pan diff --git a/ncm-network/src/main/pan/components/network/schema.pan b/ncm-network/src/main/pan/components/network/schema.pan index d303f41b3a..786d8a64d0 100755 --- a/ncm-network/src/main/pan/components/network/schema.pan +++ b/ncm-network/src/main/pan/components/network/schema.pan @@ -6,4 +6,10 @@ type network_component = { include structure_component @{experimental: rename (physical) devices} 'rename' ? boolean + + @{ + A dict mapping daemon name to CAF::Service action to take if the network configuration changes. + e.g. 'daemons/firewalld' = 'reload'; + } + 'daemons' ? caf_service_action{} }; diff --git a/ncm-network/src/main/perl/network.pm b/ncm-network/src/main/perl/network.pm index ba661b43fc..f0db5c5aaa 100755 --- a/ncm-network/src/main/perl/network.pm +++ b/ncm-network/src/main/perl/network.pm @@ -194,6 +194,7 @@ Readonly my $NEW => 2; # changes to file, but same config (eg for new file formats) Readonly my $KEEPS_STATE => 3; +Readonly::Hash my %ALLOWED_ACTIONS => { restart => 1, reload => 1, stop_sleep_start => 1 }; # wrapper around -x for easy unittesting # is not part of CAF::Path @@ -1934,6 +1935,34 @@ sub routing_table } else { # nothing needs to be done upon change, returned for unittesting return $fh->close(); + +# Prepare and take the action for all daemons as defined in hash-reference C<$daemons>. +# Does not return anything. +sub _process_service_actions +{ + my ($self, $daemons) = @_; + my $actions = {}; + my @daemon_action = (); + + foreach my $daemon (sort keys %{$daemons || {}}) { + push(@daemon_action, $daemon, $daemons->{$daemon}); + } + + while (my ($daemon,$action) = splice(@daemon_action, 0, 2)) { + if (exists($ALLOWED_ACTIONS{$action})) { + $actions->{$action} ||= {}; + $actions->{$action}->{$daemon} = 1; + } else { + $self->error("Not a CAF::Service allowed action $action for daemon $daemon in profile (component/schema mismatch?)."); + } + } + + foreach my $action (sort keys %$actions) { + my @daemons = sort keys %{$actions->{$action}}; + $self->info("Executing action $action on services: ", join(', ', @daemons)); + my $srv = CAF::Service->new(\@daemons, log => $self); + # CAF::Service does all the logging we need + $srv->$action(); } } @@ -2221,6 +2250,12 @@ sub Configure } }; + # If the configuration was changed, process any requested daemon actions + if ($config_changed) { + $self->debug(5, "Configuration changed, processing daemon actions."); + $self->_process_service_actions($comp_tree->{daemons}); + } + return 1; } diff --git a/ncm-network/src/test/perl/actions.t b/ncm-network/src/test/perl/actions.t new file mode 100644 index 0000000000..f0f6d84295 --- /dev/null +++ b/ncm-network/src/test/perl/actions.t @@ -0,0 +1,43 @@ +# -*- mode: cperl -*- +use strict; +use warnings; + +BEGIN { + *CORE::GLOBAL::sleep = sub {}; +} + +use Test::More; +use Test::Quattor qw(actions); +use Test::MockModule; + +use NCM::Component::network; + + +my $mock = Test::MockModule->new('CAF::Service'); + +our ($restart, $reload, $stop_sleep_start) = qw(0 0 0); + +$mock->mock('restart', sub { + my $self = shift; + $restart += scalar @{$self->{services}}; +}); +$mock->mock('reload', sub { + my $self = shift; + $reload += scalar @{$self->{services}}; +}); +$mock->mock('stop_sleep_start', sub { + my $self = shift; + $stop_sleep_start += scalar @{$self->{services}}; +}); + + +my $cfg = get_config_for_profile('actions'); +my $cmp = NCM::Component::network->new('network'); + +is($cmp->Configure($cfg), 1, "Component runs correctly with daemon actions set"); + +is($restart, 1, "$restart/1 restarts triggered"); +is($reload, 2, "$reload/2 reloads triggered"); +is($stop_sleep_start, 3, "$stop_sleep_start/3 stop_sleep_starts triggered"); + +done_testing(); diff --git a/ncm-network/src/test/resources/actions.pan b/ncm-network/src/test/resources/actions.pan new file mode 100644 index 0000000000..84cc7de284 --- /dev/null +++ b/ncm-network/src/test/resources/actions.pan @@ -0,0 +1,14 @@ +object template actions; + +include 'simple_base_profile'; + +prefix "/software/components/network/daemons"; + +"test_restart_1" = 'restart'; + +"test_reload_1" = 'reload'; +"test_reload_2" = 'reload'; + +"test_stop_sleep_start_1" = 'stop_sleep_start'; +"test_stop_sleep_start_2" = 'stop_sleep_start'; +"test_stop_sleep_start_3" = 'stop_sleep_start';