2017-12-15 10 views
0

Ich mache nicht blockierende ssh in über 300 Funkgeräte in unserem Netzwerk mit POE :: Component :: OpenSSH und eine separate POE :: Session für jedes Gerät. Das Skript, das ich habe, ist in funktionierender Form, aber einige der Geräte wurden nicht mit dem richtigen Passwort konfiguriert (wir behalten das gleiche Passwort für alle Geräte aus Gründen der Einfachheit daher verwenden dasselbe Passwort, um ssh in jedes Gerät). Manchmal machen die Ingenieure einen Fehler und installieren ein Gerät mit einem Nicht-Standard-SSH-Passwort. In diesem Fall, wenn OpenSSH sich nicht authentifizieren kann, bleibt POE :: Session hängen (_stop wird nie aufgerufen und das Skript wird nie beendet). Ich weiß, es ist kein reines programmatisches Problem. Wir installieren jeden Tag wenige Geräte in unserem Netzwerk und ich kann nicht darauf zählen, dass unsere Techniker jedes Mal das richtige Passwort eingeben. Auch wenn ich das Passwort auf unseren bestehenden Geräten korrigiere, ist es unvermeidlich, dass ein Gerät in Zukunft ein falsches Passwort hat, das meinen Prozess zum Erliegen bringt.OpenSSH POE Sitzung stecken

Ich kann $ kernel-> stop aber das mag ich nicht. Ich möchte, dass sich die Sitzung selbst löscht. Gibt es eine Möglichkeit, die von POE :: Component :: OpenSSH verwendeten Ressourcen/Dienste innerhalb der Sitzung mit einer Watcher-Sitzung zu löschen? Jede Hilfe wird geschätzt. Bitte beachten Sie meinen Code unten.

use strict; 
use warnings; 
use POE; 
use POE::Component::OpenSSH; 
use POE::Component::Client::Ping; 
use Data::Dumper; 

my $domain = shift; 
my @args = ($domain); 
my $session = POE::Session->create(
     args => \@args, 
     inline_states => { 
       _start => \&start, 
       configcapture => \&configcapture, 
       activecapture => \&activecapture, 
       detectdfs => \&dfs, 
       pong => \&pingresult, 
       handlerror => \&handlerror, 
       _stop => \&stop, 
     }, 
); 

POE::Kernel->run(); 
exit; 

sub start { 
     $_[KERNEL]->sig(DIE => 'sig_DIE'); 
     print "STARTING ... for $_[ARG0] \n"; 
     $_[HEAP]{'domain'} = $domain; 

     my $ssh = POE::Component::OpenSSH->new(
       args => ['[email protected]'.$domain.':6022', passwd => '123' ], 
     ); 

     $ssh->capture({event => 'configcapture', timeout => 2}, 
         'cat /tmp/system.cfg | grep radio.1.freq'); 
     $ssh->capture({event => 'activecapture', timeout => 2}, 
         '/usr/www/status.cgi'); 
     $_[KERNEL]->delay(detectdfs => 5); 
} 

sub configcapture { 
     $_[HEAP]{'configfreq'} = $_[ARG0]{'result'}[0]; 
} 

sub activecapture { 
     $_[HEAP]{'activefreq'} = $_[ARG0]{'result'}[0]; 
} 

sub dfs { 
     if(defined($_[HEAP]{'configfreq'}) && 
      defined($_[HEAP]{'activefreq'})) { 
       print "CONFIG: $_[HEAP]{'configfreq'}\n"; 
       print "ACTIVE: $_[HEAP]{'activefreq'}\n"; 
     } 
} 

sub stop { 
     my ($self, $output) = @_; 
     print "Ending Session Here \n"; 
} 
+0

Set '$ Net :: OpenSSH :: debug = -1' am Anfang des Skripts laufen es gegen eine der Maschinen mit dem falschen Passwort und hänge dann die Ausgabe an deine Frage hier an. Anstelle von [POE :: Component :: OpenSSH] (https://metacpan.org/pod/POE::Component::OpenSSH) können Sie auch den Anweisungen auf [Net :: OpenSSH] folgen (https: //metacpan.org/pod/Net::OpenSSH) Dokumentation über [wie man es aus einem ereignisorientierten Framework verwendet] (https://metacpan.org/pod/Net::OpenSSH#AnyEvent- (und-ähnliche-Frameworks)). – salva

+0

Vielleicht könnten Sie die Argumente 'timeout' und' kill_ssh_on_timeout' im Net :: OpenSSH 'args' übergeben? – NetMage

Antwort

0

Danke für die Nachrichten. Ich habe die Lösung selbst gefunden. Ich musste die timeout beim Konstruieren POE :: Component :: OpenSSH hinzufügen, so dass es das Ereignis _stop für jede Sitzung aufgerufen. Aber das Skript war immer noch nicht beendet.

Da POE :: Component :: OpenSSH POE :: Component :: Generic verwendet, um den blockierenden Net :: OpenSSH-Prozess als POE-Sitzung zu erzeugen, musste ich einfach die shutdown-Methode von POE :: Component :: Generic für aufrufen openssh component object, die festgefahren waren (bcoz des falschen Passworts oder was auch immer) und alle Sitzungen wurden sauber beendet und das Skript beendet.

sehen Sie bitte die Lösung unter:

$_[HEAP]{'ssh'} = POE::Component::OpenSSH->new(
       args => [[email protected], passwd => '123', timeout => 180, async => 1, master_opts => [-o => "StrictHostKeyChecking=no"]], 
     ); 

und dann, wenn in _stop

my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; 
delete $heap->{wheel}; 
$kernel->alias_remove($heap->{alias}); 
$kernel->alarm_remove_all(); 
$_[HEAP]{'ssh'}->object->shutdown; 
delete($_[HEAP]{'ssh'}); 
Verwandte Themen