App-RemoteCommand

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


0.91  2017-09-07 01:49:45 JST
  - Create Net::OpenSSH instances first, and wait them by wait_for_master()

0.90  2017-09-03 01:00:41 JST
  - Full rewrite; use our own event-loop

0.04  2017-05-05 13:04:47 JST
  - add screencast
  - switch to Module::Build::Tiny
  - improve prompt function

0.03  2016-11-21 23:00:40 JST
  - remove IO::Prompt dependency

0.02  2015-10-14 01:45:07 JST
  - simplify signal handling; only handle INT signal
  - able to specify script args
  - introduce --sudo=USER, --quiet options
  - deprecate --user, --identity options

lib/App/RemoteCommand.pm  view on Meta::CPAN

package App::RemoteCommand v1.0.0;
use v5.24;
use warnings;
use experimental qw(lexical_subs signatures);

use App::RemoteCommand::Pool;
use App::RemoteCommand::SSH;
use App::RemoteCommand::Select;
use App::RemoteCommand::Util qw(prompt DEBUG logger);

use File::Basename ();
use File::Copy ();
use File::Temp ();
use Getopt::Long ();
use IO::Select;
use List::Util ();
use POSIX 'strftime';
use Pod::Usage ();
use String::Glob::Permute 'string_glob_permute';

lib/App/RemoteCommand.pm  view on Meta::CPAN

        chmod 0755, $tempfile;
        $self->{script} = $tempfile;
    }

    $self->{format} = $self->make_format(
        append_hostname => $append_hostname,
        append_time => $append_time,
    );

    if ($ask_sudo_password) {
        my $password = prompt $SUDO_PROMPT;
        $self->{sudo_password} = $password;
    }
    $self->{host} = $host_file ? $self->parse_host_file($host_file)
                               : $self->parse_host_arg($host_arg);
    $self;
}

sub cancel ($self, $signal) {
    $self->{pending}->@* = ();
    for my $ssh ($self->{running}->all) {

lib/App/RemoteCommand/Util.pm  view on Meta::CPAN

package App::RemoteCommand::Util;
use v5.24;
use warnings;
use experimental qw(lexical_subs signatures);

use Exporter 'import';
our @EXPORT_OK = qw(prompt DEBUG logger);

use constant DEBUG => $ENV{PERL_RCOMMAND_DEBUG} ? 1 : 0;

use Term::ReadKey 'ReadMode';

sub logger (@args) {
    my $msg = @args == 1 ? $args[0] : sprintf shift(@args), @args;
    warn " | $msg\n";
}

sub prompt ($msg) {
    local $| = 1;
    print $msg;
    ReadMode 'noecho', \*STDIN;
    my $SIGNAL = "Catch SIGINT\n";
    my $answer;
    eval {
        local $SIG{INT} = sub (@) { die $SIGNAL };
        $answer = <STDIN>;
    };
    my $error = $@;

script/rcommand  view on Meta::CPAN

=head1 SYNOPSIS

  $ rcommand [OPTIONS] HOSTS COMMANDS
  $ rcommand [OPTIONS] --host-file FILE COMMANDS
  $ rcommand [OPTIONS] HOSTS --script SCRIPT [SCRIPT_ARGS]

=head1 OPTIONS

  -s, --script=SCRIPT       execute local script file instead of COMMANDS argument
  -H, --host-file=FILE      set target hosts by host listed file
  -a, --ask-sudo-password   raise prompt for sudo password first
      --sudo-password=PASS  set sudo password
  -c, --concurrency=NUM     parallel concurrency, default 5
      --append-hostname     append hostname to each output line, default on
      --append-time         append time to each output line, default off
      --sudo=USER           execute COMMAND or SCRIPT with sudo -u USER
  -F                        ssh configfile
  -q, --quiet               do not show SUCCESS/FAIL results
  -h, --help                show this help
  -v, --version             show version



( run in 0.796 second using v1.01-cache-2.11-cpan-0b5f733616e )