def get(self, tenant_id):
     global engine
     global upPortByLvlPort
     global W
     abort_if_tenant_doesnt_exist(tenant_id)
     hosts = laas.VecInt()
     l1UpPorts = laas.VecPairInt()
     l2UpPorts = laas.VecPairInt()
     if not engine.getTenantAlloc(tenant_id, hosts, l1UpPorts, l2UpPorts):
         portNames = []
         for i in range(0, l2UpPorts.size()):
             iNp = l2UpPorts[i]
             allocSwIdx = iNp[0]
             pn = iNp[1]
             for j in range(0, W[1]):
                 swIdx = allocSwIdx * W[1] + j
                 key = [2, swIdx, pn].__str__()
                 name = upPortByLvlPort[key]
                 if name is None:
                     portNames.append("UNDEF")
                 else:
                     portNames.append(name)
         return portNames
     else:
         abort(
             410,
             message="Fail to get L2 ports for tenant {}".format(tenant_id))
 def get(self, tenant_id):
     global engine
     global dnPortByLvlPort
     global M
     abort_if_tenant_doesnt_exist(tenant_id)
     hosts = laas.VecInt()
     l1UpPorts = laas.VecPairInt()
     l2UpPorts = laas.VecPairInt()
     if not engine.getTenantAlloc(tenant_id, hosts, l1UpPorts, l2UpPorts):
         portNames = []
         for i in range(0, hosts.size()):
             j = hosts[i]
             k = j / M[0]
             p = j % M[0]
             key = [1, k, p].__str__()
             name = dnPortByLvlPort[key]
             if name is None:
                 portNames.append("UNDEF")
             else:
                 portNames.append(name)
         return portNames
     else:
         abort(
             408,
             message="Fail to get L0 ports for tenant {}".format(tenant_id))
def addOpenStackTenent(id):
    global engine
    global osCmdId

    directory = 'OSCfg'
    if not os.path.exists(directory):
        os.makedirs(directory)

    osCmdId = osCmdId + 1
    cmdName = "cmd-%d.sh" % osCmdId
    logName = "cmd-%d.log" % osCmdId
    fileName = os.path.join(directory, cmdName)
    F = open(fileName, 'w')
    if F is None:
        raise LaaSFailure("Cannot write OS cmd file: %s" % fileName)
    logFile = os.path.join(directory, logName)

    F.write("#!/bin/bash\n")
    F.write("#\n# Adding tenant %d to OpenStack\n#\n" % id)
    aggrName = "laas-aggr-%d" % id
    tenantName = "laas-tenant-%d" % id
    F.write("echo Adding tenant %d to OpenStack > %s\n" % (id, logFile))
    F.write("keystone tenant-create --name %s --description \"LaaS Tenant %d\" >> %s\n" % \
            (tenantName, id, logFile))
    F.write("tenantId=`keystone tenant-get %s | awk '/ id /{print $4}'` >> %s\n" % \
            (tenantName, logFile))
    F.write("nova aggregate-create %s >> %s\n" % (aggrName, logFile))
    # HACK for now we assume no need for key
    F.write(
        "nova aggregate-set-metadata %s filter_tenant_id=$tenantId >> %s\n" %
        (aggrName, logFile))

    hosts = laas.VecInt()
    l1UpPorts = laas.VecPairInt()
    l2UpPorts = laas.VecPairInt()
    if engine.getTenantAlloc(id, hosts, l1UpPorts, l2UpPorts):
        raise LaaSFailure("Cannot get tenant %d information" % id)

    for i in range(0, hosts.size()):
        j = hosts[i]
        key = [0, j, 0].__str__()
        nameNPort = upPortByLvlPort[key]  # = {'sName': sName, 'pNum': pNum}
        if nameNPort is not None:
            F.write("nova aggregate-add-host %s %s >> %s\n" %
                    (aggrName, nameNPort['sName'], logName))
    F.close()
    if callOpenStack:
        safeExecute(fileName)
    return 0
