Several fixes:
authorClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Wed, 28 Sep 2011 22:46:08 +0000 (19:46 -0300)
committerClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Wed, 28 Sep 2011 22:46:08 +0000 (19:46 -0300)
 - Add specific hostname to application deployment logging
 - Use os.urandom instead of random.SystemRandom (more appropriate)
 - Fix fuckminsterfülerene-style deadlock in spanning deployment by including
   the application class when defining deployment groups. This ensures
   ordered dependencies (which are implemented as thread synchronization),
   and avoids deadlocks.

src/nepi/testbeds/planetlab/application.py
src/nepi/testbeds/planetlab/execute.py
src/nepi/testbeds/planetlab/interfaces.py
src/nepi/testbeds/planetlab/multicast.py
src/nepi/util/tunchannel_impl.py

index 8fa3271..3d680ea 100644 (file)
@@ -77,9 +77,7 @@ class Dependency(object):
         self._master_passphrase = None
         self._master_prk = None
         self._master_puk = None
-        self._master_token = ''.join(map(chr,[rng.randint(0,255) 
-                                      for rng in (random.SystemRandom(),)
-                                      for i in xrange(8)] )).encode("hex")
+        self._master_token = os.urandom(8).encode("hex")
         self._build_pid = None
         self._build_ppid = None
         
@@ -190,7 +188,7 @@ class Dependency(object):
                     else:
                         raise RuntimeError, "Failed to setup application"
                 else:
-                    self._logger.info("Setup ready: %s", self)
+                    self._logger.info("Setup ready: %s at %s", self, self.node.hostname)
             else:
                 self.setup()
         
@@ -238,7 +236,7 @@ class Dependency(object):
             buildscript = self._do_build_master()
             
         if buildscript is not None:
-            self._logger.info("Building %s", self)
+            self._logger.info("Building %s at %s", self, self.node.hostname)
             
             # upload build script
             try:
@@ -293,8 +291,8 @@ class Dependency(object):
         
         waitmaster = (
             "{ . ./.ssh-agent.sh ; "
-            "while [[ $(ssh -q -o UserKnownHostsFile=%(hostkey)s %(sshopts)s %(master)s cat %(token_path)s.retcode || /bin/true) != %(token)s ]] ; do sleep 5 ; done ; "
-            "if [[ $(ssh -q -o UserKnownHostsFile=%(hostkey)s %(sshopts)s %(master)s cat %(token_path)s || /bin/true) != %(token)s ]] ; then echo BAD TOKEN ; exit 1 ; fi ; "
+            "while [[ $(. ./.ssh-agent.sh > /dev/null ; ssh -q -o UserKnownHostsFile=%(hostkey)s %(sshopts)s %(master)s cat %(token_path)s.retcode || /bin/true) != %(token)s ]] ; do sleep 5 ; done ; "
+            "if [[ $(. ./.ssh-agent.sh > /dev/null ; ssh -q -o UserKnownHostsFile=%(hostkey)s %(sshopts)s %(master)s cat %(token_path)s || /bin/true) != %(token)s ]] ; then echo BAD TOKEN ; exit 1 ; fi ; "
             "}" 
         ) % {
             'hostkey' : 'master_known_hosts',
@@ -304,7 +302,7 @@ class Dependency(object):
             'sshopts' : sshopts,
         }
         
-        syncfiles = "scp -p -o UserKnownHostsFile=%(hostkey)s %(sshopts)s %(files)s ." % {
+        syncfiles = ". ./.ssh-agent.sh && scp -p -o UserKnownHostsFile=%(hostkey)s %(sshopts)s %(files)s ." % {
             'hostkey' : 'master_known_hosts',
             'files' : ' '.join(files),
             'sshopts' : sshopts,
@@ -384,7 +382,7 @@ class Dependency(object):
         else:
             raise RuntimeError, "Failed to set up build slave %s: cannot get pid" % (self.home_path,)
 
-        self._logger.info("Deploying %s", self)
+        self._logger.info("Deploying %s at %s", self, self.node.hostname)
         
     def _do_wait_build(self):
         pid = self._build_pid
@@ -410,7 +408,7 @@ class Dependency(object):
                     break
                 elif status is not rspawn.RUNNING:
                     bustspin += 1
-                    time.sleep(5)
+                    time.sleep(delay*(5.5+random.random()))
                     if bustspin > 12:
                         self._build_pid = self._build_ppid = None
                         break
@@ -534,7 +532,7 @@ class Dependency(object):
 
     def _do_install(self):
         if self.install:
-            self._logger.info("Installing %s", self)
+            self._logger.info("Installing %s at %s", self, self.node.hostname)
             
             # Install application
             try:
index 1aed9f4..69abd71 100644 (file)
@@ -387,6 +387,7 @@ class TestbedController(testbed_impl.TestbedController):
                 app.node.architecture,
                 app.node.operatingSystem,
                 app.node.pl_distro,
+                app.__class__,
             )
         
         depgroups = collections.defaultdict(list)
@@ -469,9 +470,7 @@ class TestbedController(testbed_impl.TestbedController):
             suffix = ".pub")
             
         # Create secure 256-bits temporary passphrase
-        passphrase = ''.join(map(chr,[rng.randint(0,255) 
-                                      for rng in (random.SystemRandom(),)
-                                      for i in xrange(32)] )).encode("hex")
+        passphrase = os.urandom(32).encode("hex")
                 
         # Copy keys
         oprk = open(self.sliceSSHKey, "rb")
index 42cfd23..552360d 100644 (file)
@@ -170,11 +170,7 @@ class TunIface(object):
         # Generate an initial random cryptographic key to use for tunnelling
         # Upon connection, both endpoints will agree on a common one based on
         # this one.
-        self.tun_key = ( ''.join(map(chr, [ 
-                    r.getrandbits(8) 
-                    for i in xrange(32) 
-                    for r in (random.SystemRandom(),) ])
-                ).encode("base64").strip() )        
+        self.tun_key = os.urandom(32).encode("base64").strip()
         
 
     def __str__(self):
index 71df64c..ffb25d4 100644 (file)
@@ -144,7 +144,7 @@ class MulticastRouter(application.Application):
         
         # download rpms and pack into a tar archive
         return command % {
-            'nonifaces' : ' '.join([iface.if_name for iface in self.nonifaces]),
+            'nonifaces' : ' '.join([iface.if_name for iface in self.nonifaces if iface.if_name]),
             'debugbit' : (debugbit if self.stderr else ""),
         }
     command = property(_command_get, _non_set)
index d543c94..ec74181 100644 (file)
@@ -84,11 +84,7 @@ class TunChannel(object):
         # Generate an initial random cryptographic key to use for tunnelling
         # Upon connection, both endpoints will agree on a common one based on
         # this one.
-        self.tun_key = ( ''.join(map(chr, [ 
-                    r.getrandbits(8) 
-                    for i in xrange(32) 
-                    for r in (random.SystemRandom(),) ])
-                ).encode("base64").strip() )        
+        self.tun_key = os.urandom(32).encode("base64").strip()
         
 
     def __str__(self):