stash workers within poller instance, and load plugins explicitly

This commit is contained in:
Oliver Gorwits
2017-11-15 22:09:05 +00:00
parent 2431365583
commit 620b3fe544
7 changed files with 106 additions and 66 deletions

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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(@_);

View File

@@ -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 $_;

View File

@@ -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

View File

@@ -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',