#!/usr/bin/env python

import getopt
import os
import sys
import zlib

import isi.config.ifs
import isi.fs.restripe.group

def usage(exitcode):
    print >>sys.stderr, """Usage: %s [OPTION]... [COMMAND]

Runs the passed command once per cluster no matter how many nodes
it's run on. Useful for things like the newsyslog-on-ifs crontab
entry, which wants to be in each nodes' crontab but should only be
run once per cluster. By default, only run the node on the lowest
devid.

Options:
   -h, --help           Print this message and exit
   -s, --hash           Hash the command and use it as a lookup into the
                        device list, effectively running the command on a
                        random node, rather than running on the lowest devid.
""" % (os.path.basename(sys.argv[0]))

gi = isi.fs.restripe.group.GroupInfo()
online_group = sorted(gi.getNodeList())

use_hashing = False

try:
    if len(sys.argv) < 2:
        usage(1)
    opts, args = getopt.getopt(sys.argv[1:], 'hs', ['help', 'hash'])
    for o, a in opts:
        if o in ['-h', '--help']:
            usage(0)
        if o in ['-s', '--hash']:
            use_hashing = True
            
except getopt.GetoptError:
    usage(1)
                               

if len(online_group) == 0:
    print >>sys.stderr, sys.argv[0], "found no group info, exiting."
    sys.exit(1)

try:
    local_devid = isi.config.ifs.get()['current node id']
except isi.config.ifs.error as e:
    print >>sys.stderr, sys.argv[0], "could not read local devid, exiting."
    sys.exit(1)

cmd = ' '.join(args)    
idx = (zlib.crc32(cmd) % len(online_group)) if use_hashing else 0

if local_devid == online_group[idx]:
    os.system(cmd)
