> I'd like to use Rush to run a single command once on each
> of the Macs on our network to run some administrative commands.
>
> Is there a way to use rush to run a command once, and only once,
> on each machine?
Yes, you can do this either with a custom submit script
(see example below) or with submit-generic.
To ensure rush only runs the command once on each machine:
1) Submit with cpus set to include ".1" as part of the cpu specification
to prevent parallel execution (eg. +any=100.1)
2) Follow the command you want to run with 'rush -an localhost'
so it doesn't run your command more than once on each machine.
3) Submit the job with just enough frames for each machine to run on.
So for instance, here's a script with some variables at the top.
When you run this script, it submits itself to run $CMDS on all
the machines in $HOSTGROUP at priority $PRIORITY using $LOGDIR
to log the output.
-------------------------------------------------------- snip: START
#!/usr/bin/perl -w
use strict;
$|=1;
### ###
### CHANGE THESE! ###
### ###
my $LOGDIR = "//net/tmp/logs"; # empty dir on file server
my $TITLE = "RUN_ONCE"; # title of job
my $HOSTGROUP = "+any"; # hostgroup to run commands on
my $PRIORITY = "100"; # priority of job
my $CMDS = "hostname; id"; # command(s) to run
# RETURN HOW MANY HOSTS ARE IN THE SPECIFIED HOSTGROUP
sub NumHostsInHostGroup($) {
my ($hostgroup) = @_;
my @hosts = `rush -lhg $hostgroup`;
return($#hosts);
}
### MAIN
# NO ARGS? SUBMIT JOB
if ( ! defined($ARGV[0]) ) {
if ( defined($ENV{RUSH_ISDAEMON}) ) { exit(1); } # Prevent worms
if ( ! -d $LOGDIR ) { # create log directory if none
unless(mkdir($LOGDIR, 0777)) {
print STDERR "mkdir ${LOGDIR}: $!\n"; exit(1);
}
}
my $numhosts = NumHostsInHostGroup($HOSTGROUP);
# SUBMIT JOB
open(SUBMIT, "|rush -submit");
print SUBMIT <<"EOF";
title ${TITLE}
frames 1-${numhosts}
logdir ${LOGDIR}
command perl ${0} -render
cpus ${HOSTGROUP}=${numhosts}.1\@${PRIORITY}
EOF
close(SUBMIT);
if ( $? >> 8 ) { print STDERR "--- Submit failed\n"; exit(1); }
exit(0);
}
# ARG IS "-render"? RUNNING ON REMOTE MACHINE
if ( $ARGV[0] eq "-render" ) {
print "--- Working on frame $ENV{RUSH_FRAME}\n";
my $err = system($CMDS);
system("rush -an $ENV{RUSH_HOSTNAME}"); # add this machine to neverhosts for job
exit( $err == 0 ? 0 : 1 ); # Fail if commands returned non-zero
}
-------------------------------------------------------- snip: END
Note: If you want to run things as root, you'd have to either
use sudo or a setuid shell, as rush won't allow you to submit
jobs as root.
|