Skip to content

Commit

Permalink
Implement --exec @node cmd [args...]
Browse files Browse the repository at this point in the history
This command might be usefull, e.g. if sshd is not responding.

Examples:

  clusterd --exec @theinternet restart sshd.service
  clusterd --exec @theinternet dmesg
  clusterd --exec @theinternet 'grep sshd /var/log/messages|tail -100'

The remote command is executed by bash, so the pipe in the last example
is on the remote node

stdout and stderr are delivered seperatly and might be redirected to
different channels on the local side.

If the remote command exits with a non-zero exit status, the local
command fails with exit status 1.

The slave part already existed, because we once had a remote
execution command. We removed it, because it was considered to
be to dangerous. The former remote execution command allowed parallel
execution on all nodes, which enabled an admin to kill all systems
by mistake in an instance. Now we only enable remote execution on a
single node.
  • Loading branch information
donald committed Dec 29, 2016
1 parent 98e18f5 commit cd33094
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions clusterd
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,22 @@ sub expand_netgroup_hosts {
return @out;
}

sub exec_at {
my ($host,@cmd)=@_;
sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n";
my $s=new IO::Socket::INET(PeerAddr=>$host,PeerPort=>$CLP_PORT);
unless (defined $s) {
die "$host: $!\n";
}
clp_send_message($s,'CMD',@cmd);
my $pbuffer='';
my $olbuffer='';
my $elbuffer='';
Donald::Select::reader($s,\&cmd_rx,$host,$s,\$pbuffer,\$olbuffer,\$elbuffer);
$slave=1;
Donald::Select::run() if $slave;;
}

sub lsof {
my ($pattern)=@_;
sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n";
Expand Down Expand Up @@ -1367,13 +1383,13 @@ sub cmd_msg {
} elsif ($channel eq 'O') {
my $msg=$$olbufref.substr($data,1);
for ($msg=~/([^\n]*\n)/gs) {
print "$host $_";
print "$host: $_";
}
($$olbufref)=$msg=~/([^\n]*)\z/;
} elsif ($channel eq 'E') {
my $msg=$$elbufref.substr($data,1);
for ($msg=~/([^\n]*\n)/gs) {
print STDERR "$host $_";
print STDERR "$host: $_";
}
($$elbufref)=$msg=~/([^\n]*)\z/;
}
Expand All @@ -1389,6 +1405,7 @@ usage: $0 [options]
--push-amd-tar # broadcast /etc/amd
--send-restart # broadcast a restart request to all nodes
--exec mkmotd # execute /usr/sbin/mkmotd.pl on all nodes
--exec @node cmd [args...] # execute cmd on node
--flush-gidcache # flush rpc auth.unix.gid cache on all nodes
--lsof=pattern
Expand Down Expand Up @@ -1423,9 +1440,15 @@ if (defined $options{'push'}) {
$donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n";
push_file($donald_s,$options{'push'});
} elsif (defined $options{'exec'}) {
sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n";
$donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n";
send_exec($donald_s,$options{'exec'});
if (substr($options{'exec'},0,1) eq '@') {
length(length($options{'exec'})>1) or die USAGE;
@ARGV>=1 or die USAGE;
exec_at(substr($options{'exec'},1),@ARGV);
} else {
sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n";
$donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n";
send_exec($donald_s,$options{'exec'});
}
} elsif (defined $options{'push_amd_tar'}) {
sync_cluster_pw() or die "$CLUSTER_PW_FILE: $!\n";
$donald_s=new Donald::Select::INET(Proto=>'udp') or die "$!\n";
Expand Down

0 comments on commit cd33094

Please sign in to comment.