Commit 9b5eb740 authored by David Johnson's avatar David Johnson

The dynamic version of the openstack geni-lib script.

This has support for generating arguments to AddNodes() and
DeleteNodes(), which means re-reading the current manifest to know what
the original parameters were, so that the appropriate args (like which
image, which lans to join, etc) go to AddNodes().
parent 31e3c47f
#!/usr/bin/env python #!/usr/bin/env python
##
## This file is a dynamic version of the Cloudlab OpenStack profile. Its core
## class, OSDynSliceManagerHelper, implements the DynSliceManagerHelper interface,
## which the DynSliceManager uses to create and control a dynamic slice where
## nodes are added and deleted on demand.
##
## This script is intended to be both a standalone script, and one that is
## imported by a manager. In the latter case, the manager looks for several
## key variables to learn about a Helper class or object. The variables it
## looks for are DYNSLICE_CLASS and DYNSLICE_HELPER. The former is a class
## it will instantiate; the latter is a an object it will just invoke operations
## on. Finally, near the very end, it will also handle the case where it runs
## in the Cloudlab Portal to generate an rspec.
##
import protogeniclientlib
import geni.portal as portal import geni.portal as portal
import geni.rspec.pg as RSpec import geni.rspec.pg as RSpec
import geni.rspec.igext as IG import geni.rspec.igext as IG
...@@ -7,17 +23,81 @@ from lxml import etree as ET ...@@ -7,17 +23,81 @@ from lxml import etree as ET
import crypt import crypt
import random import random
import os import os
import argparse
from argparse import Namespace
generator = None helper = None
# Don't want this as a param yet # Don't want this as a param yet
TBURL = "http://www.emulab.net/downloads/openstack-setup-v17-johnsond.tar.gz" TBURL = "http://www.emulab.net/downloads/openstack-setup-v17-johnsond.tar.gz"
TBCMD = "sudo mkdir -p /root/setup && sudo -H /tmp/setup/setup-driver.sh 2>&1 | sudo tee /root/setup/setup-driver.log" TBCMD = "sudo mkdir -p /root/setup && sudo -H /tmp/setup/setup-driver.sh 2>&1 | sudo tee /root/setup/setup-driver.log"
TBCMD_DYNNODE = "sudo mkdir -p /root/setup && sudo -H /tmp/setup/setup-driver-add-dyn-node.sh 2>&1 | sudo tee /root/setup/setup-driver.log" TBCMD_ADDNODE = "sudo mkdir -p /root/setup && sudo -H /tmp/setup/setup-driver-add-dyn-node.sh 2>&1 | sudo tee /root/setup/setup-driver.log"
TBCMD_DELNODE = "sudo -H /tmp/setup/setup-controller-delete-nodes.sh %s 2>&1 | sudo tee -a /root/setup/setup-delete-nodes.log"
TBPATH = "/tmp" TBPATH = "/tmp"
class OSPGenerator(object): #
def __init__(self): # This is a simple class that allows the geni-lib Portal context object to
# receive params from a dict. By default, it doesn't know how to do that...
#
class OSContext(portal.Context):
def __init__(self,):
super(OSContext,self).__init__()
pass
def bindParametersDict(self,paramValues):
namespace = Namespace()
for name in self._parameterOrder:
opts = self._parameters[name]
val = paramValues.get(name, opts['defaultValue'])
try:
if type(opts['defaultValue']) == bool:
if val == "False" or val == "false":
val = False
elif val == "True" or val == "true":
val = True
else:
val = portal.ParameterType.argparsemap[opts['type']](val)
pass
pass
else:
val = portal.ParameterType.argparsemap[opts['type']](val)
pass
pass
except:
print "ERROR: Could not coerce '%s' to '%s'" \
% (val, opts['type'])
continue
if opts['legalValues'] and \
val not in portal.Context._legalList(opts['legalValues']):
print "ERROR: Illegal value '%s'" % (val,),[name]
else:
setattr(namespace, name, val)
pass
pass
# This might not return.
self.verifyParameters()
self._bindingDone = True
return namespace
def getParameterNames(self):
return self._parameters.keys()
def getParameterUpperCaseNameMap(self):
retval = {}
for pname in self._parameters.keys():
retval[pname.upper()] = pname
pass
return retval
pass
class OSDynSliceManagerHelper(protogeniclientlib.DynSliceManagerHelper,
protogeniclientlib.DynSliceClientEndpoint):
def __init__(self,manager=None,server=None,debug=None):
protogeniclientlib.DynSliceManagerHelper.__init__(self,server=server,
manager=manager)
protogeniclientlib.DynSliceClientEndpoint.__init__(self,debug=debug)
# #
# Create our in-memory model of the RSpec -- the resources we're # Create our in-memory model of the RSpec -- the resources we're
# going to request in our experiment, and their configuration. # going to request in our experiment, and their configuration.
...@@ -36,15 +116,17 @@ class OSPGenerator(object): ...@@ -36,15 +116,17 @@ class OSPGenerator(object):
self.flatlans = {} self.flatlans = {}
self.vlans = {} self.vlans = {}
self.alllans = [] self.alllans = []
self.alllannames = []
self.computeNodeList = "" self.computeNodeList = ""
self.computeNodeIndex = 0 self.computeNodeIndex = 0
self.mgmtlan = None self.mgmtlan = None
self.mgmtlanname = None
self.generateIPs = False self.generateIPs = False
# #
# This geni-lib script is designed to run in the CloudLab Portal. # This geni-lib script is designed to run in the CloudLab Portal.
# #
self.pc = portal.Context() self.pc = OSContext()
# #
# Define *many* parameters; see the help docs in geni-lib to # Define *many* parameters; see the help docs in geni-lib to
...@@ -150,7 +232,7 @@ class OSPGenerator(object): ...@@ -150,7 +232,7 @@ class OSPGenerator(object):
pass pass
# Assume a /16 for every network # Assume a /16 for every network
def get_next_ipaddr(self,lan): def _getNextIPAddr(self,lan):
ipaddr = self.ipdb[lan]['base'] ipaddr = self.ipdb[lan]['base']
backpart = '' backpart = ''
...@@ -176,15 +258,10 @@ class OSPGenerator(object): ...@@ -176,15 +258,10 @@ class OSPGenerator(object):
return ipaddr + backpart return ipaddr + backpart
def get_netmask(self,lan): def _getNetmask(self,lan):
return self.ipdb[lan]['netmask'] return self.ipdb[lan]['netmask']
def generate(self): def _verifyParameters(self):
#
# Get any input parameter values that will override our defaults.
#
self.params = self.pc.bindParameters()
# #
# Verify our parameters and throw errors. # Verify our parameters and throw errors.
# #
...@@ -311,6 +388,70 @@ class OSPGenerator(object): ...@@ -311,6 +388,70 @@ class OSPGenerator(object):
# Give the library a chance to return nice JSON-formatted # Give the library a chance to return nice JSON-formatted
# exception(s) and/or warnings; this might sys.exit(). # exception(s) and/or warnings; this might sys.exit().
self.pc.verifyParameters() self.pc.verifyParameters()
pass
def _initStateFromParameters(self):
#
# Ok, get down to business -- we are going to create CloudLab
# LANs to be used as (openstack networks), based on user's
# parameters. We might also generate IP addresses for the
# nodes, so set up some quick, brutally stupid IP address
# generation for each LAN.
#
if self.params.managementLanType == 'flat':
self.ipdb['mgmt-lan'] = { 'base':'192.168','netmask':'255.255.0.0','values':[-1,-1,0,0] }
pass
for i in range(1,self.params.flatDataLanCount + 1):
dlanstr = "%s-%d" % ('flat-lan',i)
self.ipdb[dlanstr] = { 'base' : '10.%d' % (i + self.dataOffset + self.ipSubnetsUsed,),'netmask' : '255.255.0.0',
'values' : [-1,-1,10,0] }
self.flatlanstrs[i] = dlanstr
self.ipSubnetsUsed += 1
self.alllannames.append(dlanstr)
pass
for i in range(1,self.params.vlanDataLanCount + 1):
dlanstr = "%s-%d" % ('vlan-lan-',i)
self.ipdb[dlanstr] = { 'base' : '10.%d' % (i + self.dataOffset + self.ipSubnetsUsed,),'netmask' : '255.255.0.0',
'values' : [-1,-1,10,0] }
self.vlanstrs[i] = dlanstr
self.ipSubnetsUsed += 1
self.alllannames.append(dlanstr)
pass
for i in range(1,self.params.vxlanDataLanCount + 1):
dlanstr = "%s-%d" % ('vxlan-lan',i)
self.ipdb[dlanstr] = { 'base' : '10.%d' % (i + self.dataOffset + self.ipSubnetsUsed,),'netmask' : '255.255.0.0',
'values' : [-1,-1,10,0] }
self.ipSubnetsUsed += 1
pass
if self.params.release == "juno":
self.image_os = 'UBUNTU14-10-64'
else:
self.image_os = 'UBUNTU15-04-64'
pass
if self.params.fromScratch:
self.image_tag_cn = 'STD'
self.image_tag_nm = 'STD'
self.image_tag_cp = 'STD'
else:
self.image_tag_cn = 'OSCN'
self.image_tag_nm = 'OSNM'
self.image_tag_cp = 'OSCP'
pass
self.computeNodeDiskImage = "urn:publicid:IDN+utah.cloudlab.us+image+emulab-ops//%s-%s" % (self.image_os,self.image_tag_cp)
pass
def generateRspec(self):
# Get any input parameter values that will override our defaults.
self.params = self.pc.bindParameters()
# Verify our parameters.
self._verifyParameters()
# Setup local state needed to build the rspec or add nodes later.
self._initStateFromParameters()
detailedParamAutoDocs = '' detailedParamAutoDocs = ''
for param in self.pc._parameterOrder: for param in self.pc._parameterOrder:
...@@ -364,37 +505,6 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -364,37 +505,6 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
tour.Instructions(IG.Tour.MARKDOWN,tourInstructions) tour.Instructions(IG.Tour.MARKDOWN,tourInstructions)
self.rspec.addTour(tour) self.rspec.addTour(tour)
#
# Ok, get down to business -- we are going to create CloudLab
# LANs to be used as (openstack networks), based on user's
# parameters. We might also generate IP addresses for the
# nodes, so set up some quick, brutally stupid IP address
# generation for each LAN.
#
if self.params.managementLanType == 'flat':
self.ipdb['mgmt-lan'] = { 'base':'192.168','netmask':'255.255.0.0','values':[-1,-10,0,0] }
pass
for i in range(1,self.params.flatDataLanCount + 1):
dlanstr = "%s-%d" % ('flat-lan',i)
self.ipdb[dlanstr] = { 'base' : '10.%d' % (i + self.dataOffset + self.ipSubnetsUsed,),'netmask' : '255.255.0.0',
'values' : [-1,-1,10,0] }
self.flatlanstrs[i] = dlanstr
self.ipSubnetsUsed += 1
pass
for i in range(1,self.params.vlanDataLanCount + 1):
dlanstr = "%s-%d" % ('vlan-lan-',i)
self.ipdb[dlanstr] = { 'base' : '10.%d' % (i + self.dataOffset + self.ipSubnetsUsed,),'netmask' : '255.255.0.0',
'values' : [-1,-1,10,0] }
self.vlanstrs[i] = dlanstr
self.ipSubnetsUsed += 1
pass
for i in range(1,self.params.vxlanDataLanCount + 1):
dlanstr = "%s-%d" % ('vxlan-lan',i)
self.ipdb[dlanstr] = { 'base' : '10.%d' % (i + self.dataOffset + self.ipSubnetsUsed,),'netmask' : '255.255.0.0',
'values' : [-1,-1,10,0] }
self.ipSubnetsUsed += 1
pass
# #
# Ok, actually build the data LANs now... # Ok, actually build the data LANs now...
# #
...@@ -410,6 +520,9 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -410,6 +520,9 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
pass pass
self.flatlans[i] = datalan self.flatlans[i] = datalan
self.alllans.append(datalan) self.alllans.append(datalan)
if not datalan.client_id in self.alllannames:
self.alllannames.append(datalan.client_id)
pass
pass pass
for i in range(1,self.params.vlanDataLanCount + 1): for i in range(1,self.params.vlanDataLanCount + 1):
datalan = RSpec.LAN("vlan-lan-%d" % (i,)) datalan = RSpec.LAN("vlan-lan-%d" % (i,))
...@@ -420,6 +533,9 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -420,6 +533,9 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
datalan.type = "vlan" datalan.type = "vlan"
self.vlans[i] = datalan self.vlans[i] = datalan
self.alllans.append(datalan) self.alllans.append(datalan)
if not datalan.client_id in self.alllannames:
self.alllannames.append(datalan.client_id)
pass
pass pass
# #
...@@ -428,6 +544,7 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -428,6 +544,7 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
# Cloudlab public control network. # Cloudlab public control network.
# #
if self.params.managementLanType == 'flat': if self.params.managementLanType == 'flat':
self.mgmtlanname = 'mgmt-lan'
self.mgmtlan = RSpec.LAN('mgmt-lan') self.mgmtlan = RSpec.LAN('mgmt-lan')
if self.params.multiplexFlatLans: if self.params.multiplexFlatLans:
self.mgmtlan.link_multiplexing = True self.mgmtlan.link_multiplexing = True
...@@ -438,28 +555,17 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -438,28 +555,17 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
pass pass
else: else:
self.mgmtlan = None self.mgmtlan = None
self.mgmtlanname = None
pass pass
# #
# Construct the disk image URNs we're going to set the various # Construct the disk image URNs we're going to set the various
# nodes to load. # nodes to load.
# #
if self.params.release == "juno":
image_os = 'UBUNTU14-10-64'
else:
image_os = 'UBUNTU15-04-64'
pass
if self.params.fromScratch:
image_tag_cn = 'STD'
image_tag_nm = 'STD'
image_tag_cp = 'STD'
else:
image_tag_cn = 'OSCN'
image_tag_nm = 'OSNM'
image_tag_cp = 'OSCP'
pass
self.ctl_disk_image = "urn:publicid:IDN+utah.cloudlab.us+image+emulab-ops//%s-%s" % (image_os,image_tag_cn) self.ctl_disk_image = \
"urn:publicid:IDN+utah.cloudlab.us+image+emulab-ops//%s-%s" \
% (self.image_os,self.image_tag_cn)
# #
# Add the controller node. # Add the controller node.
...@@ -472,8 +578,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -472,8 +578,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
iface = controller.addInterface("if%d" % (i,)) iface = controller.addInterface("if%d" % (i,))
datalan.addInterface(iface) datalan.addInterface(iface)
if self.generateIPs: if self.generateIPs:
addr = RSpec.IPv4Address(self.get_next_ipaddr(datalan.client_id), addr = RSpec.IPv4Address(self._getNextIPAddr(datalan.client_id),
self.get_netmask(datalan.client_id)) self._getNetmask(datalan.client_id))
iface.addAddress(addr) iface.addAddress(addr)
pass pass
i += 1 i += 1
...@@ -482,8 +588,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -482,8 +588,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
iface = controller.addInterface("ifM") iface = controller.addInterface("ifM")
self.mgmtlan.addInterface(iface) self.mgmtlan.addInterface(iface)
if self.generateIPs: if self.generateIPs:
addr = RSpec.IPv4Address(self.get_next_ipaddr(self.mgmtlan.client_id), addr = RSpec.IPv4Address(self._getNextIPAddr(self.mgmtlan.client_id),
self.get_netmask(self.mgmtlan.client_id)) self._getNetmask(self.mgmtlan.client_id))
iface.addAddress() iface.addAddress()
pass pass
pass pass
...@@ -496,14 +602,14 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -496,14 +602,14 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
# #
networkManager = RSpec.RawPC(self.params.networkManagerHost) networkManager = RSpec.RawPC(self.params.networkManagerHost)
networkManager.Site("1") networkManager.Site("1")
networkManager.disk_image = "urn:publicid:IDN+utah.cloudlab.us+image+emulab-ops//%s-%s" % (image_os,image_tag_nm) networkManager.disk_image = "urn:publicid:IDN+utah.cloudlab.us+image+emulab-ops//%s-%s" % (self.image_os,self.image_tag_nm)
i = 0 i = 0
for datalan in self.alllans: for datalan in self.alllans:
iface = networkManager.addInterface("if%d" % (i,)) iface = networkManager.addInterface("if%d" % (i,))
datalan.addInterface(iface) datalan.addInterface(iface)
if self.generateIPs: if self.generateIPs:
addr = RSpec.IPv4Address(self.get_next_ipaddr(datalan.client_id), addr = RSpec.IPv4Address(self._getNextIPAddr(datalan.client_id),
self.get_netmask(datalan.client_id)) self._getNetmask(datalan.client_id))
iface.addAddress(addr) iface.addAddress(addr)
pass pass
i += 1 i += 1
...@@ -512,8 +618,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -512,8 +618,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
iface = networkManager.addInterface("ifM") iface = networkManager.addInterface("ifM")
self.mgmtlan.addInterface(iface) self.mgmtlan.addInterface(iface)
if self.generateIPs: if self.generateIPs:
addr = RSpec.IPv4Address(self.get_next_ipaddr(self.mgmtlan.client_id), addr = RSpec.IPv4Address(self._getNextIPAddr(self.mgmtlan.client_id),
self.get_netmask(self.mgmtlan.client_id)) self._getNetmask(self.mgmtlan.client_id))
iface.addAddress(addr) iface.addAddress(addr)
pass pass
pass pass
...@@ -543,8 +649,6 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -543,8 +649,6 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
computeNodeNamesBySite[2].append(cpname) computeNodeNamesBySite[2].append(cpname)
pass pass
self.computeNodeDiskImage = "urn:publicid:IDN+utah.cloudlab.us+image+emulab-ops//%s-%s" % (image_os,image_tag_cp)
for (siteNumber,cpnameList) in computeNodeNamesBySite.iteritems(): for (siteNumber,cpnameList) in computeNodeNamesBySite.iteritems():
for cpname in cpnameList: for cpname in cpnameList:
cpnode = RSpec.RawPC(cpname) cpnode = RSpec.RawPC(cpname)
...@@ -555,8 +659,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -555,8 +659,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
iface = cpnode.addInterface("if%d" % (i,)) iface = cpnode.addInterface("if%d" % (i,))
datalan.addInterface(iface) datalan.addInterface(iface)
if self.generateIPs: if self.generateIPs:
addr = RSpec.IPv4Address(self.get_next_ipaddr(datalan.client_id), addr = RSpec.IPv4Address(self._getNextIPAddr(datalan.client_id),
self.get_netmask(datalan.client_id)) self._getNetmask(datalan.client_id))
iface.addAddress(addr) iface.addAddress(addr)
pass pass
i += 1 i += 1
...@@ -565,8 +669,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -565,8 +669,8 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
iface = cpnode.addInterface("ifM") iface = cpnode.addInterface("ifM")
self.mgmtlan.addInterface(iface) self.mgmtlan.addInterface(iface)
if self.generateIPs: if self.generateIPs:
iface.addAddress(RSpec.IPv4Address(get_next_ipaddr(self.mgmtlan.client_id), iface.addAddress(RSpec.IPv4Address(_getNextIPAddr(self.mgmtlan.client_id),
get_netmask(self.mgmtlan.client_id))) _getNetmask(self.mgmtlan.client_id)))
pass pass
pass pass
cpnode.addService(RSpec.Install(url=TBURL, path=TBPATH)) cpnode.addService(RSpec.Install(url=TBURL, path=TBPATH))
...@@ -588,38 +692,117 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se ...@@ -588,38 +692,117 @@ The profile's setup scripts are automatically installed on each node in `/tmp/se
apool = IG.AddressPool("nm",self.params.publicIPCount) apool = IG.AddressPool("nm",self.params.publicIPCount)
self.rspec.addResource(apool) self.rspec.addResource(apool)
parameters = OSPParameters(self) parameters = OSParameters(self)
self.rspec.addResource(parameters) self.rspec.addResource(parameters)
###if not self.params.adminPass or len(self.params.adminPass) == 0: ###if not self.params.adminPass or len(self.params.adminPass) == 0:
if True: if True:
stuffToEncrypt = OSPEmulabEncrypt(self) stuffToEncrypt = OSEmulabEncrypt(self)
self.rspec.addResource(stuffToEncrypt) self.rspec.addResource(stuffToEncrypt)
pass pass
return self.rspec.toXMLString(True) return self.rspec.toXMLString(True)
def setComputeNodeIndex(self,idx): def _setStateFromManifest(self,wrappedPGManifest):
self.computeNodeIndex = idx if not wrappedPGManifest:
return None
# Grab parameters from the manifest
paramValues = {}
ns = { 'ns0':"http://www.protogeni.net/resources/rspec/ext/johnsond/1" }
xl = wrappedPGManifest.root.xpath('ns0:profile_parameters/ns0:parameter',
namespaces=ns)
upperParamNames = self.pc.getParameterUpperCaseNameMap()
paramNames = self.pc.getParameterNames()
for elem in xl:
[k,v] = elem.text.split('=')
# Maybe strip string delimiters
if (v[0] == '"' and v[-1] == '"') or (v[0] == "'" and v[-1] == "'"):
v = v[1:-1]
pass
if upperParamNames.has_key(k):
paramValues[upperParamNames[k]] = v
pass pass
pass
# Get any input parameter values that will override our defaults.
self.params = self.pc.bindParametersDict(paramValues)
# Verify our parameters.
self._verifyParameters()
def addNewNodes(self,count=1): # Setup local state needed to build the rspec or add nodes later.
self._initStateFromParameters()
# Grab the netmasks and ip addresses we have already assigned.
# We just start assigning at the current highest one.
for lan in self.alllannames:
ipinfo = wrappedPGManifest.getLinkAddressInfo(lan)
if ipinfo.has_key('netmasks'):
self.ipdb[lan]['netmask'] = ipinfo['netmasks'][0]
if ipinfo.has_key('max_ip'):
[o0,o1,o2,o3] = ipinfo['max_ip'].split('.')
self.ipdb[lan]['values'][2] = int(o2)
self.ipdb[lan]['values'][3] = int(o3)
pass
pass
if self.mgmtlanname:
lan = self.mgmtlanname
ipinfo = wrappedPGManifest.getLinkAddressInfo(lan)
if ipinfo.has_key('netmasks'):
self.ipdb[lan]['netmask'] = ipinfo['netmasks'][0]
if ipinfo.has_key('max_ip'):
[o0,o1,o2,o3] = ipinfo['max_ip'].split('.')
self.ipdb[lan]['values'][2] = int(o2)
self.ipdb[lan]['values'][3] = int(o3)
pass
pass
# Find our max compute node ID.
for node in wrappedPGManifest.nodes:
cid = node.name
if cid.startswith(self.params.computeHostBaseName):
cid_num = int(cid[(len(self.params.computeHostBaseName)+1):])
if cid_num > self.computeNodeIndex:
self.computeNodeIndex = cid_num
pass
pass
pass
pass
def generateAddNodesArgs(self,count=1):
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
# If we don't have params yet, try to get them from our manifest
if not self.params:
wrappedPGManifest = self.server.get_wrapped_manifest()
self._setStateFromManifest(wrappedPGManifest)
pass
# Build the arguments for AddNodes().
retval = {} retval = {}
for i in range(self.computeNodeIndex + 1,self.computeNodeIndex + count + 1): for i in range(self.computeNodeIndex + 1,self.computeNodeIndex + count + 1):
nn = "%s-%d" % (self.params.computeHostBaseName,i) nn = "%s-%d" % (self.params.computeHostBaseName,i)
lans = [] lans = []
for datalan in self.alllans: for datalan in self.alllannames:
lan = { 'name' : datalan.client_id } lan = { 'name' : datalan }