From: Greg Ercolano <erco@(email surpressed)>
Subject: [SYSADMIN Q+A] How to use Rush to run one command on each machine
   Date: Tue, 05 Jul 2011 20:05:49 -0400
Msg# 2112
View Complete Thread (1 article) | All Threads
Last Next
> 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.


Last Next