Ticket #29: Nepi-in-Nepi FINISHED
authorClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Tue, 3 May 2011 13:26:50 +0000 (15:26 +0200)
committerClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Tue, 3 May 2011 13:26:50 +0000 (15:26 +0200)
Wooow...

src/nepi/core/metadata.py
src/nepi/util/constants.py
src/nepi/util/proxy.py
test/testbeds/planetlab/integration_ns3.py [new file with mode: 0755]

index 9c50ef5..fe92e05 100644 (file)
@@ -198,6 +198,12 @@ class Metadata(object):
                 flags = Attribute.DesignOnly,
                 validation_function = validation.is_string
         )),
+        (DC.DEPLOYMENT_KEY, dict(name = DC.DEPLOYMENT_KEY,
+                help = "Path to SSH key to use for connecting",
+                type = Attribute.STRING,
+                flags = Attribute.DesignOnly,
+                validation_function = validation.is_string
+        )),
         (DC.DEPLOYMENT_PORT, dict(name = DC.DEPLOYMENT_PORT,
                 help = "Port on the Host",
                 type = Attribute.INTEGER,
index 82b0db6..ec00adc 100644 (file)
@@ -38,6 +38,7 @@ class DeploymentConfiguration:
     DEPLOYMENT_HOST = "deployment_host"
     DEPLOYMENT_USER = "deployment_user"
     DEPLOYMENT_PORT = "deployment_port"
+    DEPLOYMENT_KEY  = "deployment_key"
     
     DEPLOYMENT_ENVIRONMENT_SETUP = "deployment_environment_setup"
     
index 7af0543..cc9c235 100644 (file)
@@ -199,7 +199,7 @@ def get_access_config_params(access_config):
     root_dir = access_config.get_attribute_value(DC.ROOT_DIRECTORY)
     log_level = access_config.get_attribute_value(DC.LOG_LEVEL)
     log_level = to_server_log_level(log_level)
-    user = host = port = agent = None
+    user = host = port = agent = key = None
     communication = access_config.get_attribute_value(DC.DEPLOYMENT_COMMUNICATION)
     environment_setup = (
         access_config.get_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP)
@@ -211,7 +211,8 @@ def get_access_config_params(access_config):
         host = access_config.get_attribute_value(DC.DEPLOYMENT_HOST)
         port = access_config.get_attribute_value(DC.DEPLOYMENT_PORT)
         agent = access_config.get_attribute_value(DC.USE_AGENT)
-    return (root_dir, log_level, user, host, port, agent, environment_setup)
+        key = access_config.get_attribute_value(DC.DEPLOYMENT_KEY)
+    return (root_dir, log_level, user, host, port, key, agent, environment_setup)
 
 class AccessConfiguration(AttributesMap):
     def __init__(self, params = None):
@@ -262,10 +263,10 @@ def create_controller(xml, access_config = None):
         
         return controller
     elif mode == DC.MODE_DAEMON:
-        (root_dir, log_level, user, host, port, agent, environment_setup) = \
+        (root_dir, log_level, user, host, port, key, agent, environment_setup) = \
                 get_access_config_params(access_config)
         return ExperimentControllerProxy(root_dir, log_level,
-                experiment_xml = xml, host = host, port = port, user = user, 
+                experiment_xml = xml, host = host, port = port, user = user, ident_key = key,
                 agent = agent, launch = launch,
                 environment_setup = environment_setup)
     raise RuntimeError("Unsupported access configuration '%s'" % mode)
@@ -280,10 +281,10 @@ def create_testbed_controller(testbed_id, testbed_version, access_config):
             raise ValueError, "Unsupported instantiation mode: %s with lanch=False" % (mode,)
         return  _build_testbed_controller(testbed_id, testbed_version)
     elif mode == DC.MODE_DAEMON:
-        (root_dir, log_level, user, host, port, agent, environment_setup) = \
+        (root_dir, log_level, user, host, port, key, agent, environment_setup) = \
                 get_access_config_params(access_config)
         return TestbedControllerProxy(root_dir, log_level, testbed_id = testbed_id, 
-                testbed_version = testbed_version, host = host, port = port,
+                testbed_version = testbed_version, host = host, port = port, ident_key = key,
                 user = user, agent = agent, launch = launch,
                 environment_setup = environment_setup)
     raise RuntimeError("Unsupported access configuration '%s'" % mode)
@@ -704,7 +705,7 @@ class ExperimentControllerServer(server.Server):
 class TestbedControllerProxy(object):
     def __init__(self, root_dir, log_level, testbed_id = None, 
             testbed_version = None, launch = True, host = None, 
-            port = None, user = None, agent = None,
+            port = None, user = None, ident_key = None, agent = None,
             environment_setup = ""):
         if launch:
             if testbed_id == None or testbed_version == None:
@@ -719,6 +720,7 @@ class TestbedControllerProxy(object):
                                 testbed_version)
                 proc = server.popen_ssh_subprocess(python_code, host = host,
                     port = port, user = user, agent = agent,
+                    ident_key = ident_key,
                     environment_setup = environment_setup)
                 if proc.poll():
                     err = proc.stderr.read()
@@ -1114,7 +1116,7 @@ class TestbedControllerProxy(object):
 class ExperimentControllerProxy(object):
     def __init__(self, root_dir, log_level, experiment_xml = None, 
             launch = True, host = None, port = None, user = None, 
-            agent = None, environment_setup = ""):
+            ident_key = None, agent = None, environment_setup = ""):
         if launch:
             # launch server
             if experiment_xml == None:
