Changeset 5bf359d for fedd/federation/proxy_emulab_segment.py
- Timestamp:
- May 28, 2010 3:16:46 AM (14 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-3.01, version-3.02
- Children:
- 2f6820c
- Parents:
- 06cc65b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/federation/proxy_emulab_segment.py
r06cc65b r5bf359d 14 14 15 15 class start_segment(proxy_segment): 16 """ 17 This starts an experiment on an emulab accessed remotely via ssh. Most of 18 the experiment constuction has been done by the emulab_access object. This 19 just does the wrangling of the emulab commands and collected the node to 20 physical mapping. The routine throws service errors. 21 """ 22 16 23 def __init__(self, log=None, keyfile=None, debug=False): 17 24 proxy_segment.__init__(self, log=log, keyfile=keyfile, debug=debug) … … 28 35 29 36 def get_state(self, user, host, pid, eid): 37 """ 38 Return the state of the experiment as reported by emulab 39 """ 30 40 # command to test experiment state 31 41 expinfo_exec = "/usr/testbed/bin/expinfo" … … 80 90 81 91 def get_mapping(self, user, host, pid, eid): 92 """ 93 Get the physical to virtual mapping from the expinfo command and save 94 it in the self.map member. 95 """ 82 96 # command to test experiment state 83 97 expinfo_exec = "/usr/testbed/bin/expinfo" … … 143 157 144 158 145 def __call__(self, parent, eid, pid, user, tclfile, tmpdir, timeout=0): 146 """ 147 Start a sub-experiment on a federant. 148 149 Get the current state, modify or create as appropriate, ship data 150 and configs and start the experiment. There are small ordering 151 differences based on the initial state of the sub-experiment. 152 """ 153 # ops node in the federant 154 host = "%s%s" % (parent.ops, parent.domain) 159 def make_null_experiment(self, user, host, pid, eid, tmpdir): 160 """ 161 Create a null copy of the experiment so that we capture any logs there 162 if the modify fails. Emulab software discards the logs from a failed 163 startexp 164 """ 165 try: 166 f = open("%s/null.tcl" % tmpdir, "w") 167 print >>f, self.null 168 f.close() 169 except EnvironmentError, e: 170 raise service_error(service_error.internal, 171 "Cannot stage tarfile/rpm: %s" % e.strerror) 172 173 if not self.scp_file("%s/null.tcl" % tmpdir, user, host): 174 return False 175 self.log.info("[start_segment]: Creating %s" % eid) 176 timedout = False 177 try: 178 if not self.ssh_cmd(user, host, 179 ("/usr/testbed/bin/startexp -i -f -w -p %s " + 180 "-e %s null.tcl") % (pid, eid), "startexp", 181 timeout=60 * 10): 182 return False 183 except self.ssh_cmd_timeout: 184 timedout = True 185 186 if timedout: 187 state = self.get_state(user, host, pid, eid) 188 if state != "swapped": 189 return False 190 return True 191 192 def set_up_experiment_filespace(self, user, host, pid, eid, tmpdir): 193 """ 194 Send all the software and configuration files into the experiment's 195 file space. To reduce the number of ssh connections, we script many 196 changes and execute the script. 197 """ 155 198 # Configuration directories on the remote machine 156 199 proj_dir = "/proj/%s/exp/%s/tmp" % (pid, eid) … … 159 202 lsoftdir = "%s/software" % tmpdir 160 203 161 state = self.get_state(user, host, pid, eid)162 163 if not self.scp_file(tclfile, user, host):164 return False165 166 if state == 'none':167 # Create a null copy of the experiment so that we capture any168 # logs there if the modify fails. Emulab software discards the169 # logs from a failed startexp170 try:171 f = open("%s/null.tcl" % tmpdir, "w")172 print >>f, self.null173 f.close()174 except EnvironmentError, e:175 raise service_error(service_error.internal,176 "Cannot stage tarfile/rpm: %s" % e.strerror)177 178 if not self.scp_file("%s/null.tcl" % tmpdir, user, host):179 return False180 self.log.info("[start_segment]: Creating %s" % eid)181 timedout = False182 try:183 if not self.ssh_cmd(user, host,184 ("/usr/testbed/bin/startexp -i -f -w -p %s " +185 "-e %s null.tcl") % (pid, eid), "startexp",186 timeout=60 * 10):187 return False188 except self.ssh_cmd_timeout:189 timedout = True190 191 if timedout:192 state = self.get_state(user, host, pid, eid)193 if state != "swapped":194 return False195 196 204 # Open up a temporary file to contain a script for setting up the 197 205 # filespace for the new experiment. … … 237 245 user, host, "%s/%s" % (softdir, f)): 238 246 return False 239 # Stage the new configuration (active experiments will stay swapped 240 # in now) 247 return True 248 249 def swap_in(self, user, host, pid, eid): 250 """ 251 Swap experiment in. This includes code to cope with the experiment 252 swaping command timing out, but the experiment being swapped in 253 successfully. 254 """ 255 self.log.info("[start_segment]: Swapping %s in" % eid) 256 timedout = False 257 try: 258 if not self.ssh_cmd(user, host, 259 "/usr/testbed/bin/swapexp -w %s %s in" % (pid, eid), 260 "swapexp", timeout=25*60): 261 return False 262 except self.ssh_cmd_timeout: 263 timedout = True 264 265 # If the command was terminated, but completed successfully, 266 # report success. 267 if timedout: 268 self.log.debug("[start_segment]: swapin timed out " +\ 269 "checking state") 270 state = self.get_state(user, host, pid, eid) 271 self.log.debug("[start_segment]: state is %s" % state) 272 return state == 'active' 273 274 return True 275 276 277 def __call__(self, parent, eid, pid, user, tclfile, tmpdir, timeout=0): 278 """ 279 Start a sub-experiment on a federant. 280 281 Get the current state, modify or create as appropriate, ship data 282 and configs and start the experiment. There are small ordering 283 differences based on the initial state of the sub-experiment. 284 """ 285 # ops node in the federant 286 host = "%s%s" % (parent.ops, parent.domain) 287 state = self.get_state(user, host, pid, eid) 288 289 if not self.scp_file(tclfile, user, host): 290 return False 291 292 if state == 'none': 293 # Put a dummy in place to capture logs, and establish an experiment 294 # directory. 295 if not self.make_null_experiment(user, host, pid, eid, tmpdir): 296 return False 297 298 if not self.set_up_experiment_filespace(user, host, pid, eid, tmpdir): 299 return False 300 301 # With the filespace in place, we can modify and swap in. 241 302 self.log.info("[start_segment]: Modifying %s" % eid) 242 303 try: … … 253 314 # Active experiments are still swapped, this swaps the others in. 254 315 if state != 'active': 255 self.log.info("[start_segment]: Swapping %s" % eid) 256 timedout = False 257 try: 258 if not self.ssh_cmd(user, host, 259 "/usr/testbed/bin/swapexp -w %s %s in" % (pid, eid), 260 "swapexp", timeout=25*60): 261 return False 262 except self.ssh_cmd_timeout: 263 timedout = True 264 265 # If the command was terminated, but completed successfully, 266 # report success. 267 if timedout: 268 self.log.debug("[start_segment]: swapin timed out " +\ 269 "checking state") 270 state = self.get_state(user, host, pid, eid) 271 self.log.debug("[start_segment]: state is %s" % state) 272 return state == 'active' 316 if not self.swap_in(user, host, pid, eid): 317 return False 273 318 # Everything has gone OK. 274 319 self.get_mapping(user, host, pid,eid)
Note: See TracChangeset
for help on using the changeset viewer.