App-Netdisco
view release on metacpan or search on metacpan
lib/App/Netdisco/Worker/Plugin.pm view on Meta::CPAN
package App::Netdisco::Worker::Plugin;
use Dancer ':syntax';
use Dancer::Plugin;
use App::Netdisco::Util::Permission qw/acl_matches acl_matches_only/;
use aliased 'App::Netdisco::Worker::Status';
use Term::ANSIColor qw(:constants :constants256);
use Scope::Guard 'guard';
use Storable 'dclone';
register 'register_worker' => sub {
my ($self, $first, $second) = plugin_args(@_);
my $workerconf = (ref $first eq 'HASH' ? $first : {});
my $code = (ref $first eq 'CODE' ? $first : $second);
return error "bad param to register_worker"
unless ((ref sub {} eq ref $code) and (ref {} eq ref $workerconf));
my $package = (caller)[0];
($workerconf->{package} = $package) =~ s/^App::Netdisco::Worker::Plugin:://;
if ($package =~ m/Plugin::(\w+)(?:::(\w+))?/) {
$workerconf->{action} ||= lc($1);
$workerconf->{namespace} ||= lc($2) if $2;
}
return error "failed to parse action in '$package'"
unless $workerconf->{action};
$workerconf->{title} ||= '';
$workerconf->{phase} ||= 'user';
$workerconf->{namespace} ||= '_base_';
$workerconf->{priority} ||= (exists $workerconf->{driver}
? (setting('driver_priority')->{$workerconf->{driver}} || 0) : 0);
my $worker = sub {
my $job = shift or die 'missing job param';
# use DDP; p $workerconf;
debug YELLOW, "\N{RIGHTWARDS BLACK ARROW} worker ", GREY10, $workerconf->{package},
($workerconf->{pyworklet} ? (' '. $workerconf->{pyworklet}) : ''),
GREY10, ' p', MAGENTA, $workerconf->{priority},
($workerconf->{title} ? (GREY10, ' "', BRIGHT_BLUE, $workerconf->{title}, GREY10, '"') : ''),
RESET;
if ($job->is_cancelled) {
return $job->add_status( Status->info('skip: job is cancelled') );
}
if ($job->is_offline
and $workerconf->{phase} eq 'main'
and $workerconf->{priority} > 0
and $workerconf->{priority} < setting('driver_priority')->{'direct'}) {
return $job->add_status( Status->info('skip: networked worker but job is running offline') );
}
# support part-actions via action::namespace
if ($job->only_namespace and $workerconf->{phase} ne 'check') {
# skip namespaces not the requested ::namespace
if (not ($workerconf->{namespace} eq lc( $job->only_namespace )
# apart from discover::properties which needs to run, so that's early
# phase for unknown devices, but not ::hooks/early (if implemented)
or (($job->only_namespace ne 'hooks') and ($workerconf->{phase} eq 'early')
and ($job->device and not $job->device->in_storage)) )) {
return;
}
}
my @newuserconf = ();
my @userconf = @{ dclone (setting('device_auth') || []) };
# worker might be vendor/platform specific
if (ref $job->device) {
my $no = (exists $workerconf->{no} ? $workerconf->{no} : undef);
my $only = (exists $workerconf->{only} ? $workerconf->{only} : undef);
return $job->add_status( Status->info('skip: acls restricted') )
if ($no and acl_matches($job->device, $no))
or ($only and not acl_matches_only($job->device, $only));
( run in 0.368 second using v1.01-cache-2.11-cpan-5511b514fd6 )