+ Implemented option to cleanup directories on PlanetLab slivers.
[nepi.git] / src / nepi / testbeds / planetlab / execute.py
index 8574112..467d9fe 100644 (file)
@@ -49,10 +49,11 @@ class TestbedController(testbed_impl.TestbedController):
         
         self._load_blacklist()
 
-        self._sliceapi = None
-        self._plcapi = None
         self._slice_id = None
-        
+        self._plcapi = None
+        self._sliceapi = None
+        self._vsys_vnet = None
+
         self._logger = logging.getLogger('nepi.testbeds.planetlab')
         
         self.recovering = False
@@ -79,22 +80,20 @@ class TestbedController(testbed_impl.TestbedController):
             if not self.sfa:
                 self._sliceapi = self.plcapi
             else:
-                import sfiapi
-                self._sliceapi = sfiapi.sfiapi()
+                from nepi.util import sfiapi
+                self._sliceapi = sfiapi.sfiapi(self.slice_id)
         return self._sliceapi
 
     @property
     def slice_id(self):
         if not self._slice_id:
-            self._slice_id = self.plcapi.GetSliceId(self.slicename)
+            self._slice_id = self.sliceapi.GetSliceId(self.slicename)
         return self._slice_id
     
     @property
     def vsys_vnet(self):
-        if not hasattr(self, '_vsys_vnet'):
-            self._vsys_vnet = plutil.getVnet(
-                self.plcapi,
-                self.slicename)
+        if not self._vsys_vnet:
+            self._vsys_vnet = self.sliceapi.GetSliceVnetSysTag(self.slicename)
         return self._vsys_vnet
 
     def _load_blacklist(self):
@@ -108,9 +107,7 @@ class TestbedController(testbed_impl.TestbedController):
             
         try:
             self._blacklist = set(
-                map(int,
-                    map(str.strip, bl.readlines())
-                )
+                map(str.strip, bl.readlines())
             )
         finally:
             bl.close()
@@ -146,8 +143,10 @@ class TestbedController(testbed_impl.TestbedController):
             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:
@@ -212,7 +211,7 @@ class TestbedController(testbed_impl.TestbedController):
         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
@@ -225,32 +224,36 @@ class TestbedController(testbed_impl.TestbedController):
                 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)
         
@@ -270,14 +273,16 @@ class TestbedController(testbed_impl.TestbedController):
             # 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,)
@@ -310,9 +315,9 @@ class TestbedController(testbed_impl.TestbedController):
     def do_provisioning(self):
         if self._to_provision:
             # Add new nodes to the slice
-            cur_nodes = self.sliceapi.GetSliceNodes(self.slicename)
+            cur_nodes = self.sliceapi.GetSliceNodes(self.slice_id)
             new_nodes = list(set(cur_nodes) | self._to_provision)
-            self.sliceapi.AddSliceNodes(self.slicename, nodes=new_nodes)
+            self.sliceapi.AddSliceNodes(self.slice_id, nodes=new_nodes)
 
         # cleanup
         self._just_provisioned = self._to_provision
@@ -364,7 +369,7 @@ class TestbedController(testbed_impl.TestbedController):
                 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:
@@ -528,6 +533,12 @@ class TestbedController(testbed_impl.TestbedController):
         # 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:
@@ -675,6 +686,7 @@ class TestbedController(testbed_impl.TestbedController):
                     Parallel(metadata.NS3DEPENDENCY),
                     Parallel(metadata.DEPENDENCY),
                     Parallel(metadata.APPLICATION),
+                    Parallel(metadata.CCNXDAEMON),
                 ])
 
             # Tunnels are not harmed by configuration after
@@ -727,7 +739,8 @@ class TestbedController(testbed_impl.TestbedController):
     def _make_node(self, parameters):
         args = dict({'sliceapi': self.sliceapi})
         node = self._make_generic(parameters, self._node.Node, **args)
-        node.enable_cleanup = self.dedicatedSlice
+        node.enable_proc_cleanup = self.cleanProc
+        node.enable_home_cleanup = self.cleanHome
         return node
 
     def _make_node_iface(self, parameters):
@@ -745,8 +758,10 @@ class TestbedController(testbed_impl.TestbedController):
     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)