]> mj.ucw.cz Git - bex.git/blob - lib/bin/bex-ls
a57598365fb148a253d1be9340a9714e74dd1274
[bex.git] / lib / bin / bex-ls
1 #!/usr/bin/perl
2 # Batch EXecutor 3.0 -- Show Queued Jobs
3 # (c) 2011-2012 Martin Mares <mj@ucw.cz>
4
5 use strict;
6 use warnings;
7 use Getopt::Long;
8 use POSIX;
9 use BEX;
10
11 my $op_by_job;
12 my $op_by_host;
13 my $op_rm;
14 my $op_move_to;
15
16 my $queue_name;
17 my $given_job;
18
19 sub usage() {
20         print <<AMEN ;
21 Usage: bex ls [<options and actions>] [[!]<machine-or-class> ...]
22
23 Actions:
24     --by-job            Show jobs sorted by job ID (default)
25 -h, --by-host           Show jobs sorted by host
26     --rm                Remove jobs from the queue
27     --move-to=<queue>   Move jobs to a different queue
28
29 Options:
30 -j, --job=<id>          Act on the specified job (default: on all)
31 -q, --queue=<name>      Act on the given queue
32 AMEN
33         exit 0;
34 }
35
36 GetOptions(
37         "by-job!" => \$op_by_job,
38         "h|by-host!" => \$op_by_host,
39         "rm!" => \$op_rm,
40         "move-to=s" => \$op_move_to,
41         "j|job=s" => \$given_job,
42         "q|queue=s" => \$queue_name,
43         "help" => \&usage,
44 ) or die "Try `bex ls --help' for more information.\n";
45
46 my @machines = BEX::Config::parse_machine_list(@ARGV ? @ARGV : '*');
47 my $queue = BEX::Queue->new($queue_name);
48
49 # Select jobs
50 my %jobs = ();
51 my %machs = ();
52 for my $m (@machines) {
53         for my $j ($queue->scan($m)) {
54                 if (defined $given_job) {
55                         next if $j ne $given_job;
56                 }
57                 push @{$jobs{$j}}, $m;
58                 push @{$machs{$m}}, $j;
59         }
60 }
61
62 sub do_ls();
63 sub do_rm();
64 sub do_move_to();
65
66 my $ops = 0 + defined($op_by_host) + defined($op_by_job) + defined($op_rm) + defined($op_move_to);
67 if ($ops > 1) { die "Multiple actions are not allowed\n"; }
68
69 if ($op_rm) { do_rm(); }
70 elsif (defined $op_move_to) { do_move_to(); }
71 else { do_ls(); }
72 exit 0;
73
74 sub do_ls()
75 {
76         my %stat = ();
77         my %mach_locked = ();
78         for my $m (keys %machs) {
79                 $mach_locked{$m} = $queue->is_locked($m, undef);
80                 for my $j (@{$machs{$m}}) {
81                         my $st = $queue->read_job_status($m, $j);
82                         if (defined($st->{'Time'}) && defined($st->{'Status'})) {
83                                 $stat{$m}{$j} = ' [' . $st->{'Status'} . ' on ' .
84                                                 POSIX::strftime('%Y-%m-%d', localtime $st->{'Time'}) . ']';
85                         } else {
86                                 $stat{$m}{$j} = '';
87                         }
88                         if ($mach_locked{$m} || $queue->is_locked($m, $j)) {
89                                 $stat{$m}{$j} .= ' [LOCKED]';
90                         }
91                 }
92         }
93
94         if ($queue->is_locked(undef, undef)) {
95                 print "### Queue lock present\n\n";
96         }
97
98         if ($op_by_host) {
99                 for my $m (sort keys %machs) {
100                         print "$m", ($mach_locked{$m} ? ' [LOCKED]' : ''), "\n";
101                         for my $j (@{$machs{$m}}) {
102                                 print "\t" . $queue->job_name($j) . $stat{$m}{$j}, "\n";
103                         }
104                 }
105         } else {
106                 for my $j (sort keys %jobs) {
107                         print $queue->job_name($j), "\n";
108                         for my $m (sort @{$jobs{$j}}) {
109                                 print "\t$m", $stat{$m}{$j}, "\n";
110                         }
111                 }
112         }
113 }
114
115 sub do_rm()
116 {
117         my $err = 0;
118         for my $m (sort keys %machs) {
119                 for my $j (sort @{$machs{$m}}) {
120                         if (!$queue->lock($m, $j)) {
121                                 print STDERR "Cannot remove $m:", $queue->job_name($j), ", it is locked\n";
122                                 $err = 1;
123                         } else {
124                                 $queue->update_job_status($m, $j, 'REMOVED');
125                                 $queue->remove($m, $j);
126                                 print "Removed $m:", $queue->job_name($j), "\n";
127                         }
128                 }
129         }
130         $queue->unlock;
131         exit $err;
132 }
133
134 sub do_move_to()
135 {
136         my $err = 0;
137         my $dest = BEX::Queue->new($op_move_to);
138         $dest->{'Name'} ne $queue->{'Name'} or die "Moving to the same queue is not permitted\n";
139         for my $j (sort keys %jobs) {
140                 my $job = BEX::Job->new_from_file($queue->job_file($j));
141                 for my $m (sort @{$jobs{$j}}) {
142                         if (!$queue->lock($m, $j)) {
143                                 print STDERR "Cannot move $m:", $queue->job_name($j), ", it is locked\n";
144                                 $err = 1;
145                         } else {
146                                 my $enq = $dest->enqueue($m, $job);
147                                 if ($enq) {
148                                         $dest->update_job_status($m, $job->id, 'NEW', 'Moved to this queue');
149                                 } else {
150                                         $dest->log($m, $job->id, 'REQUEUE', 'Moved to this queue');
151                                 }
152                                 $queue->update_job_status($m, $job->id, 'REMOVED', 'Moved from this queue');
153                                 $queue->remove($m, $j);
154                                 print "Moved $m:", $dest->job_name($j);
155                                 print " (already queued)" if !$enq;
156                                 print "\n";
157                         }
158                 }
159         }
160         $queue->unlock;
161         exit $err;
162 }