App-RemoteCommand

 view release on metacpan or  search on metacpan

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

package App::RemoteCommand::SSH;
use v5.16;
use warnings;

use App::RemoteCommand::Util qw(DEBUG logger);
use Net::OpenSSH;
use IO::Pty;

sub _ssh {
    my ($self, %args) = @_;
    my $loglevel = DEBUG ? "error" : "quiet";
    Net::OpenSSH->new($args{host},
        async => 1,
        strict_mode => 0,
        timeout => 6,
        kill_ssh_on_timeout => 1,
        master_setpgrp => 1,
        master_opts => [
            -o => "ConnectTimeout=5",
            -o => "StrictHostKeyChecking=no",
            -o => "UserKnownHostsFile=/dev/null",
            -o => "LogLevel=$loglevel",
            ($args{configfile} ? (-F => $args{configfile}) : ()),
        ],
    );
}

use constant STATE_TODO          => 1;
use constant STATE_CONNECTING    => 2;
use constant STATE_CONNECTED     => 3;
use constant STATE_DISCONNECTING => 4;
use constant STATE_DONE          => 5;

sub new {
    my ($class, %args) = @_;
    bless {
        %args,
        ssh => undef,
        cmd => [],
        at_exit => undef,
        state => STATE_TODO,
        exit => -1,
        current => undef,
        sudo => undef,
    }, $class;
}

sub add {
    my ($self, $cmd) = @_;
    push @{$self->{cmd}}, $cmd;
}

sub at_exit {
    my $self = shift;
    @_ ? $self->{at_exit} = shift : $self->{at_exit};
}

sub cancel {
    my ($self, $signal) = @_;

    DEBUG and logger " CANCEL %s, state %s", $self->host, $self->{state};

    if ($self->{state} == STATE_TODO) {
        $self->{state} == STATE_DONE;
    } elsif ($self->{state} == STATE_CONNECTING) {
        @{$self->{cmd}} = ();
        undef $self->{at_exit};
        my $master_pid = $self->{ssh}->get_master_pid;
        DEBUG and logger " SEND SIG$signal %s, process group for master pid %d", $self->host, $master_pid;
        kill $signal => -$master_pid;
    } elsif ($self->{state} == STATE_CONNECTED) {
        @{$self->{cmd}} = ();
        if ($signal
            and $self->{current}
            and $self->{current}{type} eq "cmd"
            and my $pid = $self->{current}{pid}
        ) {
            DEBUG and logger " SEND SIG$signal %s, pid %s", $self->host, $pid;
            kill $signal => $pid;

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.236 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )