113540Sandrea.mondelli@ucf.edu#!/usr/bin/env python2.7
22357Sktlim@umich.edu# Copyright (c) 2006 The Regents of The University of Michigan
32357Sktlim@umich.edu# All rights reserved.
42357Sktlim@umich.edu#
52357Sktlim@umich.edu# Redistribution and use in source and binary forms, with or without
62357Sktlim@umich.edu# modification, are permitted provided that the following conditions are
72357Sktlim@umich.edu# met: redistributions of source code must retain the above copyright
82357Sktlim@umich.edu# notice, this list of conditions and the following disclaimer;
92357Sktlim@umich.edu# redistributions in binary form must reproduce the above copyright
102357Sktlim@umich.edu# notice, this list of conditions and the following disclaimer in the
112357Sktlim@umich.edu# documentation and/or other materials provided with the distribution;
122357Sktlim@umich.edu# neither the name of the copyright holders nor the names of its
132357Sktlim@umich.edu# contributors may be used to endorse or promote products derived from
142357Sktlim@umich.edu# this software without specific prior written permission.
152357Sktlim@umich.edu#
162357Sktlim@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172357Sktlim@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182357Sktlim@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192357Sktlim@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202357Sktlim@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212357Sktlim@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222357Sktlim@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232357Sktlim@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242357Sktlim@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252357Sktlim@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262357Sktlim@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272357Sktlim@umich.edu#
282357Sktlim@umich.edu# Authors: Kevin Lim
292357Sktlim@umich.edu
302357Sktlim@umich.eduimport os, os.path, shutil, signal, socket, sys
312357Sktlim@umich.edufrom os import environ as env
322357Sktlim@umich.edufrom os.path import join as joinpath, expanduser
332357Sktlim@umich.edu
342357Sktlim@umich.edudef date():
352357Sktlim@umich.edu    import time
362357Sktlim@umich.edu    return time.strftime('%a %b %e %H:%M:%S %Z %Y', time.localtime())
372357Sktlim@umich.edu
382357Sktlim@umich.edudef cleandir(dir):
392357Sktlim@umich.edu    for root, dirs, files in os.walk(dir, False):
402357Sktlim@umich.edu        for name in files:
412357Sktlim@umich.edu            os.remove(joinpath(root, name))
422357Sktlim@umich.edu        for name in dirs:
432357Sktlim@umich.edu            os.rmdir(joinpath(root, name))
442357Sktlim@umich.edu
452357Sktlim@umich.educlass rsync:
462357Sktlim@umich.edu    def __init__(self):
472357Sktlim@umich.edu        self.sudo = False
482357Sktlim@umich.edu        self.rsync = 'rsync'
492357Sktlim@umich.edu        self.compress = False
502357Sktlim@umich.edu        self.archive = True
512357Sktlim@umich.edu        self.delete = False
522357Sktlim@umich.edu        self.options = ''
532357Sktlim@umich.edu
542357Sktlim@umich.edu    def do(self, src, dst):
552357Sktlim@umich.edu        args = []
562357Sktlim@umich.edu        if self.sudo:
572357Sktlim@umich.edu            args.append('sudo')
582357Sktlim@umich.edu
592357Sktlim@umich.edu        args.append(self.rsync)
602357Sktlim@umich.edu        if (self.archive):
612357Sktlim@umich.edu            args.append('-a')
622357Sktlim@umich.edu        if (self.compress):
632357Sktlim@umich.edu            args.append('-z')
642357Sktlim@umich.edu        if (self.delete):
652357Sktlim@umich.edu            args.append('--delete')
662357Sktlim@umich.edu        if len(self.options):
672357Sktlim@umich.edu            args.append(self.options)
682357Sktlim@umich.edu        args.append(src)
692357Sktlim@umich.edu        args.append(dst)
702357Sktlim@umich.edu
712357Sktlim@umich.edu        return os.spawnvp(os.P_WAIT, args[0], args)
722357Sktlim@umich.edu
732357Sktlim@umich.educlass JobDir(object):
742357Sktlim@umich.edu    def __init__(self, dir):
752357Sktlim@umich.edu        self.dir = dir
762357Sktlim@umich.edu
772357Sktlim@umich.edu    def file(self, filename):
782357Sktlim@umich.edu        return joinpath(self.dir, filename)
792357Sktlim@umich.edu
802357Sktlim@umich.edu    def create(self):
812357Sktlim@umich.edu        if os.path.exists(self.dir):
822357Sktlim@umich.edu            if not os.path.isdir(self.dir):
832357Sktlim@umich.edu                sys.exit('%s is not a directory.  Cannot build job' % self.dir)
842357Sktlim@umich.edu        else:
852357Sktlim@umich.edu            os.mkdir(self.dir)
862357Sktlim@umich.edu
872357Sktlim@umich.edu    def exists(self):
882357Sktlim@umich.edu        return os.path.isdir(self.dir)
892357Sktlim@umich.edu
902357Sktlim@umich.edu    def clean(self):
912357Sktlim@umich.edu        cleandir(self.dir)
922357Sktlim@umich.edu
932357Sktlim@umich.edu    def hasfile(self, filename):
942357Sktlim@umich.edu        return os.path.isfile(self.file(filename))
952357Sktlim@umich.edu
962357Sktlim@umich.edu    def echofile(self, filename, string):
972357Sktlim@umich.edu        filename = self.file(filename)
982357Sktlim@umich.edu        try:
992357Sktlim@umich.edu            f = file(filename, 'w')
1002357Sktlim@umich.edu            print >>f, string
1012357Sktlim@umich.edu            f.flush()
1022357Sktlim@umich.edu            f.close()
1032357Sktlim@umich.edu        except IOError,e:
1042357Sktlim@umich.edu            sys.exit(e)
1052357Sktlim@umich.edu
1062357Sktlim@umich.edu    def rmfile(self, filename):
1072357Sktlim@umich.edu        filename = self.file(filename)
1082357Sktlim@umich.edu        if os.path.isfile(filename):
1092357Sktlim@umich.edu            os.unlink(filename)
1102357Sktlim@umich.edu
1112357Sktlim@umich.edu    def readval(self, filename):
1122357Sktlim@umich.edu        filename = self.file(filename)
1132357Sktlim@umich.edu        f = file(filename, 'r')
1142357Sktlim@umich.edu        value = f.readline().strip()
1152357Sktlim@umich.edu        f.close()
1162357Sktlim@umich.edu        return value
1172357Sktlim@umich.edu
1182357Sktlim@umich.edu    def setstatus(self, string):
1192357Sktlim@umich.edu        filename = self.file('.status')
1202357Sktlim@umich.edu        try:
1212357Sktlim@umich.edu            f = file(filename, 'a')
1222357Sktlim@umich.edu            print >>f, string
1232357Sktlim@umich.edu            f.flush()
1242357Sktlim@umich.edu            f.close()
1252357Sktlim@umich.edu        except IOError,e:
1262357Sktlim@umich.edu            sys.exit(e)
1272357Sktlim@umich.edu
1282357Sktlim@umich.edu    def getstatus(self):
1292357Sktlim@umich.edu        filename = self.file('.status')
1302357Sktlim@umich.edu        try:
1312357Sktlim@umich.edu            f = file(filename, 'r')
1322357Sktlim@umich.edu        except IOError, e:
1332357Sktlim@umich.edu            return 'none'
1342357Sktlim@umich.edu
1352357Sktlim@umich.edu        # fast forward to the end
1362357Sktlim@umich.edu        for line in f: pass
1372357Sktlim@umich.edu
1382357Sktlim@umich.edu        # the first word on the last line is the status
1392357Sktlim@umich.edu        return line.split(' ')[0]
1402357Sktlim@umich.edu
1412357Sktlim@umich.edu    def __str__(self):
1422357Sktlim@umich.edu        return self.dir
1432357Sktlim@umich.edu
1442357Sktlim@umich.eduif __name__ == '__main__':
1452357Sktlim@umich.edu    import platform
1462357Sktlim@umich.edu    binaries = { 'i686' : 'm5.i386',
1472357Sktlim@umich.edu                 'x86_64' : 'm5.amd64' }
1482357Sktlim@umich.edu    binary = binaries[platform.machine()]
1492357Sktlim@umich.edu
1502357Sktlim@umich.edu    cwd = os.getcwd()
1512357Sktlim@umich.edu    rootdir = env.setdefault('ROOTDIR', os.path.dirname(cwd))
1522357Sktlim@umich.edu    oar_jobid = int(env['OAR_JOBID'])
1532357Sktlim@umich.edu    oar_jobname = os.path.basename(cwd)
1542357Sktlim@umich.edu    #pbs_jobname = env['PBS_JOBNAME']
1552357Sktlim@umich.edu    basedir = joinpath(rootdir, 'Base')
1562357Sktlim@umich.edu    jobname = env.setdefault('JOBNAME', oar_jobname)
1572357Sktlim@umich.edu    jobfile = env.setdefault('JOBFILE', joinpath(rootdir, 'Test.py'))
1582357Sktlim@umich.edu    outdir = env.setdefault('OUTPUT_DIR', cwd)
1592357Sktlim@umich.edu    env['POOLJOB'] = 'True'
1602357Sktlim@umich.edu
1612357Sktlim@umich.edu    if os.path.isdir("/work"):
1622357Sktlim@umich.edu        workbase = "/work"
1632357Sktlim@umich.edu    else:
1642357Sktlim@umich.edu        workbase = "/tmp/"
1652357Sktlim@umich.edu
1662357Sktlim@umich.edu    workdir = joinpath(workbase, '%s.%s' % (env['USER'], oar_jobid))
1672357Sktlim@umich.edu    host = socket.gethostname()
1682357Sktlim@umich.edu
1692357Sktlim@umich.edu    os.umask(0022)
1702357Sktlim@umich.edu
1712357Sktlim@umich.edu    jobdir = JobDir(outdir)
1722357Sktlim@umich.edu
1732357Sktlim@umich.edu    started = date()
1742357Sktlim@umich.edu    jobdir.echofile('.running', started)
1752357Sktlim@umich.edu    jobdir.rmfile('.queued')
1762357Sktlim@umich.edu    jobdir.echofile('.host', host)
1772357Sktlim@umich.edu
1782357Sktlim@umich.edu    jobdir.setstatus('running on %s on %s' % (host, started))
1792357Sktlim@umich.edu
1802357Sktlim@umich.edu    if os.path.isdir(workdir):
1812357Sktlim@umich.edu        cleandir(workdir)
1822357Sktlim@umich.edu    else:
1832357Sktlim@umich.edu        os.mkdir(workdir)
1842357Sktlim@umich.edu
1852357Sktlim@umich.edu    if False and os.path.isdir('/z/dist'):
1862357Sktlim@umich.edu        sync = rsync()
1872357Sktlim@umich.edu        sync.delete = True
1882357Sktlim@umich.edu        sync.sudo = True
1892357Sktlim@umich.edu        sync.do('poolfs::dist/m5/', '/z/dist/m5/')
1902357Sktlim@umich.edu
1912357Sktlim@umich.edu    try:
1922357Sktlim@umich.edu        os.chdir(workdir)
1932357Sktlim@umich.edu    except OSError,e:
1942357Sktlim@umich.edu        sys.exit(e)
1952357Sktlim@umich.edu
1962357Sktlim@umich.edu    os.symlink(jobdir.file('output'), 'status.out')
1972357Sktlim@umich.edu
1982357Sktlim@umich.edu    args = [ joinpath(basedir, binary), joinpath(basedir, 'run.py') ]
1992357Sktlim@umich.edu    if not len(args):
2002357Sktlim@umich.edu        sys.exit("no arguments")
2012357Sktlim@umich.edu
2022357Sktlim@umich.edu    print 'starting job... %s' % started
2032357Sktlim@umich.edu    print ' '.join(args)
2042357Sktlim@umich.edu    print
2052357Sktlim@umich.edu    sys.stdout.flush()
2062357Sktlim@umich.edu
2072357Sktlim@umich.edu    childpid = os.fork()
2082357Sktlim@umich.edu    if not childpid:
2092357Sktlim@umich.edu        # Execute command
2102357Sktlim@umich.edu        sys.stdin.close()
2112357Sktlim@umich.edu        fd = os.open(jobdir.file("output"),
2122357Sktlim@umich.edu                     os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
2132357Sktlim@umich.edu        os.dup2(fd, sys.stdout.fileno())
2142357Sktlim@umich.edu        os.dup2(fd, sys.stderr.fileno())
2152357Sktlim@umich.edu        os.execvp(args[0], args)
2162357Sktlim@umich.edu
2172357Sktlim@umich.edu    def handler(signum, frame):
2182357Sktlim@umich.edu        if childpid != 0:
2192357Sktlim@umich.edu            os.kill(childpid, signum)
2202357Sktlim@umich.edu
2212357Sktlim@umich.edu    signal.signal(signal.SIGHUP, handler)
2222357Sktlim@umich.edu    signal.signal(signal.SIGINT, handler)
2232357Sktlim@umich.edu    signal.signal(signal.SIGQUIT, handler)
2242357Sktlim@umich.edu    signal.signal(signal.SIGTERM, handler)
2252357Sktlim@umich.edu    signal.signal(signal.SIGCONT, handler)
2262357Sktlim@umich.edu    signal.signal(signal.SIGUSR1, handler)
2272357Sktlim@umich.edu    signal.signal(signal.SIGUSR2, handler)
2282357Sktlim@umich.edu
2292357Sktlim@umich.edu    done = 0
2302357Sktlim@umich.edu    while not done:
2312357Sktlim@umich.edu        try:
2322357Sktlim@umich.edu            thepid,ec = os.waitpid(childpid, 0)
2332357Sktlim@umich.edu            if ec:
2342357Sktlim@umich.edu                print 'Exit code ', ec
2352357Sktlim@umich.edu                status = 'failure'
2362357Sktlim@umich.edu            else:
2372357Sktlim@umich.edu                status = 'success'
2382357Sktlim@umich.edu            done = 1
2392357Sktlim@umich.edu        except OSError:
2402357Sktlim@umich.edu            pass
2412357Sktlim@umich.edu
2422357Sktlim@umich.edu    complete = date()
2432357Sktlim@umich.edu    print '\njob complete... %s' % complete
2442357Sktlim@umich.edu    jobdir.echofile('.%s' % status, complete)
2452357Sktlim@umich.edu    jobdir.rmfile('.running')
2462357Sktlim@umich.edu    jobdir.setstatus('%s on %s' % (status, complete))
247