Dependency support fixes:
authorClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Fri, 22 Apr 2011 14:14:13 +0000 (16:14 +0200)
committerClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Fri, 22 Apr 2011 14:14:13 +0000 (16:14 +0200)
 * sudo through SSH needs -S, since we don't allocate a tty
 * missing metadata
 * fix broken regex in test
 * be happy

src/nepi/testbeds/planetlab/metadata_v01.py
src/nepi/testbeds/planetlab/node.py
src/nepi/testbeds/planetlab/rspawn.py
src/nepi/util/server.py
test/testbeds/planetlab/execute.py

index 42133e5..5152d48 100644 (file)
@@ -481,7 +481,9 @@ factories_info = dict({
             "status_function": status_application,
             "stop_function": stop_application,
             "configure_function": configure_application,
-            "box_attributes": ["command", "sudo", "stdin"],
+            "box_attributes": ["command", "sudo", "stdin",
+                               "depends", "build-depends", "build",
+                               "sources" ],
             "connector_types": ["node"],
             "traces": ["stdout", "stderr"]
         }),
index f5d159a..0e31046 100644 (file)
@@ -27,6 +27,9 @@ class Node(object):
         'max_bandwidth' : ('bw%(timeframe)s', '[value'),
     }    
     
+    DEPENDS_PIDFILE = '/tmp/nepi-depends.pid'
+    DEPENDS_LOGFILE = '/tmp/nepi-depends.log'
+    
     def __init__(self, api=None):
         if not api:
             api = plcapi.PLCAPI()
@@ -170,8 +173,8 @@ class Node(object):
     def install_dependencies(self):
         if self.required_packages:
             # TODO: make dependant on the experiment somehow...
-            pidfile = '/tmp/nepi-depends.pid'
-            logfile = '/tmp/nepi-depends.log'
+            pidfile = self.DEPENDS_PIDFILE
+            logfile = self.DEPENDS_LOGFILE
             
             # Start process in a "daemonized" way, using nohup and heavy
             # stdin/out redirection to avoid connection issues
@@ -196,6 +199,8 @@ class Node(object):
     
     def wait_dependencies(self, pidprobe=1, probe=10, pidmax=10):
         if self.required_packages:
+            pidfile = self.DEPENDS_PIDFILE
+            
             # get PID
             pid = ppid = None
             for probenum in xrange(pidmax):
index 55ac8ff..b656773 100644 (file)
@@ -24,7 +24,7 @@ class NOT_STARTED:
     """
 
 def remote_spawn(command, pidfile, stdout='/dev/null', stderr=STDOUT, stdin='/dev/null', home=None, create_home=False, sudo=False,
-        host = None, port = None, user = None, agent = None, ident_key = None):
+        host = None, port = None, user = None, agent = None, ident_key = None, tty = False):
     """
     Spawn a remote command such that it will continue working asynchronously.
     
@@ -67,7 +67,7 @@ def remote_spawn(command, pidfile, stdout='/dev/null', stderr=STDOUT, stdin='/de
             'stderr' : stderr,
             'stdin' : stdin,
             
-            'sudo' : 'sudo' if sudo else '',
+            'sudo' : 'sudo -S' if sudo else '',
             
             'pidfile' : server.shell_escape(pidfile),
             'gohome' : 'cd %s ; ' % (server.shell_escape(home),) if home else '',
@@ -77,7 +77,8 @@ def remote_spawn(command, pidfile, stdout='/dev/null', stderr=STDOUT, stdin='/de
         port = port,
         user = user,
         agent = agent,
-        ident_key = ident_key
+        ident_key = ident_key,
+        tty = tty 
         )
     
     if proc.wait():
@@ -199,7 +200,7 @@ fi
 """ % {
             'ppid' : ppid,
             'pid' : pid,
-            'sudo' : 'sudo' if sudo else ''
+            'sudo' : 'sudo -S' if sudo else ''
         },
         host = host,
         port = port,
index c1558d1..6d37d0d 100644 (file)
@@ -342,7 +342,8 @@ class Client(object):
 
 def popen_ssh_command(command, host, port, user, agent, 
             stdin="", 
-            ident_key = None):
+            ident_key = None,
+            tty = False):
         """
         Executes a remote commands, returns ((stdout,stderr),process)
         """
@@ -356,6 +357,8 @@ def popen_ssh_command(command, host, port, user, agent,
             args.append('-p%d' % port)
         if ident_key:
             args.extend(('-i', ident_key))
+        if tty:
+            args.append('-t')
         args.append(command)
 
         # connects to the remote host and starts a remote connection
@@ -511,7 +514,8 @@ def popen_scp(source, dest, port, agent,
  
 def popen_ssh_subprocess(python_code, host, port, user, agent, 
         python_path = None,
-        ident_key = None):
+        ident_key = None,
+        tty = False):
         if python_path:
             python_path.replace("'", r"'\''")
             cmd = """PYTHONPATH="$PYTHONPATH":'%s' """ % python_path
@@ -545,6 +549,8 @@ def popen_ssh_subprocess(python_code, host, port, user, agent,
             args.append('-p%d' % port)
         if ident_key:
             args.extend(('-i', ident_key))
+        if tty:
+            args.append('-t')
         args.append(cmd)
 
         # connects to the remote host and starts a remote rpyc connection
index 85ff6e3..b1c4e11 100755 (executable)
@@ -19,8 +19,7 @@ class PlanetLabExecuteTestCase(unittest.TestCase):
     def tearDown(self):
         shutil.rmtree(self.root_dir)
 
-    @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
-    def test_simple(self):
+    def make_instance(self):
         testbed_version = "01"
         instance = planetlab.TestbedController(testbed_version)
         slicename = "inria_nepi12"
@@ -32,6 +31,12 @@ class PlanetLabExecuteTestCase(unittest.TestCase):
         instance.defer_configure("authUser", pl_user)
         instance.defer_configure("authPass", pl_pwd)
         
+        return instance
+
+    @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+    def test_simple(self):
+        instance = self.make_instance()
+        
         instance.defer_create(2, "Node")
         instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr")
         instance.defer_create(3, "Node")
@@ -76,6 +81,38 @@ class PlanetLabExecuteTestCase(unittest.TestCase):
         instance.stop()
         instance.shutdown()
         
+    @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)")
+    def test_depends(self):
+        instance = self.make_instance()
+        
+        instance.defer_create(2, "Node")
+        instance.defer_create_set(2, "hostname", "onelab11.pl.sophia.inria.fr")
+        instance.defer_create(3, "NodeInterface")
+        instance.defer_connect(2, "devs", 3, "node")
+        instance.defer_create(4, "Internet")
+        instance.defer_connect(3, "inet", 4, "devs")
+        instance.defer_create(5, "Application")
+        instance.defer_create_set(5, "command", "gfortran --version")
+        instance.defer_create_set(5, "depends", "gcc-gfortran")
+        instance.defer_add_trace(5, "stdout")
+        instance.defer_connect(5, "node", 2, "apps")
+
+        instance.do_setup()
+        instance.do_create()
+        instance.do_connect()
+        instance.do_preconfigure()
+        instance.do_configure()
+        
+        instance.start()
+        while instance.status(5) != STATUS_FINISHED:
+            time.sleep(0.5)
+        ping_result = instance.trace(5, "stdout") or ""
+        comp_result = r".*GNU Fortran \(GCC\).*"
+        self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE),
+            "Unexpected trace:\n" + ping_result)
+        instance.stop()
+        instance.shutdown()
+        
 
 if __name__ == '__main__':
     unittest.main()