1 # Copyright (c) 2005 The Regents of The University of Michigan
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met: redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer;
8 # redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution;
11 # neither the name of the copyright holders nor the names of its
12 # contributors may be used to endorse or promote products derived from
13 # this software without specific prior written permission.
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 # Authors: Nathan Binkert
29 import os
, popen2
, re
, sys
31 class MyPOpen(object):
32 def __init__(self
, cmd
, input = None, output
= None, bufsize
= -1):
36 p2c_read
, p2c_write
= os
.pipe()
37 self
.tochild
= os
.fdopen(p2c_write
, 'w', bufsize
)
40 if isinstance(input, file):
41 p2c_read
= input.fileno()
42 elif isinstance(input, str):
43 input = file(input, 'r')
44 p2c_read
= input.fileno()
45 elif isinstance(input, int):
51 c2p_read
, c2p_write
= os
.pipe()
52 self
.fromchild
= os
.fdopen(c2p_read
, 'r', bufsize
)
55 if isinstance(output
, file):
56 c2p_write
= output
.fileno()
57 elif isinstance(output
, str):
58 output
= file(output
, 'w')
59 c2p_write
= output
.fileno()
60 elif isinstance(output
, int):
67 os
.dup2(p2c_read
, sys
.stdin
.fileno())
68 os
.dup2(c2p_write
, sys
.stdout
.fileno())
69 os
.dup2(c2p_write
, sys
.stderr
.fileno())
71 os
.execvp(cmd
[0], cmd
)
80 pid
, status
= os
.waitpid(self
.pid
, os
.WNOHANG
)
87 pid
, status
= os
.waitpid(self
.pid
, 0)
96 self
.keep_stdout
= False
97 self
.keep_stderr
= False
99 self
.mail_abort
= False
100 self
.mail_begin
= False
101 self
.mail_end
= False
110 def build(self
, script
, args
= []):
111 self
.cmd
= [ self
.qsub
]
115 arg
+= ','.join([ '%s=%s' % i
for i
in self
.env
.iteritems() ])
119 self
.cmd
.append('-h')
122 self
.cmd
.append('-olocalhost:' + self
.stdout
)
124 if self
.keep_stdout
and self
.keep_stderr
:
125 self
.cmd
.append('-koe')
126 elif self
.keep_stdout
:
127 self
.cmd
.append('-ko')
128 elif self
.keep_stderr
:
129 self
.cmd
.append('-ke')
131 self
.cmd
.append('-kn')
134 self
.cmd
.append('-joe')
136 if len(self
.node_type
):
137 self
.cmd
.append('-lnodes=' + self
.node_type
)
139 if self
.mail_abort
or self
.mail_begin
or self
.mail_end
:
148 self
.cmd
.append('-m ' + flags
)
151 self
.cmd
.append("-N%s" % self
.name
)
153 if self
.priority
!= 0:
154 self
.cmd
.append('-p' + self
.priority
)
157 self
.cmd
.append('-q' + self
.queue
)
159 self
.cmd
.extend(args
)
161 self
.command
= ' '.join(self
.cmd
+ [ self
.script
])
164 pbs
= MyPOpen(self
.cmd
+ [ self
.script
])
165 self
.result
= pbs
.fromchild
.read()
168 if ec
!= 0 and self
.pbshost
:
169 cmd
= ' '.join(self
.cmd
+ [ '-' ])
170 cmd
= [ 'ssh', '-x', self
.pbshost
, cmd
]
171 self
.command
= ' '.join(cmd
)
172 ssh
= MyPOpen(cmd
, input = self
.script
)
173 self
.result
= ssh
.fromchild
.read()