send.py revision 1816
11376Sbinkertn@umich.edu#!/usr/bin/env python 21376Sbinkertn@umich.edu# Copyright (c) 2005 The Regents of The University of Michigan 31376Sbinkertn@umich.edu# All rights reserved. 41376Sbinkertn@umich.edu# 51376Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without 61376Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are 71376Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright 81376Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer; 91376Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright 101376Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the 111376Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution; 121376Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its 131376Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from 141376Sbinkertn@umich.edu# this software without specific prior written permission. 151376Sbinkertn@umich.edu# 161376Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171376Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181376Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191376Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201376Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211376Sbinkertn@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221376Sbinkertn@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231376Sbinkertn@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241376Sbinkertn@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251376Sbinkertn@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261376Sbinkertn@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271376Sbinkertn@umich.edu# 281376Sbinkertn@umich.edu# Authors: Ali Saidi 291376Sbinkertn@umich.edu# Nathan Binkert 301376Sbinkertn@umich.edu 311385Sbinkertn@umich.eduimport os, os.path, re, socket, sys 321376Sbinkertn@umich.edufrom os import environ as env, listdir 331816Sbinkertn@umich.edufrom os.path import basename, isdir, isfile, islink, join as joinpath, normpath 341376Sbinkertn@umich.edufrom filecmp import cmp as filecmp 351816Sbinkertn@umich.edufrom shutil import copy 361376Sbinkertn@umich.edu 371385Sbinkertn@umich.edudef nfspath(dir): 381385Sbinkertn@umich.edu if dir.startswith('/.automount/'): 391385Sbinkertn@umich.edu dir = '/n/%s' % dir[12:] 401385Sbinkertn@umich.edu elif not dir.startswith('/n/'): 411385Sbinkertn@umich.edu dir = '/n/%s%s' % (socket.gethostname().split('.')[0], dir) 421385Sbinkertn@umich.edu return dir 431385Sbinkertn@umich.edu 441816Sbinkertn@umich.edudef syncdir(srcdir, destdir): 451816Sbinkertn@umich.edu srcdir = normpath(srcdir) 461816Sbinkertn@umich.edu destdir = normpath(destdir) 471816Sbinkertn@umich.edu if not isdir(destdir): 481816Sbinkertn@umich.edu sys.exit('destination directory "%s" does not exist' % destdir) 491816Sbinkertn@umich.edu 501816Sbinkertn@umich.edu for root, dirs, files in os.walk(srcdir): 511816Sbinkertn@umich.edu root = normpath(root) 521816Sbinkertn@umich.edu prefix = os.path.commonprefix([root, srcdir]) 531816Sbinkertn@umich.edu root = root[len(prefix):] 541816Sbinkertn@umich.edu if root.startswith('/'): 551816Sbinkertn@umich.edu root = root[1:] 561816Sbinkertn@umich.edu for rem in [ d for d in dirs if d.startswith('.') or d == 'SCCS']: 571816Sbinkertn@umich.edu dirs.remove(rem) 581816Sbinkertn@umich.edu 591816Sbinkertn@umich.edu for entry in dirs: 601816Sbinkertn@umich.edu newdir = joinpath(destdir, root, entry) 611816Sbinkertn@umich.edu if not isdir(newdir): 621816Sbinkertn@umich.edu os.mkdir(newdir) 631816Sbinkertn@umich.edu print 'mkdir', newdir 641816Sbinkertn@umich.edu 651816Sbinkertn@umich.edu for i,d in enumerate(dirs): 661816Sbinkertn@umich.edu if islink(joinpath(srcdir, root, d)): 671816Sbinkertn@umich.edu dirs[i] = joinpath(d, '.') 681816Sbinkertn@umich.edu 691816Sbinkertn@umich.edu for entry in files: 701816Sbinkertn@umich.edu dest = normpath(joinpath(destdir, root, entry)) 711816Sbinkertn@umich.edu src = normpath(joinpath(srcdir, root, entry)) 721816Sbinkertn@umich.edu if not isfile(dest) or not filecmp(src, dest): 731816Sbinkertn@umich.edu print 'copy %s %s' % (dest, src) 741816Sbinkertn@umich.edu copy(src, dest) 751816Sbinkertn@umich.edu 761385Sbinkertn@umich.eduprogpath = nfspath(sys.path[0]) 771376Sbinkertn@umich.eduprogname = basename(sys.argv[0]) 781376Sbinkertn@umich.eduusage = """\ 791376Sbinkertn@umich.eduUsage: 801602Sbinkertn@umich.edu %(progname)s [-c] [-e] [-f] [-j <jobfile>] [-q queue] [-v] <regexp> 811376Sbinkertn@umich.edu -c clean directory if job can be run 821376Sbinkertn@umich.edu -e only echo pbs command info, don't actually send the job 831376Sbinkertn@umich.edu -f force the job to run regardless of state 841376Sbinkertn@umich.edu -q <queue> submit job to the named queue 851602Sbinkertn@umich.edu -j <jobfile> specify the jobfile (default is <basedir>/test.py) 861376Sbinkertn@umich.edu -v be verbose 871376Sbinkertn@umich.edu 881602Sbinkertn@umich.edu %(progname)s [-j <jobfile>] -l [-v] <regexp> 891602Sbinkertn@umich.edu -j <jobfile> specify the jobfile (default is <basedir>/test.py) 901376Sbinkertn@umich.edu -l list job names, don't submit 911376Sbinkertn@umich.edu -v be verbose (list job parameters) 921376Sbinkertn@umich.edu 931376Sbinkertn@umich.edu %(progname)s -h 941376Sbinkertn@umich.edu -h display this help 951376Sbinkertn@umich.edu""" % locals() 961376Sbinkertn@umich.edu 971376Sbinkertn@umich.edutry: 981376Sbinkertn@umich.edu import getopt 991602Sbinkertn@umich.edu opts, args = getopt.getopt(sys.argv[1:], '-cd:efhj:lq:v') 1001376Sbinkertn@umich.eduexcept getopt.GetoptError: 1011376Sbinkertn@umich.edu sys.exit(usage) 1021376Sbinkertn@umich.edu 1031376Sbinkertn@umich.educlean = False 1041376Sbinkertn@umich.eduonlyecho = False 1051376Sbinkertn@umich.eduexprs = [] 1061376Sbinkertn@umich.eduforce = False 1071376Sbinkertn@umich.edulistonly = False 1081376Sbinkertn@umich.eduqueue = '' 1091376Sbinkertn@umich.eduverbose = False 1101385Sbinkertn@umich.edurootdir = nfspath(os.getcwd()) 1111602Sbinkertn@umich.edujfile = 'test.py' 1121381Sbinkertn@umich.edufor opt,arg in opts: 1131381Sbinkertn@umich.edu if opt == '-c': 1141376Sbinkertn@umich.edu clean = True 1151381Sbinkertn@umich.edu if opt == '-d': 1161381Sbinkertn@umich.edu rootdir = arg 1171381Sbinkertn@umich.edu if opt == '-e': 1181376Sbinkertn@umich.edu onlyecho = True 1191381Sbinkertn@umich.edu if opt == '-f': 1201376Sbinkertn@umich.edu force = True 1211381Sbinkertn@umich.edu if opt == '-h': 1221376Sbinkertn@umich.edu print usage 1231376Sbinkertn@umich.edu sys.exit(0) 1241602Sbinkertn@umich.edu if opt == '-j': 1251602Sbinkertn@umich.edu jfile = arg 1261381Sbinkertn@umich.edu if opt == '-l': 1271376Sbinkertn@umich.edu listonly = True 1281381Sbinkertn@umich.edu if opt == '-q': 1291381Sbinkertn@umich.edu queue = arg 1301381Sbinkertn@umich.edu if opt == '-v': 1311376Sbinkertn@umich.edu verbose = True 1321376Sbinkertn@umich.edu 1331381Sbinkertn@umich.edubasedir = joinpath(rootdir, 'Base') 1341381Sbinkertn@umich.edulinkdir = joinpath(rootdir, 'Link') 1351381Sbinkertn@umich.edu 1361376Sbinkertn@umich.edufor arg in args: 1371376Sbinkertn@umich.edu exprs.append(re.compile(arg)) 1381376Sbinkertn@umich.edu 1391381Sbinkertn@umich.eduif not listonly and not onlyecho and isdir(linkdir): 1401385Sbinkertn@umich.edu if verbose: 1411385Sbinkertn@umich.edu print 'Checking for outdated files in Link directory' 1421816Sbinkertn@umich.edu syncdir(linkdir, basedir) 1431376Sbinkertn@umich.edu 1441376Sbinkertn@umich.eduimport job, jobfile, pbs 1451376Sbinkertn@umich.edu 1461602Sbinkertn@umich.edutest = jobfile.JobFile(joinpath(basedir, jfile)) 1471376Sbinkertn@umich.edu 1481376Sbinkertn@umich.edujoblist = [] 1491376Sbinkertn@umich.edufor jobname in test.jobs: 1501376Sbinkertn@umich.edu if not exprs: 1511376Sbinkertn@umich.edu joblist.append(jobname) 1521376Sbinkertn@umich.edu continue 1531376Sbinkertn@umich.edu 1541376Sbinkertn@umich.edu for expr in exprs: 1551376Sbinkertn@umich.edu if expr.match(jobname): 1561376Sbinkertn@umich.edu joblist.append(jobname) 1571376Sbinkertn@umich.edu break 1581376Sbinkertn@umich.edu 1591376Sbinkertn@umich.eduif listonly: 1601376Sbinkertn@umich.edu if verbose: 1611376Sbinkertn@umich.edu for jobname in joblist: 1621376Sbinkertn@umich.edu test.printinfo(jobname) 1631376Sbinkertn@umich.edu else: 1641376Sbinkertn@umich.edu for jobname in joblist: 1651376Sbinkertn@umich.edu print jobname 1661376Sbinkertn@umich.edu sys.exit(0) 1671376Sbinkertn@umich.edu 1681376Sbinkertn@umich.eduif not onlyecho: 1691376Sbinkertn@umich.edu jl = [] 1701376Sbinkertn@umich.edu for jobname in joblist: 1711383Sbinkertn@umich.edu jobdir = joinpath(rootdir, jobname) 1721376Sbinkertn@umich.edu if os.path.exists(jobname): 1731376Sbinkertn@umich.edu if not force: 1741383Sbinkertn@umich.edu if os.path.isfile(joinpath(jobdir, '.success')): 1751376Sbinkertn@umich.edu continue 1761376Sbinkertn@umich.edu 1771383Sbinkertn@umich.edu if os.path.isfile(joinpath(jobdir, '.start')) and \ 1781383Sbinkertn@umich.edu not os.path.isfile(joinpath(jobdir, '.stop')): 1791376Sbinkertn@umich.edu continue 1801376Sbinkertn@umich.edu 1811376Sbinkertn@umich.edu if not clean: 1821376Sbinkertn@umich.edu sys.exit('job directory not clean!') 1831376Sbinkertn@umich.edu 1841383Sbinkertn@umich.edu job.cleandir(jobdir) 1851376Sbinkertn@umich.edu else: 1861383Sbinkertn@umich.edu os.mkdir(jobdir) 1871393Sbinkertn@umich.edu jl.append(jobname) 1881376Sbinkertn@umich.edu joblist = jl 1891376Sbinkertn@umich.edu 1901816Sbinkertn@umich.edudef setname(jobid, jobname): 1911816Sbinkertn@umich.edu # since pbs can handle jobnames of 15 characters or less, don't 1921816Sbinkertn@umich.edu # use the raj hack. 1931816Sbinkertn@umich.edu if len(jobname) <= 15: 1941816Sbinkertn@umich.edu return 1951816Sbinkertn@umich.edu 1961816Sbinkertn@umich.edu import socket 1971816Sbinkertn@umich.edu s = socket.socket() 1981816Sbinkertn@umich.edu # Connect to pbs.pool and send the jobid/jobname pair to port 1991816Sbinkertn@umich.edu # 24465 (Raj didn't realize that there are only 64k ports and 2001816Sbinkertn@umich.edu # setup inetd to point to port 90001) 2011816Sbinkertn@umich.edu s.connect(("pbs.pool", 24465)) 2021816Sbinkertn@umich.edu s.send("%s %s\n" % (jobid, jobname)) 2031816Sbinkertn@umich.edu s.close() 2041816Sbinkertn@umich.edu 2051376Sbinkertn@umich.edufor jobname in joblist: 2061376Sbinkertn@umich.edu jobdir = joinpath(rootdir, jobname) 2071376Sbinkertn@umich.edu 2081376Sbinkertn@umich.edu if not onlyecho and not os.path.isdir(jobdir): 2091376Sbinkertn@umich.edu sys.exit('%s is not a directory. Cannot build job' % jobdir) 2101376Sbinkertn@umich.edu 2111385Sbinkertn@umich.edu print 'Job name: %s' % jobname 2121385Sbinkertn@umich.edu print 'Job directory: %s' % jobdir 2131376Sbinkertn@umich.edu 2141376Sbinkertn@umich.edu qsub = pbs.qsub() 2151376Sbinkertn@umich.edu qsub.pbshost = 'simpool.eecs.umich.edu' 2161376Sbinkertn@umich.edu qsub.stdout = joinpath(jobdir, 'jobout') 2171816Sbinkertn@umich.edu qsub.name = jobname[:15] 2181376Sbinkertn@umich.edu qsub.join = True 2191376Sbinkertn@umich.edu qsub.node_type = 'FAST' 2201376Sbinkertn@umich.edu qsub.env['ROOTDIR'] = rootdir 2211816Sbinkertn@umich.edu qsub.env['JOBNAME'] = jobname 2221376Sbinkertn@umich.edu if len(queue): 2231376Sbinkertn@umich.edu qsub.queue = queue 2241385Sbinkertn@umich.edu qsub.build(joinpath(progpath, 'job.py')) 2251376Sbinkertn@umich.edu 2261385Sbinkertn@umich.edu if verbose: 2271385Sbinkertn@umich.edu print 'PBS Command: %s' % qsub.command 2281385Sbinkertn@umich.edu 2291385Sbinkertn@umich.edu if not onlyecho: 2301385Sbinkertn@umich.edu ec = qsub.do() 2311385Sbinkertn@umich.edu if ec == 0: 2321816Sbinkertn@umich.edu jobid = qsub.result 2331816Sbinkertn@umich.edu print 'PBS Jobid: %s' % jobid 2341816Sbinkertn@umich.edu setname(jobid, jobname) 2351385Sbinkertn@umich.edu else: 2361385Sbinkertn@umich.edu print 'PBS Failed' 237