Merging patch to support https proxies when running experiments using PlanetLab,...
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 16 Nov 2012 17:41:07 +0000 (18:41 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Fri, 16 Nov 2012 17:41:07 +0000 (18:41 +0100)
examples/ccnx/planetlab_ccnx_unicast.py
src/nepi/testbeds/planetlab/execute.py
src/nepi/testbeds/planetlab/metadata.py
src/nepi/testbeds/planetlab/plcapi.py

index 7808081..6b8667a 100644 (file)
@@ -36,7 +36,7 @@ signal.signal(signal.SIGTERM, _finalize)
 signal.signal(signal.SIGINT, _finalize)
 
 def create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, 
-        port_base, root_dir, exp_desc):
+        port_base, root_dir, proxy, exp_desc):
     pl_provider = FactoriesProvider("planetlab")
     slice_desc = exp_desc.add_testbed_description(pl_provider)
     slice_desc.set_attribute_value("homeDirectory", root_dir)
@@ -45,6 +45,8 @@ def create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
     slice_desc.set_attribute_value("authUser", pl_user)
     slice_desc.set_attribute_value("authPass", pl_pwd)
     slice_desc.set_attribute_value("plcHost", plc_host)
+    if proxy:
+        slice_desc.set_attribute_value("proxy", proxy)
     slice_desc.set_attribute_value("tapPortBase", port_base)
     slice_desc.set_attribute_value("p2pDeployment", True)
     # Kills all running processes before starting the experiment
@@ -132,14 +134,14 @@ def exec_ccncatchunks(slicename, port, hostname):
     return proc2
 
 def create_ed(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, 
-        port_base, root_dir, delay, port):
+        port_base, root_dir, delay, port, proxy):
 
     # Create the experiment description object
     exp_desc = ExperimentDescription()
 
     # Create the slice description object
     slice_desc = create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, 
-        port_base, root_dir, exp_desc)
+        port_base, root_dir, proxy, exp_desc)
     
     # Create the Internet box object
     pl_inet = slice_desc.create("Internet")
@@ -171,11 +173,11 @@ def create_ed(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh
     return exp_desc, pl_nodes, hostname, pl_app
 
 def run(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, 
-        port_base, root_dir, delay, port):
+        port_base, root_dir, delay, port, proxy):
 
     exp_desc, pl_nodes, hostname, pl_app = create_ed(hostnames, vsys_vnet, 
             slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, port_base, 
-            root_dir, delay, port)
+            root_dir, delay, port, proxy)
 
     xml = exp_desc.to_xml()
     controller = ExperimentController(xml, root_dir)
@@ -199,7 +201,7 @@ def run(hostnames, vsys_vnet, slicename, plc_host, pl_user, pl_pwd, pl_ssh_key,
 
     while not TERMINATE and proc1 and proc2 and proc2.poll() is None:
         time.sleep(0.5)
-   
+
     if proc1:
         if proc1.poll() < 1:
            err = proc1.stderr.read()
@@ -248,7 +250,7 @@ if __name__ == '__main__':
                  'planetlab2.esprit-tn.com' ]
     ccn_local_port = os.environ.get('CCN_LOCAL_PORT')
 
-    usage = "usage: %prog -s <pl_slice> -H <pl_host> -k <ssh_key> -u <pl_user> -p <pl_password> -v <vsys_vnet> -N <host_names> -c <node_count> -d <delay> -P <ccn-local-port>"
+    usage = "usage: %prog -s <pl_slice> -H <pl_host> -k <ssh_key> -u <pl_user> -p <pl_password> -v <vsys_vnet> -N <host_names> -c <node_count> -d <delay> -P <ccn-local-port> -x <proxy>"
 
     parser = OptionParser(usage=usage)
     parser.add_option("-s", "--slicename", dest="slicename", 
@@ -272,18 +274,22 @@ if __name__ == '__main__':
             default=pl_hostnames, type="str")
     parser.add_option("-c", "--node-count", dest="node_count", 
             help="Number of nodes to use", 
-            default=9, type="str")
+            default=9, type="int")
     parser.add_option("-d", "--delay", dest="delay", 
             help="Time to wait before retrieveing the second video stream in seconds", 
             default=40, type="int")
     parser.add_option("-P", "--ccn-local-port", dest="port", 
             help="Port to bind the CCNx daemon", 
             default=ccn_local_port, type="int")
