- Timestamp:
- Jun 23, 2010 11:22:49 AM (15 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-3.01, version-3.02
- Children:
- 7888aee
- Parents:
- 1b6cc95
- Location:
- fedd/federation
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/federation/emulab_access.py
r1b6cc95 r181aeb4 72 72 self.ssh_pubkey_file = config.get("access","ssh_pubkey_file") 73 73 self.ssh_port = config.get("access","ssh_port") or "22" 74 self.boss = config.get("access", "boss") 75 self.xmlrpc_cert = config.get("access", "xmlrpc_cert") 76 self.xmlrpc_certpw = config.get("access", "xmlrpc_certpw") 74 77 75 78 self.dragon_endpoint = config.get("access", "dragon") … … 1037 1040 1038 1041 starter = self.start_segment(keyfile=self.ssh_privkey_file, 1039 debug=self.create_debug, log=alloc_log) 1042 debug=self.create_debug, log=alloc_log, boss=self.boss, 1043 cert=self.xmlrpc_cert) 1040 1044 rv = starter(self, ename, proj, user, expfile, tmpdir) 1041 1045 except service_error, e: … … 1094 1098 "Can't find experiment name for %s" % aid) 1095 1099 stopper = self.stop_segment(keyfile=self.ssh_privkey_file, 1096 debug=self.create_debug )1100 debug=self.create_debug, boss=self.boss, cert=self.xmlrpc_cert) 1097 1101 stopper(self, user, proj, ename) 1098 1102 return { 'allocID': req['allocID'] } -
fedd/federation/local_emulab_segment.py
r1b6cc95 r181aeb4 13 13 14 14 from local_segment import local_segment 15 from federation.emulab_segment import emulab_segment 15 16 16 class start_segment(local_segment): 17 def __init__(self, log=None, keyfile=None, debug=False): 17 18 class start_segment(local_segment, emulab_segment): 19 def __init__(self, log=None, keyfile=None, debug=False, boss=None, 20 cert=None): 18 21 local_segment.__init__(self, log=log, keyfile=keyfile, debug=debug) 19 self.null = """ 20 set ns [new Simulator] 21 source tb_compat.tcl 22 23 set a [$ns node] 24 25 $ns rtproto Session 26 $ns run 27 """ 22 emulab_segment.__init__(self, boss=boss, cert=cert) 28 23 self.node = { } 29 30 def get_state(self, pid, eid):31 """32 Return the state of the experiment as reported by emulab33 """34 # command to test experiment state35 expinfo_exec = "/usr/testbed/bin/expinfo"36 # Regular expressions to parse the expinfo response37 state_re = re.compile("State:\s+(\w+)")38 no_exp_re = re.compile("^No\s+such\s+experiment")39 swapping_re = re.compile("^No\s+information\s+available.")40 state = None # Experiment state parsed from expinfo41 # The expinfo ssh command. Note the identity restriction to use42 # only the identity provided in the pubkey given.43 cmd = [ expinfo_exec, pid, eid]44 45 dev_null = None46 try:47 dev_null = open("/dev/null", "a")48 except EnvironmentError, e:49 self.log.error("[get_state]: can't open /dev/null: %s" %e)50 51 if self.debug:52 state = 'swapped'53 rv = 054 else:55 self.log.debug("Checking state")56 status = subprocess.Popen(cmd, stdout=subprocess.PIPE,57 stderr=dev_null, close_fds=True)58 for line in status.stdout:59 m = state_re.match(line)60 if m: state = m.group(1)61 else:62 for reg, st in ((no_exp_re, "none"),63 (swapping_re, "swapping")):64 m = reg.match(line)65 if m: state = st66 rv = status.wait()67 68 # If the experiment is not present the subcommand returns a69 # non-zero return value. If we successfully parsed a "none"70 # outcome, ignore the return code.71 if rv != 0 and state != 'none':72 raise service_error(service_error.internal,73 "Cannot get status of segment:%s/%s" % (pid, eid))74 elif state not in ('active', 'swapped', 'swapping', 'none'):75 raise service_error(service_error.internal,76 "Cannot get status of segment:%s/%s" % (pid, eid))77 else:78 self.log.debug("State is %s" % state)79 return state80 81 def get_mapping(self, pid, eid):82 """83 Get the physical to virtual mapping from the expinfo command and save84 it in the self.map member.85 """86 # command to test experiment state87 expinfo_exec = "/usr/testbed/bin/expinfo"88 # The expinfo command.89 cmd = [ expinfo_exec, '-m', pid, eid]90 91 dev_null = None92 try:93 dev_null = open("/dev/null", "a")94 except EnvironmentError, e:95 self.log.error("[get_state]: can't open /dev/null: %s" %e)96 97 if self.debug:98 rv = 099 else:100 self.log.debug("Getting mapping for %s %s" % (pid, eid))101 phys_start = re.compile('^Physical\s+Node\s+Mapping')102 phys_line = re.compile('(\S+)(\s+\S+)*\s+(\S+)')103 phys_end = re.compile('^$')104 status = subprocess.Popen(cmd, stdout=subprocess.PIPE,105 stderr=dev_null, close_fds=True)106 107 # Parse the info output. Format:108 #109 # stuff110 # Physical Node Mapping:111 # ID Type OS Physical112 # --------------- ------------ --------------- ------------113 # virtual dummy dummy physical114 #115 foundit = False116 skip = 0117 for line in status.stdout:118 if phys_start.match(line):119 skip = 2120 foundit = True121 elif not foundit:122 continue123 elif skip > 0:124 skip -= 1125 elif phys_end.match(line):126 break127 else:128 m = phys_line.match(line.strip())129 if m: self.node[m.group(1)] = m.group(3)130 else: self.log.warn(131 "Matching failed while parsing node mapping: " +\132 "line %s" % line)133 rv = status.wait()134 135 # If the experiment is not present the subcommand returns a136 # non-zero return value. If we successfully parsed a "none"137 # outcome, ignore the return code.138 if rv != 0 :139 raise service_error(service_error.internal,140 "Cannot get node mapping of segment:%s/%s" % (pid, eid))141 else:142 return True143 144 def make_null_experiment(self, pid, eid, tmpdir):145 """146 Create a null copy of the experiment so that we capture any logs there147 if the modify fails. Emulab software discards the logs from a failed148 startexp.149 """150 try:151 f = open("%s/null.tcl" % tmpdir, "w")152 print >>f, self.null153 f.close()154 except EnvironmentError, e:155 raise service_error(service_error.internal,156 "Cannot stage null.tcl: %s" % e.strerror)157 158 timedout = False159 try:160 if not self.cmd_with_timeout(161 ("/usr/testbed/bin/startexp -i -f -w -p %s " +162 "-e %s %s/null.tcl") % (pid, eid, tmpdir), "startexp",163 timeout=60 * 10):164 return False165 except self.cmd_timeout:166 timedout = True167 168 if timedout:169 state = self.get_state(pid, eid)170 return state == "swapped"171 else:172 return True173 24 174 25 def set_up_experiment_filespace(self, pid, eid, tmpdir): … … 207 58 return True 208 59 209 def swap_in(self, pid, eid):210 """211 Swap experiment in. This includes code to cope with the experiment212 swaping command timing out, but the experiment being swapped in213 successfully.214 """215 self.log.info("[start_segment]: Swapping %s" % eid)216 timedout = False217 try:218 if not self.cmd_with_timeout(219 "/usr/testbed/bin/swapexp -w %s %s in" % (pid, eid),220 "swapexp", timeout=25*60):221 return False222 except self.cmd_timeout:223 timedout = True224 225 # If the command was terminated, but completed successfully,226 # report success.227 if timedout:228 self.log.debug("[start_segment]: swapin timed out " +\229 "checking state")230 state = self.get_state(pid, eid)231 self.log.debug("[start_segment]: state is %s" % state)232 return state == 'active'233 else:234 return True235 236 60 def __call__(self, parent, eid, pid, user, tclfile, tmpdir, timeout=0): 237 61 """ … … 251 75 if not self.set_up_experiment_filespace(pid, eid, tmpdir): 252 76 return False 77 78 # Put the file into a string to pass to emulab. 79 try: 80 tcl = "".join([ l for l in open(tclfile,"r")]) 81 except EnvironmentError, e: 82 self.log.error("Can't read %s: %s" % (tclfile, e)) 83 return False 253 84 254 85 # Stage the new configuration (active experiments will stay swapped 255 86 # in now) 256 self.log.info("[start_segment]: Modifying %s" % eid) 257 try: 258 if not self.cmd_with_timeout( 259 "/usr/testbed/bin/modexp -r -s -w %s %s %s" % \ 260 (pid, eid, tclfile), 261 "modexp", timeout= 60 * 10): 262 return False 263 except self.cmd_timeout: 264 self.log.error("Modify command failed to complete in time") 265 # There's really no way to see if this succeeded or failed, so 266 # if it hangs, assume the worst. 87 if not self.modify_exp(pid, eid, tcl): 88 self.log.error("modify failed") 267 89 return False 268 90 # Active experiments are still swapped, this swaps the others in. 269 91 if state != 'active': 270 if not self.swap_ in(pid, eid):92 if not self.swap_exp(pid, eid, 'in'): 271 93 return False 272 94 # Everything has gone OK. … … 274 96 return True 275 97 276 class stop_segment(local_segment): 277 def __init__(self, log=None, keyfile=None, debug=False): 98 class stop_segment(local_segment, emulab_segment): 99 def __init__(self, log=None, keyfile=None, debug=False, boss=None, 100 cert=None): 278 101 local_segment.__init__(self, log=log, keyfile=keyfile, debug=debug) 102 emulab_segment.__init__(self, boss=boss, cert=cert) 279 103 280 104 def __call__(self, parent, user, pid, eid): … … 287 111 # Clean out tar files: we've gone over quota in the past 288 112 self.cmd_with_timeout("rm -rf /proj/%s/software/%s" % (pid, eid)) 289 rv = self.cmd_with_timeout( 290 "/usr/testbed/bin/swapexp -w %s %s out" % (pid, eid), 291 timeout = 60*10) 113 rv = self.swap_exp(pid, eid, 'out') 292 114 except self.cmd_timeout: 293 115 rv = False -
fedd/federation/proxy_emulab_segment.py
r1b6cc95 r181aeb4 21 21 """ 22 22 23 def __init__(self, log=None, keyfile=None, debug=False): 23 def __init__(self, log=None, keyfile=None, debug=False, boss=None, 24 cert=None): 24 25 proxy_segment.__init__(self, log=log, keyfile=keyfile, debug=debug) 25 26 self.null = """ … … 321 322 322 323 class stop_segment(proxy_segment): 323 def __init__(self, log=None, keyfile=None, debug=False ):324 def __init__(self, log=None, keyfile=None, debug=False, boss=None, cert=None): 324 325 proxy_segment.__init__(self, log=log, keyfile=keyfile, debug=debug) 325 326
Note: See TracChangeset
for help on using the changeset viewer.