Replacing RM.rtype() for RM.get_type() for consistency
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Thu, 21 Nov 2013 19:26:47 +0000 (20:26 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Thu, 21 Nov 2013 19:26:47 +0000 (20:26 +0100)
27 files changed:
doc/user_manual/ec_api.tex
doc/user_manual/release_cycle.tex
doc/user_manual/user_manual.pdf
doc/user_manual/user_manual.tex
src/nepi/execution/ec.py
src/nepi/execution/resource.py
src/nepi/execution/trace.py
src/nepi/resources/linux/application.py
src/nepi/resources/linux/ccn/ccnapplication.py
src/nepi/resources/linux/ccn/ccncontent.py
src/nepi/resources/linux/ccn/ccnping.py
src/nepi/resources/linux/ccn/ccnr.py
src/nepi/resources/linux/ccn/fibentry.py
src/nepi/resources/linux/interface.py
src/nepi/resources/linux/node.py
src/nepi/resources/omf/application.py
src/nepi/resources/omf/channel.py
src/nepi/resources/omf/interface.py
src/nepi/resources/omf/node.py
src/nepi/resources/planetlab/openvswitch/ovs.py
src/nepi/resources/planetlab/openvswitch/ovsport.py
src/nepi/resources/planetlab/openvswitch/tunnel.py
src/nepi/resources/planetlab/tap.py
test/execution/resource.py
test/resources/linux/application.py
test/resources/omf/vlc_normal_case.py
test/resources/planetlab/node.py

index 68599dd..4c3cd25 100644 (file)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
-\begin{itemize}
-  \item EC API
-    \begin{itemize}
-        \item register resource
-        \item RM States (State transition DIAGRAM)
-        \item RM Actions
-        \item Attributes
-        \item The critical attribute
-        \item Traces (how to collect traces to the local repo, talk about the Collector RM)
-        \item deploy (interactive deployment)
-        \item workflow - register condition
-    \end{itemize}
-  \item Resource Factory
-    \begin{itemize}
-        \item Populate factory (happens automatically)
-        \item How to discover available rm types and their resources
-    \end{itemize}
-\end{itemize}
+The ExperimentController (EC) is the entity in charge of turning the 
+experiment description into a running experiment. 
+In order to do this the EC needs to know which resources are to be 
+used, how they should be configured and how resources relate to one another.
+To this pourpose the EC exposes methods to register resources, specify their 
+configuration, and register dependencies between. These methods are part of
+the EC design API.
+Likewise, in order to deploy and control resources, and collect data, 
+the EC exposes another set of methods, which form the execution API. 
+These two APIs are described in detail in the rest of this chapter.
+
+\section{The experiment script}
+
+NEPI is a Python-based language and all classes and functions can
+be used by importing the \emph{nepi} module from a Python script.
+
+In particular, the ExperimentController class can be imported as follows:
+
+\begin{lstlisting}[language=Python]
+
+from nepi.execution.ec import ExperimentController
+
+\end{lstlisting}
+
+Once this is done, an ExperimentController instance must be instantiated
+for a particular experiment. The ExperimentController constructor receives
+the optional argument \emph{exp\_id}. This argument is important because
+it defines the experiment identity and allows to distinguish among different
+experiments. If an experiment id is not explicitly given, NEPI will automatically
+generate a unique id for the experiment. 
+
+\begin{lstlisting}[language=Python]
+
+ec = ExperimentController(exp_id = "my-exp-id")
+
+\end{lstlisting}
+
+The experiment id can always be retrieved as follows
+
+\begin{lstlisting}[language=Python]
+
+exp_id = ec.exp_id 
+
+\end{lstlisting}
+
+%TODO: What is the run_id ??
+
+\section{The design API}
+
+Once an ExperimentController has been instantiated, it is possible to start
+describing the experiment. The design API is the set of methods which
+allow to do so.
+
+\subsection{Registering resources}
+
+Every resource supported by NEPI is controlled by a specific ResourceManager 
+(RM). The RM instances are automatically created by the EC, and the user does 
+not need to interact with them directly. 
+
+Each type of RM is associated with a \emph{type\_id} which uniquely identifies 
+a concrete kind of resource (e.g PlanetLab node, application that runs in
+a Linux machine, etc).
+The \emph{type\_ids} are string identifiers, and they are required  
+to register a resource with the EC.
+
+To discover all the available RMs and their \emph{type\_ids} we
+can make use of the ResourceFactory class.
+This class is a \emph{Singleton} that holds the templates and information 
+of all the RMs supported by NEPI. We can retrieve this information as follows:
+
+\begin{lstlisting}[language=Python]
+
+from nepi.execution.resource import ResourceFactory
+
+for type_id in ResourceFactory.resource_types():
+    rm_type = ResourceFactory.get_resource_type(type_id)
+    print type_id, ":", rm_type.get_help()
+
+\end{lstlisting}
+
+Once the \emph{type\_id} of the resource is known, the registration of a
+new resource with the EC is simple:
+
+\begin{lstlisting}[language=Python]
+
+type_id = "SomeRMType"
+guid = ec.register_resources(type_id)
+
+\end{lstlisting}
+
+When a resource is registered, the EC instantiates a RM of the 
+requested \emph{type\_id} and assigns a global unique identifier 
+(guid) to it. The guid is an incremental integer number and it 
+is the value returned by the \emph{register\_resource} method.
+The EC keeps internal references to all RMs, which the user can
+reference using the corresponding guid value.
+
+\subsection{Attributes}
+
+ResourceManagers expose the configurable parameters of resources
+through a list of attributes. An attribute can be seen as a
+\emph{{name:value}} pair, that represents a certain aspect of
+the resource (whether information or configuration information).
+
+It is possible to discover the list of attributes exposed by an 
+RM type as follows:
+
+\begin{lstlisting}[language=Python]
+from nepi.execution.resource import ResourceFactory
+
+type_id = "SomeRMType"
+rm_type = ResourceFactory.get_resource_type(type_id)
+
+for attr in rm_type.get_attributes():
+    print "       ",  attr.name, ":", attr.help
+    
+\end{lstlisting}
+
+To configure or retrieve the value of a certain attribute of
+an registered resource we can use the \emph{get} and \emph{set}
+methods of the EC.
+
+\begin{lstlisting}[language=Python]
+
+old_value = ec.get(guid, "attr_name")
+ec.set(guid, "attr_name", new_value)
+new_value = ec.get(guid, "attr_name")
+
+\end{lstlisting}
+
+% Critical attribute
+Since each RM type exposes the characteristics of a particular type
+of resource, it is to be expected that different RMs will have different
+attributes. However, there a particular attribute that is common to all RMs.
+This is the \emph{critical} attribute, and it is meant to indicate to the EC
+how it should behave when a failure occurs during the experiment. 
+The \emph{critical} attribute has a default value of \emph{True}, since
+all resources are considered critical by default. 
+When this attribute is set to \emph{False} the EC will ignore failures on that 
+resource and carry on with the experiment. Otherwise, the EC will immediately 
+interrupt the experiment.
+
+\subsection{Traces}
+
+A Trace represent a stream of data collected during the experiment and associated
+to a single resource. ResourceManagers expose a list of traces, which are identified
+by a name. Particular traces might or might not need activation, since some traces
+are enabled by default.
+
+It is possible to discover the list of traces exposed by an 
+RM type as follows:
+
+\begin{lstlisting}[language=Python]
+from nepi.execution.resource import ResourceFactory
+
+type_id = "SomeRMType"
+rm_type = ResourceFactory.get_resource_type(type_id)
+
+for trace in rm_type.get_traces():
+    print "       ",  trace.name, ":", trace.enabled
+    
+\end{lstlisting}
+
+The \emph{enable\_trace} method allows to enable a specific trace for a 
+RM instance
+
+\begin{lstlisting}[language=Python]
+
+ec.enable_trace(guid, "trace-name")
+
+print ec.trace_enabled(guid, "trace-name")
+
+\end{lstlisting}
+
+\subsection{Registering connections}
+
+\subsection{States and actions}
+
+\subsection{Registering conditions}
+
+\section{The execution API}
+
+\subsection{Deploying an experiment}
+
+%TODO: Talk about groups
+%TODO: Talk about interactive deploymet
+
+\subsection{Getting attributes}
+
+\subsection{Quering the state}
+
+\subsection{Getting traces}
+    
+% TODO: Give examples of Traces (how to collect traces to the local repo, talk about the Collector RM)
+
+% how to retrieve an application trace when the Node failed? (critical attribute)
+
+\subsection{The collector RM}
+
+
+
 
index 7b628d2..358b03d 100644 (file)
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+Releases in NEPI do not occur in strictly regular periods. Usually a new
+release will be done every 4 or 5 months.
+
+\section{The development branch}
+
+The main development branch for NEPI 3 is \emph{nepi-3-dev}. 
+There might be other branches to develop new features, but they will 
+eventually end up being merged into the \emph{nepi-3-dev} branch. 
+
+\section{Versioning}
+
+Releases are named following the \emph{major.minor.revision} convention.
+The \emph{major} number reflects a major change in functionality or architecture. 
+It is to be expected that this number will remind in 3 for a long period.
+
+The \emph{minor} number reflects the incorporation of new features into NEPI.
+This number is expected to be increased on each release.
+
+The \emph{revision} number is incremented when a considerable number of
+bugs have been fixed. No release will be done when only the \emph{revision}
+number is incremented.
+
+\section{The release process}
+
+The creation of a new NEPI release will always follow the same sequence of steps.
+
+\begin{enumerate}
+  \item A new \emph{nepi-3.<minor>-pre-release} branch will be created from the \emph{nepi-3-dev} branch
+  \item During two to three weeks intensive work on testing will be carried out on the new branch. No new functionality will be added on this branch and only changes that fix bugs will be accepted.
+  \item At the end of this period, the pre-release branch will be branched again into the release branch, named \emph{nepi-3.<minor>-release}
+  \item A tag will be added to this new branch including the revision number (i.e. \emph{release-3.<minor>.<revision>})
+  \item Finally, the pre-release branch will be merged into the development branch, nepi-3-dev, to incorporate to it all the bug fixes.
+\end{enumerate}
+
 %%TODO: Explain how to create patch
 
-TODO
index 7a2b557..44dd84b 100644 (file)
Binary files a/doc/user_manual/user_manual.pdf and b/doc/user_manual/user_manual.pdf differ
index 7dbf1e9..bb1da3f 100644 (file)
 %%\label{unit_testing}
 %%\input{unit_testing.tex}
 
-%%\chapter{Release Cycle}
-%%\label{release_cycle}
-%%\input{release_cycle.tex}
+\chapter{Release Cycle}
+\label{release_cycle}
+\input{release_cycle.tex}
 
 %%\chapter{Coding Style}
 %%\label{coding_style}
index ec216b7..aa83517 100644 (file)
@@ -326,7 +326,7 @@ class ExperimentController(object):
                 guids.remove(guid)
                 rm = self.get_resource(guid)
                 self.logger.debug(" %s guid %d DONE - state is %s, required is >= %s " % (
-                    rm.rtype(), guid, hrrstate, hrstate))
+                    rm.get_rtype(), guid, hrrstate, hrstate))
             else:
                 # Debug...
                 self.logger.debug(" WAITING FOR guid %d - state is %s, required is >= %s " % (
index 325895a..a6238b1 100644 (file)
@@ -248,7 +248,7 @@ class ResourceManager(Logger):
         cls._register_traces()
 
     @classmethod
-    def rtype(cls):
+    def get_rtype(cls):
         """ Returns the type of the Resource Manager
 
         """
@@ -284,7 +284,7 @@ class ResourceManager(Logger):
         return cls._backend
 
     def __init__(self, ec, guid):
-        super(ResourceManager, self).__init__(self.rtype())
+        super(ResourceManager, self).__init__(self.get_rtype())
         
         self._guid = guid
         self._ec = weakref.ref(ec)
@@ -1032,7 +1032,7 @@ class ResourceFactory(object):
     @classmethod
     def register_type(cls, rclass):
         """Register a new Ressource Manager"""
-        cls._resource_types[rclass.rtype()] = rclass
+        cls._resource_types[rclass.get_rtype()] = rclass
 
     @classmethod
     def create(cls, rtype, ec, guid):
index 19065db..4ad5774 100644 (file)
@@ -37,10 +37,10 @@ class Trace(object):
 
     """
 
-    def __init__(self, name, help):
+    def __init__(self, name, help, enabled = False):
         self._name = name
         self._help = help
-        self.enabled = False
+        self.enabled = enabled
 
     @property
     def name(self):
index c1de543..8cac699 100644 (file)
@@ -163,8 +163,8 @@ class LinuxApplication(ResourceManager):
 
     @classmethod
     def _register_traces(cls):
-        stdout = Trace("stdout", "Standard output stream")
-        stderr = Trace("stderr", "Standard error stream")
+        stdout = Trace("stdout", "Standard output stream", enabled = True)
+        stderr = Trace("stderr", "Standard error stream", enabled = True)
 
         cls._register_trace(stdout)
         cls._register_trace(stderr)
@@ -194,7 +194,7 @@ class LinuxApplication(ResourceManager):
 
     @property
     def node(self):
-        node = self.get_connected(LinuxNode.rtype())
+        node = self.get_connected(LinuxNode.get_rtype())
         if node: return node[0]
         return None
 
index ec5312e..89c949c 100644 (file)
@@ -35,7 +35,7 @@ class LinuxCCNApplication(LinuxApplication):
 
     @property
     def ccnd(self):
-        ccnd = self.get_connected(LinuxCCND.rtype())
+        ccnd = self.get_connected(LinuxCCND.get_rtype())
         if ccnd: return ccnd[0]
         return None
 
index 2595eda..84f6185 100644 (file)
@@ -58,7 +58,7 @@ class LinuxCCNContent(LinuxApplication):
         
     @property
     def ccnr(self):
-        ccnr = self.get_connected(LinuxCCNR.rtype())
+        ccnr = self.get_connected(LinuxCCNR.get_rtype())
         if ccnr: return ccnr[0]
         return None
 
index 934db3c..f654a2a 100644 (file)
@@ -61,7 +61,7 @@ class LinuxCCNPing(LinuxCCNPingServer):
 
     @property
     def ccnpingserver(self):
-        ccnpingserver = self.get_connected(LinuxCCNPingServer.rtype())
+        ccnpingserver = self.get_connected(LinuxCCNPingServer.get_rtype())
         if ccnpingserver: return ccnpingserver[0]
         return None
 
index 6213b74..e65779a 100644 (file)
@@ -191,7 +191,7 @@ class LinuxCCNR(LinuxApplication):
 
     @property
     def ccnd(self):
-        ccnd = self.get_connected(LinuxCCND.rtype())
+        ccnd = self.get_connected(LinuxCCND.get_rtype())
         if ccnd: return ccnd[0]
         return None
 
index 1010f2f..cebc105 100644 (file)
@@ -90,7 +90,7 @@ class LinuxFIBEntry(LinuxApplication):
 
     @property
     def ccnd(self):
-        ccnd = self.get_connected(LinuxCCND.rtype())
+        ccnd = self.get_connected(LinuxCCND.get_rtype())
         if ccnd: return ccnd[0]
         return None
 
index 59bbe2a..7b8eadc 100644 (file)
@@ -92,13 +92,13 @@ class LinuxInterface(ResourceManager):
 
     @property
     def node(self):
-        node = self.get_connected(LinuxNode.rtype())
+        node = self.get_connected(LinuxNode.get_rtype())
         if node: return node[0]
         return None
 
     @property
     def channel(self):
-        chan = self.get_connected(LinuxChannel.rtype())
+        chan = self.get_connected(LinuxChannel.get_rtype())
         if chan: return chan[0]
         return None
 
index b547ce5..cbc0099 100644 (file)
@@ -298,24 +298,16 @@ class LinuxNode(ResourceManager):
         # To work arround this, repeat the operation N times or
         # until the result is not empty string
         out = ""
-        retrydelay = 1.0
-        for i in xrange(2):
-            try:
-                (out, err), proc = self.execute("cat /etc/issue", 
-                        retry = 5,
-                        with_lock = True,
-                        blocking = True)
-
-                if out.strip() != "":
-                    return out
-            except:
-                trace = traceback.format_exc()
-                msg = "Error detecting OS: %s " % trace
-                self.error(msg, out, err)
-                return False
-
-            time.sleep(min(30.0, retrydelay))
-            retrydelay *= 1.5
+        try:
+            (out, err), proc = self.execute("cat /etc/issue", 
+                    with_lock = True,
+                    blocking = True)
+        except:
+            trace = traceback.format_exc()
+            msg = "Error detecting OS: %s " % trace
+            self.error(msg, out, err)
+        
+        return out
 
     @property
     def use_deb(self):
@@ -368,7 +360,7 @@ class LinuxNode(ResourceManager):
         # Node needs to wait until all associated interfaces are 
         # ready before it can finalize deployment
         from nepi.resources.linux.interface import LinuxInterface
-        ifaces = self.get_connected(LinuxInterface.rtype())
+        ifaces = self.get_connected(LinuxInterface.get_rtype())
         for iface in ifaces:
             if iface.state < ResourceState.READY:
                 self.ec.schedule(reschedule_delay, self.deploy)
@@ -963,35 +955,25 @@ class LinuxNode(ResourceManager):
             return True
 
         out = err = ""
+        msg = "Unresponsive host. Wrong answer. "
+
         # The underlying SSH layer will sometimes return an empty
         # output (even if the command was executed without errors).
         # To work arround this, repeat the operation N times or
         # until the result is not empty string
-        retrydelay = 1.0
-        for i in xrange(2):
-            try:
-                (out, err), proc = self.execute("echo 'ALIVE'",
-                        retry = 5,
-                        blocking = True,
-                        with_lock = True)
-        
-                if out.find("ALIVE") > -1:
-                    return True
-            except:
-                trace = traceback.format_exc()
-                msg = "Unresponsive host. Error reaching host: %s " % trace
-                self.error(msg, out, err)
-                return False
-
-            time.sleep(min(30.0, retrydelay))
-            retrydelay *= 1.5
+        try:
+            (out, err), proc = self.execute("echo 'ALIVE'",
+                    blocking = True,
+                    with_lock = True)
+    
+            if out.find("ALIVE") > -1:
+                return True
+        except:
+            trace = traceback.format_exc()
+            msg = "Unresponsive host. Error reaching host: %s " % trace
 
-        if out.find("ALIVE") > -1:
-            return True
-        else:
-            msg = "Unresponsive host. Wrong answer. "
-            self.error(msg, out, err)
-            return False
+        self.error(msg, out, err)
+        return False
 
     def find_home(self):
         """ Retrieves host home directory
@@ -1000,28 +982,19 @@ class LinuxNode(ResourceManager):
         # output (even if the command was executed without errors).
         # To work arround this, repeat the operation N times or
         # until the result is not empty string
-        retrydelay = 1.0
-        for i in xrange(2):
-            try:
-                (out, err), proc = self.execute("echo ${HOME}",
-                        retry = 5,
-                        blocking = True,
-                        with_lock = True)
-        
-                if out.strip() != "":
-                    self._home_dir =  out.strip()
-                    break
-            except:
-                trace = traceback.format_exc()
-                msg = "Impossible to retrieve HOME directory" % trace
-                self.error(msg, out, err)
-                return False
-
-            time.sleep(min(30.0, retrydelay))
-            retrydelay *= 1.5
+        msg = "Impossible to retrieve HOME directory"
+        try:
+            (out, err), proc = self.execute("echo ${HOME}",
+                    blocking = True,
+                    with_lock = True)
+    
+            if out.strip() != "":
+                self._home_dir =  out.strip()
+        except:
+            trace = traceback.format_exc()
+            msg = "Impossible to retrieve HOME directory" % trace
 
         if not self._home_dir:
-            msg = "Impossible to retrieve HOME directory"
             self.error(msg, out, err)
             raise RuntimeError, msg
 
index 6ce9923..65f1f4a 100644 (file)
@@ -102,7 +102,7 @@ class OMFApplication(OMFResource):
 
     @property
     def node(self):
-        rm_list = self.get_connected(OMFNode.rtype())
+        rm_list = self.get_connected(OMFNode.get_rtype())
         if rm_list: return rm_list[0]
         return None
 
@@ -124,10 +124,10 @@ class OMFApplication(OMFResource):
 
         """
         rm = self.ec.get_resource(guid)
-        if rm.rtype() not in self._authorized_connections:
+        if rm.get_rtype() not in self._authorized_connections:
             msg = ("Connection between %s %s and %s %s refused: "
                     "An Application can be connected only to a Node" ) % \
-                (self.rtype(), self._guid, rm.rtype(), guid)
+                (self.get_rtype(), self._guid, rm.get_rtype(), guid)
             self.debug(msg)
 
             return False
@@ -135,14 +135,14 @@ class OMFApplication(OMFResource):
         elif len(self.connections) != 0 :
             msg = ("Connection between %s %s and %s %s refused: "
                     "This Application is already connected" ) % \
-                (self.rtype(), self._guid, rm.rtype(), guid)
+                (self.get_rtype(), self._guid, rm.get_rtype(), guid)
             self.debug(msg)
 
             return False
 
         else :
             msg = "Connection between %s %s and %s %s accepted" % (
-                    self.rtype(), self._guid, rm.rtype(), guid)
+                    self.get_rtype(), self._guid, rm.get_rtype(), guid)
             self.debug(msg)
 
             return True
@@ -195,7 +195,7 @@ class OMFApplication(OMFResource):
             self.set('env', " ")
 
         # Some information to check the information in parameter
-        msg = " " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + \
+        msg = " " + self.get_rtype() + " ( Guid : " + str(self._guid) +") : " + \
             self.get('appid') + " : " + self.get('path') + " : " + \
             self.get('args') + " : " + self.get('env')
         self.info(msg)
index 707c95c..17478fd 100644 (file)
@@ -85,14 +85,14 @@ class OMFChannel(OMFResource):
         """
         rm = self.ec.get_resource(guid)
         
-        if rm.rtype() in self._authorized_connections:
+        if rm.get_rtype() in self._authorized_connections:
             msg = "Connection between %s %s and %s %s accepted" % (
-                    self.rtype(), self._guid, rm.rtype(), guid)
+                    self.get_rtype(), self._guid, rm.get_rtype(), guid)
             self.debug(msg)
             return True
 
         msg = "Connection between %s %s and %s %s refused" % (
-                self.rtype(), self._guid, rm.rtype(), guid)
+                self.get_rtype(), self._guid, rm.get_rtype(), guid)
         self.debug(msg)
         
         return False
