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.
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
@@ -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";
@@ -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/;
}
@@ -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
@@ -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";

0 comments on commit cd33094

Please sign in to comment.