diff --git a/lib/App/Netdisco/DB.pm b/lib/App/Netdisco/DB.pm index 72898442..a6272a1e 100644 --- a/lib/App/Netdisco/DB.pm +++ b/lib/App/Netdisco/DB.pm @@ -11,7 +11,7 @@ __PACKAGE__->load_namespaces( ); our # try to hide from kwalitee - $VERSION = 41; # schema version used for upgrades, keep as integer + $VERSION = 42; # schema version used for upgrades, keep as integer use Path::Class; use File::ShareDir 'dist_dir'; diff --git a/lib/App/Netdisco/DB/Result/Admin.pm b/lib/App/Netdisco/DB/Result/Admin.pm index 439046fe..6378efaf 100644 --- a/lib/App/Netdisco/DB/Result/Admin.pm +++ b/lib/App/Netdisco/DB/Result/Admin.pm @@ -114,4 +114,17 @@ between the date stamp and time stamp. That is: sub finished_stamp { return (shift)->get_column('finished_stamp') } +=head1 RELATIONSHIPS + +=head2 ignored + +Retuns the set of C entries which may apply to this job. They +match the device IP and job action, and may refer to one or more backends. + +=cut + +__PACKAGE__->has_many( ignored => 'App::Netdisco::DB::Result::DeviceIgnore', + { 'foreign.device' => 'self.device', 'foreign.action' => 'self.action' }, +); + 1; diff --git a/lib/App/Netdisco/DB/Result/DeviceIgnore.pm b/lib/App/Netdisco/DB/Result/DeviceIgnore.pm new file mode 100644 index 00000000..23ddb430 --- /dev/null +++ b/lib/App/Netdisco/DB/Result/DeviceIgnore.pm @@ -0,0 +1,23 @@ +use utf8; +package App::Netdisco::DB::Result::DeviceIgnore; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; +__PACKAGE__->table("device_ignore"); +__PACKAGE__->add_columns( + "backend", + { data_type => "text", is_nullable => 0 }, + "device", + { data_type => "inet", is_nullable => 0 }, + "action", + { data_type => "text", is_nullable => 0 }, + "failures", + { data_type => "integer", is_nullable => 1, default_value => '0' }, + "ignore", + { data_type => "boolean", is_nullable => 1, default_value => \'false' }, +); +__PACKAGE__->set_primary_key("backend", "device", "action"); + +1; diff --git a/lib/App/Netdisco/DB/ResultSet.pm b/lib/App/Netdisco/DB/ResultSet.pm index 7fbf8c56..953c8e80 100644 --- a/lib/App/Netdisco/DB/ResultSet.pm +++ b/lib/App/Netdisco/DB/ResultSet.pm @@ -5,8 +5,11 @@ use warnings; use base 'DBIx::Class::ResultSet'; -__PACKAGE__->load_components( - qw{Helper::ResultSet::SetOperations Helper::ResultSet::Shortcut}); +__PACKAGE__->load_components(qw/ + Helper::ResultSet::SetOperations + Helper::ResultSet::Shortcut + Helper::ResultSet::CorrelateRelationship +/); =head1 ADDITIONAL METHODS diff --git a/lib/App/Netdisco/JobQueue/PostgreSQL.pm b/lib/App/Netdisco/JobQueue/PostgreSQL.pm index efcc15a1..230067c2 100644 --- a/lib/App/Netdisco/JobQueue/PostgreSQL.pm +++ b/lib/App/Netdisco/JobQueue/PostgreSQL.pm @@ -30,11 +30,17 @@ sub _getsome { return () if ((!defined $num_slots) or ($num_slots < 1)); return () if ((!defined $where) or (ref {} ne ref $where)); - my $rs = schema('netdisco')->resultset('Admin') - ->search( - { status => 'queued', %$where }, - { order_by => 'random()', rows => $num_slots }, - ); + my $fqdn = hostfqdn || 'localhost'; + my $jobs = schema('netdisco')->resultset('Admin'); + + my $rs = $jobs->search({ + status => 'queued', + device => { '-not_in' => $jobs->correlate('ignored')->search({ + backend => $fqdn, + -or => [{ failures => { '>=', 10 } },{ '-bool' => 'ignore' }], + }, { columns => 'device' })->as_query }, + %$where, + }, { order_by => 'random()', rows => $num_slots }); my @returned = (); while (my $job = $rs->next) { diff --git a/share/schema_versions/App-Netdisco-DB-41-42-PostgreSQL.sql b/share/schema_versions/App-Netdisco-DB-41-42-PostgreSQL.sql new file mode 100644 index 00000000..b7bee310 --- /dev/null +++ b/share/schema_versions/App-Netdisco-DB-41-42-PostgreSQL.sql @@ -0,0 +1,12 @@ +BEGIN; + +CREATE TABLE "device_ignore" ( + "backend" text NOT NULL, + "device" inet NOT NULL, + "action" text NOT NULL, + "failures" integer DEFAULT 0, + "ignore" boolean DEFAULT false, + PRIMARY KEY ("backend", "device", "action") +); + +COMMIT;