def delOpenStackTenant(id):
    global engine
    global osCmdId
    global callOpenStack

    hosts = laas.VecInt()
    l1UpPorts = laas.VecPairInt()
    l2UpPorts = laas.VecPairInt()
    if engine.getTenantAlloc(id, hosts, l1UpPorts, l2UpPorts):
        raise LaaSFailure("Cannot get tenant %d information" % id)

    directory = 'OSCfg'
    if not os.path.exists(directory):
        os.makedirs(directory)

    osCmdId = osCmdId + 1
    cmdName = "cmd-%d.sh" % osCmdId
    logName = "cmd-%d.log" % osCmdId
    fileName = os.path.join(directory, cmdName)
    F = open(fileName, 'w')
    if F is None:
        raise LaaSFailure("Cannot write OS cmd file: %s" % fileName)
    logFile = os.path.join(directory, logName)

    F.write("#!/bin/bash\n")
    F.write("#\n# Removing tenant %d from OpenStack\n#\n" % id)
    aggrName = "laas-aggr-%d" % id
    tenantName = "laas-tenant-%d" % id

    for i in range(0, hosts.size()):
        j = hosts[i]
        key = [0, j, 0].__str__()
        nameNPort = upPortByLvlPort[key]  # = {'sName': sName, 'pNum': pNum}
        if nameNPort is not None:
            F.write("nova aggregate-remove-host %s %s >> %s\n" %
                    (aggrName, nameNPort['sName'], logName))
    F.write("nova aggregate-delete %s >> %s\n" % (aggrName, logFile))
    F.write("keystone tenant-delete %s >> %s\n" % (tenantName, logFile))
    F.close()
    if callOpenStack:
        safeExecute(fileName)
    return 0
 def get(self, tenant_id):
     global engine
     global nameByLevelIdx
     abort_if_tenant_doesnt_exist(tenant_id)
     hosts = laas.VecInt()
     l1UpPorts = laas.VecPairInt()
     l2UpPorts = laas.VecPairInt()
     if not engine.getTenantAlloc(tenant_id, hosts, l1UpPorts, l2UpPorts):
         hostNames = []
         for i in range(0, hosts.size()):
             j = hosts[i]
             key = [0, j].__str__()
             name = nameByLevelIdx[key]
             if name is None:
                 hostNames.append("UNDEF")
             else:
                 hostNames.append(name)
         return hostNames
     else:
         abort(407,
               message="Fail to get hosts for tenant {}".format(tenant_id))
 def get(self, tenant_id):
     global engine
     global upPortByLvlPort
     abort_if_tenant_doesnt_exist(tenant_id)
     hosts = laas.VecInt()
     l1UpPorts = laas.VecPairInt()
     l2UpPorts = laas.VecPairInt()
     if not engine.getTenantAlloc(tenant_id, hosts, l1UpPorts, l2UpPorts):
         portNames = []
         for i in range(0, l1UpPorts.size()):
             iNp = l1UpPorts[i]
             key = [1, iNp[0], iNp[1]].__str__()
             name = upPortByLvlPort[key]
             if name is None:
                 portNames.append("UNDEF")
             else:
                 portNames.append(name)
         return portNames
     else:
         abort(
             409,
             message="Fail to get L1 ports for tenant {}".format(tenant_id))
 def post(self):
     global W
     args = parser.parse_args()
     tenant_id = args['id']
     abort_if_tenant_exist(tenant_id)
     g = laas.VecInt(1)
     g[0] = args['n']
     if not engine.allocTenant(tenant_id, g):
         hosts = laas.VecInt()
         l1UpPorts = laas.VecPairInt()
         l2UpPorts = laas.VecPairInt()
         engine.getTenantAlloc(tenant_id, hosts, l1UpPorts, l2UpPorts)
         TENANTS[tenant_id] = {
             'N': args['n'],
             'hosts': hosts.size(),
             'l1Ports': l1UpPorts.size(),
             'l2Ports': W[1] * l2UpPorts.size()
         }
         updateSDNConf()
         addOpenStackTenent(tenant_id)
         return TENANTS[tenant_id], 201
     else:
         abort(406, message="Fail to allocate tenant {}".format(tenant_id))
