X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Ftestbeds%2Fplanetlab%2Fmetadata.py;h=39f506dc4d7b1ef1ad5a481921f0dea311eb3091;hb=99729cc9825f7351b9c4fdba580bb41278f50e9a;hp=af60f846e2eae015ff2f39abb5ef5b41de35bb90;hpb=e4cc10183d8bf93d4fac5bd03b74011c69010843;p=nepi.git diff --git a/src/nepi/testbeds/planetlab/metadata.py b/src/nepi/testbeds/planetlab/metadata.py index af60f846..39f506dc 100644 --- a/src/nepi/testbeds/planetlab/metadata.py +++ b/src/nepi/testbeds/planetlab/metadata.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- import time @@ -23,6 +22,7 @@ NODEIFACE = "NodeInterface" TUNIFACE = "TunInterface" TAPIFACE = "TapInterface" APPLICATION = "Application" +CCNXDAEMON = "CCNxDaemon" DEPENDENCY = "Dependency" NEPIDEPENDENCY = "NepiDependency" NS3DEPENDENCY = "NS3Dependency" @@ -203,7 +203,7 @@ def connect_dep(testbed_instance, node_guid, app_guid, node=None, app=None): if app.depends: node.required_packages.update(set( app.depends.split() )) - + if app.add_to_path: if app.home_path and app.home_path not in node.pythonpath: node.pythonpath.append(app.home_path) @@ -324,6 +324,16 @@ def create_application(testbed_instance, guid): testbed_instance.elements[guid] = element +def create_ccnxdaemon(testbed_instance, guid): + parameters = testbed_instance._get_parameters(guid) + element = testbed_instance._make_application(parameters, + clazz = testbed_instance._app.CCNxDaemon ) + + # Just inject configuration stuff + element.home_path = "nepi-ccnd-%s" % (guid,) + + testbed_instance.elements[guid] = element + def create_dependency(testbed_instance, guid): parameters = testbed_instance._get_parameters(guid) element = testbed_instance._make_dependency(parameters) @@ -390,6 +400,15 @@ def create_netpipe(testbed_instance, guid): ### Start/Stop functions ### +def prestart_ccnxdaemon(testbed_instance, guid): + # ccnx daemon needs to start before the rest of the + # ccn applications + start_application(testbed_instance, guid) + +def stop_ccndaemon(testbed_instance, guid): + app = testbed_instance.elements[guid] + app.kill() + def start_application(testbed_instance, guid): parameters = testbed_instance._get_parameters(guid) traces = testbed_instance._get_traces(guid) @@ -471,36 +490,19 @@ def preconfigure_tuniface(testbed_instance, guid): element.validate() # First-phase setup - if element.peer_proto: - if element.peer_iface and isinstance(element.peer_iface, testbed_instance._interfaces.TunIface): - # intra tun - listening = id(element) < id(element.peer_iface) - else: - # cross tun - if not element.tun_addr or not element.tun_port: - listening = True - elif not element.peer_addr or not element.peer_port: - listening = True - else: - # both have addresses... - # ...the one with the lesser address listens - listening = element.tun_addr < element.peer_addr - element.prepare( - 'tun-%s' % (guid,), - listening) + element.prepare('tun-%s' % (guid,)) def postconfigure_tuniface(testbed_instance, guid): element = testbed_instance._elements[guid] # Second-phase setup - element.setup() + element.launch() -def wait_tuniface(testbed_instance, guid): +def prestart_tuniface(testbed_instance, guid): element = testbed_instance._elements[guid] # Second-phase setup - element.async_launch_wait() - + element.wait() def configure_node(testbed_instance, guid): node = testbed_instance._elements[guid] @@ -640,7 +642,7 @@ connector_types = dict({ "help": "Connector to a routing daemon", "name": "router", "max": 1, - "min": 1 + "min": 0 }), "fwd": dict({ "help": "Forwarder this routing daemon communicates with", @@ -714,10 +716,22 @@ connections = [ }), dict({ "from": (TESTBED_ID, NODE, "apps"), - "to": (TESTBED_ID, (APPLICATION, DEPENDENCY, NEPIDEPENDENCY, NS3DEPENDENCY, MULTICASTANNOUNCER), "node"), + "to": (TESTBED_ID, (APPLICATION, CCNXDAEMON, MULTICASTANNOUNCER), "node"), "init_code": connect_dep, "can_cross": False }), + dict({ + "from": (TESTBED_ID, NODE, "deps"), + "to": (TESTBED_ID, (DEPENDENCY, NEPIDEPENDENCY, NS3DEPENDENCY), "node"), + "init_code": connect_dep, + "can_cross": False + }), + dict({ + "from": (TESTBED_ID, NODE, "pipes"), + "to": (TESTBED_ID, NETPIPE, "node"), + "init_code": connect_node_netpipe, + "can_cross": False + }), dict({ "from": (TESTBED_ID, NODE, "apps"), "to": (TESTBED_ID, MULTICASTFORWARDER, "node"), @@ -1112,7 +1126,14 @@ attributes = dict({ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, "validation_function": validation.is_string }), - "sudo": dict({ + "ccnroutes": dict({ + "name": "ccnroutes", + "help": "Route can be static (e.g. udp ip) or multicast (e.g. udp 224.0.0.204 2869). To separate different route use '|' ", + "type": Attribute.STRING, + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, + "validation_function": validation.is_string + }), + "sudo": dict({ "name": "sudo", "help": "Run with root privileges", "type": Attribute.BOOL, @@ -1158,6 +1179,24 @@ attributes = dict({ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, "validation_function": validation.is_string }), + "ccnsources": dict({ + "name": "ccnsources", + "help": "Path to local tar with ccnx sources." + "Default source is http://www.ccnx.org/releases/ccnx-0.5.1.tar.gz", + "type": Attribute.STRING, + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, + "validation_function": validation.is_string + }), + "ccnxversion": dict({ + "name": "ccnxversion", + "help": "Version of ccnx source code to install in the node.", + "type": Attribute.ENUM, + "value": "ccnx-0.6.0", + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, + "allowed": ["ccnx-0.6.0", + "ccnx-0.5.1"], + "validation_function": validation.is_enum, + }), "build": dict({ "name": "build", "help": "Build commands to execute after deploying the sources. " @@ -1319,14 +1358,15 @@ create_order = [ INTERNET, NODE, NODEIFACE, CLASSQUEUEFILTER, TOSQUEUEFILTER, MULTICASTANNOUNCER, MULTICASTFORWARDER, MULTICASTROUTER, TUNFILTER, TAPIFACE, TUNIFACE, NETPIPE, - NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, APPLICATION ] + NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, CCNXDAEMON, APPLICATION ] configure_order = [ INTERNET, Parallel(NODE), NODEIFACE, Parallel(MULTICASTANNOUNCER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTROUTER), Parallel(TAPIFACE), Parallel(TUNIFACE), NETPIPE, - Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(APPLICATION) ] + Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(CCNXDAEMON), + Parallel(APPLICATION)] # Start (and prestart) node after ifaces, because the node needs the ifaces in order to set up routes start_order = [ INTERNET, @@ -1334,11 +1374,13 @@ start_order = [ INTERNET, Parallel(TAPIFACE), Parallel(TUNIFACE), Parallel(NODE), NETPIPE, Parallel(MULTICASTANNOUNCER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTROUTER), - Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(APPLICATION) ] + Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), Parallel(CCNXDAEMON), + Parallel(APPLICATION)] # cleanup order shutdown_order = [ Parallel(APPLICATION), + Parallel (CCNXDAEMON), Parallel(MULTICASTROUTER), Parallel(MULTICASTFORWARDER), Parallel(MULTICASTANNOUNCER), Parallel(TAPIFACE), Parallel(TUNIFACE), Parallel(NETPIPE), Parallel(NEPIDEPENDENCY), Parallel(NS3DEPENDENCY), Parallel(DEPENDENCY), @@ -1361,6 +1403,10 @@ factories_info = dict({ "max_reliability", "min_bandwidth", "max_bandwidth", + "min_load", + "max_load", + "min_cpu", + "max_cpu", # NEPI-in-NEPI attributes ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP, @@ -1383,7 +1429,7 @@ factories_info = dict({ "create_function": create_tuniface, "preconfigure_function": preconfigure_tuniface, "configure_function": postconfigure_tuniface, - "prestart_function": wait_tuniface, + "prestart_function": prestart_tuniface, "box_attributes": [ "up", "if_name", "mtu", "snat", "pointopoint", "multicast", "bwlimit", "txqueuelen", @@ -1399,7 +1445,7 @@ factories_info = dict({ "create_function": create_tapiface, "preconfigure_function": preconfigure_tuniface, "configure_function": postconfigure_tuniface, - "prestart_function": wait_tuniface, + "prestart_function": prestart_tuniface, "box_attributes": [ "up", "if_name", "mtu", "snat", "pointopoint", "multicast", "bwlimit", "txqueuelen", @@ -1528,6 +1574,21 @@ factories_info = dict({ "traces": ["stdout", "stderr", "buildlog", "output"], "tags": [tags.APPLICATION], }), + + CCNXDAEMON: dict({ + "help": "CCNx daemon", + "category": FC.CATEGORY_APPLICATIONS, + "create_function": create_ccnxdaemon, + "prestart_function": prestart_ccnxdaemon, + "status_function": status_application, + "stop_function": stop_application, + "configure_function": configure_application, + "box_attributes": ["ccnroutes", "ccnsources", "build", + "install", "ccnxversion", "sources"], + "connector_types": ["node"], + "traces": ["stdout", "stderr", "buildlog", "output"], + "tags": [tags.APPLICATION], + }), DEPENDENCY: dict({ "help": "Requirement for package or application to be installed on some node", "category": FC.CATEGORY_APPLICATIONS, @@ -1623,6 +1684,20 @@ factories_info = dict({ }) testbed_attributes = dict({ + "slice_hrn": dict({ + "name": "sliceHrn", + "help": "The hierarchical Resource Name (HRN) for the PlanetLab slice.", + "type": Attribute.STRING, + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable | Attribute.NoDefaultValue, + "validation_function": validation.is_string + }), + "sfa": dict({ + "name": "sfa", + "help": "Activates the use of SFA for node reservation.", + "type": Attribute.BOOL, + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable | Attribute.NoDefaultValue, + "validation_function": validation.is_bool + }), "slice": dict({ "name": "slice", "help": "The name of the PlanetLab slice to use", @@ -1708,16 +1783,26 @@ testbed_attributes = dict({ "range": (2000,30000), "validation_function": validation.is_integer_range(2000,30000) }), - "dedicated_slice": dict({ - "name": "dedicatedSlice", + "clean_proc": dict({ + "name": "cleanProc", "help": "Set to True if the slice will be dedicated to this experiment. " - "NEPI will perform node and slice cleanup, making sure slices are " + "NEPI will perform node and slice process cleanup, making sure slices are " "in a clean, repeatable state before running the experiment.", "type": Attribute.BOOL, "value": False, "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, "validation_function": validation.is_bool }), + "clean_home": dict({ + "name": "cleanHome", + "help": "Set to True all preexistent directories in the home " + "directory of each sliver will be removed before the " + "start of the experiment.", + "type": Attribute.BOOL, + "value": False, + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, + "validation_function": validation.is_bool + }), }) supported_recovery_policies = [