source: fedd/federation/emulab_segment.py @ 06c1dba

compt_changesinfo-ops
Last change on this file since 06c1dba was 06c1dba, checked in by Ted Faber <faber@…>, 12 years ago

Fisrt step to multi-user - checkpoint

  • Property mode set to 100644
File size: 5.2 KB
RevLine 
[181aeb4]1#!/usr/local/bin/python
2
[06c1dba]3import sys, os
4import re
[181aeb4]5
[06c1dba]6import tempfile
7import subprocess
8import logging 
9import time
10import signal
[1ae1aa2]11
[06c1dba]12import util
[181aeb4]13
[06c1dba]14from ssh_emulab_segment import ssh_emulab_segment
15from xmlrpc_emulab_segment import xmlrpc_emulab_segment
[181aeb4]16
17
[06c1dba]18class start_segment(ssh_emulab_segment, xmlrpc_emulab_segment):
19    def __init__(self, log=None, keyfile=None, debug=False, boss=None,
20            cert=None):
21        ssh_emulab_segment.__init__(self, log=log, keyfile=keyfile, debug=debug)
22        xmlrpc_emulab_segment.__init__(self, boss=boss, cert=cert)
[181aeb4]23
[06c1dba]24    def set_up_experiment_filespace(self, user, host, pid, eid, tmpdir):
[181aeb4]25        """
[06c1dba]26        Send all the software and configuration files into the experiment's
27        file space.  To reduce the number of ssh connections, we script many
28        changes and execute the script.
[181aeb4]29        """
[06c1dba]30        # Configuration directories on the remote machine
31        proj_dir = "/proj/%s/exp/%s/tmp" % (pid, eid)
32        softdir = "/proj/%s/software/%s" % (pid, eid)
33        # Local software dir
34        lsoftdir = "%s/software" % tmpdir
35
36        # Open up a temporary file to contain a script for setting up the
37        # filespace for the new experiment.
38        self.log.info("[start_segment]: creating script file")
39        try:
40            sf, scriptname = tempfile.mkstemp()
41            scriptfile = os.fdopen(sf, 'w')
42        except EnvironmentError:
43            return False
[181aeb4]44
[06c1dba]45        scriptbase = os.path.basename(scriptname)
46
47        # Script the filesystem changes
48        print >>scriptfile, "/bin/rm -rf %s" % proj_dir
49        # Clear and create the software directory
50        print >>scriptfile, "/bin/rm -rf %s/*" % softdir
51        print >>scriptfile, 'mkdir -p %s' % proj_dir
52        if os.path.isdir(lsoftdir):
53            print >>scriptfile, 'mkdir -p %s' % softdir
54        print >>scriptfile, "rm -f %s" % scriptbase
55        scriptfile.close()
56
57        # Move the script to the remote machine
58        # XXX: could collide tempfile names on the remote host
59        if self.scp_file(scriptname, user, host, scriptbase):
60            os.remove(scriptname)
[181aeb4]61        else:
[06c1dba]62            return False
[181aeb4]63
[06c1dba]64        # Execute the script (and the script's last line deletes it)
65        if not self.ssh_cmd(user, host, "sh -x %s" % scriptbase):
66            return False
[181aeb4]67
[06c1dba]68        for f in os.listdir(tmpdir):
69            if not os.path.isdir("%s/%s" % (tmpdir, f)):
70                if not self.scp_file("%s/%s" % (tmpdir, f), user, host,
71                        "%s/%s" % (proj_dir, f)):
72                    return False
73        if os.path.isdir(lsoftdir):
74            for f in os.listdir(lsoftdir):
75                if not os.path.isdir("%s/%s" % (lsoftdir, f)):
76                    if not self.scp_file("%s/%s" % (lsoftdir, f), 
77                            user, host, "%s/%s" % (softdir, f)):
78                        return False
79        return True
[181aeb4]80
81
[06c1dba]82    def __call__(self, parent, eid, pid, user, tclfile, tmpdir, timeout=0, 
83            gid=None):
[181aeb4]84        """
[06c1dba]85        Start a sub-experiment on a federant.
[181aeb4]86
[06c1dba]87        Get the current state, and terminate the experiment if it exists. The
88        group membership of the experiment is difficult to determine or change,
89        so start with a clean slate.  Create a new one and ship data
90        and configs and start the experiment.  There are small ordering
91        differences based on the initial state of the sub-experiment.
[05c41f5]92        """
93
[06c1dba]94        state = self.get_state(pid, eid)
[05c41f5]95
[06c1dba]96        if state != 'none':
97            self.terminate_exp(pid, eid)
[05c41f5]98
[06c1dba]99        if not self.make_null_experiment(pid, eid, tmpdir, gid):
100            return False
[6e33086]101
[06c1dba]102        if not self.set_up_experiment_filespace(pid, eid, tmpdir):
103            return False
[1ae1aa2]104
[06c1dba]105        # Put the file into a string to pass to emulab.
106        try:
107            tcl = "".join([ l for l in open(tclfile,"r")])
108        except EnvironmentError, e:
109            self.log.error("Can't read %s: %s" % (tclfile, e))
110            return False
111       
112        # Stage the new configuration
113        if not self.modify_exp(pid, eid, tcl):
114            self.log.error("modify failed")
115            return False
[1ae1aa2]116
[06c1dba]117        if not self.swap_exp(pid, eid, 'in'):
118            self.log.error("swap in failed")
119            return False
120        # Everything has gone OK.
121        self.get_mapping(pid,eid)
122        return True
[1ae1aa2]123
[06c1dba]124class stop_segment(local_segment, emulab_segment):
125    def __init__(self, log=None, keyfile=None, debug=False, boss=None, 
126            cert=None):
127        local_segment.__init__(self, log=log, keyfile=keyfile, debug=debug)
128        emulab_segment.__init__(self, boss=boss, cert=cert)
[181aeb4]129
[06c1dba]130    def __call__(self, parent, user, pid, eid, gid=None, terminate=False):
[b709861]131        """
[06c1dba]132        Stop a sub experiment by calling swapexp on the federant
[b709861]133        """
134
[06c1dba]135        self.log.info("[stop_segment]: Stopping %s" % eid)
136        rv = False
137        try:
138            # Clean out tar files: we've gone over quota in the past
139            self.ssh_cmd("rm -rf /proj/%s/software/%s" % (pid, eid))
140            rv = self.swap_exp(pid, eid, 'out')
141            if terminate:
142                rv = self.terminate_exp(pid, eid)
143        except self.cmd_timeout:
144            rv = False
145        return rv
146
147class info_segment(local_segment, emulab_segment):
148    def __init__(self, log=None, keyfile=None, debug=False, boss=None, 
149            cert=None):
150        local_segment.__init__(self, log=log, keyfile=keyfile, debug=debug)
151        emulab_segment.__init__(self, boss=boss, cert=cert)
152
153    def __call__(self, parent, user, pid, eid):
154        self.log.info("[info_segment]: Getting info from %s" % eid)
155        self.get_mapping(pid,eid)
156        return True
157
158class operation_segment(local_segment, emulab_segment):
159    def __init__(self, log=None, keyfile=None, debug=False, boss=None, 
160            cert=None):
161        local_segment.__init__(self, log=log, keyfile=keyfile, debug=debug)
162        emulab_segment.__init__(self, boss=boss, cert=cert)
163
164    def __call__(self, parent, op, targets, param, top):
165        for l, p in targets.items():
166            self.log.info("[operation_segment]: Calling op %s on %s(%s)" % \
167                    (op, l,p))
168            self.do_operation(op, l, p, param, top)
169        return True
Note: See TracBrowser for help on using the repository browser.