-#!/usr/bin/env python
# -*- coding: utf-8 -*-
from constants import TESTBED_ID, TESTBED_VERSION
import logging
import metadata
import weakref
+import util as plutil
class TempKeyError(Exception):
pass
self._just_provisioned = set()
self._load_blacklist()
-
+
+ self._slice_id = None
+ self._plcapi = None
+ self._sliceapi = None
+ self._vsys_vnet = None
+
self._logger = logging.getLogger('nepi.testbeds.planetlab')
self.recovering = False
return self._home_directory
@property
- def plapi(self):
- if not hasattr(self, '_plapi'):
+ def plcapi(self):
+ if not self._plcapi:
import plcapi
-
- if self.authUser:
- self._plapi = plcapi.PLCAPI(
- username = self.authUser,
- password = self.authString,
- hostname = self.plcHost,
- urlpattern = self.plcUrl
+ self._plcapi = plcapi.plcapi(
+ self.authUser,
+ self.authString,
+ self.plcHost,
+ self.plcUrl
)
+ return self._plcapi
+
+ @property
+ def sliceapi(self):
+ if not self._sliceapi:
+ if not self.sfa:
+ self._sliceapi = self.plcapi
else:
- # anonymous access - may not be enough for much
- self._plapi = plcapi.PLCAPI()
- return self._plapi
+ from nepi.util import sfiapi
+ self._sliceapi = sfiapi.sfiapi(self.slice_id)
+ return self._sliceapi
@property
def slice_id(self):
- if not hasattr(self, '_slice_id'):
- slices = self.plapi.GetSlices(self.slicename, fields=('slice_id',))
- if slices:
- self._slice_id = slices[0]['slice_id']
- else:
- # If it wasn't found, don't remember this failure, keep trying
- return None
+ if not self._slice_id:
+ self._slice_id = self.sliceapi.GetSliceId(self.slicename)
return self._slice_id
@property
def vsys_vnet(self):
- if not hasattr(self, '_vsys_vnet'):
- slicetags = self.plapi.GetSliceTags(
- name = self.slicename,
- tagname = 'vsys_vnet',
- fields=('value',))
- if slicetags:
- self._vsys_vnet = slicetags[0]['value']
- else:
- # If it wasn't found, don't remember this failure, keep trying
- return None
+ if not self._vsys_vnet:
+ self._vsys_vnet = self.sliceapi.GetSliceVnetSysTag(self.slicename)
return self._vsys_vnet
-
+
def _load_blacklist(self):
blpath = environ.homepath('plblacklist')
try:
self._blacklist = set(
- map(int,
- map(str.strip, bl.readlines())
- )
+ map(str.strip, bl.readlines())
)
finally:
bl.close()
get_attribute_value("tapPortBase")
self.p2pDeployment = self._attributes.\
get_attribute_value("p2pDeployment")
- self.dedicatedSlice = self._attributes.\
- get_attribute_value("dedicatedSlice")
-
+ self.cleanProc = self._attributes.\
+ get_attribute_value("cleanProc")
+ self.cleanHome = self._attributes.\
+ get_attribute_value("cleanHome")
+ self.sfa = self._attributes.\
+ get_attribute_value("sfa")
+ if self.sfa:
+ self._slice_id = self._attributes.\
+ get_attribute_value("sliceHrn")
+
if not self.slicename:
raise RuntimeError, "Slice not set"
if not self.authUser:
reserved = set(self._blacklist)
for guid, node in self._elements.iteritems():
if isinstance(node, self._node.Node) and node._node_id is not None:
- reserved.add(node._node_id)
+ reserved.add(node.hostname)
# Initial algo:
# look for perfectly defined nodes
filter_slice_id = self.slice_id)
node_id = None
+ candidate_hosts = set(candidates.keys() if candidates else [])
reserve_lock.acquire()
try:
- candidates -= reserved
- if len(candidates) == 1:
- node_id = iter(candidates).next()
- reserved.add(node_id)
- elif not candidates:
+ candidate_hosts -= reserved
+ if len(candidate_hosts) == 1:
+ hostname = iter(candidate_hosts).next()
+ node_id = candidates[hostname]
+ reserved.add(hostname)
+ elif not candidate_hosts:
# Try again including unassigned nodes
reserve_lock.release()
try:
candidates = node.find_candidates()
finally:
reserve_lock.acquire()
- candidates -= reserved
- if len(candidates) > 1:
+ candidate_hosts = set(candidates.keys() if candidates else [])
+ candidate_hosts -= reserved
+ if len(candidate_hosts) > 1:
return
- if len(candidates) == 1:
- node_id = iter(candidates).next()
+ if len(candidate_hosts) == 1:
+ hostname = iter(candidate_hosts).next()
+ node_id = candidates[hostname]
to_provision.add(node_id)
- reserved.add(node_id)
+ reserved.add(hostname)
elif not candidates:
- raise RuntimeError, "Cannot assign resources for node %s, no candidates sith %s" % (guid,
+ raise RuntimeError, "Cannot assign resources for node %s, no candidates with %s" % (guid,
node.make_filter_description())
finally:
reserve_lock.release()
-
+
if node_id is not None:
node.assign_node_id(node_id)
# If we have only one candidate, simply use it
candidates = node.find_candidates(
filter_slice_id = filter_slice_id)
- candidates -= reserved
- reqs.append(candidates)
+ for r in reserved:
+ if candidates.has_key(r):
+ del candidates[r]
+ reqs.append(candidates.values())
nodes.append(node)
for guid, node in self._elements.iteritems():
if isinstance(node, self._node.Node) and node._node_id is None:
runner.put(genreqs, node, self.slice_id)
runner.sync()
-
+
if nodes and reqs:
if recover:
raise RuntimeError, "Impossible to recover: unassigned host for Nodes %r" % (nodes,)
def do_provisioning(self):
if self._to_provision:
# Add new nodes to the slice
- cur_nodes = self.plapi.GetSlices(self.slicename, ['node_ids'])[0]['node_ids']
+ cur_nodes = self.sliceapi.GetSliceNodes(self.slice_id)
new_nodes = list(set(cur_nodes) | self._to_provision)
- self.plapi.UpdateSlice(self.slicename, nodes=new_nodes)
+ self.sliceapi.AddSliceNodes(self.slice_id, nodes=new_nodes)
# cleanup
self._just_provisioned = self._to_provision
if isinstance(node, self._node.Node):
if not node.is_alive():
self._logger.warn("Blacklisting %s for unresponsiveness", node.hostname)
- self._blacklist.add(node._node_id)
+ self._blacklist.add(node.hostname)
node.unassign_node()
try:
# TODO: take on account schedule time for the task
element = self._elements[guid]
if element:
+ if name == "up":
+ if value == True:
+ element.if_up()
+ else:
+ element.if_down()
+
try:
setattr(element, name, value)
except:
Parallel(metadata.NS3DEPENDENCY),
Parallel(metadata.DEPENDENCY),
Parallel(metadata.APPLICATION),
+ Parallel(metadata.CCNXDAEMON),
])
# Tunnels are not harmed by configuration after
finally:
self.recovering = True
- def _make_generic(self, parameters, kind):
- app = kind(self.plapi)
+ def _make_generic(self, parameters, kind, **kwargs):
+ args = dict({'api': self.plcapi})
+ args.update(kwargs)
+ app = kind(**args)
app.testbed = weakref.ref(self)
# Note: there is 1-to-1 correspondence between attribute names
return app
def _make_node(self, parameters):
- node = self._make_generic(parameters, self._node.Node)
- node.enable_cleanup = self.dedicatedSlice
+ args = dict({'sliceapi': self.sliceapi})
+ node = self._make_generic(parameters, self._node.Node, **args)
+ node.enable_proc_cleanup = self.cleanProc
+ node.enable_home_cleanup = self.cleanHome
return node
def _make_node_iface(self, parameters):
def _make_internet(self, parameters):
return self._make_generic(parameters, self._interfaces.Internet)
- def _make_application(self, parameters):
- return self._make_generic(parameters, self._app.Application)
+ def _make_application(self, parameters, clazz = None):
+ if not clazz:
+ clazz = self._app.Application
+ return self._make_generic(parameters, clazz)
def _make_dependency(self, parameters):
return self._make_generic(parameters, self._app.Dependency)