2 from select import select
11 class ExceptionTimeout(Exception): pass
12 class ExceptionReadTimeout(Exception): pass
14 ssh_options = { 'StrictHostKeyChecking':'no',
16 'PasswordAuthentication':'no',
17 'ConnectTimeout':'%s' % COMMAND_TIMEOUT}
19 class Sopen(subprocess.Popen):
20 def kill(self, sig = signal.SIGTERM):
22 # NOTE: this also kills parent... so doesn't work like I want.
23 # NOTE: adding 'exec' before the cmd removes the extra sh, and
24 # partially addresses this problem.
25 #os.killpg(os.getpgid(self.pid), signal.SIGKILL)
26 os.kill(self.pid, sig)
28 # no such process, due to it already exiting...
32 def read_t(stream, count=1, timeout=COMMAND_TIMEOUT*2):
37 lin, lout, lerr = select([stream], [], [], timeout)
40 raise ExceptionReadTimeout("TIMEOUT reading from command")
43 outbytes = stream.read(count)
45 print 'no content yet.'
47 # the select timeout should catch this.
56 lin, lout, lerr = select([stream], [], [], timeout)
58 raise ExceptionReadTimeout("TIMEOUT reading from command")
60 return stream.read(count)
66 def run_noexcept(self, cmd, timeout=COMMAND_TIMEOUT*2):
69 return CMD.run(self,cmd,timeout)
70 except ExceptionTimeout:
71 print traceback.print_exc()
72 return ("", "ScriptTimeout")
73 except ExceptionReadTimeout:
74 print traceback.print_exc()
75 return ("", "RunningScriptTimeout")
76 except KeyboardInterrupt:
77 print "Interrupted, exiting..."
79 except Exception, err:
80 #from monitor.common import email_exception
84 def system(self, cmd, timeout=COMMAND_TIMEOUT*2):
85 (o,e) = self.run(cmd, timeout)
88 if self.s.returncode is None:
90 return self.s.returncode
92 def run(self, cmd, timeout=COMMAND_TIMEOUT*2):
94 s = Sopen(cmd, shell=True,
95 stdin=subprocess.PIPE,
96 stdout=subprocess.PIPE,
97 stderr=subprocess.PIPE,
100 (f_in, f_out, f_err) = (s.stdin, s.stdout, s.stderr)
101 lout, lin, lerr = select([f_out], [], [f_err], timeout)
102 if len(lin) == 0 and len(lout) == 0 and len(lerr) == 0:
103 # Reached a timeout! Nuke process so it does not hang.
104 print "TIMEOUT!!!!!!!!!!!!!!!!!!!"
105 s.kill(signal.SIGKILL)
106 raise ExceptionTimeout("TIMEOUT Running: %s" % cmd)
109 #print len(lin), len(lout), len(lerr)
115 #o_value = f_out.read()
116 flags = fcntl.fcntl(f_out, fcntl.F_GETFL)
117 fcntl.fcntl(f_out, fcntl.F_SETFL, flags | os.O_NONBLOCK)
120 o_value = read_t(f_out,1,30)
121 except ExceptionReadTimeout:
122 s.kill(signal.SIGKILL)
123 raise ExceptionReadTimeout("TIMEOUT: failed to read from cmd: %s" % cmd)
125 e_value = f_err.read()
127 o_value = o_value.strip()
128 e_value = e_value.strip()
134 s.kill(signal.SIGKILL)
136 return (o_value, e_value)
138 def runargs(self, args, timeout=COMMAND_TIMEOUT*2):
140 #print "CMD.run(%s)" % " ".join(args)
141 s = Sopen(args, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
143 (f_in, f_out, f_err) = (s.stdin, s.stdout, s.stderr)
144 lout, lin, lerr = select([f_out], [], [f_err], timeout)
145 if len(lin) == 0 and len(lout) == 0 and len(lerr) == 0:
146 # Reached a timeout! Nuke process so it does not hang.
147 s.kill(signal.SIGKILL)
148 raise ExceptionTimeout("TIMEOUT Running: %s" % cmd)
149 o_value = f_out.read()
151 if o_value == "": # An error has occured
152 e_value = f_err.read()
154 o_value = o_value.strip()
155 e_value = e_value.strip()
160 s.kill(signal.SIGKILL)
162 return (o_value, e_value)
166 def __init__(self, user, host, port=22, options = ssh_options):
167 self.options = options
173 def __options_to_str(self):
175 for o,v in self.options.iteritems():
176 options = options + "-o %s=%s " % (o,v)
179 def run(self, cmd, timeout=COMMAND_TIMEOUT*2):
180 cmd = "ssh -p %s %s %s@%s '%s'" % (self.port, self.__options_to_str(),
181 self.user, self.host, cmd)
182 #print "SSH.run(%s)" % cmd
183 return CMD.run(self, cmd, timeout)
185 def get_file(self, rmt_filename, local_filename=None):
186 if local_filename == None:
187 local_filename = "./"
188 cmd = "scp -P %s -B %s %s@%s:%s %s" % (self.port, self.__options_to_str(),
189 self.user, self.host,
190 rmt_filename, local_filename)
192 # errors will be on stderr,
193 # success will have a blank stderr...
194 return CMD.run_noexcept(self, cmd)
196 def run_noexcept(self, cmd):
197 cmd = "ssh -p %s %s %s@%s '%s'" % (self.port, self.__options_to_str(),
198 self.user, self.host, cmd)
199 #print "SSH.run_noexcept(%s)" % cmd
200 return CMD.run_noexcept(self, cmd)
202 def run_noexcept2(self, cmd, timeout=COMMAND_TIMEOUT*2):
203 cmd = "exec ssh -p %s %s %s@%s %s" % (self.port, self.__options_to_str(),
204 self.user, self.host, cmd)
206 r = CMD.run_noexcept(self, cmd, timeout)
211 def system2(self, cmd, timeout=COMMAND_TIMEOUT*2):
212 cmd = "ssh -p %s %s %s@%s %s" % (self.port, self.__options_to_str(),
213 self.user, self.host, cmd)
214 #print "SSH.system2(%s)" % cmd
215 return CMD.system(self, cmd, timeout)
218 cmd = "ssh -p %s %s %s@%s '%s'" % (self.port, self.__options_to_str(),
219 self.user, self.host, cmd)
222 (f_in, f_out, f_err) = os.popen3(cmd)
225 if value == "": # An error has occured
227 value = value.strip()
230 print " == %s" % value
238 self.start = time.time()
241 self.end = time.time()
242 t = self.end-self.start
246 self.end = time.time()
247 t = self.end-self.start
248 self.start = self.end