X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Ftestbeds%2Fplanetlab%2Fmetadata.py;h=9f1d14fa334646a4c0328d86a6650465632b4fe7;hb=dbbdae09cbc0c1a4dd98f3b0a27cf3a95262384b;hp=d099a8c5873a35db0e8709c553a1513ff46ca2f1;hpb=e4750fb2ceaa2117c93c6722674add32f8160cff;p=nepi.git diff --git a/src/nepi/testbeds/planetlab/metadata.py b/src/nepi/testbeds/planetlab/metadata.py index d099a8c5..9f1d14fa 100644 --- a/src/nepi/testbeds/planetlab/metadata.py +++ b/src/nepi/testbeds/planetlab/metadata.py @@ -22,6 +22,7 @@ NODEIFACE = "NodeInterface" TUNIFACE = "TunInterface" TAPIFACE = "TapInterface" APPLICATION = "Application" +CCNXDAEMON = "CCNxDaemon" DEPENDENCY = "Dependency" NEPIDEPENDENCY = "NepiDependency" NS3DEPENDENCY = "NS3Dependency" @@ -29,14 +30,15 @@ INTERNET = "Internet" NETPIPE = "NetPipe" TUNFILTER = "TunFilter" CLASSQUEUEFILTER = "ClassQueueFilter" +LOGGINGCLASSQUEUEFILTER = "LoggingClassQueueFilter" TOSQUEUEFILTER = "TosQueueFilter" MULTICASTFORWARDER = "MulticastForwarder" MULTICASTANNOUNCER = "MulticastAnnouncer" MULTICASTROUTER = "MulticastRouter" -TUNFILTERS = (TUNFILTER, CLASSQUEUEFILTER, TOSQUEUEFILTER) +TUNFILTERS = (TUNFILTER, CLASSQUEUEFILTER, LOGGINGCLASSQUEUEFILTER, TOSQUEUEFILTER) TAPFILTERS = (TUNFILTER, ) -ALLFILTERS = (TUNFILTER, CLASSQUEUEFILTER, TOSQUEUEFILTER) +ALLFILTERS = (TUNFILTER, CLASSQUEUEFILTER, LOGGINGCLASSQUEUEFILTER, TOSQUEUEFILTER) PL_TESTBED_ID = "planetlab" @@ -202,7 +204,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) @@ -309,6 +311,11 @@ def create_classqueuefilter(testbed_instance, guid): element = testbed_instance._make_class_queue_filter(parameters) testbed_instance.elements[guid] = element +def create_loggingclassqueuefilter(testbed_instance, guid): + parameters = testbed_instance._get_parameters(guid) + element = testbed_instance._make_logging_class_queue_filter(parameters) + testbed_instance.elements[guid] = element + def create_tosqueuefilter(testbed_instance, guid): parameters = testbed_instance._get_parameters(guid) element = testbed_instance._make_tos_queue_filter(parameters) @@ -323,6 +330,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) @@ -389,6 +406,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) @@ -414,6 +440,15 @@ def status_application(testbed_instance, guid): app = testbed_instance.elements[guid] return app.status() +def status_dependency(testbed_instance, guid): + if guid not in testbed_instance.elements.keys(): + return AS.STATUS_NOT_STARTED + + dep = testbed_instance.elements[guid] + if dep.deployed(): + return AS.STATUS_RUNNING + return AS.STATUS_FINISHED + ### Configure functions ### def configure_nodeiface(testbed_instance, guid): @@ -696,7 +731,7 @@ connections = [ }), dict({ "from": (TESTBED_ID, NODE, "apps"), - "to": (TESTBED_ID, (APPLICATION, MULTICASTANNOUNCER), "node"), + "to": (TESTBED_ID, (APPLICATION, CCNXDAEMON, MULTICASTANNOUNCER), "node"), "init_code": connect_dep, "can_cross": False }), @@ -1022,12 +1057,25 @@ attributes = dict({ "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, "validation_function": validation.is_number, }), - + "timeframe": dict({ + "name": "timeframe", + "help": "Past time period in which to check information about the node. Values are year,month, week, latest", + "type": Attribute.ENUM, + "value": "week", + "flags": Attribute.ExecReadOnly | Attribute.ExecImmutable, + "allowed": ["latest", + "week", + "month", + "year"], + "validation_function": validation.is_enum, + }), + "up": dict({ "name": "up", "help": "Link up", "type": Attribute.BOOL, - "value": False, + "value": True, + "flags": Attribute.NoDefaultValue, "validation_function": validation.is_bool }), "primary": dict({ @@ -1106,7 +1154,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, @@ -1152,6 +1207,26 @@ attributes = dict({ "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, + }), + "ccnlocalport" : dict({ + "name" : "ccnLocalPort", + "help" : "Local port to bind the ccn daemon. (i.e. CCN_LOCAL_PORT=)", + "type" : Attribute.INTEGER, + "flags" : Attribute.DesignInvisible | \ + Attribute.ExecInvisible | \ + Attribute.ExecImmutable | \ + Attribute.Metadata, + "validation_function" : validation.is_integer, + }), "build": dict({ "name": "build", "help": "Build commands to execute after deploying the sources. " @@ -1307,20 +1382,29 @@ traces = dict({ "name": "dropped_stats", "help": "Information on dropped packets on a filer or queue associated to a network interface", }), + "queue_stats_f": dict({ + "name": "queue_stats_f", + "help": "Detailled, fine-grained information on egress queue state, csv format.", + }), + "queue_stats_b": dict({ + "name": "queue_stats_b", + "help": "Detailled, fine-grained information on ingress queue state, csv format.", + }), }) create_order = [ - INTERNET, NODE, NODEIFACE, CLASSQUEUEFILTER, TOSQUEUEFILTER, + INTERNET, NODE, NODEIFACE, CLASSQUEUEFILTER, LOGGINGCLASSQUEUEFILTER, 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, @@ -1328,11 +1412,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), @@ -1359,6 +1445,7 @@ factories_info = dict({ "max_load", "min_cpu", "max_cpu", + "timeframe", # NEPI-in-NEPI attributes ATTR_NEPI_TESTBED_ENVIRONMENT_SETUP, @@ -1464,7 +1551,7 @@ factories_info = dict({ "connector_types": ["->fd","udp","tcp"], }), CLASSQUEUEFILTER : dict({ - "help": "TUN classfull queue, uses a separate queue for each user-definable class.\n\n" + "help": "TUN classful queue, uses a separate queue for each user-definable class.\n\n" "It takes two arguments, both of which have sensible defaults:\n" "\tsize: the base size of each class' queue\n" "\tclasses: the class definitions, which follow the following syntax:\n" @@ -1498,6 +1585,18 @@ factories_info = dict({ "connector_types": ["->fd","udp","tcp"], "traces": ["dropped_stats"], }), + LOGGINGCLASSQUEUEFILTER : dict({ + "help": "TUN classful queue, uses a separate queue for each user-definable class.\n" + "See ClassQueueFilter. This version adds detailled queue state tracing.", + "category": FC.CATEGORY_CHANNELS, + "create_function": create_loggingclassqueuefilter, + "box_attributes": [ + "args", + "tun_proto", "tun_addr", "tun_port", "tun_key", "tun_cipher", + ], + "connector_types": ["->fd","udp","tcp"], + "traces": ["dropped_stats","queue_stats_f","queue_stats_b"], + }), TOSQUEUEFILTER : dict({ "help": "TUN classfull queue that classifies according to the TOS (RFC 791) IP field.\n\n" "It takes a size argument that specifies the size of each class. As TOS is a " @@ -1526,11 +1625,27 @@ 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", "build", "ccnlocalport", + "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, "create_function": create_dependency, "preconfigure_function": configure_dependency, + "status_function": status_dependency, "box_attributes": ["depends", "build-depends", "build", "install", "sources", "rpm-fusion" ], "connector_types": ["node"], @@ -1621,6 +1736,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", @@ -1689,7 +1818,7 @@ testbed_attributes = dict({ "pl_log_level": dict({ "name": "plLogLevel", "help": "Verbosity of logging of planetlab events.", - "value": "ERROR", + "value": "INFO", "type": Attribute.ENUM, "allowed": ["DEBUG", "INFO", @@ -1706,16 +1835,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 = [