From: Alina Quereilhac Date: Sun, 6 May 2012 14:18:37 +0000 (+0200) Subject: + Implemented option to cleanup directories on PlanetLab slivers. X-Git-Tag: nepi-3.0.0~163^2~16 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=99729cc9825f7351b9c4fdba580bb41278f50e9a;p=nepi.git + Implemented option to cleanup directories on PlanetLab slivers. --- diff --git a/examples/ccnx/ccnx-0.6.0rc3.tar.gz b/examples/ccnx/ccnx-0.6.0rc3.tar.gz new file mode 100644 index 00000000..48d6ff71 Binary files /dev/null and b/examples/ccnx/ccnx-0.6.0rc3.tar.gz differ diff --git a/examples/ccnx/planetlab_ccnx_unicast.py b/examples/ccnx/planetlab_ccnx_unicast.py index 3b5a673a..39c4489e 100644 --- a/examples/ccnx/planetlab_ccnx_unicast.py +++ b/examples/ccnx/planetlab_ccnx_unicast.py @@ -46,8 +46,12 @@ def create_slice_desc(slicename, plc_host, pl_user, pl_pwd, pl_ssh_key, slice_desc.set_attribute_value("authPass", pl_pwd) slice_desc.set_attribute_value("plcHost", plc_host) slice_desc.set_attribute_value("tapPortBase", port_base) + slice_desc.set_attribute_value("p2pDeployment", True) # Kills all running processes before starting the experiment - slice_desc.set_attribute_value("dedicatedSlice", True) + slice_desc.set_attribute_value("cleanProc", True) + # NOTICE: Setting 'cleanHome' to 'True' will erase all previous + # folders in the sliver Home directory, including result files! + #slice_desc.set_attribute_value("cleanHome", True) slice_desc.set_attribute_value("plLogLevel", "DEBUG") return slice_desc @@ -63,6 +67,17 @@ def create_node(hostname, pl_inet, slice_desc): def create_ccnd(pl_node, routes, slice_desc): pl_app = slice_desc.create("CCNxDaemon") + # We can specify a default ccnx version to be either ccnx-0.5.1 or ccnx-0.6.0 + #pl_app.set_attribute_value("ccnxversion", "ccnx-0.5.1") + # We can also specify a custom local source and build and install directives + path_to_source = os.path.join(os.path.dirname(os.path.abspath(__file__)), + "ccnx-0.6.0rc3.tar.gz") + pl_app.set_attribute_value("sources", path_to_source) + pl_app.set_attribute_value("build", + "tar xzf ${SOURCES}/ccnx-0.6.0rc3.tar.gz && " + "cd ./ccnx-0.6.0rc3 && " + "./configure && make ") + pl_app.set_attribute_value("install", "cp -r ./ccnx-0.6.0rc3/bin ${SOURCES}") # We use a wildcard to replace the public IP address of the node during runtime routes = "|".join(map(lambda route: "udp {#[iface_%s].addr[0].[Address]#}" % route, routes)) # Add multicast ccn routes @@ -177,7 +192,7 @@ if __name__ == '__main__': default_hostnames = ['openlab02.pl.sophia.inria.fr', 'ple4.ipv6.lip6.fr', 'planetlab2.di.unito.it', - 'merkur.planetlab.haw-hamburg.de', + #'merkur.planetlab.haw-hamburg.de', 'planetlab1.cs.uit.no', 'planetlab3.cs.st-andrews.ac.uk', 'planetlab2.cs.uoi.gr', diff --git a/src/nepi/testbeds/planetlab/application.py b/src/nepi/testbeds/planetlab/application.py index 53592ecb..da4748ae 100644 --- a/src/nepi/testbeds/planetlab/application.py +++ b/src/nepi/testbeds/planetlab/application.py @@ -567,7 +567,7 @@ class Dependency(object): def _do_install(self): if self.install: self._logger.info("Installing %s at %s", self, self.node.hostname) - + # Install application try: self._popen_ssh_command( @@ -1107,41 +1107,62 @@ class CCNxDaemon(Application): # Attributes self.ccnroutes = None self.ccnsources = None + self.ccnxversion = "ccnx-0.6.0" - self.default_ccnx_sources = "http://www.ccnx.org/releases/ccnx-0.5.1.tar.gz" + self.ccnx_0_5_1_sources = "http://www.ccnx.org/releases/ccnx-0.5.1.tar.gz" + self.ccnx_0_6_0_sources = "http://www.ccnx.org/releases/ccnx-0.6.0.tar.gz" self.buildDepends = 'make gcc development-tools openssl-devel expat-devel libpcap-devel libxml2-devel' - self.default_build = ( + self.ccnx_0_5_1_build = ( " ( " " cd .. && " - " test -d ccnx-src/build/bin " + " test -d ccnx-0.5.1-src/build/bin " " ) || ( " # Not working, rebuild "(" - " mkdir -p ccnx-src && " - " ( %(not_custom_source)s &&" - " wget -q -c -O ccnx-src.tar.gz %(ccnx_source_url)s &&" - " tar xf ccnx-src.tar.gz --strip-components=1 -C ccnx-src " - " ) || ( " - " tar xf %(user_ccnx_tar)s --strip-components=1 -C ccnx-src " - " ) " + " mkdir -p ccnx-0.5.1-src && " + " wget -q -c -O ccnx-0.5.1-src.tar.gz %(ccnx_source_url)s &&" + " tar xf ccnx-0.5.1-src.tar.gz --strip-components=1 -C ccnx-0.5.1-src " ") && " - "cd ccnx-src && " + "cd ccnx-0.5.1-src && " "mkdir -p build/include &&" "mkdir -p build/lib &&" "mkdir -p build/bin &&" "I=$PWD/build && " "INSTALL_BASE=$I ./configure &&" "make && make install" - " )") + " )") % dict( + ccnx_source_url = server.shell_escape(self.ccnx_0_5_1_sources), + ) + + self.ccnx_0_5_1_install = ( + " ( " + " test -d ${BUILD}/ccnx-0.5.1-src/build/bin && " + " cp -r ${BUILD}/ccnx-0.5.1-src/build/bin ${SOURCES}" + " )" + ) - self.default_install = ( + self.ccnx_0_6_0_build = ( " ( " " cd .. && " - " test -d ${SOURCES}/bin " + " test -d ccnx-0.6.0-src/build/bin " " ) || ( " - " test -d ${BUILD}/ccnx-src/build/bin && " - " cp -r ${BUILD}/ccnx-src/build/bin ${SOURCES}" + # Not working, rebuild + "(" + " mkdir -p ccnx-0.6.0-src && " + " wget -q -c -O ccnx-0.6.0-src.tar.gz %(ccnx_source_url)s &&" + " tar xf ccnx-0.6.0-src.tar.gz --strip-components=1 -C ccnx-0.6.0-src " + ") && " + "cd ccnx-0.6.0-src && " + "./configure && make" + " )") % dict( + ccnx_source_url = server.shell_escape(self.ccnx_0_6_0_sources), + ) + + self.ccnx_0_6_0_install = ( + " ( " + " test -d ${BUILD}/ccnx-0.6.0-src/bin && " + " cp -r ${BUILD}/ccnx-0.6.0-src/bin ${SOURCES}" " )" ) @@ -1149,22 +1170,17 @@ class CCNxDaemon(Application): def setup(self): # setting ccn sources - not_custom_source = "true" - sources = "" - if self.ccnsources: - self.sources = self.ccnsources - sources = "${SOURCES}/%s" % os.path.basename(self.ccnsources) - not_custom_source = "false" - if not self.build: - self.build = self.default_build % dict( - ccnx_source_url = server.shell_escape(self.default_ccnx_sources), - not_custom_source = server.shell_escape(not_custom_source), - user_ccnx_tar = sources - ) - + if self.ccnxversion == 'ccnx-0.6.0': + self.build = self.ccnx_0_6_0_build + elif self.ccnxversion == 'ccnx-0.5.1': + self.build = self.ccnx_0_5_1_build + if not self.install: - self.install = self.default_install + if self.ccnxversion == 'ccnx-0.6.0': + self.install = self.ccnx_0_6_0_install + elif self.ccnxversion == 'ccnx-0.5.1': + self.install = self.ccnx_0_5_1_install super(CCNxDaemon, self).setup() diff --git a/src/nepi/testbeds/planetlab/execute.py b/src/nepi/testbeds/planetlab/execute.py index e1095ee4..467d9fee 100644 --- a/src/nepi/testbeds/planetlab/execute.py +++ b/src/nepi/testbeds/planetlab/execute.py @@ -143,8 +143,10 @@ class TestbedController(testbed_impl.TestbedController): get_attribute_value("tapPortBase") self.p2pDeployment = self._attributes.\ get_attribute_value("p2pDeployment") - self.dedicatedSlice = self._attributes.\ - get_attribute_value("dedicatedSlice") + self.cleanProc = self._attributes.\ + get_attribute_value("cleanProc") + self.cleanHome = self._attributes.\ + get_attribute_value("cleanHome") self.sfa = self._attributes.\ get_attribute_value("sfa") if self.sfa: @@ -737,7 +739,8 @@ class TestbedController(testbed_impl.TestbedController): def _make_node(self, parameters): args = dict({'sliceapi': self.sliceapi}) node = self._make_generic(parameters, self._node.Node, **args) - node.enable_cleanup = self.dedicatedSlice + node.enable_proc_cleanup = self.cleanProc + node.enable_home_cleanup = self.cleanHome return node def _make_node_iface(self, parameters): diff --git a/src/nepi/testbeds/planetlab/metadata.py b/src/nepi/testbeds/planetlab/metadata.py index 7c7c5302..39f506dc 100644 --- a/src/nepi/testbeds/planetlab/metadata.py +++ b/src/nepi/testbeds/planetlab/metadata.py @@ -1187,6 +1187,16 @@ 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, + }), "build": dict({ "name": "build", "help": "Build commands to execute after deploying the sources. " @@ -1573,7 +1583,8 @@ factories_info = dict({ "status_function": status_application, "stop_function": stop_application, "configure_function": configure_application, - "box_attributes": ["ccnroutes", "ccnsources", "build", "install"], + "box_attributes": ["ccnroutes", "ccnsources", "build", + "install", "ccnxversion", "sources"], "connector_types": ["node"], "traces": ["stdout", "stderr", "buildlog", "output"], "tags": [tags.APPLICATION], @@ -1772,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 = [ diff --git a/src/nepi/testbeds/planetlab/node.py b/src/nepi/testbeds/planetlab/node.py index 52756007..41205e55 100644 --- a/src/nepi/testbeds/planetlab/node.py +++ b/src/nepi/testbeds/planetlab/node.py @@ -130,7 +130,8 @@ class Node(object): self.ident_path = None self.server_key = None self.home_path = None - self.enable_cleanup = False + self.enable_proc_cleanup = False + self.enable_home_cleanup = False # Those are filled when an actual node is allocated self._node_id = None @@ -497,9 +498,11 @@ class Node(object): raise UnresponsiveNodeError, "Unresponsive host %s" % (self.hostname,) # Ensure the node is clean (no apps running that could interfere with operations) - if self.enable_cleanup: - self.do_cleanup() - + if self.enable_proc_cleanup: + self.do_proc_cleanup() + if self.enable_home_cleanup: + self.do_home_cleanup() + def wait_dependencies(self, pidprobe=1, probe=0.5, pidmax=10, probemax=10): # Wait for the p2p installer if self._yum_dependencies and not self._installed: @@ -534,8 +537,10 @@ class Node(object): return False def destroy(self): - if self.enable_cleanup: - self.do_cleanup() + if self.enable_proc_cleanup: + self.do_proc_cleanup() + if self.enable_home_cleanup: + self.do_home_cleanup() def blacklist(self): if self._node_id: @@ -543,12 +548,12 @@ class Node(object): import util util.appendBlacklist(self.hostname) - def do_cleanup(self): + def do_proc_cleanup(self): if self.testbed().recovering: # WOW - not now return - self._logger.info("Cleaning up %s", self.hostname) + self._logger.info("Cleaning up processes on %s", self.hostname) cmds = [ "sudo -S killall python tcpdump || /bin/true ; " @@ -577,7 +582,36 @@ class Node(object): retry = 3 ) proc.wait() - + + def do_home_cleanup(self): + if self.testbed().recovering: + # WOW - not now + return + + self._logger.info("Cleaning up home on %s", self.hostname) + + cmds = [ + "find . -maxdepth 1 ! -name '.bash*' ! -name '.' -execdir rm -rf {} + " + ] + + for cmd in cmds: + (out,err),proc = server.popen_ssh_command( + # Some apps need two kills + cmd % { + 'slicename' : self.slicename , + }, + host = self.hostname, + port = None, + user = self.slicename, + agent = None, + ident_key = self.ident_path, + server_key = self.server_key, + tty = True, # so that ps -N -T works as advertised... + timeout = 60, + retry = 3 + ) + proc.wait() + def prepare_dependencies(self): # Configure p2p yum dependency installer if self.required_packages and not self._installed: