Ignore:
Timestamp:
May 28, 2010 3:16:46 AM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-3.01, version-3.02
Children:
2f6820c
Parents:
06cc65b
Message:

More refactoring. Neaten up the code for creating segments in emulab and make the local and proxy class structures parallel. The code is more readable this way, I hope.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/proxy_emulab_segment.py

    r06cc65b r5bf359d  
    1414
    1515class 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
    1623    def __init__(self, log=None, keyfile=None, debug=False):
    1724        proxy_segment.__init__(self, log=log, keyfile=keyfile, debug=debug)
     
    2835
    2936    def get_state(self, user, host, pid, eid):
     37        """
     38        Return the state of the experiment as reported by emulab
     39        """
    3040        # command to test experiment state
    3141        expinfo_exec = "/usr/testbed/bin/expinfo" 
     
    8090
    8191    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        """
    8296        # command to test experiment state
    8397        expinfo_exec = "/usr/testbed/bin/expinfo" 
     
    143157
    144158
    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        """
    155198        # Configuration directories on the remote machine
    156199        proj_dir = "/proj/%s/exp/%s/tmp" % (pid, eid)
     
    159202        lsoftdir = "%s/software" % tmpdir
    160203
    161         state = self.get_state(user, host, pid, eid)
    162 
    163         if not self.scp_file(tclfile, user, host):
    164             return False
    165        
    166         if state == 'none':
    167             # Create a null copy of the experiment so that we capture any
    168             # logs there if the modify fails.  Emulab software discards the
    169             # logs from a failed startexp
    170             try:
    171                 f = open("%s/null.tcl" % tmpdir, "w")
    172                 print >>f, self.null
    173                 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 False
    180             self.log.info("[start_segment]: Creating %s" % eid)
    181             timedout = False
    182             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 False
    188             except self.ssh_cmd_timeout:
    189                 timedout = True
    190 
    191             if timedout:
    192                 state = self.get_state(user, host, pid, eid)
    193                 if state != "swapped":
    194                     return False
    195        
    196204        # Open up a temporary file to contain a script for setting up the
    197205        # filespace for the new experiment.
     
    237245                            user, host, "%s/%s" % (softdir, f)):
    238246                        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.
    241302        self.log.info("[start_segment]: Modifying %s" % eid)
    242303        try:
     
    253314        # Active experiments are still swapped, this swaps the others in.
    254315        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
    273318        # Everything has gone OK.
    274319        self.get_mapping(user, host, pid,eid)
Note: See TracChangeset for help on using the changeset viewer.