@@ -112,7 +112,7 @@ class OMFChannel(OMFResource):
             rm_iface = self.ec.get_resource(elt)
             for conn in rm_iface.connections:
                 rm_node = self.ec.get_resource(conn)
-                if rm_node.rtype() == "OMFNode" and rm_node.get('hostname'):
+                if rm_node.get_rtype() == "OMFNode" and rm_node.get('hostname'):
                     if rm_iface.state < ResourceState.PROVISIONED or \
                             rm_node.state < ResourceState.READY:
                         return "reschedule"
index 46d5ea1..cd2fb9d 100644 (file)
@@ -93,15 +93,15 @@ class OMFWifiInterface(OMFResource):
 
         """
         rm = self.ec.get_resource(guid)
-        if rm.rtype() in self._authorized_connections:
+        if rm.get_rtype() in self._authorized_connections:
             msg = "Connection between %s %s and %s %s accepted" % \
-                (self.rtype(), self._guid, rm.rtype(), guid)
+                (self.get_rtype(), self._guid, rm.get_rtype(), guid)
             self.debug(msg)
 
             return True
 
         msg = "Connection between %s %s and %s %s refused" % \
-             (self.rtype(), self._guid, rm.rtype(), guid)
+             (self.get_rtype(), self._guid, rm.get_rtype(), guid)
         self.debug(msg)
 
         return False
@@ -112,13 +112,13 @@ class OMFWifiInterface(OMFResource):
 
     @property
     def node(self):
-        rm_list = self.get_connected(OMFNode.rtype())
+        rm_list = self.get_connected(OMFNode.get_rtype())
         if rm_list: return rm_list[0]
         return None
 
     @property
     def channel(self):
-        rm_list = self.get_connected(OMFChannel.rtype())
+        rm_list = self.get_connected(OMFChannel.get_rtype())
         if rm_list: return rm_list[0]
         return None
 
@@ -187,7 +187,7 @@ class OMFWifiInterface(OMFResource):
             raise RuntimeError, msg
 
         # Just for information
-        self.debug(" " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + \
+        self.debug(" " + self.get_rtype() + " ( Guid : " + str(self._guid) +") : " + \
             self.get('mode') + " : " + self.get('type') + " : " + \
             self.get('essid') + " : " + self.get('ip'))
     
index daa8743..a028d7b 100644 (file)
@@ -83,15 +83,15 @@ class OMFNode(OMFResource):
 
         """
         rm = self.ec.get_resource(guid)
