Added one-shot command-line remote execution
authorFlavio Poletti <flavio@polettix.it>
Mon, 8 Feb 2010 13:39:37 +0000 (8 14:39 +0100)
committerFlavio Poletti <flavio@polettix.it>
Mon, 8 Feb 2010 13:39:37 +0000 (8 14:39 +0100)
deploy

diff --git a/deploy b/deploy
index 7fd3a2d..385c8ba 100755 (executable)
--- a/deploy
+++ b/deploy
@@ -1,7 +1,7 @@
 #!/usr/bin/env perl
 use strict;
 use warnings;
-my $VERSION = '0.6.0';
+my $VERSION = '0.7.0';
 use Carp;
 use Pod::Usage qw( pod2usage );
 use Getopt::Long qw( :config gnu_getopt );
@@ -31,6 +31,7 @@ GetOptions(
      password|pass|p:s
      prompt|P!
      script|s=s
+     commandline|command-line|S=s
      stderr|E!
      stdout|O!
      username|user|u=s
@@ -58,8 +59,16 @@ if (exists $config{password}) {
       unless $config{password};
 }
 
-($config{remote} = $config{script}) =~ s{[^\w.-]}{}mxsg;
-$config{remote} = catfile($config{dir}, $config{remote});
+if ($config{commandline}) {
+   pod2usage(-verbose => 99, -sections => 'USAGE',
+      message => 'use only one of "script" and "command-line"')
+      if exists $config{script};
+   $config{remote} = $config{commandline};
+}
+else {
+   ($config{remote} = $config{script}) =~ s{[^\w.-]}{}mxsg;
+   $config{remote} = catfile($config{dir}, $config{remote});
+}
 
 for my $hostname (@hostnames) {
    eval { operate_on_host($hostname) };
@@ -78,16 +87,18 @@ sub operate_on_host {
       exit 0 if $choice eq 'n';
    } ## end if ($config{prompt})
 
-   # Transfer file into $remote
-   my $sftp = get_sftp($hostname);
-   make_path($sftp, $config{dir});
-   $sftp->put($config{script}, $remote);
-   croak "no $remote, sorry. Stopped" unless $sftp->do_stat($remote);
+   # Transfer file into $remote, if any
+   if ($config{script}) {
+      my $sftp = get_sftp($hostname);
+      make_path($sftp, $config{dir});
+      $sftp->put($config{script}, $remote);
+      croak "no $remote, sorry. Stopped" unless $sftp->do_stat($remote);
+   }
 
-   # Execute file
+   # Execute
    my $ssh = get_ssh($hostname);
    $|++;
-   print {*STDOUT} "$remote ";
+   print {*STDOUT} $config{script} ? "$remote " : "cmd[$remote] ";
    my ($out, $err, $exit) = $ssh->cmd($remote);
    print {*STDOUT} "exit = $exit\n";
 
@@ -176,7 +187,8 @@ See version at beginning of script, variable $VERSION, or call
 
    deploy [--usage] [--help] [--man] [--version]
 
-   deploy [--debug|-D] [--dir|--directory|-d <dirname>]
+   deploy [--command-line|-S <string>] [--debug|-D]
+          [--dir|--directory|-d <dirname>]
           [--password|--pass|-p] [--prompt|-P]
           [--script|-s <scriptname>] [--stderr|-E] [--stdout|-O]
           [--username|--user|-u]
@@ -192,6 +204,9 @@ See version at beginning of script, variable $VERSION, or call
    # ... without bugging me prompting confirmations...
    shell$ deploy -s deploy-script.pl --no-prompt `cat targets`
 
+   # Execute a one-shot command remotely. Note UPPERCASE "s"
+   shell$ deploy -S 'ls -l /' `cat targets`
+
 =head1 DESCRIPTION
 
 This utility allows you to I<deploy> a script to one or more remote 
@@ -222,6 +237,15 @@ just hit enter when requested for a password, or you can pass
 C<-p> without a password on the command line (you can actually pass
 every password you can think of, it will be ignored).
 
+Starting from version 0.7.0, L<deploy> is also able to let you execute a
+one-shot command remotely via the C<--command-line|-S> option; this lets
+you avoid uploading a script and execute it and eases your life a bit if
+you have to launch a single command, e.g.:
+
+   shell$ deploy -S 'ls /path/to/whatever' `cat targets`
+
+In this case, nothing will be created in the target directory.
+
 =head2 Output Format
 
 The normal output format is geared at easing parsing by other programs. It
@@ -242,6 +266,12 @@ following format:
 
    </path/to/deployed/program> exit = <exit-code>
 
+in case a script is uploaded, or the following format:
+
+   cmd[<command to be executed>] exit = <exit-code>
+
+in case a single one-shot command is sent (see option C<--command-line|-S>).
+
 =item *
 
 0 or more lines starting with C<STDOUT > (note the space);
@@ -292,6 +322,13 @@ If you pass L<--stdout> you will get:
 
 =over
 
+=item --command-line | -S
+
+set a one-shot command to be executed instead of a script to be uploaded
+and then executed. This option is incompatible with C<--script|-s>, because
+with this you're requesting to execute a one-shot command, while with
+that you're requesting to upload a file and then execute it.
+
 =item --debug | -D
 
 turns on debug mode, which should print out more stuff during operations.
@@ -356,6 +393,8 @@ script will be sanitised (only alphanumeric, C<_>, C<.> and C<-> will
 be retained), so be careful if you have to look for the uploaded
 script later.
 
+This option is incompatible with C<--command-line|-S>.
+
 =item --stderr | -E
 
 select only the STDERR channel from the responses got via SSH. This