diff --git a/lib/App/Netdisco/Web.pm b/lib/App/Netdisco/Web.pm index 928ced16..06a68138 100644 --- a/lib/App/Netdisco/Web.pm +++ b/lib/App/Netdisco/Web.pm @@ -34,7 +34,7 @@ sub _load_web_plugins { if $plugin !~ m/^\+/; $plugin =~ s/^\+//; - $ENV{PLUGIN_LOAD_DEBUG} && debug "loading Netdisco plugin $plugin"; + $ENV{PLUGIN_LOAD_DEBUG} && debug "loading web plugin $plugin"; Module::Load::load $plugin; } } diff --git a/lib/App/Netdisco/Worker.pm b/lib/App/Netdisco/Worker.pm deleted file mode 100644 index 5118d574..00000000 --- a/lib/App/Netdisco/Worker.pm +++ /dev/null @@ -1,46 +0,0 @@ -package App::Netdisco::Worker; - -use strict; -use warnings; - -use Module::Load (); -use Module::Find qw/findsubmod findallmod/; - -use Dancer ':syntax'; -use Dancer::Factory::Hook; - -sub import { - my ($class, $action) = @_; - die "missing action\n" unless $action; - - my @user_plugins = @{ setting('extra_worker_plugins') || [] }; - my @check_plugins = findsubmod 'App::Netdisco::Worker::Plugin'; - my @phase_plugins = map { findallmod $_ } @check_plugins; - - # load worker plugins for our action - foreach my $plugin (@user_plugins, @check_plugins, @phase_plugins) { - $plugin =~ s/^X::/App::NetdiscoX::Worker::Plugin::/; - next unless $plugin =~ m/::Plugin::${action}(?:::|$)/i; - - debug "loading worker plugin $plugin"; - Module::Load::load $plugin; - } - - # now vars->{workers} is populated, we set the dispatch order - my $workers = vars->{'workers'}->{$action} || {}; - # use DDP; p vars->{'workers'}; - - foreach my $phase (qw/check early main user/) { - foreach my $namespace (sort keys %{ $workers->{$phase} }) { - foreach my $priority (sort {$b <=> $a} - keys %{ $workers->{$phase}->{$namespace} }) { - - # D::Factory::Hook::register_hook() does not work?! - hook "nd2_core_${phase}" => $_ - for @{ $workers->{$phase}->{$namespace}->{$priority} }; - } - } - } -} - -true; diff --git a/lib/App/Netdisco/Worker/Loader.pm b/lib/App/Netdisco/Worker/Loader.pm new file mode 100644 index 00000000..cdb9ce2e --- /dev/null +++ b/lib/App/Netdisco/Worker/Loader.pm @@ -0,0 +1,56 @@ +package App::Netdisco::Worker::Loader; + +use strict; +use warnings; + +use Module::Load (); +use Array::Iterator; +use Dancer qw/:moose :syntax/; + +use Moo::Role; +use namespace::clean; + +has [qw/workers_check + workers_early + workers_main + workers_user/] => ( is => 'rw' ); + +sub load_workers { + my $self = shift; + my $action = $self->job->action or die "missing action\n"; + + my @core_plugins = @{ setting('worker_plugins') || [] }; + my @user_plugins = @{ setting('extra_worker_plugins') || [] }; + + # load worker plugins for our action + foreach my $plugin (@user_plugins, @core_plugins) { + $plugin =~ s/^X::/+App::NetdiscoX::Worker::Plugin::/; + $plugin = 'App::Netdisco::Worker::Plugin::'. $plugin + if $plugin !~ m/^\+/; + $plugin =~ s/^\+//; + + next unless $plugin =~ m/::Plugin::${action}(?:::|$)/i; + $ENV{PLUGIN_LOAD_DEBUG} && debug "loading worker plugin $plugin"; + Module::Load::load $plugin; + } + + # now vars->{workers} is populated, we set the dispatch order + my $workers = vars->{'workers'}->{$action} || {}; + #use DDP; p vars->{'workers'}; + + foreach my $phase (qw/check early main user/) { + my $pname = "workers_${phase}"; + my @wset = (); + + foreach my $namespace (sort keys %{ $workers->{$phase} }) { + foreach my $priority (sort {$b <=> $a} + keys %{ $workers->{$phase}->{$namespace} }) { + push @wset, @{ $workers->{$phase}->{$namespace}->{$priority} }; + } + } + + $self->$pname( Array::Iterator->new({ __array__ => \@wset }) ); + } +} + +true; diff --git a/lib/App/Netdisco/Worker/Plugin.pm b/lib/App/Netdisco/Worker/Plugin.pm index a537a02e..16d19b0a 100644 --- a/lib/App/Netdisco/Worker/Plugin.pm +++ b/lib/App/Netdisco/Worker/Plugin.pm @@ -7,9 +7,6 @@ use App::Netdisco::Util::Permission qw/check_acl_no check_acl_only/; use aliased 'App::Netdisco::Worker::Status'; use Scope::Guard 'guard'; -Dancer::Factory::Hook->instance()->install_hooks("nd2_core_${_}") - for qw/check early main user/; - register 'register_worker' => sub { my ($self, $first, $second) = plugin_args(@_); diff --git a/lib/App/Netdisco/Worker/Runner.pm b/lib/App/Netdisco/Worker/Runner.pm index ee2de7de..e07fe420 100644 --- a/lib/App/Netdisco/Worker/Runner.pm +++ b/lib/App/Netdisco/Worker/Runner.pm @@ -1,8 +1,6 @@ package App::Netdisco::Worker::Runner; use Dancer qw/:moose :syntax/; -use Dancer::Factory::Hook; - use App::Netdisco::Util::Device 'get_device'; use App::Netdisco::Util::Permission qw/check_acl_no check_acl_only/; use aliased 'App::Netdisco::Worker::Status'; @@ -14,6 +12,7 @@ use Scope::Guard 'guard'; use Moo::Role; use namespace::clean; +with 'App::Netdisco::Worker::Loader'; has 'job' => ( is => 'rw' ); # mixin code to run workers loaded via plugins @@ -26,7 +25,7 @@ sub run { $self->job($job); $job->device( get_device($job->device) ); - Module::Load::load 'App::Netdisco::Worker' => $job->action; + $self->load_workers(); # finalise job status when we exit my $statusguard = guard { $job->finalise_status }; @@ -56,26 +55,25 @@ sub run { set(device_auth => \@newuserconf); # run check phase and if there are workers then one MUST be successful - $self->run_workers('nd2_core_check'); + $self->run_workers('workers_check'); return if not $job->check_passed; # run other phases - $self->run_workers("nd2_core_${_}") for qw/early main user/; + $self->run_workers("workers_${_}") for qw/early main user/; } sub run_workers { my $self = shift; - my $job = $self->job or die error 'no job in worker job slot'; - my $hook = shift - or return $job->add_status( Status->error('missing hook param') ); + my $job = $self->job or die error 'no job in worker job slot'; - my $store = Dancer::Factory::Hook->instance(); - (my $phase = $hook) =~ s/^nd2_core_//; + my $set = shift + or return $job->add_status( Status->error('missing set param') ); + return unless ref $self->$set and $self->$set->get_length(); - return unless scalar @{ $store->get_hooks_for($hook) }; + (my $phase = $set) =~ s/^workers_//; $job->enter_phase($phase); - foreach my $worker (@{ $store->get_hooks_for($hook) }) { + while (my $worker = $self->$set->get_next()) { try { $job->add_status( $worker->($job) ) } catch { debug "=> $_" if $_; diff --git a/share/config.yml b/share/config.yml index 5448b650..f0ecb523 100644 --- a/share/config.yml +++ b/share/config.yml @@ -258,6 +258,45 @@ job_prio: - nbtstat - expire +worker_plugins: + - 'Arpnip' + - 'Arpnip::Nodes' + - 'Arpnip::Subnets' + - 'Arpwalk' + - 'Contact' + - 'Delete' + - 'Discover' + - 'Discover::CanonicalIP' + - 'Discover::Entities' + - 'Discover::Neighbors' + - 'Discover::PortPower' + - 'Discover::Properties' + - 'Discover::VLANs' + - 'Discover::Wireless' + - 'Discover::WithNodes' + - 'DiscoverAll' + - 'Expire' + - 'ExpireNodes' + - 'Graph' + - 'Location' + - 'Macsuck' + - 'Macsuck::Nodes' + - 'Macsuck::WirelessNodes' + - 'Macwalk' + - 'Monitor' + - 'Nbtstat' + - 'Nbtstat::Core' + - 'Nbtwalk' + - 'PortControl' + - 'PortName' + - 'Power' + - 'Psql' + - 'Renumber' + - 'Show' + - 'Stats' + - 'Vlan' + - 'Vlan::Core' + extra_worker_plugins: [] # - Discover::ConfigBackup::CLI diff --git a/xt/30-backend-workers.t b/xt/30-backend-workers.t index 139b5ddd..7845277d 100644 --- a/xt/30-backend-workers.t +++ b/xt/30-backend-workers.t @@ -98,10 +98,6 @@ sub do_job { # include local plugins config->{'extra_worker_plugins'} = ["X::${pkg}"]; - # clear out any previous installed hooks - # TODO: do this in Worker.pm on every reimport ? - Dancer::Factory::Hook->init( Dancer::Factory::Hook->instance() ); - my $job = App::Netdisco::Backend::Job->new({ job => 0, device => '192.0.2.1',