diff --git a/Changes b/Changes index 15f4ccd..0dada3f 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ 4.10_03 0000-00-00 Duncan Ferguson - Fix for multiple range expansion, as in 'h{a,b}{1,2}' (Github issue #97) (Thanks to lazyfrosch) - Upgrade Perl::Tidy requirement to version 20171214 (Github issue #99) (Thanks to eserte) +- Add in 'external command pipe' to allow for some commands being passed in from the command line 4.10_02 2017-08-08 Duncan Ferguson - Include coverage tests in the resources diff --git a/lib/App/ClusterSSH.pm b/lib/App/ClusterSSH.pm index 73a657b..056eef2 100644 --- a/lib/App/ClusterSSH.pm +++ b/lib/App/ClusterSSH.pm @@ -171,6 +171,22 @@ sub exit_prog() { my ($self) = @_; $self->debug( 3, "Exiting via normal routine" ); + if ( $self->config->{external_command_pipe} + && -e $self->config->{external_command_pipe} ) + { + close( $self->{external_command_pipe_fh} ) + or warn( + "Could not close pipe " + . $self->config->{external_command_pipe} . ": ", + $! + ); + $self->debug( 2, "Removing external command pipe" ); + unlink( $self->config->{external_command_pipe} ) + || warn "Could not unlink " + . $self->config->{external_command_pipe} + . ": ", $!; + } + # for each of the client windows, send a kill. # to make sure we catch all children, even when they haven't # finished starting or received the kill signal, do it like this @@ -1435,6 +1451,35 @@ sub setup_repeat() { $self->config->{internal_count} ); + # See if there are any commands in the external command pipe + { + my $ext_cmd; + sysread( $self->{external_command_pipe_fh}, $ext_cmd, 400 ); + if ($ext_cmd) { + my @external_commands = split( /\n/, $ext_cmd ); + for my $cmd_line (@external_commands) { + chomp($cmd_line); + my ( $cmd, @tags ) = split /\s+/, $cmd_line; + $self->debug( 2, + "Got external command: $cmd -> @tags" ); + + for ($cmd) { + if (m/^open$/) { + my @new_hosts = $self->resolve_names(@tags); + $self->open_client_windows(@new_hosts); + $self->build_hosts_menu(); + last; + } + if (m/^retile$/) { + $self->retile_hosts(); + last; + } + warn "Unknown external command: $cmd_line", $/; + } + } + } + } + #$self->debug( 3, "Number of servers in hash is: ", scalar( keys(%servers) ) ); foreach my $svr ( keys(%servers) ) { @@ -2233,6 +2278,44 @@ sub run { $windows{main_window}->positionfrom('user') ; # user puts it somewhere, leave it there + # set up external command pipe + if ( $self->config->{external_command_pipe} ) { + + if ( -e $self->config->{external_command_pipe} ) { + $self->debug( 1, "Removing pre-existing external command pipe" ); + unlink( $self->config->{external_command_pipe} ) + or die( + "Could not remove " + . $self->config->{external_command_pipe} + . " prior to creation: " + . $!, + $/ + ); + } + + $self->debug( 2, "Creating external command pipe" ); + + mkfifo( + $self->config->{external_command_pipe}, + oct( $self->config->{external_command_mode} ) + ) + or die( + "Could not create " + . $self->config->{external_command_pipe} . ": ", + $! + ); + + sysopen( + $self->{external_command_pipe_fh}, + $self->config->{external_command_pipe}, + O_NONBLOCK | O_RDONLY + ) + or die( + "Could not open " . $self->config->{external_command_pipe} . ": ", + $! + ); + } + $self->debug( 2, "Setting up repeat" ); $self->setup_repeat(); diff --git a/lib/App/ClusterSSH/Config.pm b/lib/App/ClusterSSH/Config.pm index 20bc74a..46da727 100644 --- a/lib/App/ClusterSSH/Config.pm +++ b/lib/App/ClusterSSH/Config.pm @@ -77,6 +77,8 @@ my %default_config = ( extra_tag_file => '', extra_cluster_file => '', external_cluster_command => '', + external_command_mode => '0600', + external_command_pipe => '', unmap_on_redraw => "no", # Debian #329440 diff --git a/lib/App/ClusterSSH/Getopt.pm b/lib/App/ClusterSSH/Getopt.pm index bdf2232..b7848ad 100644 --- a/lib/App/ClusterSSH/Getopt.pm +++ b/lib/App/ClusterSSH/Getopt.pm @@ -675,6 +675,22 @@ would replace the with the client's name in each window.} q{Set the initial position of the console - if empty then let the window manager decide. Format is '++', i.e. '+0+0' is top left hand corner of the screen, '+0-70' is bottom left hand side of screen (more or less).} ); + output '=item external_command_mode = 0600'; + output $self->loc(q{File mode bits for the external_command_pipe.}); + + output '=item external_command_pipe = '; + output $self->loc( + q{Define the full path to an external command pipe that can be written to for controlling some aspects of ClusterSSH, such as opening sessions to more clusters. + +Commands: + +C<< open >> - open new sessions to provided tag or hostname + +C<< retile >> - force window retiling + +e.g.: C<< echo 'open localhost' >> /path/to/external_command_pipe >>} + ); + output '=item external_cluster_command = '; output $self->loc( q{Define the full path to an external command that can be used to resolve tags to host names. This command can be written in any language. The script must accept a list of tags to resolve and output a list of hosts (space separated on a single line). Any tags that cannot be resolved should be returned unchanged. diff --git a/t/15config.t b/t/15config.t index b4093b4..99c6873 100644 --- a/t/15config.t +++ b/t/15config.t @@ -88,6 +88,8 @@ Readonly::Hash my %default_config => { extra_tag_file => "", extra_cluster_file => "", external_cluster_command => '', + external_command_mode => '0600', + external_command_pipe => '', unmap_on_redraw => "no", @@ -547,6 +549,8 @@ console=console console_args= console_position= external_cluster_command= +external_command_mode=0600 +external_command_pipe= extra_cluster_file= extra_tag_file= fillscreen=no