-        if rm.rtype() in self._authorized_connections:
+        if rm.get_rtype() in self._authorized_connections:
             msg = "Connection between %s %s and %s %s accepted" % (
-                    self.rtype(), self._guid, rm.rtype(), guid)
+                    self.get_rtype(), self._guid, rm.get_rtype(), guid)
             self.debug(msg)
 
             return True
 
         msg = "Connection between %s %s and %s %s refused" % (
-                self.rtype(), self._guid, rm.rtype(), guid)
+                self.get_rtype(), self._guid, rm.get_rtype(), guid)
         self.debug(msg)
 
         return False
index 32552e0..a201329 100644 (file)
@@ -72,7 +72,7 @@ class OVSWitch(LinuxApplication):
 
     @property
     def node(self):
-        node = self.get_connected(PlanetlabNode.rtype())
+        node = self.get_connected(PlanetlabNode.get_rtype())
         if node: return node[0]
         return None
 
@@ -101,13 +101,13 @@ class OVSWitch(LinuxApplication):
 
 #        """
 #        rm = self.ec.get_resource(guid)
-#        if rm.rtype() in self._authorized_connections:
+#        if rm.get_rtype() in self._authorized_connections:
 #            msg = "Connection between %s %s and %s %s accepted" % \
-#                (self.rtype(), self._guid, rm.rtype(), guid)
+#                (self.get_rtype(), self._guid, rm.get_rtype(), guid)
 #            self.debug(msg)
 #            return True
 #        msg = "Connection between %s %s and %s %s refused" % \
-#             (self.rtype(), self._guid, rm.rtype(), guid)
+#             (self.get_rtype(), self._guid, rm.get_rtype(), guid)
 #        self.debug(msg)
 #        return False
 
@@ -291,7 +291,7 @@ class OVSWitch(LinuxApplication):
         # Node needs to wait until all associated RMs are released
         # to be released
         from nepi.resources.planetlab.openvswitch.ovsport import OVSPort
-        rm = self.get_connected(OVSPort.rtype())
+        rm = self.get_connected(OVSPort.get_rtype())
 
         if rm[0].state < ResourceState.FINISHED:
             self.ec.schedule(reschedule_delay, self.release)
index a78c66a..bb84af6 100644 (file)
@@ -69,16 +69,16 @@ class OVSPort(LinuxApplication):
 
     @property
     def node(self):
-        rm_list = self.get_connected(OVSWitch.rtype())
+        rm_list = self.get_connected(OVSWitch.get_rtype())
         if rm_list:
             for elt in rm_list:
-                node = elt.get_connected(PlanetlabNode.rtype())
+                node = elt.get_connected(PlanetlabNode.get_rtype())
                 if node: return node[0]
         return node[0]
 
     @property
     def ovswitch(self):
-        ovswitch = self.get_connected(OVSWitch.rtype())
+        ovswitch = self.get_connected(OVSWitch.get_rtype())
         if ovswitch: return ovswitch[0]
         return None
         
@@ -99,11 +99,11 @@ class OVSPort(LinuxApplication):
 
 #        """
 #        rm = self.ec.get_resource(guid)
-#        if rm.rtype() in self._authorized_connections:
-#            msg = "Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)
+#        if rm.get_rtype() in self._authorized_connections:
+#            msg = "Connection between %s %s and %s %s accepted" % (self.get_rtype(), self._guid, rm.get_rtype(), guid)
 #            self.debug(msg)
 #            return True
-#        msg = "Connection between %s %s and %s %s refused" % (self.rtype(), self._guid, rm.rtype(), guid)
+#        msg = "Connection between %s %s and %s %s refused" % (self.get_rtype(), self._guid, rm.get_rtype(), guid)
 #        self.debug(msg)
 
     def get_host_ip(self):
@@ -207,7 +207,7 @@ class OVSPort(LinuxApplication):
         # OVS needs to wait until all associated RMs are released
         # to be released
         from nepi.resources.planetlab.openvswitch.tunnel import OVSTunnel
-        rm = self.get_connected(OVSTunnel.rtype())
+        rm = self.get_connected(OVSTunnel.get_rtype())
 
         if rm and rm[0].state < ResourceState.FINISHED:
             self.ec.schedule(reschedule_delay, self.release)
index e27a512..a494212 100644 (file)
@@ -139,11 +139,11 @@ class OVSTunnel(LinuxApplication):
         # Get connected to the nodes
         res = []
         if hasattr(endpoint, "create_port"):
-            rm_list = endpoint.get_connected(OVSWitch.rtype())
+            rm_list = endpoint.get_connected(OVSWitch.get_rtype())
             if rm_list:
-                rm = rm_list[0].get_connected(PlanetlabNode.rtype())
+                rm = rm_list[0].get_connected(PlanetlabNode.get_rtype())
         else:
-            rm = endpoint.get_connected(PlanetlabNode.rtype())
+            rm = endpoint.get_connected(PlanetlabNode.get_rtype())
 
         if rm :
             res.append(rm[0])
index 736c973..fc15662 100644 (file)
@@ -88,10 +88,55 @@ class PlanetlabTap(LinuxApplication):
 
     @property
     def node(self):
-        node = self.get_connected(PlanetlabNode.rtype())
+        node = self.get_connected(PlanetlabNode.get_rtype())
         if node: return node[0]
         return None
 
+    """
+    def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
+        self.info("Retrieving '%s' trace %s " % (name, attr))
+
+        path = os.path.join(self.run_home, name)
+        
+        command = "(test -f %s && echo 'success') || echo 'error'" % path
+        (out, err), proc = self.node.execute(command)
+
+        if (err and proc.poll()) or out.find("error") != -1:
+            msg = " Couldn't find trace %s " % name
+            self.error(msg, out, err)
+            return None
+    
+        if attr == TraceAttr.PATH:
+            return path
+
+        if attr == TraceAttr.ALL:
+            (out, err), proc = self.node.check_output(self.run_home, name)
+            
+            if proc.poll():
+                msg = " Couldn't read trace %s " % name
+                self.error(msg, out, err)
+                return None
+
+            return out
+
+        if attr == TraceAttr.STREAM:
+            cmd = "dd if=%s bs=%d count=1 skip=%d" % (path, block, offset)
+        elif attr == TraceAttr.SIZE:
+            cmd = "stat -c%%s %s " % path
+
+        (out, err), proc = self.node.execute(cmd)
+
+        if proc.poll():
+            msg = " Couldn't find trace %s " % name
+            self.error(msg, out, err)
+            return None
+        
+        if attr == TraceAttr.SIZE:
+            out = int(out.strip())
+
+        return out
+    """
+
     def upload_sources(self):
         # upload vif-creation python script
         pl_vif_create = os.path.join(os.path.dirname(__file__), "scripts",
@@ -211,7 +256,7 @@ class PlanetlabTap(LinuxApplication):
         # Node needs to wait until all associated RMs are released
         # to be released
         from nepi.resources.linux.udptunnel import UdpTunnel
-        rms = self.get_connected(UdpTunnel.rtype())
+        rms = self.get_connected(UdpTunnel.get_rtype())
         for rm in rms:
             if rm.state < ResourceState.STOPPED:
                 self.ec.schedule(reschedule_delay, self.release)
index d6398eb..fa3277a 100755 (executable)
@@ -65,8 +65,8 @@ class Interface(ResourceManager):
         super(Interface, self).__init__(ec, guid)
 
     def do_deploy(self):
-        node = self.get_connected(Node.rtype())[0]
-        chan = self.get_connected(Channel.rtype())[0]
+        node = self.get_connected(Node.get_rtype())[0]
+        chan = self.get_connected(Channel.get_rtype())[0]
 
         if node.state < ResourceState.PROVISIONED:
             self.ec.schedule("0.5s", self.deploy)
@@ -90,7 +90,7 @@ class Node(ResourceManager):
             self.logger.debug(" -------- PROVISIONED ------- ")
             self.ec.schedule("1s", self.deploy)
         elif self.state == ResourceState.PROVISIONED:
-            ifaces = self.get_connected(Interface.rtype())
+            ifaces = self.get_connected(Interface.get_rtype())
             for rm in ifaces:
                 if rm.state < ResourceState.READY:
                     self.ec.schedule("0.5s", self.deploy)
@@ -106,7 +106,7 @@ class Application(ResourceManager):
         super(Application, self).__init__(ec, guid)
 
     def do_deploy(self):
-        node = self.get_connected(Node.rtype())[0]
+        node = self.get_connected(Node.get_rtype())[0]
         if node.state < ResourceState.READY:
             self.ec.schedule("0.5s", self.deploy)
         else:
@@ -126,7 +126,7 @@ class ErrorApplication(ResourceManager):
         super(ErrorApplication, self).__init__(ec, guid)
 
     def do_deploy(self):
-        node = self.get_connected(Node.rtype())[0]
+        node = self.get_connected(Node.get_rtype())[0]
         if node.state < ResourceState.READY:
             self.ec.schedule("0.5s", self.deploy)
         else:
@@ -141,13 +141,13 @@ class ResourceFactoryTestCase(unittest.TestCase):
         ResourceFactory.register_type(MyResource)
         ResourceFactory.register_type(AnotherResource)
 
-        self.assertEquals(MyResource.rtype(), "MyResource")
+        self.assertEquals(MyResource.get_rtype(), "MyResource")
         self.assertEquals(len(MyResource._attributes), 2)
 
-        self.assertEquals(ResourceManager.rtype(), "Resource")
+        self.assertEquals(ResourceManager.get_rtype(), "Resource")
         self.assertEquals(len(ResourceManager._attributes), 1)
 
-        self.assertEquals(AnotherResource.rtype(), "AnotherResource")
+        self.assertEquals(AnotherResource.get_rtype(), "AnotherResource")
         self.assertEquals(len(AnotherResource._attributes), 1)
 
         self.assertEquals(len(ResourceFactory.resource_types()), 2)
index 6b02d20..934081c 100755 (executable)
@@ -238,8 +238,8 @@ main (void)
         ec.set(node, "cleanHome", True)
         ec.set(node, "cleanProcesses", True)
 
-        sources = "http://nepi.inria.fr/code/nef/archive/tip.tar.gz " \
-                " http://nepi.inria.fr/code/nef/raw-file/8ace577d4079/src/nef/images/menu/connect.png"
+        sources = "http://yans.pl.sophia.inria.fr/code/nef/archive/tip.tar.gz " \
+                " http://yans.pl.sophia.inria.fr/code/nef/raw-file/8ace577d4079/src/nef/images/menu/connect.png"
 
         app = ec.register_resource("LinuxApplication")
         ec.set(app, "sources", sources)
index 5d9dfde..184a79d 100755 (executable)
@@ -36,16 +36,16 @@ import unittest
 class OMFResourceFactoryTestCase(unittest.TestCase):
     def test_creation_phase(self):
 
-        self.assertEquals(OMFNode.rtype(), "OMFNode")
+        self.assertEquals(OMFNode.get_rtype(), "OMFNode")
         self.assertEquals(len(OMFNode._attributes), 6)
 
-        self.assertEquals(OMFWifiInterface.rtype(), "OMFWifiInterface")
+        self.assertEquals(OMFWifiInterface.get_rtype(), "OMFWifiInterface")
         self.assertEquals(len(OMFWifiInterface._attributes), 10)
 
-        self.assertEquals(OMFChannel.rtype(), "OMFChannel")
+        self.assertEquals(OMFChannel.get_rtype(), "OMFChannel")
         self.assertEquals(len(OMFChannel._attributes), 6)
 
-        self.assertEquals(OMFApplication.rtype(), "OMFApplication")
+        self.assertEquals(OMFApplication.get_rtype(), "OMFApplication")
         self.assertEquals(len(OMFApplication._attributes), 13)
 
 class OMFEachTestCase(unittest.TestCase):
index 982192b..b177a96 100755 (executable)
@@ -59,7 +59,7 @@ def create_node(ec, username, pl_user, pl_password, hostname = None,
 
 class PLNodeFactoryTestCase(unittest.TestCase):
     def test_creation_phase(self):
-        self.assertEquals(PlanetlabNode.rtype(), "PlanetlabNode")
+        self.assertEquals(PlanetlabNode.get_rtype(), "PlanetlabNode")
         self.assertEquals(len(PlanetlabNode._attributes), 29)