+    parser.add_option("-x", "--proxy", dest="proxy", 
+            help="Https proxy between here and PlanetLab machines", 
+            default=None, type="str")
     (options, args) = parser.parse_args()
 
     hostnames = map(string.strip, options.hostnames.split(",")) if options.hostnames else default_hostnames
     if options.node_count > 0 and options.node_count < len(hostnames):
        hostnames = hostnames[0:options.node_count]
+
     vsys_vnet = options.vsys_vnet
     slicename = options.slicename
     pl_host = options.pl_host
@@ -292,7 +298,8 @@ if __name__ == '__main__':
     pl_ssh_key = options.pl_ssh_key
     delay = options.delay
     port = options.port
+    proxy = options.proxy
 
     run(hostnames, vsys_vnet, slicename, pl_host, pl_user, pl_pwd, pl_ssh_key, 
-            port_base, root_dir, delay, port)
+            port_base, root_dir, delay, port, proxy)
 
index c04bba5..9ae17b4 100644 (file)
@@ -70,7 +70,8 @@ class TestbedController(testbed_impl.TestbedController):
                     self.authUser,
                     self.authString,
                     self.plcHost,
-                    self.plcUrl
+                    self.plcUrl,
+                    self.proxy
                     )
         return self._plcapi
 
@@ -139,6 +140,8 @@ class TestbedController(testbed_impl.TestbedController):
             get_attribute_value("plcUrl")
         self.logLevel = self._attributes.\
             get_attribute_value("plLogLevel")
+        self.proxy = self._attributes.\
+            get_attribute_value("proxy")
         self.tapPortBase = self._attributes.\
             get_attribute_value("tapPortBase")
         self.p2pDeployment = self._attributes.\
index 9f1d14f..c6f79ba 100644 (file)
@@ -1787,6 +1787,13 @@ testbed_attributes = dict({
             "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
             "validation_function": validation.is_string
         }),
+        "proxy": dict({
+            "name": "proxy",
+            "help": "Https proxy to connect to the outside world",
+            "type": Attribute.STRING,
+            "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable,
+            "validation_function": validation.is_string
+        }),
         "p2p_deployment": dict({
             "name": "p2pDeployment",
             "help": "Enable peer-to-peer deployment of applications and dependencies. "
index 00a06a8..d1d7980 100644 (file)
@@ -72,7 +72,7 @@ class PLCAPI(object):
      
     _required_methods = set()
 
-    def __init__(self, username=None, password=None, sessionkey=None,
+    def __init__(self, username=None, password=None, sessionkey=None, proxy=None,
             hostname = "www.planet-lab.eu",
             urlpattern = "https://%(hostname)s:443/PLCAPI/",
             localPeerName = "PLE"):
@@ -85,6 +85,21 @@ class PLCAPI(object):
         
         self._localPeerName = localPeerName
         self._url = urlpattern % {'hostname':hostname}
+        if (proxy is not None):
+            import urllib2
+            class HTTPSProxyTransport(xmlrpclib.Transport):
+                def __init__(self, proxy, use_datetime=0):
+                    opener = urllib2.build_opener(urllib2.ProxyHandler({"https" : proxy}))
+                    xmlrpclib.Transport.__init__(self, use_datetime)
+                    self.opener = opener
+                def request(self, host, handler, request_body, verbose=0):
+                    req = urllib2.Request('https://%s%s' % (host, handler), request_body)
+                    req.add_header('User-agent', self.user_agent)
+                    self.verbose = verbose
+                    return self.parse_response(self.opener.open(req))
+            self._proxyTransport = lambda : HTTPSProxyTransport(proxy)
+        else:
+            self._proxyTransport = lambda : None
         
         self.threadlocal = threading.local()
     
@@ -93,6 +108,7 @@ class PLCAPI(object):
         # Cannot reuse same proxy in all threads, py2.7 is not threadsafe
         return xmlrpclib.ServerProxy(
             self._url ,
+            transport = self._proxyTransport(),
             allow_none = True)
         
     @property
@@ -329,14 +345,15 @@ class PLCAPI(object):
         else:
             return None
  
-def plcapi(auth_user, auth_string, plc_host, plc_url):
+def plcapi(auth_user, auth_string, plc_host, plc_url, proxy):
     api = None
     if auth_user:
         api = PLCAPI(
             username = auth_user,
             password = auth_string,
             hostname = plc_host,
-            urlpattern = plc_url
+            urlpattern = plc_url,
+            proxy = proxy
         )
     else:
         # anonymous access - may not be enough for much