use lib 'lib';
use BEX;
-my $by_host;
+my $op_by_job;
+my $op_by_host;
+my $op_rm;
+my $op_move_to;
+
my $queue_name;
my $given_job;
GetOptions(
- "h|by-host!" => \$by_host,
+ "by-job!" => \$op_by_job,
+ "h|by-host!" => \$op_by_host,
+ "rm!" => \$op_rm,
+ "move-to=s" => \$op_move_to,
"j|job=s" => \$given_job,
"q|queue=s" => \$queue_name,
) or die <<AMEN ;
-Usage: bq [<options>] [[!]<machine-or-class> ...]
+Usage: bq [<options and actions>] [[!]<machine-or-class> ...]
+
+Actions:
+ --by-job Show jobs sorted by job ID (default)
+-h, --by-host Show jobs sorted by host
+ --rm Remove jobs from the queue
+ --move-to=<queue> Move jobs to a different queue
Options:
--h, --by-host Show jobs sorted by host (default: by job)
--j, --job=<id> Show only instances of the specified job
--q, --queue=<name> Show jobs in the given queue
+-j, --job=<id> Act on the specified job (default: on all)
+-q, --queue=<name> Act on the given queue
AMEN
my @machines = BEX::Config::parse_machine_list(@ARGV ? @ARGV : '*');
my $queue = BEX::Queue->new($queue_name);
+# Select jobs
my %jobs = ();
my %machs = ();
-my %subj = ();
-my %stat = ();
-my %mach_locked = ();
for my $m (@machines) {
- $mach_locked{$m} = $queue->is_locked($m, undef);
for my $j ($queue->scan($m)) {
if (defined $given_job) {
next if $j ne $given_job;
}
push @{$jobs{$j}}, $m;
push @{$machs{$m}}, $j;
- my $job = $queue->job_metadata($j);
- $subj{$j} = ' (' . $job->{'Subject'} . ')';
-
}
}
-# Read status of each job
-for my $m (keys %machs) {
- for my $j (@{$machs{$m}}) {
- my $st = $queue->read_job_status($m, $j);
- if (defined($st->{'Time'}) && defined($st->{'Status'})) {
- $stat{$m}{$j} = ' [' . $st->{'Status'} . ' on ' .
- POSIX::strftime('%Y-%m-%d', localtime $st->{'Time'}) . ']';
- } else {
- $stat{$m}{$j} = '';
- }
- if ($mach_locked{$m} || $queue->is_locked($m, $j)) {
- $stat{$m}{$j} .= ' [LOCKED]';
+sub do_ls();
+sub do_rm();
+sub do_move_to();
+
+my $ops = 0 + defined($op_by_host) + defined($op_by_job) + defined($op_rm) + defined($op_move_to);
+if ($ops > 1) { die "Multiple actions are not allowed\n"; }
+
+if ($op_rm) { do_rm(); }
+elsif (defined $op_move_to) { do_move_to(); }
+else { do_ls(); }
+exit 0;
+
+sub do_ls()
+{
+ my %stat = ();
+ my %mach_locked = ();
+ for my $m (keys %machs) {
+ $mach_locked{$m} = $queue->is_locked($m, undef);
+ for my $j (@{$machs{$m}}) {
+ my $st = $queue->read_job_status($m, $j);
+ if (defined($st->{'Time'}) && defined($st->{'Status'})) {
+ $stat{$m}{$j} = ' [' . $st->{'Status'} . ' on ' .
+ POSIX::strftime('%Y-%m-%d', localtime $st->{'Time'}) . ']';
+ } else {
+ $stat{$m}{$j} = '';
+ }
+ if ($mach_locked{$m} || $queue->is_locked($m, $j)) {
+ $stat{$m}{$j} .= ' [LOCKED]';
+ }
}
}
-}
-if ($queue->is_locked(undef, undef)) {
- print "### Queue lock present\n\n";
+ if ($queue->is_locked(undef, undef)) {
+ print "### Queue lock present\n\n";
+ }
+
+ if ($op_by_host) {
+ for my $m (sort keys %machs) {
+ print "$m", ($mach_locked{$m} ? ' [LOCKED]' : ''), "\n";
+ for my $j (@{$machs{$m}}) {
+ print "\t" . $queue->job_name($j) . $stat{$m}{$j}, "\n";
+ }
+ }
+ } else {
+ for my $j (sort keys %jobs) {
+ print $queue->job_name($j), "\n";
+ for my $m (sort @{$jobs{$j}}) {
+ print "\t$m", $stat{$m}{$j}, "\n";
+ }
+ }
+ }
}
-if ($by_host) {
+sub do_rm()
+{
+ my $err = 0;
for my $m (sort keys %machs) {
- print "$m", ($mach_locked{$m} ? ' [LOCKED]' : ''), "\n";
- for my $j (@{$machs{$m}}) {
- print "\t$j", $subj{$j}, $stat{$m}{$j}, "\n";
+ for my $j (sort @{$machs{$m}}) {
+ if (!$queue->lock($m, $j)) {
+ print STDERR "Cannot remove $m:", $queue->job_name($j), ", it is locked\n";
+ $err = 1;
+ } else {
+ $queue->log($m, $j, 'REMOVED');
+ $queue->write_job_status($m, $j, { 'Time' => time, 'Status' => 'REMOVED' });
+ $queue->remove($m, $j);
+ print "Removed $m:", $queue->job_name($j), "\n";
+ }
}
}
-} else {
+ $queue->unlock;
+ exit $err;
+}
+
+sub do_move_to()
+{
+ my $err = 0;
+ my $dest = BEX::Queue->new($op_move_to);
+ $dest->{'Name'} ne $queue->{'Name'} or die "Moving to the same queue is not permitted\n";
for my $j (sort keys %jobs) {
- print $j, $subj{$j}, "\n";
+ my $job = BEX::Job->new_from_file($queue->job_file($j));
for my $m (sort @{$jobs{$j}}) {
- print "\t$m", $stat{$m}{$j}, "\n";
+ if (!$queue->lock($m, $j)) {
+ print STDERR "Cannot move $m:", $queue->job_name($j), ", it is locked\n";
+ $err = 1;
+ } else {
+ my $enq = $dest->enqueue($m, $job);
+ $dest->write_job_status($m, $job->id, { 'Time' => time, 'Status' => 'NEW', 'Message' => 'Moved to this queue' });
+ $queue->log($m, $j, 'REMOVED', "Moved to another queue");
+ $queue->write_job_status($m, $j, { 'Time' => time, 'Status' => 'REMOVED', 'Message' => 'Moved to another queue' });
+ $queue->remove($m, $j);
+ print "Moved $m:", $queue->job_name($j);
+ print " (already queued)" if !$enq;
+ print "\n";
+ }
}
}
+ $queue->unlock;
+ exit $err;
}