00001
00002
00003 import os
00004 import re
00005 import signal
00006 import time
00007
00008 def RemoveChildProcesses(timeout=0):
00009 """Delete all child processes starting with those without children and working up.
00010 Allow child 'timeout' seconds before killing."""
00011 killed_process = 1
00012 my_pid = os.getpid()
00013 print "Debug: Removing child processes after %d secs. Parent process is %d" % (timeout,my_pid)
00014 while killed_process:
00015
00016 killed_process = 0
00017 parents = {}
00018 children = {}
00019 time_cmds = {}
00020 ps_cmd = "ps -o pid,ppid,stime,cmd"
00021 inp = os.popen(ps_cmd,"r")
00022 for line in inp:
00023 if re.search(ps_cmd,line): continue
00024 print "Debug PS line: ",line,
00025 mo = re.search(r"(\d+)\s+(\d+)\s+(.*)",line)
00026 if mo:
00027 (pid,ppid,cmd) = mo.groups()
00028 parents[int(pid)] = int(ppid)
00029 time_cmds[int(pid)] = cmd
00030 inp.close()
00031 for child,parent in parents.iteritems():
00032 antecedent = parent
00033 while parents.has_key(antecedent):
00034 if children.has_key(antecedent): children[antecedent].append(child)
00035 else: children[antecedent] = [child]
00036 antecedent = parents[antecedent]
00037
00038 if not children.has_key(my_pid): break
00039 for child in children[my_pid]:
00040 if children.has_key(child): continue
00041
00042 mo = re.search(r"(\d\d):(\d\d)",time_cmds[child])
00043 if mo:
00044 start_hour = int(mo.group(1))
00045 start_min = int(mo.group(2))
00046 now_hour = int(time.strftime("%H"))
00047 now_min = int(time.strftime("%M"))
00048 time_run = (now_hour*24 + now_min - start_hour*24 -start_min)*60
00049 if time_run >= 0 and time_run < timeout:
00050 print "Debug: Child %d has run %d secs, delay killing" % (child,time_run)
00051 time.sleep(timeout - time_run)
00052 killed_process = 1
00053 continue
00054
00055 if os.path.isfile('/proc/' + str(child) + '/status'):
00056 print "Attempting to kill " + str(child) + " " + time_cmds[child]
00057 os.kill(child,signal.SIGTERM)
00058 time.sleep(1)
00059 if os.path.isfile('/proc/' + str(child) + '/status'): os.kill(child,signal.SIGKILL)
00060 time.sleep(1)
00061 if os.path.isfile('/proc/' + str(child) + '/status'): print "Failed to kill " + str(child)
00062 else: killed_process = 1
00063
00064
00065 def BuildEnvStr(d):
00066
00067 """Convert dictionary into an alphabetically sorted environment string: 'var1=val1,var2=val2...'"""
00068
00069 s = ""
00070 var_list = d.keys()
00071 var_list.sort()
00072 for var in var_list:
00073 val = d[var]
00074 val = re.compile(',').sub('\\,',val)
00075 if s: s += ','
00076 s += var + '=' + val
00077 return s
00078
00079 def ListCommaSepList(s,prefix=""):
00080 """List a comma separated list string s with each entry on a separate list starting with prefix."""
00081 l = []
00082 ParseCommaSepList(s,l)
00083 for element in l:
00084 print prefix + element
00085
00086 def ParseCommaSepList(s,l):
00087
00088 """Parse comma separated list string s (with possibly embedded \,) and append into a list l"""
00089 if not s: return l
00090 part_arg = ""
00091 for arg in s.split(','):
00092 if part_arg: arg = part_arg + arg
00093 part_arg = ""
00094 if arg[-1] == "\\": part_arg = arg[:-1] + ','
00095 else: l.append(arg)
00096 if part_arg: l.append(part_arg)
00097 return l
00098
00099 def ParseEnvStr(s):
00100
00101 """Parse environment string: 'var1=val1,var2=val2...' into dictionary and return.
00102
00103 If parse error, dictionary will be empty"""
00104
00105 d = {}
00106 l = []
00107 ParseCommaSepList(s,l)
00108 for entry in l:
00109 mo = re.search(r"^\s*(\S+)\s*=(.*)$",entry)
00110 if not mo: return None
00111 d[mo.group(1)] = mo.group(2)
00112 return d
00113
00114 def ProcessSandboxSetup(obj,in_str,sb_type):
00115
00116 """Support setting of input and output sandbox lists for Task, Jobs and Protojobs objects.
00117
00118 Args are:-
00119 obj Object whose sandbox is being setup
00120 in_str Comma separated list of sandbox files
00121 sb_type Sandbox type: either "input" or "output"
00122
00123 Returns:
00124 ok Flag, True if O.K.
00125 out_str The string to be stored ( but only if ok is True)
00126 """
00127
00128
00129
00130 l = []
00131 ParseCommaSepList(in_str,l)
00132 out_str = ""
00133 err_msg = ""
00134 for file in l:
00135 if sb_type == "input":
00136 if not os.path.isfile(file):
00137 if not err_msg: err_msg = "Cannot find input sandbox file(s):"
00138 err_msg += " '" + file + "'"
00139 else:
00140 if out_str: out_str += ","
00141 out_str += os.path.split(file)[1]
00142 else:
00143 if re.search(r"/",file):
00144 if not err_msg: err_msg = "Output sandbox file(s) contains directory:"
00145 err_msg += " '" + file + "'"
00146 else:
00147 if out_str: out_str += ","
00148 out_str += file
00149 if err_msg:
00150 print err_msg
00151 return (False,"")
00152
00153
00154
00155
00156 if sb_type != "input" or obj.GetType() == "GBSProtoJob": return (True,out_str)
00157 sbox_dir = obj.GetStoreLocation("child_dir") + "/InputSandbox"
00158 if not os.path.isdir(sbox_dir):
00159 try:
00160 os.makedirs(sbox_dir,0755)
00161 except OSError:
00162 print "Unable to create directory: " + sbox_dir
00163 return (False,"")
00164 else:
00165 os.system("rm -f " + sbox_dir + "/*")
00166
00167 for file in l:
00168 print "Copying " + file + " -> " + sbox_dir
00169 if os.system("cp " + file + " " + sbox_dir):
00170 print "Failed to copy file!"
00171 return (False,"")
00172
00173 return (True,out_str)
00174