]> mj.ucw.cz Git - bex.git/blobdiff - benq
Command used to run ssh is configurable
[bex.git] / benq
diff --git a/benq b/benq
index 0259f435950c67aa1e2ca35e9873230f2c8feaeb..76d79489a3f26ff178f802e9ad140e75a151937f 100755 (executable)
--- a/benq
+++ b/benq
 #!/usr/bin/perl
-# Batch EXecutor 2.0
+# Batch EXecutor 2.0 -- Insert to Queue
 # (c) 2011 Martin Mares <mj@ucw.cz>
 
 use strict;
 use warnings;
+use Getopt::Long;
+use File::stat;
 
 use lib 'lib';
 use BEX;
 
-my $job = BEX::Job->new;
-my $fn = $job->save;
-system "editor", $fn;
-## FIXME: Check exit code of editor
-$job = BEX::Job->new_from_file($fn);
-## FIXME: Compare and exit if no changes
+my $given_body;
+my $given_go;
+my $given_id;
+my $queue_name;
+my $requeue_id;
+my $given_subject;
+my $given_template;
 
-my $queue = BEX::Queue->new;
-for my $m (keys %BEX::Config::machines) {
-       $queue->enqueue($m, $job);
+GetOptions(
+       "b|body=s" => \$given_body,
+       "g|go!" => \$given_go,
+       "i|id=s" => \$given_id,
+       "q|queue=s" => \$queue_name,
+       "r|requeue=s" => \$requeue_id,
+       "s|subject=s" => \$given_subject,
+       "t|template=s" => \$given_template,
+) or die <<AMEN ;
+Usage: benq [<options>] [!]<machine-or-class> ...
+
+Options:
+-b, --body=<file>      Load job body from the given file
+-g, --go               Do not run editor, go enqueue the job immediately
+-i, --id=<id>          Set job ID of the new job
+-q, --queue=<name>     Insert new jobs to the given queue
+-r, --requeue=<id>     Re-queue an existing job instead of creating a new one
+-s, --subject=<subj>   Set subject of the new job
+-t, --template=<file>  Load job template (headers and body) from the given file
+AMEN
+
+# Prepare machine set
+@ARGV or die "No machines specified\n";
+my @machines = BEX::Config::parse_machine_list(@ARGV);
+@machines or die "No machines match\n";
+
+my $queue = BEX::Queue->new($queue_name);
+my $job;
+my $tmp_fn;
+
+if (defined $requeue_id) {
+       # When requeueing, just fetch the existing job
+       if (defined($given_body) || defined($given_id) || defined($given_subject) || defined($given_template)) {
+               die "Parameters of a requeued job cannot be changed\n";
+       }
+       my $fn = $queue->job_file($requeue_id);
+       -f $fn or die "Job $requeue_id not known\n";
+       $job = BEX::Job->new_from_file($fn);
+} else {
+       # Create job template
+       if (defined $given_template) {
+               $job = BEX::Job->new_from_file($given_template);
+       } else {
+               $job = BEX::Job->new;
+       }
+       $job->attr('ID', $given_id) if defined $given_id;
+       $job->attr('Subject', $given_subject) if defined $given_subject;
+       if (defined $given_body) {
+               open B, '<', $given_body or die "Cannot open $given_body: $!\n";
+               local $/;
+               $job->attr('body', <B>);
+               close B;
+       }
+
+       # Let the user edit the template
+       if (!$given_go) {
+               $tmp_fn = $job->save;
+               my $orig_stat = stat($tmp_fn) or die;
+               system "editor", $tmp_fn and die "Editor exited with an error, file kept as $tmp_fn\n";
+               my $new_stat = stat($tmp_fn) or die "File $tmp_fn disappeared under my hands: $!\n";
+               if ($new_stat->mtime <= $orig_stat->mtime && $new_stat->size == $orig_stat->size) {
+                       unlink $tmp_fn;
+                       die "Cancelled\n";
+               }
+               $job = BEX::Job->new_from_file($tmp_fn);
+       }
+}
+
+# Put the job to the queue
+print "New job ", $job->id, "\n";
+for my $m (@machines) {
+       if ($queue->enqueue($m, $job)) {
+               $queue->write_job_status($m, $job->id, { 'Time' => time, 'Status' => 'NEW' });
+               print "\t$m\n";
+       } else {
+               print "\t$m (already queued)\n";
+       }
 }
 
-unlink $fn;
+# Remove the temporary file if there's any
+unlink $tmp_fn if defined $tmp_fn;