Exemple #8
0
    def run(self):
        # we need to loop until no pending jobs or fail to place
        # we have two sorted containers:
        # pending - by arrival time
        # running - by finish time (this is a heapq by time to list of jobs)
        #
        # Whenever we advance time t we need to first clear all ended jobs
        # then we need to try placing all pending jobs arriving before t
        #
        # We advance time when either:
        # 1. Some pending job can't be placed: advance to next ending job
        # 2. No pending jobs at the time: advance to next pending job time
        #
        t0 = time()
        t = 0
        grps = laas.VecInt(1)
        while len(self.pending):
            if verbose:
                print "-I- At t=%d" % t

            # first clean all running jobs
            endT = self.running.minT()
            while endT != None and endT <= t:
                endT, endingJobs = self.running.pop()
                for j in endingJobs:
                    # note the inverse in semantics...
                    if not self.engine.deallocTenant(j.id):
                        raise SimFailure(self.engine.getLastErrorMsg())
                    else:
                        if verbose:
                            print "-V- Remove %s" % j
                endT = self.running.minT()

            # now try placement of all jobs that already arrived
            j = self.pending[0]
            placeFailed = False
            while not placeFailed and j.arrival <= t:
                grps[0] = j.N
                # the engine returns 0 for success!
                placeFailed = self.engine.allocTenant(j.id, grps, j.isolation)
                if placeFailed:
                    if not self.running.len():
                        err = "No job running but fail to place job %s" % j
                        raise SimFailure(err)
                    else:
                        if self.firstJobWaiting < 0 and t > 0:
                            self.firstJobWaiting = t
                        if verbose:
                            print "-V- Fail   %s" % j
                else:
                    # was placed:
                    hosts = laas.VecInt()
                    l1Up = laas.VecPairInt()
                    l2Up = laas.VecPairInt()
                    alloc = self.engine.getTenantAlloc(j.id, hosts, l1Up, l2Up)
                    j.actNumHosts = hosts.size()
                    j.numL1UpLinks = l1Up.size()
                    j.numL2UpLinks = l2Up.size() * self.W[1]
                    if verbose:
                        print "-V- Place  %s %d hosts %d L1 %d L2" % \
                            (j, j.actNumHosts, j.numL1UpLinks, j.numL2UpLinks)
                    self.running.insert(t + j.length, j)
                    j.start = t
                    self.lastJobPlacement = t
                    self.pending.pop(0)
                    if len(self.pending):
                        j = self.pending[0]
                    else:
                        placeFailed = True

            # we can reach here on two cases either no more ready jobs or
            # failure to place
            if placeFailed:
                # advance to next ending job time
                t = self.running.minT()
            else:
                t = self.pending[0].arrival
        t1 = time()
        self.runTime = t1 - t0
        return 0
def updateSDNConf():
    global engine
    global upPortByLvlPort
    # make sure dest dir exists
    directory = 'SDNCfg'
    if not os.path.exists(directory):
        os.makedirs(directory)

    # clear pervious settings
    deleteDirContent(directory)

    # now lets populate it again
    topoFileName = os.path.join(directory, 'topologies.conf')
    T = open(topoFileName, 'w')
    if T is None:
        raise LaaSFailure("Cannot write topologies file: %s" % topoFileName)

    groupsFileName = os.path.join(directory, 'groups.conf')
    G = open(groupsFileName, 'w')
    if G is None:
        raise LaaSFailure("Cannot write groups file: %s" % groupsFileName)

    chainsFileName = os.path.join(directory, 'chains.conf')
    C = open(chainsFileName, 'w')
    if C is None:
        raise LaaSFailure("Cannot write chains file: %s" % chainsFileName)

    link = 1
    topo = 0
    C.write(
        "unicast-step\nid: %d\ntopology: %d\nengine: updn\npath-bit: 0\nend-unicast-step\n\n"
        % (link, topo))

    # now go over all tenants
    tenants = laas.SetInt()
    engine.getTenants(tenants)
    for id in tenants:
        link = link + 1
        # topologies
        T.write("topology\n")
        T.write("id: %d\n" % id)
        T.write("sw-grp: T%d-switches\n" % id)
        T.write("hca-grp: T%d-hcas\n" % id)
        T.write("end-topology\n\n")

        # PQFT (?)
        pqftOpts = "T%d.opensm.conf" % id
        pqftOptsFileName = os.path.join(directory, pqftOpts)
        O = open(pqftOptsFileName, 'w')
        if C is None:
            raise LaaSFailure("Cannot write options file: %s" %
                              pqftOptsFileName)
        pqftStr = getPQFTStr(id)
        if pqftStr is not None:
            O.write("pqft_structure %s\n" % pqftStr)
        O.close()

        # Chain link
        C.write("unicast-step\n")
        C.write("id: %d\n" % link)
        C.write("topology: %d\n" % id)
        if pqftStr is not None:
            C.write("engine: pqft\n")
        else:
            C.write("engine: updn\n")
        C.write("config: %s\n" % pqftOptsFileName)
        C.write("path-bit: 0\n")
        C.write("end-unicast-step\n\n")

        hosts = laas.VecInt()
        l1UpPorts = laas.VecPairInt()
        l2UpPorts = laas.VecPairInt()
        if engine.getTenantAlloc(id, hosts, l1UpPorts, l2UpPorts):
            raise LaaSFailure("Cannot get tenant %d information" % id)

        # PORT GROUPS
        G.write("port-group\n")
        G.write("name: T%d-hcas\n" % id)
        G.write("obj_list: ")
        for i in range(0, hosts.size()):
            j = hosts[i]
            key = [0, j, 0].__str__()
            nameNPort = upPortByLvlPort[
                key]  # = {'sName': sName, 'pNum': pNum}
            if nameNPort is not None:
                G.write("\n   name=%s/U1:P%d" %
                        (nameNPort['sName'], nameNPort['pNum']))
        G.write(";\n")
        G.write("end-port-group\n\n")

        # collapse switch used ports to masks
        SW_PORTS = {}
        for i in range(0, l1UpPorts.size()):
            iNp = l1UpPorts[i]
            key = [1, iNp[0], iNp[1]].__str__()
            nameNPort = upPortByLvlPort[key]
            if nameNPort is not None:
                name = nameNPort['sName']
                pn = nameNPort['pNum']
                mask = 1 << pn
                if name not in SW_PORTS:
                    SW_PORTS[name] = mask
                else:
                    SW_PORTS[name] = SW_PORTS[name] | mask
        for i in range(0, l2UpPorts.size()):
            iNp = l1UpPorts[i]
            key = [1, iNp[0], iNp[1]].__str__()
            nameNPort = upPortByLvlPort[key]
            if nameNPort is not None:
                name = nameNPort['sName']
                pn = nameNPort['pNum']
                mask = 1 << pn
                if name not in SW_PORTS:
                    SW_PORTS[name] = mask
                else:
                    SW_PORTS[name] = SW_PORTS[name] | mask

        # now write the group
        G.write("port-group\n")
        G.write("name: T%d-switches\n" % id)
        if len(SW_PORTS) > 0:
            G.write("obj_list: ")
            for name in SW_PORTS:
                mask = SW_PORTS[name]
                G.write("\n   name=%s/U1 pmask=0x%x" % (name, mask))
            G.write(";\n")
        G.write("end-port-group\n\n")

    T.close()
    C.close()
    G.close()
    return 0