Changeset ecca6eb


Ignore:
Timestamp:
Sep 3, 2009 6:51:50 PM (15 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-2.00, version-3.01, version-3.02
Children:
f5ae004
Parents:
66861a2
Message:

checkpoint

Location:
fedd/federation
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/access.py

    r66861a2 recca6eb  
    99
    1010from threading import *
     11import subprocess
     12import time
    1113
    1214from util import *
     
    6365        self.eventserver = config.get("access", "eventserver")
    6466        self.certdir = config.get("access","certdir")
     67        self.ssh_privkey_file = config.get("access","ssh_privkey_file")
    6568
    6669        self.attrs = { }
     
    616619                else: self.projects[pname] = 1
    617620                self.allocation[aid]['project'] = pname
     621            else:
     622                # sproject is a static project associated with this allocation.
     623                self.allocation[aid]['sproject'] = pname
    618624
    619625            if ap.has_key('resources'):
     
    638644                for u in ap['project']['user']:
    639645                    uname = u['userID']['localname']
     646                    if u['role'] == 'experimentCreation':
     647                        self.allocation[aid]['user'] = uname
    640648                    for k in [ k['sshPubkey'] for k in u['access'] \
    641649                            if k.has_key('sshPubkey') ]:
     
    789797
    790798
    791     class emulab_segment:
     799    class proxy_emulab_segment:
    792800        class ssh_cmd_timeout(RuntimeError): pass
    793801
    794802        def __init__(self, log=None, keyfile=None, debug=False):
    795803            self.log = log or logging.getLogger(\
    796                     'fedd.experiment_control.emulab_segment')
     804                    'fedd.access.proxy_emulab_segment')
    797805            self.ssh_privkey_file = keyfile
    798806            self.debug = debug
    799807            self.ssh_exec="/usr/bin/ssh"
    800808            self.scp_exec = "/usr/bin/scp"
    801             self.ssh_cmd_timeout = emulab_segment.ssh_cmd_timeout
     809            self.ssh_cmd_timeout = access.proxy_emulab_segment.ssh_cmd_timeout
    802810
    803811        def scp_file(self, file, user, host, dest=""):
     
    822830            self.log.debug("[scp_file]: %s" % " ".join(scp_cmd))
    823831            if not self.debug:
    824                 rv = call(scp_cmd, stdout=dnull, stderr=dnull, close_fds=True,
    825                         close_fds=True)
     832                rv = subprocess.call(scp_cmd, stdout=dnull,
     833                        stderr=dnull, close_fds=True, close_fds=True)
    826834
    827835            return rv == 0
     
    848856            if not self.debug:
    849857                if dnull:
    850                     sub = Popen(sh_str, shell=True, stdout=dnull, stderr=dnull,
    851                             close_fds=True)
     858                    sub = subprocess.Popen(sh_str, shell=True, stdout=dnull,
     859                            stderr=dnull, close_fds=True)
    852860                else:
    853                     sub = Popen(sh_str, shell=True,
    854                             close_fds=True)
     861                    sub = subprocess.Popen(sh_str, shell=True, close_fds=True)
    855862                if timeout:
    856863                    i = 0
     
    876883                    return True
    877884
    878     class start_segment(emulab_segment):
     885    class start_segment(proxy_emulab_segment):
    879886        def __init__(self, log=None, keyfile=None, debug=False):
    880             experiment_control_local.emulab_segment.__init__(self,
    881                     log=log, keyfile=keyfile, debug=debug)
    882 
    883         def create_config_tree(self, src_dir, dest_dir, script):
    884             """
    885             Append commands to script that will create the directory hierarchy
    886             on the remote federant.
    887             """
    888 
    889             if os.path.isdir(src_dir):
    890                 print >>script, "mkdir -p %s" % dest_dir
    891                 print >>script, "chmod 770 %s" % dest_dir
    892 
    893                 for f in os.listdir(src_dir):
    894                     if os.path.isdir(f):
    895                         self.create_config_tree("%s/%s" % (src_dir, f),
    896                                 "%s/%s" % (dest_dir, f), script)
    897             else:
    898                 self.log.debug("[create_config_tree]: Not a directory: %s" \
    899                         % src_dir)
    900 
    901         def ship_configs(self, host, user, src_dir, dest_dir):
    902             """
    903             Copy federant-specific configuration files to the federant.
    904             """
    905             for f in os.listdir(src_dir):
    906                 if os.path.isdir(f):
    907                     if not self.ship_configs(host, user, "%s/%s" % (src_dir, f),
    908                             "%s/%s" % (dest_dir, f)):
    909                         return False
    910                 else:
    911                     if not self.scp_file("%s/%s" % (src_dir, f),
    912                             user, host, dest_dir):
    913                         return False
    914             return True
    915 
    916         def get_state(self, user, host, tb, pid, eid):
     887            access.proxy_emulab_segment.__init__(self, log=log,
     888                    keyfile=keyfile, debug=debug)
     889            self.null = """
     890set ns [new Simulator]
     891source tb_compat.tcl
     892
     893set a [$ns node]
     894
     895$ns rtproto Session
     896$ns run
     897"""
     898
     899        def get_state(self, user, host, pid, eid):
    917900            # command to test experiment state
    918901            expinfo_exec = "/usr/testbed/bin/expinfo" 
     
    939922                rv = 0
    940923            else:
    941                 status = Popen(cmd, stdout=PIPE, stderr=dev_null,
    942                         close_fds=True)
     924                self.log.debug("Checking state")
     925                status = subprocess.Popen(cmd, stdout=subprocess.PIPE,
     926                        stderr=dev_null, close_fds=True)
    943927                for line in status.stdout:
    944928                    m = state_re.match(line)
     
    956940            if rv != 0 and state != 'none':
    957941                raise service_error(service_error.internal,
    958                         "Cannot get status of segment %s:%s/%s" % \
    959                                 (tb, pid, eid))
     942                        "Cannot get status of segment:%s/%s" % (pid, eid))
    960943            elif state not in ('active', 'swapped', 'swapping', 'none'):
    961944                raise service_error(service_error.internal,
    962                         "Cannot get status of segment %s:%s/%s" % \
    963                                 (tb, pid, eid))
    964             else: return state
    965 
    966 
    967         def __call__(self, tb, eid, tbparams, tmpdir, timeout=0):
     945                        "Cannot get status of segment:%s/%s" % (pid, eid))
     946            else:
     947                self.log.debug("State is %s" % state)
     948                return state
     949
     950
     951        def __call__(self, parent, eid, pid, user, tclfile, tmpdir, timeout=0):
    968952            """
    969953            Start a sub-experiment on a federant.
     
    974958            """
    975959            # ops node in the federant
    976             host = "%s%s" % (tbparams[tb]['host'], tbparams[tb]['domain'])
    977             user = tbparams[tb]['user']     # federant user
    978             pid = tbparams[tb]['project']   # federant project
    979             # XXX
    980             base_confs = ( "hosts",)
    981             tclfile = "%s.%s.tcl" % (eid, tb)   # sub-experiment description
     960            host = "%s%s" % (parent.ops, parent.domain)
    982961            # Configuration directories on the remote machine
    983962            proj_dir = "/proj/%s/exp/%s/tmp" % (pid, eid)
    984             tarfiles_dir = "/proj/%s/tarfiles/%s" % (pid, eid)
    985             rpms_dir = "/proj/%s/rpms/%s" % (pid, eid)
    986 
    987             state = self.get_state(user, host, tb, pid, eid)
    988 
    989             self.log.debug("[start_segment]: %s: %s" % (tb, state))
    990             self.log.info("[start_segment]:transferring experiment to %s" % tb)
    991 
    992             if not self.scp_file("%s/%s/%s" % \
    993                     (tmpdir, tb, tclfile), user, host):
     963            softdir = "/proj/%s/software/%s" % (pid, eid)
     964            # Local software dir
     965            lsoftdir = "%s/software" % tmpdir
     966
     967            state = self.get_state(user, host, pid, eid)
     968
     969            if not self.scp_file(tclfile, user, host):
    994970                return False
    995971           
     
    998974                # logs there if the modify fails.  Emulab software discards the
    999975                # logs from a failed startexp
     976                try:
     977                    f = open("%s/null.tcl" % tmpdir, "w")
     978                    print >>f, self.null
     979                    f.close()
     980                except IOError, e:
     981                    raise service_error(service_error.internal,
     982                            "Cannot stage tarfile/rpm: %s" % e.strerror)
     983
    1000984                if not self.scp_file("%s/null.tcl" % tmpdir, user, host):
    1001985                    return False
    1002                 self.log.info("[start_segment]: Creating %s on %s" % (eid, tb))
     986                self.log.info("[start_segment]: Creating %s" % eid)
    1003987                timedout = False
    1004988                try:
     
    1012996
    1013997                if timedout:
    1014                     state = self.get_state(user, host, tb, pid, eid)
     998                    state = self.get_state(user, host, pid, eid)
    1015999                    if state != "swapped":
    10161000                        return False
    1017 
    10181001           
    10191002            # Open up a temporary file to contain a script for setting up the
     
    10301013            # Script the filesystem changes
    10311014            print >>scriptfile, "/bin/rm -rf %s" % proj_dir
    1032             # Clear and create the tarfiles and rpm directories
    1033             for d in (tarfiles_dir, rpms_dir):
    1034                 print >>scriptfile, "/bin/rm -rf %s/*" % d
    1035                 print >>scriptfile, "mkdir -p %s" % d
     1015            # Clear and create the software directory
     1016            print >>scriptfile, "/bin/rm -rf %s/*" % softdir
    10361017            print >>scriptfile, 'mkdir -p %s' % proj_dir
    1037             self.create_config_tree("%s/%s" % (tmpdir, tb),
    1038                     proj_dir, scriptfile)
    1039             if os.path.isdir("%s/tarfiles" % tmpdir):
    1040                 self.create_config_tree("%s/tarfiles" % tmpdir, tarfiles_dir,
    1041                         scriptfile)
    1042             if os.path.isdir("%s/rpms" % tmpdir):
    1043                 self.create_config_tree("%s/rpms" % tmpdir, rpms_dir,
    1044                         scriptfile)
     1018            if os.path.isdir(lsoftdir):
     1019                print >>scriptfile, 'mkdir -p %s' % softdir
    10451020            print >>scriptfile, "rm -f %s" % scriptbase
    10461021            scriptfile.close()
     
    10571032                return False
    10581033
    1059             for f in base_confs:
    1060                 if not self.scp_file("%s/%s" % (tmpdir, f), user, host,
    1061                         "%s/%s" % (proj_dir, f)):
    1062                     return False
    1063             if not self.ship_configs(host, user, "%s/%s" % (tmpdir, tb),
    1064                     proj_dir):
    1065                 return False
    1066             if os.path.isdir("%s/tarfiles" % tmpdir):
    1067                 if not self.ship_configs(host, user,
    1068                         "%s/tarfiles" % tmpdir, tarfiles_dir):
    1069                     return False
    1070             if os.path.isdir("%s/rpms" % tmpdir):
    1071                 if not self.ship_configs(host, user,
    1072                         "%s/rpms" % tmpdir, tarfiles_dir):
    1073                     return False
     1034            for f in os.listdir(tmpdir):
     1035                if not os.path.isdir("%s/%s" % (tmpdir, f)):
     1036                    if not self.scp_file("%s/%s" % (tmpdir, f), user, host,
     1037                            "%s/%s" % (proj_dir, f)):
     1038                        return False
     1039            if os.path.isdir(lsoftdir):
     1040                for f in os.listdir(lsoftdir):
     1041                    if not os.path.isdir("%s/%s" % (lsoftdir, f)):
     1042                        if not self.scp_file("%s/%s" % (lsoftdir, f),
     1043                                user, host, "%s/%s" % (softdir, f)):
     1044                            return False
    10741045            # Stage the new configuration (active experiments will stay swapped
    10751046            # in now)
    1076             self.log.info("[start_segment]: Modifying %s on %s" % (eid, tb))
     1047            self.log.info("[start_segment]: Modifying %s" % eid)
    10771048            try:
    10781049                if not self.ssh_cmd(user, host,
    10791050                        "/usr/testbed/bin/modexp -r -s -w %s %s %s" % \
    1080                                 (pid, eid, tclfile),
     1051                                (pid, eid, tclfile.rpartition('/')[2]),
    10811052                        "modexp", timeout= 60 * 10):
    10821053                    return False
     
    10881059            # Active experiments are still swapped, this swaps the others in.
    10891060            if state != 'active':
    1090                 self.log.info("[start_segment]: Swapping %s in on %s" % \
    1091                         (eid, tb))
     1061                self.log.info("[start_segment]: Swapping %s" % eid)
    10921062                timedout = False
    10931063                try:
     
    11041074                    self.log.debug("[start_segment]: swapin timed out " +\
    11051075                            "checking state")
    1106                     state = self.get_state(user, host, tb, pid, eid)
     1076                    state = self.get_state(user, host, pid, eid)
    11071077                    self.log.debug("[start_segment]: state is %s" % state)
    11081078                    return state == 'active'
     
    11101080            return True
    11111081
    1112     class stop_segment(emulab_segment):
     1082    class stop_segment(proxy_emulab_segment):
    11131083        def __init__(self, log=None, keyfile=None, debug=False):
    11141084            experiment_control_local.emulab_segment.__init__(self,
     
    11371107
    11381108    def generate_portal_configs(self, topo, pubkey_base, secretkey_base,
    1139             tmpdir):
     1109            tmpdir, master):
     1110
     1111        seer_out = False
    11401112        for p in [ e for e in topo.elements \
    11411113                if isinstance(e, topdl.Computer) and e.get_attribute('portal')]:
     
    11451117            lproj, leid = lexp.split('/', 1)
    11461118            ldomain = e.get_attribute('domain')
     1119            mexp = e.get_attribute('masterexperiment')
     1120            mproj, meid = mexp.split("/", 1)
     1121            mdomain = e.get_attribute('masterdomain')
    11471122            scriptdir = e.get_attribute('scriptdir')
    11481123            active = e.get_attribute('active')
    1149             type = e.get_attribute('type')
     1124            type = e.get_attribute('portal_type')
    11501125            segid = fedid(hexstr=e.get_attribute('peer_segment'))
    11511126            for e in topo.elements:
     
    11701145                print >>f, "RemoteEventServerName: event-server%s" % rdomain
    11711146                print >>f, "SeerControl: control.%s.%s%s" % \
    1172                         (leid.lower(), lproj.lower(), ldomain)
     1147                        (meid.lower(), mproj.lower(), mdomain)
    11731148                print >>f, "Type: %s" % type
    11741149                print >>f, "RemoteExperiment: %s" % rexp
     
    11881163                raise service_error(service_error.internal,
    11891164                        "Can't write protal config %s: %s" % (cfn, e))
     1165           
     1166            # XXX: This little seer config file needs to go away.
     1167            if not seer_out:
     1168                try:
     1169                    seerfn = "%s/seer.conf" % tmpdir
     1170                    f = open(seerfn, "w")
     1171                    if not master:
     1172                        print >>f, "ControlNode: control.%s.%s%s" % \
     1173                            (meid.lower(), mproj.lower(), mdomain)
     1174                    print >>f, "ExperimentID: %s" % mexp
     1175                    f.close()
     1176                except IOError, e:
     1177                    raise service_error(service_error.internal,
     1178                            "Can't write seer.conf: %s" %e)
     1179                seer_out = True
     1180
     1181
     1182    def generate_client_conf(self, user, proj, eid, tmpdir):
     1183        try:
     1184            f = open("%s/client.conf" % tmpdir, "w")
     1185            if self.attrs.has_key('SMBshare'):
     1186                print >>f, "SMBshare: %s" % self.attrs['SMBshare']
     1187            print >>f, "ProjectUser: %s" % user
     1188            print >>f, "ProjectName: %s" % proj
     1189            print >>f, "ExperimentID: %s/%s" % (proj, eid)
     1190            f.close()
     1191        except IOError, e:
     1192            raise service_error(service_error.internal,
     1193                    "Cannot write client.conf: %s" %s)
     1194
     1195    def generate_ns2(self, topo, expfn, softdir, master):
     1196        t = topo.clone()
     1197
     1198        # Weed out the things we aren't going to instantiate: Segments, portal
     1199        # substrates, and portal interfaces.  (The copi in the for loop allows
     1200        # us to delete from e.elements in side the for loop).
     1201        for e in [e for e in t.elements]:
     1202            if isinstance(e, topdl.Segment):
     1203                t.elements.remove(e)
     1204            if isinstance(e, topdl.Computer):
     1205                e.interface = [i for i in e.interface \
     1206                        if not i.get_attribute('portal')]
     1207        t.substrates = [ s for s in t.substrates \
     1208                if not s.get_attribute('portal')]
     1209        t.incorporate_elements()
     1210
     1211        # Localize the software locations
     1212        for e in t.elements:
     1213            for s in getattr(e, 'software', []):
     1214                s.location = re.sub("^.*/", softdir, s.location)
     1215
     1216
     1217        # Customize the ns2 output for local portal commands and images
     1218        filters = []
     1219
     1220        if master: cmdname = 'MasterConnectorCmd'
     1221        else:cmdname = 'SlaveConnectorCmd'
     1222
     1223        if self.attrs.has_key(cmdname):
     1224            filters.append(topdl.generate_portal_command_filter(
     1225                self.attrs.get(cmdname)))
     1226
     1227        if self.attrs.has_key('connectorImage'):
     1228            filters.append(topdl.generate_portal_image_filter(
     1229                self.attrs.get('connectorImage')))
     1230
     1231        if self.attrs.has_key('connectorType'):
     1232            filters.append(topdl.generate_portal_hardware_filter(
     1233                self.attrs.get('connectorType')))
     1234
     1235        # Convert to ns and write it out
     1236        expfile = topdl.topology_to_ns2(t, filters)
     1237        try:
     1238            f = open(expfn, "w")
     1239            print >>f, expfile
     1240            f.close()
     1241        except IOError:
     1242            raise service_error(service_error.internal,
     1243                    "Cannot write experiment file %s: %s" % (expfn,e))
    11901244
    11911245    def StartSegment(self, req, fid):
     
    12141268
    12151269        configs = set(('hosts', 'ssh_pubkey', 'ssh_secretkey'))
    1216         keys = set(('ssh_pubkey', 'ssh_secretkey'))
    1217 
    12181270
    12191271        try:
     
    12211273        except KeyError:
    12221274            raise service_error(server_error.req, "Badly formed request")
     1275
    12231276        auth_attr = req['allocID']['fedid']
     1277        aid = "%s" % auth_attr
    12241278        attrs = req.get('fedAttr', [])
    1225         print auth_attr
    1226         print "%s" % auth_attr
    1227         if self.auth.check_attribute(fid, auth_attr):
    1228             print "OK"
    1229         else:
    1230             print "Fail"
     1279        if not self.auth.check_attribute(fid, auth_attr):
     1280            raise service_error(service_error.access, "Access denied")
    12311281
    12321282        if req.has_key('segmentdescription') and \
     
    12381288                    "Request missing segmentdescription'")
    12391289
     1290        master = req.get('master', False)
     1291
    12401292        certfile = "%s/%s.pem" % (self.certdir, auth_attr)
    12411293        try:
    12421294            tmpdir = tempfile.mkdtemp(prefix="access-")
     1295            softdir = "%s/software" % tmpdir
    12431296        except IOError:
    12441297            raise service_error(service_error.internal, "Cannot create tmp dir")
    12451298
    12461299        sw = set()
    1247         for e in [c for c in topo.elements if getattr(c, 'software', False)]:
    1248             for s in e.software:
     1300        for e in topo.elements:
     1301            for s in getattr(e, 'software', []):
    12491302                sw.add(s.location)
     1303        if len(sw) > 0:
     1304            os.mkdir(softdir)
    12501305        for s in sw:
    1251             get_url(s, certfile, tmpdir)
     1306            get_url(s, certfile, softdir)
    12521307
    12531308        for a in attrs:
     
    12551310                get_url(a['value'], certfile, tmpdir)
    12561311            if a['attribute'] == 'ssh_pubkey':
    1257                 pubkey_base = a['attribute'].rpartition('/')[2]
     1312                pubkey_base = a['value'].rpartition('/')[2]
    12581313            if a['attribute'] == 'ssh_secretkey':
    1259                 secretkey_base = a['attribute'].rpartition('/')[2]
    1260 
    1261         self.generate_portal_configs(topo, pubkey_base, secretkey_base, tmpdir)
     1314                secretkey_base = a['value'].rpartition('/')[2]
     1315            if a['attribute'] == 'experiment_name':
     1316                ename = a['value']
     1317
     1318        proj = None
     1319        user = None
     1320        self.state_lock.acquire()
     1321        if self.allocation.has_key(aid):
     1322            proj = self.allocation[aid].get('project', None)
     1323            if not proj:
     1324                proj = self.allocation[aid].get('sproject', None)
     1325            user = self.allocation[aid].get('user', None)
     1326        self.state_lock.release()
     1327
     1328        if not proj:
     1329            raise service_error(service_error.internal,
     1330                    "Can't find project for %s" %aid)
     1331
     1332        if not user:
     1333            raise service_error(service_error.internal,
     1334                    "Can't find creation user for %s" %aid)
     1335
     1336        expfile = "%s/experiment.tcl" % tmpdir
     1337
     1338        self.generate_portal_configs(topo, pubkey_base,
     1339                secretkey_base, tmpdir, master)
     1340        self.generate_ns2(topo, expfile,
     1341                "/proj/%s/software/%s/" % (proj, ename), master)
     1342        self.generate_client_conf(user, proj, ename, tmpdir)
     1343        starter = self.start_segment(keyfile=self.ssh_privkey_file, debug=False)
     1344        starter(self, ename, proj, user, expfile, tmpdir)
    12621345
    12631346        return { 'allocID': req['allocID'] }
  • fedd/federation/experiment_control.py

    r66861a2 recca6eb  
    21512151            self.caller = caller
    21522152
    2153         def __call__(self, uri, aid, topo, attrs=None):
     2153        def __call__(self, uri, aid, topo, master, attrs=None):
    21542154            req = {
    21552155                    'allocID': { 'fedid' : aid },
     
    21572157                        'topdldescription': topo.to_dict(),
    21582158                    },
     2159                    'master': master,
    21592160                }
    21602161            if attrs:
     
    22042205                        trusted_certs=self.trusted_certs,
    22052206                        caller=self.call_StartSegment),
    2206                     args=(uri, aid, topo[tb], attrs), name=tb,
     2207                    args=(uri, aid, topo[tb], False, attrs), name=tb,
    22072208                    pdata=thread_pool, trace_file=self.trace_file)
    22082209            threads.append(t)
     
    22312232                    trusted_certs=self.trusted_certs,
    22322233                    caller=self.call_StartSegment)
    2233             if not starter(uri, aid, topo[master], attrs):
     2234            if not starter(uri, aid, topo[master], True, attrs):
    22342235                failed.append(master)
    22352236
     
    26682669                                                "/usr/local/federation/bin"),
    26692670                                            ('active', "%s" % active),
    2670                                             ('type', 'both'),
    2671                                             ('startup', 'sudo -H /usr/local/federation/bin/fed-tun.pl -f /proj/%s/exp/%s/tmp/%s%s.gw.conf >& /tmp/bridge.log' % (sproject, eid, myname.lower(), sdomain.lower())))
     2671                                            ('portal_type', 'both'),
     2672                                            ('startup', 'sudo -H /usr/local/federation/bin/fed-tun.pl -f /proj/%s/exp/%s/tmp/%s.%s.%s%s.gw.conf >& /tmp/bridge.log' % (sproject, eid, myname.lower(), eid.lower(), sproject.lower(), sdomain.lower())))
    26722673                                    ],
    26732674                                interface=[
     
    28362837                            (url_base, expid)
    28372838                },
     2839                {
     2840                    'attribute': 'experiment_name',
     2841                    'value': eid,
     2842                },
    28382843            ]
    28392844
  • fedd/federation/topdl.py

    r66861a2 recca6eb  
    231231    def clone(self):
    232232        return ID(self.fedid, self.uuid, self.uri, self.localname,
    233                 self.kernberosUsername)
     233                self.kerberosUsername)
    234234
    235235    def to_dict(self):
     
    327327        return Segment(self.id.clone(), self.type, self.uri,
    328328                interface=[i.clone() for i in self.interface],
    329                 attribute=[a.clone() for a in attribute])
     329                attribute=[a.clone() for a in self.attribute])
    330330
    331331    def to_dict(self):
     
    579579
    580580def to_tcl_name(n):
    581     t = re.subst('-(\d+)', '(\1)', n)
     581    t = re.sub('-(\d+)', '(\1)', n)
    582582    return t
     583
     584def generate_portal_command_filter(cmd):
     585    def rv(e):
     586        s =""
     587        if isinstance(e, Computer):
     588            gw = e.get_attribute('portal')
     589            if gw:
     590                s = "%s $%s\n" % (cmd, to_tcl_name(e.name[0]))
     591        return s
     592    return rv
    583593
    584594def generate_portal_image_filter(image):
     
    588598            gw = e.get_attribute('portal')
    589599            if gw:
    590                 s = "tb-set-node-os $%s %s" % (to_tcl_name(e.name[0]), image)
     600                s = "tb-set-node-os $%s %s\n" % (to_tcl_name(e.name[0]), image)
    591601        return s
    592602    return rv
    593603
    594 def generate_portal_command_filter(cmd):
     604def generate_portal_hardware_filter(type):
    595605    def rv(e):
    596606        s =""
     
    598608            gw = e.get_attribute('portal')
    599609            if gw:
    600                 s = "%s $%s" % (cmd, to_tcl_name(e.name[0]))
     610                s = "tb-set-hardware $%s %s\n" % (to_tcl_name(e.name[0]), type)
    601611        return s
    602612    return rv
     
    620630                if osid:
    621631                    out += "tb-set-node-os $%s %s\n" % (name, osid)
     632            hw = e.get_attribute('type')
     633            if hw:
     634                out += "tb-set-hardware $%s %s\n" % (name, hw)
    622635            for s in e.software:
    623636                if s.install:
Note: See TracChangeset for help on using the changeset viewer.