@@ -1128,6 +1130,7 @@ class ExperimentControllerProxy(object):
                         s.run()" % (root_dir, log_level, xml)
                 proc = server.popen_ssh_subprocess(python_code, host = host,
                     port = port, user = user, agent = agent,
+                    ident_key = ident_key,
                     environment_setup = environment_setup)
                 if proc.poll():
                     err = proc.stderr.read()
diff --git a/test/testbeds/planetlab/integration_ns3.py b/test/testbeds/planetlab/integration_ns3.py
new file mode 100755 (executable)
index 0000000..c086f07
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import getpass
+from nepi.core.design import ExperimentDescription, FactoriesProvider
+from nepi.core.execute import ExperimentController
+from nepi.util import proxy
+from nepi.util.constants import DeploymentConfiguration as DC, ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP
+import os
+import shutil
+import tempfile
+import test_util
+import time
+import unittest
+import re
+
+class PlanetLabCrossIntegrationTestCase(unittest.TestCase):
+    def setUp(self):
+        self.root_dir = tempfile.mkdtemp()
+
+    def tearDown(self):
+        try:
+            shutil.rmtree(self.root_dir)
+        except:
+            # retry
+            time.sleep(0.1)
+            shutil.rmtree(self.root_dir)
+
+    def make_experiment_desc(self):
+        testbed_id = "planetlab"
+        testbed_version = "01"
+        slicename = "inria_nepi12"
+        pl_ssh_key = os.environ.get(
+            "PL_SSH_KEY",
+            "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'],) )
+        pl_user, pl_pwd = test_util.pl_auth()
+
+        exp_desc = ExperimentDescription()
+        pl_provider = FactoriesProvider(testbed_id, testbed_version)
+        pl_desc = exp_desc.add_testbed_description(pl_provider)
+        pl_desc.set_attribute_value("homeDirectory", self.root_dir)
+        pl_desc.set_attribute_value("slice", slicename)
+        pl_desc.set_attribute_value("sliceSSHKey", pl_ssh_key)
+        pl_desc.set_attribute_value("authUser", pl_user)
+        pl_desc.set_attribute_value("authPass", pl_pwd)
+        
+        return pl_desc, exp_desc
+
+    @test_util.skipUnless(test_util.pl_auth() is not None, 
+        "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+    @test_util.skipUnless(os.environ.get('NEPI_FULL_TESTS','').lower() in ('1','yes','true','on'),
+        "Test is expensive, requires NEPI_FULL_TESTS=yes")
+    def test_ns3_in_pl(self):
+        ns3_testbed_id = "ns3"
+        ns3_testbed_version = "3_9_RC3"
+        
+        pl, exp = self.make_experiment_desc()
+        
+        node1 = pl.create("Node")
+        node1.set_attribute_value("hostname", "onelab11.pl.sophia.inria.fr")
+        node1.set_attribute_value("label", "node1")
+        iface1 = pl.create("NodeInterface")
+        iface1.set_attribute_value("label", "node1iface")
+        inet = pl.create("Internet")
+        node1.connector("devs").connect(iface1.connector("node"))
+        iface1.connector("inet").connect(inet.connector("devs"))
+        
+        plnepi = pl.create("NepiDependency")
+        plns3 = pl.create("NS3Dependency")
+        plnepi.connector("node").connect(node1.connector("deps"))
+        plns3.connector("node").connect(node1.connector("deps"))
+
+        ns3_provider = FactoriesProvider(ns3_testbed_id, ns3_testbed_version)
+        ns3_desc = exp.add_testbed_description(ns3_provider)
+        ns3_desc.set_attribute_value("homeDirectory", "tb-ns3")
+        ns3_desc.set_attribute_value(DC.DEPLOYMENT_HOST, "{#[node1iface].addr[0].[Address]#}")
+        ns3_desc.set_attribute_value(DC.DEPLOYMENT_USER, 
+            pl.get_attribute_value("slice"))
+        ns3_desc.set_attribute_value(DC.DEPLOYMENT_KEY, 
+            pl.get_attribute_value("sliceSSHKey"))
+        ns3_desc.set_attribute_value(DC.DEPLOYMENT_MODE, DC.MODE_DAEMON)
+        ns3_desc.set_attribute_value(DC.DEPLOYMENT_COMMUNICATION, DC.ACCESS_SSH)
+        ns3_desc.set_attribute_value(DC.DEPLOYMENT_ENVIRONMENT_SETUP, 
+            "{#[node1].[%s]#}" % (ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP,))
+
+        xml = exp.to_xml()
+
+        controller = ExperimentController(xml, self.root_dir)
+        controller.start()
+        # just test that it starts...
+        controller.stop()
+        controller.shutdown()
+
+if __name__ == '__main__':
+    unittest.main()
+