gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r23065 - in gnunet-planetlab/gplmt: . contrib contrib/taskl


From: gnunet
Subject: [GNUnet-SVN] r23065 - in gnunet-planetlab/gplmt: . contrib contrib/tasklists gplmt
Date: Fri, 3 Aug 2012 16:01:14 +0200

Author: wachs
Date: 2012-08-03 16:01:14 +0200 (Fri, 03 Aug 2012)
New Revision: 23065

Added:
   gnunet-planetlab/gplmt/contrib/tasklist_schema.xsd
   gnunet-planetlab/gplmt/gplmt/
   gnunet-planetlab/gplmt/gplmt/Configuration.py
   gnunet-planetlab/gplmt/gplmt/Nodes.py
   gnunet-planetlab/gplmt/gplmt/Notifications.py
   gnunet-planetlab/gplmt/gplmt/SCP.py
   gnunet-planetlab/gplmt/gplmt/Tasks.py
   gnunet-planetlab/gplmt/gplmt/Util.py
   gnunet-planetlab/gplmt/gplmt/Worker.py
Removed:
   gnunet-planetlab/gplmt/Configuration.py
   gnunet-planetlab/gplmt/Nodes.py
   gnunet-planetlab/gplmt/Notifications.py
   gnunet-planetlab/gplmt/SCP.py
   gnunet-planetlab/gplmt/Tasks.py
   gnunet-planetlab/gplmt/Util.py
   gnunet-planetlab/gplmt/Worker.py
   gnunet-planetlab/gplmt/tasklist_schema.xsd
Modified:
   gnunet-planetlab/gplmt/README
   gnunet-planetlab/gplmt/contrib/tasklists/check_fedora_version.xml
   gnunet-planetlab/gplmt/contrib/tasklists/check_node.xml
   gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc12.xml
   gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc8.xml
   gnunet-planetlab/gplmt/contrib/tasklists/start_gnunet.xml
   gnunet-planetlab/gplmt/contrib/tasklists/stop_gnunet.xml
   gnunet-planetlab/gplmt/contrib/tasklists/test_sftp_tasks.xml
   gnunet-planetlab/gplmt/contrib/tasklists/test_tasks.xml
   gnunet-planetlab/gplmt/contrib/tasklists/update_gnunet.xml
   gnunet-planetlab/gplmt/gplmt.py
Log:
cleanup

Deleted: gnunet-planetlab/gplmt/Configuration.py
===================================================================
--- gnunet-planetlab/gplmt/Configuration.py     2012-08-03 14:00:04 UTC (rev 
23064)
+++ gnunet-planetlab/gplmt/Configuration.py     2012-08-03 14:01:14 UTC (rev 
23065)
@@ -1,128 +0,0 @@
-#!/usr/bin/python
-#
-#    This file is part of GNUnet.
-#    (C) 2010 Christian Grothoff (and other contributing authors)
-#
-#    GNUnet is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published
-#    by the Free Software Foundation; either version 2, or (at your
-#    option) any later version.
-#
-#    GNUnet is distributed in the hope that it will be useful, but
-#    WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#    General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with GNUnet; see the file COPYING.  If not, write to the
-#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#    Boston, MA 02111-1307, USA.
-#
-# GNUnet Planetlab deployment and automation toolset 
-#
-# Configuration
-
-import ConfigParser
-import os
-
-class TransferMode:
-    none=0
-    sftp=1
-    scp=2
-
-class Configuration:
-    def __init__(self, filename, logger):
-        assert (None != logger)
-        self.filename = filename
-        self.logger = logger
-        self.notifications = ""
-        self.pl_slicename = ""
-        self.pl_api_url = ""
-        self.pl_username = ""
-        self.pl_password = ""
-        self.pl_use_nodes = False     
-        self.taskfile = ""
-        self.nodesfile = ""
-        self.ssh_add_unkown_hostkeys = False
-        self.ssh_keyfile = None
-        self.ssh_password = ""
-        self.ssh_use_known_hosts = False
-        self.ssh_transfer = TransferMode.scp
-    def load (self):        
-        self.logger.log ("Loading configuration file '" + self.filename + "'")
-        if (False == os.path.exists (self.filename)):
-            print "File does not exist: '" + self.filename + "'"
-            return False
-        config = ConfigParser.RawConfigParser()
-        try:
-            config.read(self.filename)
-        except ConfigParser.Error as e:
-            print "Error parsing configuration: " + str (e)
-            return False
-        
-        # required values
-        try: 
-            self.pl_slicename = config.get("planetlab", "slice")
-        except ConfigParser.NoOptionError as e:
-            print "Error parsing configuration: " + str (e)
-            return False
-        # optional values
-        try:
-            self.pl_use_nodes = config.getboolean ("planetlab", "use_pl_nodes")
-        except ConfigParser.NoOptionError as e:
-            pass    
-        try:
-            self.pl_api_url = config.get("planetlab", "api_url")
-        except ConfigParser.NoOptionError as e:
-            pass
-        try:
-            self.pl_username = config.get("planetlab", "username")
-        except ConfigParser.NoOptionError as e:
-            pass
-        try:
-            self.pl_password = config.get("planetlab", "password")
-        except ConfigParser.NoOptionError as e:
-            pass          
-        try: 
-            # gplmt options
-            self.taskfile = config.get("gplmt", "tasks")
-        except ConfigParser.NoOptionError as e:
-            pass
-        
-        try: 
-            self.nodesfile = config.get("gplmt", "nodes")
-        except ConfigParser.NoOptionError as e:
-            pass
-        
-        # ssh options
-        try: 
-            self.ssh_add_unkown_hostkeys = config.getboolean ("ssh", 
"add_unkown_hostkeys")
-        except ConfigParser.NoOptionError as e:
-            pass
-        try: 
-            self.ssh_use_known_hosts = config.getboolean ("ssh", 
"ssh_use_known_hosts")
-        except ConfigParser.NoOptionError as e:
-            pass
-        try: 
-            self.ssh_keyfile = config.get("ssh", "ssh_keyfile") 
-        except ConfigParser.NoOptionError as e:
-            pass
-        try: 
-            self.ssh_password = config.get("ssh", "ssh_password")
-        except ConfigParser.NoOptionError as e:
-            pass        
-        try: 
-            transfer = config.get("ssh", "ssh_transfer")
-            if (transfer == "scp"):
-                self.ssh_transfer = TransferMode.scp
-            elif (transfer == "sftp"):
-                self.ssh_transfer = TransferMode.sftp
-            else:
-                print "Invalid ssh transfer mode: only SFTP or SCP are 
supported"
-                return False
-        except ConfigParser.NoOptionError as e:
-            pass  
-        
-        
-        return True
-        
\ No newline at end of file

Deleted: gnunet-planetlab/gplmt/Nodes.py
===================================================================
--- gnunet-planetlab/gplmt/Nodes.py     2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/Nodes.py     2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,102 +0,0 @@
-#!/usr/bin/python
-#
-#    This file is part of GNUnet.
-#    (C) 2010 Christian Grothoff (and other contributing authors)
-#
-#    GNUnet is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published
-#    by the Free Software Foundation; either version 2, or (at your
-#    option) any later version.
-#
-#    GNUnet is distributed in the hope that it will be useful, but
-#    WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#    General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with GNUnet; see the file COPYING.  If not, write to the
-#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#    Boston, MA 02111-1307, USA.
-#
-# GNUnet Planetlab deployment and automation toolset 
-#
-# Tasks
-import sys, os, urllib, xmlrpclib, socket
-
-class Nodes:
-    def __init__(self, filename, logger):
-        assert (None != logger)
-        self.logger = logger
-        self.filename = filename
-        self.nodes = list ()
-    def load (self):        
-        self.logger.log ("Loading nodes file '" + self.filename + "'")
-        try:
-            fobj = open (self.filename, "r") 
-            for line in fobj: 
-                line = line.strip() 
-                self.logger.log ("Found node '" + line + "'")
-                self.nodes.append(line)
-            fobj.close()
-        except IOError:
-            print "File " + self.filename + " not found"
-            return False
-        self.logger.log ("Loaded " + str(len(self.nodes)) + " nodes")
-        return True
-
-class StringNodes:
-    def __init__(self, str, logger):
-        assert (None != logger)
-        self.str = str
-        self.logger = logger
-        self.nodes = list ()
-    def load (self):        
-        self.logger.log ("Loading nodes '" + self.str + "'")
-        self.nodes.append(self.str)
-        self.logger.log ("Loaded " + str(len(self.nodes)) + " nodes")
-        return True    
-
-class PlanetLabNodes:
-    def __init__(self, configuration, logger):
-        assert (None != logger)
-        self.logger = logger
-        self.configuration = configuration
-        self.nodes = list ()
-    def load (self):        
-
-        if (self.configuration.pl_password == ""):
-            print "No PlanetLab password given in configuration fail!"
-            return False
-        if (self.configuration.pl_username == ""):            
-            print "No PlanetLab username given in configuration, fail!"
-            return False
-        if (self.configuration.pl_api_url == ""):            
-            print "No PlanetLab API url given in configuration, fail!"
-            return False
-        self.logger.log ("Retrieving nodes assigned to slice '" + 
self.configuration.pl_slicename + "' for user " +self.configuration.pl_username)
-        try:
-            server = xmlrpclib.ServerProxy(self.configuration.pl_api_url)
-        except:
-            print "Could not connect to PlanetLab API, fail!"
-            return False
-        
-        slice_data = {}
-        slice_data['name'] = self.configuration.pl_slicename
-
-        auth = {}
-        auth['Username'] = self.configuration.pl_username
-        auth['AuthString'] = self.configuration.pl_password
-        auth['AuthMethod'] = "password"
-        
-        try:
-            node_ids = server.GetSlices(auth, [slice_data['name']], 
['node_ids'])[0]['node_ids']
-            node_hostnames = [node['hostname'] for node in 
server.GetNodes(auth, node_ids, ['hostname'])]
-        except Exception as e:
-            print "Could not retrieve data from PlanetLab API: " + str(e)
-            return False            
-        
-        for node in node_hostnames:
-            self.logger.log ("Planetlab API returned: " + node)            
-            self.nodes.append(node)
-        self.logger.log ("Planetlab API returned " + str(len(self.nodes)) + " 
nodes")     
-        return True
\ No newline at end of file

Deleted: gnunet-planetlab/gplmt/Notifications.py
===================================================================
--- gnunet-planetlab/gplmt/Notifications.py     2012-08-03 14:00:04 UTC (rev 
23064)
+++ gnunet-planetlab/gplmt/Notifications.py     2012-08-03 14:01:14 UTC (rev 
23065)
@@ -1,166 +0,0 @@
-#!/usr/bin/python
-#
-#    This file is part of GNUnet.
-#    (C) 2010 Christian Grothoff (and other contributing authors)
-#
-#    GNUnet is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published
-#    by the Free Software Foundation; either version 2, or (at your
-#    option) any later version.
-#
-#    GNUnet is distributed in the hope that it will be useful, but
-#    WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#    General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with GNUnet; see the file COPYING.  If not, write to the
-#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#    Boston, MA 02111-1307, USA.
-#
-# GNUnet Planetlab deployment and automation toolset 
-#
-# Notifications     
-import Tasks
-import time
-
-class Notification:
-    def __init__(self, logger):
-        assert (None != logger)
-        self.logger = logger
-    def node_connected (self, node, success):
-        assert (0)
-    def node_disconnected (self, node, success):
-        assert (0) 
-    def tasklist_started (self, node, tasks):
-        assert (0)
-    def tasklist_completed (self, node, tasks, success):
-        assert (0)
-    def task_started (self, node, tasks):
-        assert (0)
-    def task_completed (self, node, tasks, success):
-        assert (0)
-
-class NodeCollection:
-    def __init__(self):
-        self.nodes = list ()
-    def add (self, node):
-        self.nodes.append (node)
-    def get (self, name):
-        for n in self.nodes:
-            if (n.name == name):
-                return n
-        return None
-        
-class Task:
-    def __init__(self, task, result, fail):
-        self.task = task
-        self.result = result
-        self.fail = fail
-        
-class Node:
-    def __init__(self, name):
-        self.name = name
-        self.start = time.time()
-        self.end = 0
-        self.tasks = list ()
-
-
-class FileLoggerNotification (Notification):
-    def __init__(self, logger):
-        assert (None != logger)
-        self.logger = logger
-        self.nodes = NodeCollection ()
-    def node_connected (self, node, success):
-        return
-    def node_disconnected (self, node, success):
-        return 
-    def tasklist_started (self, node, tasks):
-        return
-    def tasklist_completed (self, node, tasks, success):
-        self.nodes.add (Node(node))
-        if (success == True):
-            print node + " : Tasklist '" +  tasks.name + "' completed 
successfully"
-        else:
-            print node + " : Tasklist '" +  tasks.name + "' completed with 
failure"
-    def task_started (self, node, task):
-        return
-    def task_completed (self, node, task, result):
-        return   
-
-
-class TaskListResultNotification (Notification):
-    def __init__(self, logger):
-        assert (None != logger)
-        self.logger = logger
-        #self.nodes = NodeCollection ()
-    def summarize (self):
-        for n in self.nodes:
-            tsk_str = ""
-            for t in n.tasks:
-                tsk_f = "[e]"
-                if (t.fail == True):
-                    tsk_f = "[f]"
-                else:
-                    tsk_f = "[s]"
-                tsk_str += t.task.name + " " + tsk_f + " ->"
-            print n.name
-    def node_connected (self, node, success):
-        return
-    def node_disconnected (self, node, success):
-        return 
-    def tasklist_started (self, node, tasks):
-        return
-    def tasklist_completed (self, node, tasks, success):
-        if (success == True):
-            print node + " : Tasklist '" +  tasks.name + "' completed 
successfully"
-        else:
-            print node + " : Tasklist '" +  tasks.name + "' completed with 
failure"
-    def task_started (self, node, task):
-        return
-    def task_completed (self, node, task, result):
-        return         
-
-class SimpleNotification (Notification):
-    def __init__(self, logger):
-        assert (None != logger)
-        self.logger = logger
-        #self.nodes = NodeCollection ()
-    def summarize (self):
-        for n in self.nodes:
-            tsk_str = ""
-            for t in n.tasks:
-                tsk_f = "[e]"
-                if (t.fail == True):
-                    tsk_f = "[f]"
-                else:
-                    tsk_f = "[s]"
-                tsk_str += t.task.name + " " + tsk_f + " ->"
-            print n.name
-    def node_connected (self, node, success):
-        if (success == True):
-            print node + " : connected successfully"
-        else:
-            print node + " : connection failed"
-    def node_disconnected (self, node, success):
-        if (success == True):
-            print node + " : disconnected"
-        else:
-            print node + " : disconnected with failure"    
-    def tasklist_started (self, node, tasks):
-        print node + " : Tasklist '" +  tasks.name + "' started"
-        #self.nodes.add (Node(node))
-    def tasklist_completed (self, node, tasks, success):
-        if (success == True):
-            print node + " : Tasklist '" +  tasks.name + "' completed 
successfully"
-        else:
-            print node + " : Tasklist '" +  tasks.name + "' completed with 
failure"
-    def task_started (self, node, task):
-        print node + " : Task '" +  task.name + "' started"
-    def task_completed (self, node, task, result):
-        if (result == Tasks.Taskresult.success):
-            print node + " : Task '" +  task.name + "' completed successfully"
-        elif (result == Tasks.Taskresult.src_file_not_found):
-            print node + " : Task '" +  task.name + "' failed : source file 
not found"
-        else:
-            print node + " : Task '" +  task.name + "' completed with failure" 
            
\ No newline at end of file

Modified: gnunet-planetlab/gplmt/README
===================================================================
--- gnunet-planetlab/gplmt/README       2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/README       2012-08-03 14:01:14 UTC (rev 23065)
@@ -34,6 +34,11 @@
 - Task list validation against XML Schema
 - Extensible logging functionality
 
+Content
+=============
+
+
+
 Dependencies:
 =============
 

Deleted: gnunet-planetlab/gplmt/SCP.py
===================================================================
--- gnunet-planetlab/gplmt/SCP.py       2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/SCP.py       2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,395 +0,0 @@
-# scp.py
-# Copyright (C) 2008 James Bardin <address@hidden>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-"""
-Utilities for sending files over ssh using the scp1 protocol.
-"""
-
-import os
-from socket import timeout as SocketTimeout
-
-class SCPClient(object):
-    """
-    An scp1 implementation, compatible with openssh scp.
-    Raises SCPException for all transport related errors. Local filesystem
-    and OS errors pass through. 
-
-    Main public methods are .put and .get 
-    The get method is controlled by the remote scp instance, and behaves 
-    accordingly. This means that symlinks are resolved, and the transfer is
-    halted after too many levels of symlinks are detected.
-    The put method uses os.walk for recursion, and sends files accordingly.
-    Since scp doesn't support symlinks, we send file symlinks as the file
-    (matching scp behaviour), but we make no attempt at symlinked directories.
-
-    Convenience methods:
-        put_r:  put with recursion
-        put_p:  put preserving times
-        put_rp: put with recursion, preserving times
-        get_r:  get with recursion
-        get_p:  get preserving times
-        get_rp: get with recursion, preserving times
-    """
-    def __init__(self, transport, buff_size = 16384, socket_timeout = 5.0,
-                 callback = None):
-        """
-        Create an scp1 client.
-
-        @param transport: an existing paramiko L{Transport}
-        @type transport: L{Transport}
-        @param buff_size: size of the scp send buffer.
-        @type buff_size: int
-        @param socket_timeout: channel socket timeout in seconds
-        @type socket_timeout: float
-        @param callback: callback function for transfer status
-        @type callback: func
-        """
-        self.transport = transport
-        self.buff_size = buff_size
-        self.socket_timeout = socket_timeout
-        self.channel = None
-        self.preserve_times = False
-        self.callback = callback
-        self._recv_dir = ''
-        self._utime = None
-        self._dirtimes = {}
-
-    def put(self, files, remote_path = '.', 
-            recursive = False, preserve_times = False):
-        """
-        Transfer files to remote host.
-
-        @param files: A single path, or a list of paths to be transfered.
-            recursive must be True to transfer directories.
-        @type files: string OR list of strings
-        @param remote_path: path in which to receive the files on the remote
-            host. defaults to '.'
-        @type remote_path: str
-        @param recursive: transfer files and directories recursively
-        @type recursive: bool
-        @param preserve_times: preserve mtime and atime of transfered files
-            and directories.
-        @type preserve_times: bool
-        """
-        self.preserve_times = preserve_times
-        self.channel = self.transport.open_session()
-        self.channel.settimeout(self.socket_timeout)
-        scp_command = ('scp -t %s\n', 'scp -r -t %s\n')[recursive]
-        self.channel.exec_command(scp_command % remote_path)
-        self._recv_confirm()
-       
-        if not isinstance(files, (list, tuple)):
-            files = [files]
-        
-        if recursive:
-            self._send_recursive(files)
-        else:
-            self._send_files(files)
-        
-        if self.channel:
-            self.channel.close()
-    
-    def put_r(self, files, remote_path = '.'):
-        """
-        Convenience function for a recursive put
-
-        @param files: A single path, or a list of paths to be transfered.
-        @type files: str, list
-        @param remote_path: path in which to receive the files on the remote
-            host. defaults to '.'
-        @type remote_path: bool
-        """
-        self.put(files, remote_path, recursive = True)
-
-    def put_p(self, files, remote_path = '.'):
-        """
-        Convenience function to put preserving times.
-
-        @param files: A single path, or a list of paths to be transfered.
-        @type files: str, list
-        @param remote_path: path in which to receive the files on the remote
-            host. defaults to '.'
-        @type remote_path: bool
-        """
-        self.put(files, remote_path, preserve_times = True)
-   
-    def put_rp(self, files, remote_path = '.'):
-        """
-        Convenience function for a recursive put, preserving times.
-
-        @param files: A single path, or a list of paths to be transfered.
-        @type files: str, list
-        @param remote_path: path in which to receive the files on the remote
-            host. defaults to '.'
-        @type remote_path: bool
-        """
-        self.put(files, remote_path, recursive = True, preserve_times = True)
-
-    def get(self, remote_path, local_path = '',
-            recursive = False, preserve_times = False):
-        """
-        Transfer files from remote host to localhost
-
-        @param remote_path: path to retreive from remote host. since this is
-            evaluated by scp on the remote host, shell wildcards and 
-            environment variables may be used.
-        @type remote_path: str
-        @param local_path: path in which to receive files locally
-        @type local_path: str
-        @param recursive: transfer files and directories recursively
-        @type recursive: bool
-        @param preserve_times: preserve mtime and atime of transfered files
-            and directories.
-        @type preserve_times: bool
-        """
-        self._recv_dir = local_path or os.getcwd() 
-        rcsv = ('', ' -r')[recursive]
-        prsv = ('', ' -p')[preserve_times]
-        self.channel = self.transport.open_session()
-        self.channel.settimeout(self.socket_timeout)
-        self.channel.exec_command('scp%s%s -f %s' % (rcsv, prsv, remote_path))
-        self._recv_all()
-        
-        if self.channel:
-            self.channel.close()
-
-    def get_r(self, remote_path, local_path = '.'):
-        """
-        Convenience function for a recursive get
-
-        @param remote_path: path to retrieve from server
-        @type remote_path: str
-        @param local_path: path in which to recieve files. default cwd
-        @type local_path: str
-        """
-        self.get(remote_path, local_path, recursive = True)
-
-    def get_p(self, remote_path, local_path = '.'):
-        """
-        Convenience function for get, preserving times.
-
-        @param remote_path: path to retrieve from server
-        @type remote_path: str
-        @param local_path: path in which to recieve files. default cwd
-        @type local_path: str
-        """
-        self.get(remote_path, local_path, preserve_times = True)
-
-    def get_rp(self, remote_path, local_path = '.'):
-        """
-        Convenience function for a recursive get, preserving times.
-
-        @param remote_path: path to retrieve from server
-        @type remote_path: str
-        @param local_path: path in which to recieve files. default cwd
-        @type local_path: str
-        """
-        self.get(remote_path, local_path, recursive = True, preserve_times = 
True)
-
-    def _read_stats(self, name):
-        """return just the file stats needed for scp"""
-        stats = os.stat(name)
-        mode = oct(stats.st_mode)[-4:]
-        size = stats.st_size
-        atime = int(stats.st_atime)
-        mtime = int(stats.st_mtime)
-        return (mode, size, mtime, atime)
-
-    def _send_files(self, files): 
-        for name in files:
-            basename = os.path.basename(name)
-            (mode, size, mtime, atime) = self._read_stats(name)
-            if self.preserve_times:
-                self._send_time(mtime, atime)
-            file_hdl = file(name, 'rb')
-            self.channel.sendall('C%s %d %s\n' % (mode, size, basename))
-            self._recv_confirm()
-            file_pos = 0
-            buff_size = self.buff_size
-            chan = self.channel
-            while file_pos < size:
-                chan.sendall(file_hdl.read(buff_size))
-                file_pos = file_hdl.tell()
-                if self.callback:
-                    self.callback(file_pos, size)
-            chan.sendall('\x00')
-            file_hdl.close()
-
-    def _send_recursive(self, files):
-        for base in files:
-            lastdir = base
-            for root, dirs, fls in os.walk(base):
-                # pop back out to the next dir in the walk
-                while lastdir != os.path.commonprefix([lastdir, root]):
-                    self._send_popd()
-                    lastdir = os.path.split(lastdir)[0]
-                self._send_pushd(root)
-                lastdir = root
-                self._send_files([os.path.join(root, f) for f in fls])
-        
-    def _send_pushd(self, directory):
-        (mode, size, mtime, atime) = self._read_stats(directory)
-        basename = os.path.basename(directory)
-        if self.preserve_times:
-            self._send_time(mtime, atime)
-        self.channel.sendall('D%s 0 %s\n' % (mode, basename))
-        self._recv_confirm()
-
-    def _send_popd(self):
-        self.channel.sendall('E\n')
-        self._recv_confirm()
-
-    def _send_time(self, mtime, atime):
-        self.channel.sendall('T%d 0 %d 0\n' % (mtime, atime))
-        self._recv_confirm()
-
-    def _recv_confirm(self):
-        # read scp response
-        msg = ''
-        try:
-            msg = self.channel.recv(512)
-        except SocketTimeout:
-            raise SCPException('Timout waiting for scp response')
-        if msg and msg[0] == '\x00':
-            return
-        elif msg and msg[0] == '\x01':
-            raise SCPException(msg[1:])
-        elif self.channel.recv_stderr_ready():
-            msg = self.channel.recv_stderr(512)
-            raise SCPException(msg)
-        elif not msg:
-            raise SCPException('No response from server')
-        else:
-            raise SCPException('Invalid response from server: ' + msg)
-    
-    def _recv_all(self):
-        # loop over scp commands, and recive as necessary
-        command = {'C': self._recv_file,
-                   'T': self._set_time,
-                   'D': self._recv_pushd,
-                   'E': self._recv_popd}
-        while not self.channel.closed:
-            # wait for command as long as we're open
-            self.channel.sendall('\x00')
-            msg = self.channel.recv(1024)
-            if not msg: # chan closed while recving
-                break
-            code = msg[0]
-            try:
-                command[code](msg[1:])
-            except KeyError:
-                raise SCPException(repr(msg))
-        # directory times can't be set until we're done writing files
-        self._set_dirtimes()
-    
-    def _set_time(self, cmd):
-        try:
-            times = cmd.split()
-            mtime = int(times[0])
-            atime = int(times[2]) or mtime
-        except:
-            self.channel.send('\x01')
-            raise SCPException('Bad time format')
-        # save for later
-        self._utime = (mtime, atime)
-
-    def _recv_file(self, cmd):
-        chan = self.channel
-        parts = cmd.split()
-        try:
-            mode = int(parts[0], 8)
-            size = int(parts[1])
-            path = os.path.join(self._recv_dir, parts[2])
-        except:
-            chan.send('\x01')
-            chan.close()
-            raise SCPException('Bad file format')
-        
-        try:
-            file_hdl = file(path, 'wb')
-        except IOError, e:
-            chan.send('\x01'+e.message)
-            chan.close()
-            raise
-
-        buff_size = self.buff_size
-        pos = 0
-        chan.send('\x00')
-        try:
-            while pos < size:
-                # we have to make sure we don't read the final byte
-                if size - pos <= buff_size:
-                    buff_size = size - pos
-                file_hdl.write(chan.recv(buff_size))
-                pos = file_hdl.tell()
-                if self.callback:
-                    self.callback(pos, size)
-            
-            msg = chan.recv(512)
-            if msg and msg[0] != '\x00':
-                raise SCPException(msg[1:])
-        except SocketTimeout:
-            chan.close()
-            raise SCPException('Error receiving, socket.timeout')
-
-        file_hdl.truncate()
-        try:
-            os.utime(path, self._utime)
-            self._utime = None
-            os.chmod(path, mode)
-            # should we notify the other end?
-        finally:
-            file_hdl.close()
-        # '\x00' confirmation sent in _recv_all
-
-    def _recv_pushd(self, cmd):
-        parts = cmd.split()
-        try:
-            mode = int(parts[0], 8)
-            path = os.path.join(self._recv_dir, parts[2])
-        except:
-            self.channel.send('\x01')
-            raise SCPException('Bad directory format')
-        try:
-            if not os.path.exists(path):
-                os.mkdir(path, mode)
-            elif os.path.isdir(path):
-                os.chmod(path, mode)
-            else:
-                raise SCPException('%s: Not a directory' % path)
-            self._dirtimes[path] = (self._utime)
-            self._utime = None
-            self._recv_dir = path
-        except (OSError, SCPException), e:
-            self.channel.send('\x01'+e.message)
-            raise
-
-    def _recv_popd(self, *cmd):
-        self._recv_dir = os.path.split(self._recv_dir)[0]
-        
-    def _set_dirtimes(self):
-        try:
-            for d in self._dirtimes:
-                os.utime(d, self._dirtimes[d])
-        finally:
-            self._dirtimes = {}
-
-
-class SCPException(Exception):
-    """SCP exception class"""
-    pass

Deleted: gnunet-planetlab/gplmt/Tasks.py
===================================================================
--- gnunet-planetlab/gplmt/Tasks.py     2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/Tasks.py     2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,278 +0,0 @@
-#!/usr/bin/python
-#
-#    This file is part of GNUnet.
-#    (C) 2010 Christian Grothoff (and other contributing authors)
-#
-#    GNUnet is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published
-#    by the Free Software Foundation; either version 2, or (at your
-#    option) any later version.
-#
-#    GNUnet is distributed in the hope that it will be useful, but
-#    WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#    General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with GNUnet; see the file COPYING.  If not, write to the
-#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#    Boston, MA 02111-1307, USA.
-#
-# GNUnet Planetlab deployment and automation toolset 
-#
-# Nodes
-try: 
-    import xml
-    from xml.parsers import expat  
-    from minixsv import pyxsval as xsv 
-    from elementtree import ElementTree
-    elementtree_loaded = True 
-    from genxmlif import GenXmlIfError
-except ImportError: 
-    pass
-
-glogger = None
-
-supported_operations = ["run", "monitor", "get", "put"]
-
-class Taskresult:
-    unspecified = -1
-    success = 0
-    timeout = 1
-    fail = 2 
-    return_value_did_not_match = 3
-    output_did_not_match = 4
-    src_file_not_found = 5
-    
-
-class Operation:
-    none=0
-    run=1
-    monitor=2
-    get=3
-    put=4
-
-class Task:
-    def __init__(self):
-        self.id = -1
-        self.name = ""
-        self.type = Operation.none
-        self.command = ""
-        self.arguments = ""
-        self.timeout = 0
-        self.expected_return_code = -1
-        self.expected_output = None
-        self.stop_on_fail = False
-        self.set = None
-        self.src = None
-        self.dest = None
-    def log (self):
-        glogger.log ("Task " + str(self.id) + ": " + self.name)
-    def check (self):
-        if (Operation.none):
-            return False
-        if (self.type == Operation.run):                   
-            if ((self.id == -1) or (self.name == "") or (self.command == "")):
-                return False
-        if (self.type == Operation.put):                   
-            if ((self.id == -1) or (self.name == "") or 
-                (self.src == None) or (self.dest == None)):
-                return False
-        if (self.type == Operation.get):                   
-            if ((self.id == -1) or (self.name == "") or 
-                (self.src == None) or (self.dest == None)):
-                return False            
-        return True
-                        
-class Taskset:
-    def __init__(self):
-        self.set = list()
-
-
-def handle_task (elem, tasks):
-    t = Task ()
-    
-    if (None != elem.attrib.get("name")):
-        t.name = elem.attrib.get("name")
-
-    if (None != elem.attrib.get("id")):
-        t.id = elem.attrib.get("id")
-    
-    if (tasks.startid != -1):
-        if (tasks.startid == t.id):
-            tasks.startid_found = True
-            glogger.log ("Task " + str (t.id) + " '" + t.name + "' has start 
ID") 
-        if (tasks.startid_found == False):
-            glogger.log ("Task " + str (t.id) + " '" + t.name + "' skipped")
-            return None;
-    
-    if (None != elem.attrib.get("enabled")):
-        if ("FALSE" == str(elem.attrib.get("enabled")).upper()):
-            glogger.log ("Task " + str (t.id) + " '" + t.name + "' is 
disabled")
-            return
-    
-    if (elem.tag == "run"):     
-        t.type = Operation.run
-    elif (elem.tag == "monitor"):            
-        t.type = Operation.monitor
-    elif (elem.tag == "get"):            
-        t.type = Operation.get
-    elif (elem.tag == "put"):       
-        t.type = Operation.put
-    else:
-        t.type = Operation.none
-        
-    for child in elem:
-        if ((child.tag == "command") and (child.text != None)):
-            t.command = child.text
-        if ((child.tag == "arguments") and (child.text != None)):
-            t.arguments = child.text
-        if (child.tag == "timeout"):
-            try:
-                t.timeout = int(child.text)
-            except ValueError:
-                print "Invalid timeout '"+child.text+"' for task id " + str 
(t.id) + " name " + t.name
-        if (child.tag == "expected_return_code"):
-            try:
-                t.expected_return_code = int(child.text)
-            except ValueError:
-                print "Invalid expected return code '" +child.text+ "' for 
task id " + str (t.id) + " name " + t.name
-        if ((child.tag == "expected_output") and (child.text != None)):
-            t.expected_output = child.text                            
-        if ((child.tag == "stop_on_fail") and (child.text != None)):
-            if (str.upper(child.text) == "TRUE"):
-                t.stop_on_fail = True
-            else:
-                t.stop_on_fail = False        
-        if ((child.tag == "source") and (child.text != None)):
-            t.src = child.text
-        if ((child.tag == "destination") and (child.text != None)):
-            t.dest = child.text                
-
-    if (False == t.check()):
-        print "Parsed invalid task with id " + str (t.id) + " name '" + t.name 
+ "'"
-        return None 
-    else:
-        t.log ()
-        return t
-
-def handle_sequence (elem, tasks):
-    if (None != elem.attrib.get("enabled")):
-        if ("FALSE" == str(elem.attrib.get("enabled")).upper()):
-            glogger.log ("Element was disabled")
-            return
-    for child in elem:
-            handle_child (child, tasks)
-            
-def handle_parallel (elem, tasks):
-    glogger.log ("Found parallel execution with " + str(len(elem)) + " 
elements")
-    if (None != elem.attrib.get("enabled")):
-        if ("FALSE" == str(elem.attrib.get("enabled")).upper()):
-            glogger.log ("Element was disabled")
-            return
-    ptask = Taskset ()
-    for child in elem:
-        if (elem.tag in supported_operations):
-            t = handle_task (elem)
-            if (None != t):
-                ptask.set.append(t)
-                print "Added " + t.name + " to set"
-        elif (elem.tag == "parallel"):
-            glogger.log ("x")
-        #    handle_parallel (elem, l)
-        elif (elem.tag == "sequence"):
-            glogger.log ("x")
-        #        handle_sequence (elem, l)
-        else:
-            print "Invalid element in task file: " + elem.tag
-    tasks.l.append (ptask)            
-    
-def handle_child (elem, tasks):
-    global support_operations
-    if (elem.tag in supported_operations):
-        t = handle_task (elem, tasks)
-        if (None != t):
-            tasks.l.append(t)
-    elif (elem.tag == "parallel"):
-        handle_parallel (elem, tasks)
-    elif (elem.tag == "sequence"):
-        handle_sequence (elem, tasks)
-    else:
-        print "Invalid element in task file: " + elem.tag
-
-def print_sequence (l):
-    for i in l:
-        print "->",
-        if (i.__class__.__name__ == "Task"):
-            print i.name,
-        elif (i.__class__.__name__ == "Taskset"):
-            print "{",
-            print_sequence (i.set)
-            print "}",
-
-    
-
-class Tasks:
-    def __init__(self, filename, logger, startid):
-        assert (None != logger)
-        global glogger
-        glogger = logger
-        self.logger = logger
-        self.filename = filename
-        self.name = "<Undefined>"
-        self.l = list ()
-        self.startid = startid
-        self.startid_found = False
-    def load (self):        
-        self.logger.log ("Loading tasks file '" + self.filename + "'")
-        enabled = True
-        try:
-            xsv.parseAndValidate (self.filename)
-        except xsv.xsvalErrorHandler.XsvalError as e:
-            print "File '" + self.filename + "' does not validate against 
schema: \n" + str(e)
-            return False
-        except GenXmlIfError as e:
-            print "File '" + self.filename + "' is not well-formed: \n" + 
str(e)
-            return False
-        except IOError:
-            print "File '" + self.filename + "' not found \n"
-            return False
-        
-        try:
-            root = ElementTree.parse (self.filename).getroot()
-            if (None != root.attrib.get("name")):
-                self.name = root.attrib.get("name")
-            if (None != root.attrib.get("enabled")):
-                if (False == root.attrib.get("enabled")):
-                    enabled = False
-        except expat.ExpatError as e:
-            print "File '" + self.filename + "'is malformed: " + str(e)
-            return False                
-        except IOError:
-            print "File '" + self.filename + "' not found"
-            return False
-        if (enabled == True):
-            for child in root:
-                handle_child (child, self)
-        else:
-            print "Tasklist " + self.filename + " was disabled"
-        #print_sequence (self.l)
-        
-        return True
-
-        
-    def copy (self):
-        t = Tasks (self.filename, self.logger, -1)
-        # Create a copy of the task list as described in 
-        # http://docs.python.org/library/copy.html
-        t.filename = self.filename
-        t.name = self.name
-        t.l = self.l[:]
-        return t
-    def get (self):
-        if (len (self.l) > 0):
-            item = self.l[0]
-            self.l.remove(item)
-            return item
-        else:
-            return None

Deleted: gnunet-planetlab/gplmt/Util.py
===================================================================
--- gnunet-planetlab/gplmt/Util.py      2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/Util.py      2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,35 +0,0 @@
-#!/usr/bin/python
-#
-#    This file is part of GNUnet.
-#    (C) 2010 Christian Grothoff (and other contributing authors)
-#
-#    GNUnet is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published
-#    by the Free Software Foundation; either version 2, or (at your
-#    option) any later version.
-#
-#    GNUnet is distributed in the hope that it will be useful, but
-#    WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#    General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with GNUnet; see the file COPYING.  If not, write to the
-#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#    Boston, MA 02111-1307, USA.
-#
-# GNUnet Planetlab deployment and automation toolset 
-#
-# Utilities
-
-class Logger:
-
-    def __init__(self, verbose):
-        if (True == verbose):
-            self.verbose = True
-        else:
-            self.verbose = False
-    def log (self, message):
-        global main
-        if (True == self.verbose):
-            print (message)
\ No newline at end of file

Deleted: gnunet-planetlab/gplmt/Worker.py
===================================================================
--- gnunet-planetlab/gplmt/Worker.py    2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/Worker.py    2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,288 +0,0 @@
-#!/usr/bin/python
-#
-#    This file is part of GNUnet.
-#    (C) 2010 Christian Grothoff (and other contributing authors)
-#
-#    GNUnet is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published
-#    by the Free Software Foundation; either version 2, or (at your
-#    option) any later version.
-#
-#    GNUnet is distributed in the hope that it will be useful, but
-#    WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#    General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with GNUnet; see the file COPYING.  If not, write to the
-#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#    Boston, MA 02111-1307, USA.
-#
-# GNUnet Planetlab deployment and automation toolset 
-#
-# Worker
-
-import Tasks
-import threading
-import socket
-import os
-import time
-import sys
-import select
-from SCP import SCPClient
-from Configuration import Configuration
-from Configuration import TransferMode
-
-try:
-    import paramiko
-    from paramiko.ssh_exception import SSHException
-except ImportError:
-    pass
-
-# Global variables
-g_logger = None
-g_notifications = None
-g_configuration = None
-
-class NodeWorkerThread (threading.Thread):
-    def __init__(self, threadID, node, tasks):
-        threading.Thread.__init__(self)
-        self.threadID = threadID
-        self.node = node
-        self.tasks = tasks
-    def exec_run (self, task, transport):
-        try:
-            channel = transport.open_session()
-            channel.settimeout(1.0)
-            channel.get_pty ()
-            #print "CMD: " + task.command + " " + task.arguments
-            channel.exec_command(task.command + " " + task.arguments)
-            
-        except SSHException as e:
-            print self.node + " : Error while trying to connect: " + str(e)
-        
-        if (task.timeout > 0):
-            timeout = task.timeout
-        else:
-            timeout = -1
-        result = Tasks.Taskresult.success
-        exit_status = -1
-        start_time = time.time ()
-        
-        stdout_data = ""
-        stderr_data = ""
-        while 1:
-            if (timeout != -1):
-                delta = time.time() - start_time
-                if (delta > timeout):
-                    print "Timeout after " +str(delta) +" seconds"
-                    result = Tasks.Taskresult.timeout
-                    break
-            (r, w, e) = select.select([channel], [], [], 1)
-            if r:
-                got_data = False
-                if channel.recv_ready():
-                    data = r[0].recv(4096)
-                    if data:
-                        got_data = True
-                        #g_logger.log ('STDOUT: ' + data)
-                        stdout_data += data
-                if channel.recv_stderr_ready():
-                    data = r[0].recv_stderr(4096)
-                    if data:
-                        got_data = True
-                        #g_logger.log ('STDERR: ' + data)
-                        stderr_data += data
-                if not got_data:
-                    break
-        
-        if (result == Tasks.Taskresult.success):
-            exit_status = channel.recv_exit_status ()  
-        
-        if (result == Tasks.Taskresult.success):
-            if (task.expected_return_code != -1):                    
-                if (exit_status != task.expected_return_code):
-                    g_logger.log (self.node + " : Task '"+ task.name + "' 
completed after "+ str(time.time() - start_time) +" sec, but exit code " 
+str(exit_status)+ " was not as expected " + str(task.expected_return_code))
-                    g_logger.log (stdout_data)
-                    g_logger.log (stderr_data)
-                    result = Tasks.Taskresult.return_value_did_not_match
-                else:
-                    g_logger.log (self.node + " : Task '"+ task.name + "' 
completed after "+ str(time.time() - start_time) +" sec, exit code " 
+str(exit_status)+ " was as expected " + str(task.expected_return_code))
-            
-            if (task.expected_output != None):
-                output_contained = False
-                if (task.expected_output in stdout_data):
-                    output_contained = True
-                if (task.expected_output in stderr_data):
-                        output_contained = True                
-                if (output_contained == True):
-                    g_logger.log (self.node + " : Task '"+ task.name + "' 
expected output '"+task.expected_output+"' was found")
-                else:
-                    g_logger.log (self.node + " : Task '"+ task.name + "' 
expected output '"+task.expected_output+"' was not found")
-                    result = Tasks.Taskresult.output_did_not_match
-                    
-        if (result == Tasks.Taskresult.success):
-            g_logger.log (self.node + " : Task '"+ task.name + "' successful")
-        elif (result == Tasks.Taskresult.timeout):
-            g_logger.log (self.node + " : Task '"+ task.name + "' with 
timeout")
-        else: 
-            g_logger.log (self.node + " : Task '"+ task.name + "' failed")
-        return result
-    def exec_put (self, task, transport):
-        if (False == os.path.exists (task.src)):
-            return Tasks.Taskresult.src_file_not_found
-            
-        result = Tasks.Taskresult.success
-        try:
-            if (g_configuration.ssh_transfer == TransferMode.scp):
-                scp = SCPClient (transport)
-                scp.put (task.src, task.dest)
-            if (g_configuration.ssh_transfer == TransferMode.sftp):            
    
-                sftp = paramiko.SFTPClient.from_transport (transport)
-                sftp.put(task.src, task.dest)
-                sftp.close()
-        except paramiko.SSHException as e:
-            g_logger.log (self.node + " : Task '"+ task.name + "' :" + str(e))
-            result = Tasks.Taskresult.fail
-            pass
-        except (OSError, IOError) as e:
-            g_logger.log (self.node + " : Task '"+ task.name + "' : " + str(e))
-            result = Tasks.Taskresult.src_file_not_found 
-            pass           
-        return result
-            
-    def exec_get (self, task, transport):
-        result = Tasks.Taskresult.success
-        try:
-            if (g_configuration.ssh_transfer == TransferMode.scp): 
-                scp = SCPClient (transport)
-                scp.get (task.src, task.dest)
-            if (g_configuration.ssh_transfer == TransferMode.sftp):
-                sftp = paramiko.SFTPClient.from_transport (transport)
-                sftp.get (task.src, task.dest)
-                sftp.close()
-        except paramiko.SSHException as e:
-            g_logger.log (self.node + " : Task '"+ task.name + "' :" + str(e))
-            result = Tasks.Taskresult.fail
-            pass
-        except (OSError, IOError) as e:
-            g_logger.log (self.node + " : Task '"+ task.name + "' : " + str(e))
-            result = Tasks.Taskresult.src_file_not_found 
-            pass           
-        return result    
-          
-    def run(self):
-        g_logger.log (self.node + " : Starting tasklist " + self.tasks.name)
-        task = self.tasks.get()
-        try: 
-            ssh = paramiko.SSHClient()
-            if (g_configuration.ssh_use_known_hosts):
-                g_logger.log (self.node + " : Loading known hosts")
-                ssh.load_system_host_keys ()
-
-            # Automatically add new hostkeys
-            if (g_configuration.ssh_add_unkown_hostkeys == True):
-                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-            # check for private key existance
-            keyfile = None
-            if (g_configuration.ssh_keyfile != None): 
-                if (os.path.exists (g_configuration.ssh_keyfile)):
-                    g_logger.log (self.node + " : Found " + 
g_configuration.ssh_keyfile)
-                    keyfile = g_configuration.ssh_keyfile
-                else:
-                    g_logger.log (self.node + " : Not found " + 
g_configuration.ssh_keyfile)
-                
-            g_logger.log (self.node + " : Trying to connect to " + 
-                          g_configuration.pl_slicename + "@" + self.node + 
-                          " using password '" + g_configuration.ssh_password+ 
-                          "' and private keyfile '" +str(keyfile)+ "'")
-            ssh.connect (self.node, 
-                         username=g_configuration.pl_slicename, 
-                         password=g_configuration.ssh_password,
-                         timeout=10,
-                         key_filename=keyfile) 
-        except (IOError,
-                paramiko.SSHException,
-                paramiko.BadHostKeyException, 
-                paramiko.AuthenticationException,
-                socket.error) as e:  
-            print self.node + " : Error while trying to connect: " + str(e)
-            g_notifications.node_connected (self.node, False)
-            g_notifications.tasklist_completed (self.node, self.tasks, False)
-            return
-        
-        g_notifications.node_connected (self.node, True)
-        
-        transport = ssh.get_transport()        
-        success = True
-        result = Tasks.Taskresult.success
-        while (None != task):
-            g_logger.log (self.node + " : Running task id " +str(task.id)+" '" 
+ task.name + "'")
-            g_notifications.task_started (self.node, task)
-            if (task.__class__.__name__ == "Task"):
-                if (task.type == Tasks.Operation.run):
-                    result = self.exec_run (task, transport)
-                    g_notifications.task_completed (self.node, task, result)
-                elif (task.type == Tasks.Operation.put):
-                    result = self.exec_put (task, transport)
-                    g_notifications.task_completed (self.node, task, result)
-                elif (task.type == Tasks.Operation.get):
-                    result = self.exec_get (task, transport)
-                    g_notifications.task_completed (self.node, task, result)
-                else:
-                    print "FAIL"                    
-            elif (task.__class__.__name__ == "Taskset"):
-                g_logger.log (self.node + " : Running task set")
-            if ((task.stop_on_fail == True) and (result != 
Tasks.Taskresult.success)):
-                g_logger.log (self.node + " : Task failed and therefore 
execution is stopped")
-                transport.close()
-                success = False
-                break
-            task = self.tasks.get()
-        
-        ssh.close()
-        g_notifications.node_disconnected (self.node, True)
-        g_notifications.tasklist_completed (self.node, self.tasks, success)
-        g_logger.log (self.node + " : All tasks done for " + self.node)
-        
-
-
-class NodeWorker:
-    def __init__(self, node, tasks):
-        assert (None != node)
-        assert (None != tasks)
-        self.node = node
-        self.tasks = tasks
-        self.thread = None
-    def start (self):
-        g_logger.log ("Starting execution for node " + self.node)
-        g_notifications.tasklist_started (self.node, self.tasks)
-        self.thread = NodeWorkerThread (1, self.node, self.tasks)
-        self.thread.start()
-    
-class Worker:
-    def __init__(self, logger, configuration, nodes, tasks, notifications):
-        global g_logger;
-        global g_configuration;
-        global g_notifications;
-        assert (None != logger)
-        assert (None != nodes)
-        assert (None != tasks)
-        assert (None != notifications)
-        assert (hasattr(notifications, 'node_connected'))
-        assert (hasattr(notifications, 'node_disconnected'))        
-        assert (hasattr(notifications, 'tasklist_started'))
-        assert (hasattr(notifications, 'tasklist_completed'))
-        assert (hasattr(notifications, 'task_started'))
-        assert (hasattr(notifications, 'task_completed'))
-        self.nodes = nodes
-        self.tasks = tasks
-        g_configuration = configuration
-        g_notifications = notifications
-        g_logger = logger;
-    def start (self):
-        g_logger.log ("Starting execution")
-        for n in self.nodes.nodes:
-            nw = NodeWorker (n, self.tasks.copy())
-            nw.start()
-        

Copied: gnunet-planetlab/gplmt/contrib/tasklist_schema.xsd (from rev 22971, 
gnunet-planetlab/gplmt/tasklist_schema.xsd)
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklist_schema.xsd                          
(rev 0)
+++ gnunet-planetlab/gplmt/contrib/tasklist_schema.xsd  2012-08-03 14:01:14 UTC 
(rev 23065)
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
elementFormDefault="qualified">
+<xs:element name="tasklist" type="tasklist" />
+
+<xs:complexType name="tasklist">
+  <xs:sequence>
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="sequence" type="sequence" />
+      <xs:element name="parallel" type="parallel" />
+      <xs:element name="run" type="run" />
+      <xs:element name="monitor" type="monitor" />
+      <xs:element name="put" type="put" />
+      <xs:element name="get" type="get" />
+    </xs:choice>
+  </xs:sequence>
+  <xs:attribute name="name" type="xs:string"/>
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+<xs:complexType name="sequence">
+  <xs:sequence>
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="sequence" type="sequence" />
+      <xs:element name="parallel" type="parallel" />
+      <xs:element name="run" type="run" />
+      <xs:element name="monitor" type="monitor" />
+      <xs:element name="put" type="put" />
+      <xs:element name="get" type="get" />
+    </xs:choice>
+  </xs:sequence>
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+<xs:complexType name="parallel">
+  <xs:sequence>
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="sequence" type="sequence" />
+      <xs:element name="parallel" type="parallel" />
+      <xs:element name="run" type="run" />
+      <xs:element name="monitor" type="monitor" />
+      <xs:element name="put" type="put" />
+      <xs:element name="get" type="get" />
+    </xs:choice>
+  </xs:sequence>
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+<xs:complexType name="run">
+  <xs:sequence>
+    <xs:element name="command" type="xs:string"/>
+    <xs:element name="arguments" type="xs:string"/>
+    <xs:element name="timeout" type="xs:integer"/>
+    <xs:element name="expected_return_code"  type="xs:integer"/>
+    <xs:element name="expected_output" type="xs:string"/>
+    <xs:element name="stop_on_fail" type="xs:boolean"/>
+  </xs:sequence>
+  <xs:attribute name="id" type="xs:integer"/>  
+  <xs:attribute name="name" type="xs:string"/>
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+<xs:complexType name="monitor">
+  <xs:sequence>
+    <xs:element name="command" type="xs:string"/>
+    <xs:element name="arguments" type="xs:string"/>
+    <xs:element name="timeout" type="xs:integer"/>
+    <xs:element name="expected_return_code"  type="xs:integer"/>
+    <xs:element name="expected_output" type="xs:string"/>
+    <xs:element name="stop_on_fail" type="xs:boolean"/>
+  </xs:sequence>
+  <xs:attribute name="id" type="xs:integer"/>
+  <xs:attribute name="name" type="xs:string"/>  
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+<xs:complexType name="put">
+  <xs:sequence>
+    <xs:element name="source" type="xs:string"/>
+    <xs:element name="destination" type="xs:string"/>
+    <xs:element name="stop_on_fail" type="xs:boolean"/>
+  </xs:sequence>
+  <xs:attribute name="id" type="xs:integer"/>
+  <xs:attribute name="name" type="xs:string"/>
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+<xs:complexType name="get">
+  <xs:sequence>
+    <xs:element name="source" type="xs:string"/>
+    <xs:element name="destination" type="xs:string"/>
+    <xs:element name="stop_on_fail" type="xs:boolean"/>
+  </xs:sequence>
+  <xs:attribute name="id" type="xs:integer"/>
+  <xs:attribute name="name" type="xs:string"/>
+  <xs:attribute name="enabled" type="xs:boolean"/>
+</xs:complexType>
+
+</xs:schema>

Modified: gnunet-planetlab/gplmt/contrib/tasklists/check_fedora_version.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/check_fedora_version.xml   
2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/check_fedora_version.xml   
2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Check Fedora version on node" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Check Fedora version on node" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        
        <run id="0" name="check peer">
                <!-- Check if peer is working -->

Modified: gnunet-planetlab/gplmt/contrib/tasklists/check_node.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/check_node.xml     2012-08-03 
14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/check_node.xml     2012-08-03 
14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Check if peer can is accessible" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Check if peer can is accessible" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        <run id="0" name="check peer">
                <!-- Check if peer is working -->
         <command>sudo date</command> 

Modified: gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc12.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc12.xml     
2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc12.xml     
2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Deploy GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Deploy GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        
        <run id="0" name="check peer">
                <!-- Check if peer is working -->

Modified: gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc8.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc8.xml      
2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/deploy_gnunet_fc8.xml      
2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Deploy GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Deploy GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        
        <run id="0" name="check peer">
                <!-- Check if peer is working -->

Modified: gnunet-planetlab/gplmt/contrib/tasklists/start_gnunet.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/start_gnunet.xml   2012-08-03 
14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/start_gnunet.xml   2012-08-03 
14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Start GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Start GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        
        <run id="0" name="check peer">
                <!-- Check if peer is working -->

Modified: gnunet-planetlab/gplmt/contrib/tasklists/stop_gnunet.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/stop_gnunet.xml    2012-08-03 
14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/stop_gnunet.xml    2012-08-03 
14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Start GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Start GNUnet" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        
        <run id="0" name="check peer">
                <!-- Check if peer is working -->

Modified: gnunet-planetlab/gplmt/contrib/tasklists/test_sftp_tasks.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/test_sftp_tasks.xml        
2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/test_sftp_tasks.xml        
2012-08-03 14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="remote put/get test task list" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="remote put/get test task list" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        <put id="0" name="put testfile">
                <source>/tmp/test.file</source>
                <destination>/tmp/put.file</destination>

Modified: gnunet-planetlab/gplmt/contrib/tasklists/test_tasks.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/test_tasks.xml     2012-08-03 
14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/test_tasks.xml     2012-08-03 
14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Tasklist example" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Tasklist example" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
   <task>
         <id>0</id>
         <name>run 1</name>

Modified: gnunet-planetlab/gplmt/contrib/tasklists/update_gnunet.xml
===================================================================
--- gnunet-planetlab/gplmt/contrib/tasklists/update_gnunet.xml  2012-08-03 
14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/contrib/tasklists/update_gnunet.xml  2012-08-03 
14:01:14 UTC (rev 23065)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tasklist name="Update GNUnet to SVN HEAD" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../../tasklist_schema.xsd">
+<tasklist name="Update GNUnet to SVN HEAD" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="../tasklist_schema.xsd">
        <run id="0" name="check peer">
                <!-- Check if peer is working -->
         <command>sudo date</command> 

Added: gnunet-planetlab/gplmt/gplmt/Configuration.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/Configuration.py                               
(rev 0)
+++ gnunet-planetlab/gplmt/gplmt/Configuration.py       2012-08-03 14:01:14 UTC 
(rev 23065)
@@ -0,0 +1,134 @@
+#!/usr/bin/python
+#
+#    This file is part of GNUnet.
+#    (C) 2010 Christian Grothoff (and other contributing authors)
+#
+#    GNUnet is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published
+#    by the Free Software Foundation; either version 2, or (at your
+#    option) any later version.
+#
+#    GNUnet is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with GNUnet; see the file COPYING.  If not, write to the
+#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+#
+# GNUnet Planetlab deployment and automation toolset 
+#
+# Configuration
+
+
+try:
+    import ConfigParser
+    import os
+    import sys
+except ImportError: 
+    print "That's a bug! please check README"
+    sys.exit (1) 
+
+class TransferMode:
+    none=0
+    sftp=1
+    scp=2
+
+class Configuration:
+    def __init__(self, filename, logger):
+        assert (None != logger)
+        self.filename = filename
+        self.logger = logger
+        self.notifications = ""
+        self.pl_slicename = ""
+        self.pl_api_url = ""
+        self.pl_username = ""
+        self.pl_password = ""
+        self.pl_use_nodes = False     
+        self.taskfile = ""
+        self.nodesfile = ""
+        self.ssh_add_unkown_hostkeys = False
+        self.ssh_keyfile = None
+        self.ssh_password = ""
+        self.ssh_use_known_hosts = False
+        self.ssh_transfer = TransferMode.scp
+    def load (self):        
+        self.logger.log ("Loading configuration file '" + self.filename + "'")
+        if (False == os.path.exists (self.filename)):
+            print "File does not exist: '" + self.filename + "'"
+            return False
+        config = ConfigParser.RawConfigParser()
+        try:
+            config.read(self.filename)
+        except ConfigParser.Error as e:
+            print "Error parsing configuration: " + str (e)
+            return False
+        
+        # required values
+        try: 
+            self.pl_slicename = config.get("planetlab", "slice")
+        except ConfigParser.NoOptionError as e:
+            print "Error parsing configuration: " + str (e)
+            return False
+        # optional values
+        try:
+            self.pl_use_nodes = config.getboolean ("planetlab", "use_pl_nodes")
+        except ConfigParser.NoOptionError as e:
+            pass    
+        try:
+            self.pl_api_url = config.get("planetlab", "api_url")
+        except ConfigParser.NoOptionError as e:
+            pass
+        try:
+            self.pl_username = config.get("planetlab", "username")
+        except ConfigParser.NoOptionError as e:
+            pass
+        try:
+            self.pl_password = config.get("planetlab", "password")
+        except ConfigParser.NoOptionError as e:
+            pass          
+        try: 
+            # gplmt options
+            self.taskfile = config.get("gplmt", "tasks")
+        except ConfigParser.NoOptionError as e:
+            pass
+        
+        try: 
+            self.nodesfile = config.get("gplmt", "nodes")
+        except ConfigParser.NoOptionError as e:
+            pass
+        
+        # ssh options
+        try: 
+            self.ssh_add_unkown_hostkeys = config.getboolean ("ssh", 
"add_unkown_hostkeys")
+        except ConfigParser.NoOptionError as e:
+            pass
+        try: 
+            self.ssh_use_known_hosts = config.getboolean ("ssh", 
"ssh_use_known_hosts")
+        except ConfigParser.NoOptionError as e:
+            pass
+        try: 
+            self.ssh_keyfile = config.get("ssh", "ssh_keyfile") 
+        except ConfigParser.NoOptionError as e:
+            pass
+        try: 
+            self.ssh_password = config.get("ssh", "ssh_password")
+        except ConfigParser.NoOptionError as e:
+            pass        
+        try: 
+            transfer = config.get("ssh", "ssh_transfer")
+            if (transfer == "scp"):
+                self.ssh_transfer = TransferMode.scp
+            elif (transfer == "sftp"):
+                self.ssh_transfer = TransferMode.sftp
+            else:
+                print "Invalid ssh transfer mode: only SFTP or SCP are 
supported"
+                return False
+        except ConfigParser.NoOptionError as e:
+            pass  
+        
+        
+        return True
+        
\ No newline at end of file

Added: gnunet-planetlab/gplmt/gplmt/Nodes.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/Nodes.py                               (rev 0)
+++ gnunet-planetlab/gplmt/gplmt/Nodes.py       2012-08-03 14:01:14 UTC (rev 
23065)
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+#
+#    This file is part of GNUnet.
+#    (C) 2010 Christian Grothoff (and other contributing authors)
+#
+#    GNUnet is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published
+#    by the Free Software Foundation; either version 2, or (at your
+#    option) any later version.
+#
+#    GNUnet is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with GNUnet; see the file COPYING.  If not, write to the
+#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+#
+# GNUnet Planetlab deployment and automation toolset 
+#
+# Nodes
+
+try:
+    import sys 
+    import os 
+    import urllib
+    import xmlrpclib
+    import socket
+except ImportError: 
+    print "That's a bug! please check README"
+    sys.exit (1) 
+
+class Nodes:
+    def __init__(self, filename, logger):
+        assert (None != logger)
+        self.logger = logger
+        self.filename = filename
+        self.nodes = list ()
+    def load (self):        
+        self.logger.log ("Loading nodes file '" + self.filename + "'")
+        try:
+            fobj = open (self.filename, "r") 
+            for line in fobj: 
+                line = line.strip() 
+                self.logger.log ("Found node '" + line + "'")
+                self.nodes.append(line)
+            fobj.close()
+        except IOError:
+            print "File " + self.filename + " not found"
+            return False
+        self.logger.log ("Loaded " + str(len(self.nodes)) + " nodes")
+        return True
+
+class StringNodes:
+    def __init__(self, str, logger):
+        assert (None != logger)
+        self.str = str
+        self.logger = logger
+        self.nodes = list ()
+    def load (self):        
+        self.logger.log ("Loading nodes '" + self.str + "'")
+        self.nodes.append(self.str)
+        self.logger.log ("Loaded " + str(len(self.nodes)) + " nodes")
+        return True    
+
+class PlanetLabNodes:
+    def __init__(self, configuration, logger):
+        assert (None != logger)
+        self.logger = logger
+        self.configuration = configuration
+        self.nodes = list ()
+    def load (self):        
+
+        if (self.configuration.pl_password == ""):
+            print "No PlanetLab password given in configuration fail!"
+            return False
+        if (self.configuration.pl_username == ""):            
+            print "No PlanetLab username given in configuration, fail!"
+            return False
+        if (self.configuration.pl_api_url == ""):            
+            print "No PlanetLab API url given in configuration, fail!"
+            return False
+        self.logger.log ("Retrieving nodes assigned to slice '" + 
self.configuration.pl_slicename + "' for user " +self.configuration.pl_username)
+        try:
+            server = xmlrpclib.ServerProxy(self.configuration.pl_api_url)
+        except:
+            print "Could not connect to PlanetLab API, fail!"
+            return False
+        
+        slice_data = {}
+        slice_data['name'] = self.configuration.pl_slicename
+
+        auth = {}
+        auth['Username'] = self.configuration.pl_username
+        auth['AuthString'] = self.configuration.pl_password
+        auth['AuthMethod'] = "password"
+        
+        try:
+            node_ids = server.GetSlices(auth, [slice_data['name']], 
['node_ids'])[0]['node_ids']
+            node_hostnames = [node['hostname'] for node in 
server.GetNodes(auth, node_ids, ['hostname'])]
+        except Exception as e:
+            print "Could not retrieve data from PlanetLab API: " + str(e)
+            return False            
+        
+        for node in node_hostnames:
+            self.logger.log ("Planetlab API returned: " + node)            
+            self.nodes.append(node)
+        self.logger.log ("Planetlab API returned " + str(len(self.nodes)) + " 
nodes")     
+        return True
\ No newline at end of file

Added: gnunet-planetlab/gplmt/gplmt/Notifications.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/Notifications.py                               
(rev 0)
+++ gnunet-planetlab/gplmt/gplmt/Notifications.py       2012-08-03 14:01:14 UTC 
(rev 23065)
@@ -0,0 +1,172 @@
+#!/usr/bin/python
+#
+#    This file is part of GNUnet.
+#    (C) 2010 Christian Grothoff (and other contributing authors)
+#
+#    GNUnet is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published
+#    by the Free Software Foundation; either version 2, or (at your
+#    option) any later version.
+#
+#    GNUnet is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with GNUnet; see the file COPYING.  If not, write to the
+#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+#
+# GNUnet Planetlab deployment and automation toolset 
+#
+# Notifications     
+
+try:
+    import gplmt.Tasks as Tasks
+    import time
+    import sys
+except ImportError: 
+    print "That's a bug! please check README" 
+
+
+class Notification:
+    def __init__(self, logger):
+        assert (None != logger)
+        self.logger = logger
+    def node_connected (self, node, success):
+        assert (0)
+    def node_disconnected (self, node, success):
+        assert (0) 
+    def tasklist_started (self, node, tasks):
+        assert (0)
+    def tasklist_completed (self, node, tasks, success):
+        assert (0)
+    def task_started (self, node, tasks):
+        assert (0)
+    def task_completed (self, node, tasks, success):
+        assert (0)
+
+class NodeCollection:
+    def __init__(self):
+        self.nodes = list ()
+    def add (self, node):
+        self.nodes.append (node)
+    def get (self, name):
+        for n in self.nodes:
+            if (n.name == name):
+                return n
+        return None
+        
+class Task:
+    def __init__(self, task, result, fail):
+        self.task = task
+        self.result = result
+        self.fail = fail
+        
+class Node:
+    def __init__(self, name):
+        self.name = name
+        self.start = time.time()
+        self.end = 0
+        self.tasks = list ()
+
+
+class FileLoggerNotification (Notification):
+    def __init__(self, logger):
+        assert (None != logger)
+        self.logger = logger
+        self.nodes = NodeCollection ()
+    def node_connected (self, node, success):
+        return
+    def node_disconnected (self, node, success):
+        return 
+    def tasklist_started (self, node, tasks):
+        return
+    def tasklist_completed (self, node, tasks, success):
+        self.nodes.add (Node(node))
+        if (success == True):
+            print node + " : Tasklist '" +  tasks.name + "' completed 
successfully"
+        else:
+            print node + " : Tasklist '" +  tasks.name + "' completed with 
failure"
+    def task_started (self, node, task):
+        return
+    def task_completed (self, node, task, result):
+        return   
+
+
+class TaskListResultNotification (Notification):
+    def __init__(self, logger):
+        assert (None != logger)
+        self.logger = logger
+        #self.nodes = NodeCollection ()
+    def summarize (self):
+        for n in self.nodes:
+            tsk_str = ""
+            for t in n.tasks:
+                tsk_f = "[e]"
+                if (t.fail == True):
+                    tsk_f = "[f]"
+                else:
+                    tsk_f = "[s]"
+                tsk_str += t.task.name + " " + tsk_f + " ->"
+            print n.name
+    def node_connected (self, node, success):
+        return
+    def node_disconnected (self, node, success):
+        return 
+    def tasklist_started (self, node, tasks):
+        return
+    def tasklist_completed (self, node, tasks, success):
+        if (success == True):
+            print node + " : Tasklist '" +  tasks.name + "' completed 
successfully"
+        else:
+            print node + " : Tasklist '" +  tasks.name + "' completed with 
failure"
+    def task_started (self, node, task):
+        return
+    def task_completed (self, node, task, result):
+        return         
+
+class SimpleNotification (Notification):
+    def __init__(self, logger):
+        assert (None != logger)
+        self.logger = logger
+        #self.nodes = NodeCollection ()
+    def summarize (self):
+        for n in self.nodes:
+            tsk_str = ""
+            for t in n.tasks:
+                tsk_f = "[e]"
+                if (t.fail == True):
+                    tsk_f = "[f]"
+                else:
+                    tsk_f = "[s]"
+                tsk_str += t.task.name + " " + tsk_f + " ->"
+            print n.name
+    def node_connected (self, node, success):
+        if (success == True):
+            print node + " : connected successfully"
+        else:
+            print node + " : connection failed"
+    def node_disconnected (self, node, success):
+        if (success == True):
+            print node + " : disconnected"
+        else:
+            print node + " : disconnected with failure"    
+    def tasklist_started (self, node, tasks):
+        print node + " : Tasklist '" +  tasks.name + "' started"
+        #self.nodes.add (Node(node))
+    def tasklist_completed (self, node, tasks, success):
+        if (success == True):
+            print node + " : Tasklist '" +  tasks.name + "' completed 
successfully"
+        else:
+            print node + " : Tasklist '" +  tasks.name + "' completed with 
failure"
+    def task_started (self, node, task):
+        print node + " : Task '" +  task.name + "' started"
+    def task_completed (self, node, task, result):
+        if (result == Tasks.Taskresult.success):
+            print node + " : Task '" +  task.name + "' completed successfully"
+        elif (result == Tasks.Taskresult.src_file_not_found):
+            print node + " : Task '" +  task.name + "' failed : source file 
not found"
+        else:
+            print node + " : Task '" +  task.name + "' completed with failure" 
            
\ No newline at end of file

Added: gnunet-planetlab/gplmt/gplmt/SCP.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/SCP.py                         (rev 0)
+++ gnunet-planetlab/gplmt/gplmt/SCP.py 2012-08-03 14:01:14 UTC (rev 23065)
@@ -0,0 +1,395 @@
+# scp.py
+# Copyright (C) 2008 James Bardin <address@hidden>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+"""
+Utilities for sending files over ssh using the scp1 protocol.
+"""
+
+import os
+from socket import timeout as SocketTimeout
+
+class SCPClient(object):
+    """
+    An scp1 implementation, compatible with openssh scp.
+    Raises SCPException for all transport related errors. Local filesystem
+    and OS errors pass through. 
+
+    Main public methods are .put and .get 
+    The get method is controlled by the remote scp instance, and behaves 
+    accordingly. This means that symlinks are resolved, and the transfer is
+    halted after too many levels of symlinks are detected.
+    The put method uses os.walk for recursion, and sends files accordingly.
+    Since scp doesn't support symlinks, we send file symlinks as the file
+    (matching scp behaviour), but we make no attempt at symlinked directories.
+
+    Convenience methods:
+        put_r:  put with recursion
+        put_p:  put preserving times
+        put_rp: put with recursion, preserving times
+        get_r:  get with recursion
+        get_p:  get preserving times
+        get_rp: get with recursion, preserving times
+    """
+    def __init__(self, transport, buff_size = 16384, socket_timeout = 5.0,
+                 callback = None):
+        """
+        Create an scp1 client.
+
+        @param transport: an existing paramiko L{Transport}
+        @type transport: L{Transport}
+        @param buff_size: size of the scp send buffer.
+        @type buff_size: int
+        @param socket_timeout: channel socket timeout in seconds
+        @type socket_timeout: float
+        @param callback: callback function for transfer status
+        @type callback: func
+        """
+        self.transport = transport
+        self.buff_size = buff_size
+        self.socket_timeout = socket_timeout
+        self.channel = None
+        self.preserve_times = False
+        self.callback = callback
+        self._recv_dir = ''
+        self._utime = None
+        self._dirtimes = {}
+
+    def put(self, files, remote_path = '.', 
+            recursive = False, preserve_times = False):
+        """
+        Transfer files to remote host.
+
+        @param files: A single path, or a list of paths to be transfered.
+            recursive must be True to transfer directories.
+        @type files: string OR list of strings
+        @param remote_path: path in which to receive the files on the remote
+            host. defaults to '.'
+        @type remote_path: str
+        @param recursive: transfer files and directories recursively
+        @type recursive: bool
+        @param preserve_times: preserve mtime and atime of transfered files
+            and directories.
+        @type preserve_times: bool
+        """
+        self.preserve_times = preserve_times
+        self.channel = self.transport.open_session()
+        self.channel.settimeout(self.socket_timeout)
+        scp_command = ('scp -t %s\n', 'scp -r -t %s\n')[recursive]
+        self.channel.exec_command(scp_command % remote_path)
+        self._recv_confirm()
+       
+        if not isinstance(files, (list, tuple)):
+            files = [files]
+        
+        if recursive:
+            self._send_recursive(files)
+        else:
+            self._send_files(files)
+        
+        if self.channel:
+            self.channel.close()
+    
+    def put_r(self, files, remote_path = '.'):
+        """
+        Convenience function for a recursive put
+
+        @param files: A single path, or a list of paths to be transfered.
+        @type files: str, list
+        @param remote_path: path in which to receive the files on the remote
+            host. defaults to '.'
+        @type remote_path: bool
+        """
+        self.put(files, remote_path, recursive = True)
+
+    def put_p(self, files, remote_path = '.'):
+        """
+        Convenience function to put preserving times.
+
+        @param files: A single path, or a list of paths to be transfered.
+        @type files: str, list
+        @param remote_path: path in which to receive the files on the remote
+            host. defaults to '.'
+        @type remote_path: bool
+        """
+        self.put(files, remote_path, preserve_times = True)
+   
+    def put_rp(self, files, remote_path = '.'):
+        """
+        Convenience function for a recursive put, preserving times.
+
+        @param files: A single path, or a list of paths to be transfered.
+        @type files: str, list
+        @param remote_path: path in which to receive the files on the remote
+            host. defaults to '.'
+        @type remote_path: bool
+        """
+        self.put(files, remote_path, recursive = True, preserve_times = True)
+
+    def get(self, remote_path, local_path = '',
+            recursive = False, preserve_times = False):
+        """
+        Transfer files from remote host to localhost
+
+        @param remote_path: path to retreive from remote host. since this is
+            evaluated by scp on the remote host, shell wildcards and 
+            environment variables may be used.
+        @type remote_path: str
+        @param local_path: path in which to receive files locally
+        @type local_path: str
+        @param recursive: transfer files and directories recursively
+        @type recursive: bool
+        @param preserve_times: preserve mtime and atime of transfered files
+            and directories.
+        @type preserve_times: bool
+        """
+        self._recv_dir = local_path or os.getcwd() 
+        rcsv = ('', ' -r')[recursive]
+        prsv = ('', ' -p')[preserve_times]
+        self.channel = self.transport.open_session()
+        self.channel.settimeout(self.socket_timeout)
+        self.channel.exec_command('scp%s%s -f %s' % (rcsv, prsv, remote_path))
+        self._recv_all()
+        
+        if self.channel:
+            self.channel.close()
+
+    def get_r(self, remote_path, local_path = '.'):
+        """
+        Convenience function for a recursive get
+
+        @param remote_path: path to retrieve from server
+        @type remote_path: str
+        @param local_path: path in which to recieve files. default cwd
+        @type local_path: str
+        """
+        self.get(remote_path, local_path, recursive = True)
+
+    def get_p(self, remote_path, local_path = '.'):
+        """
+        Convenience function for get, preserving times.
+
+        @param remote_path: path to retrieve from server
+        @type remote_path: str
+        @param local_path: path in which to recieve files. default cwd
+        @type local_path: str
+        """
+        self.get(remote_path, local_path, preserve_times = True)
+
+    def get_rp(self, remote_path, local_path = '.'):
+        """
+        Convenience function for a recursive get, preserving times.
+
+        @param remote_path: path to retrieve from server
+        @type remote_path: str
+        @param local_path: path in which to recieve files. default cwd
+        @type local_path: str
+        """
+        self.get(remote_path, local_path, recursive = True, preserve_times = 
True)
+
+    def _read_stats(self, name):
+        """return just the file stats needed for scp"""
+        stats = os.stat(name)
+        mode = oct(stats.st_mode)[-4:]
+        size = stats.st_size
+        atime = int(stats.st_atime)
+        mtime = int(stats.st_mtime)
+        return (mode, size, mtime, atime)
+
+    def _send_files(self, files): 
+        for name in files:
+            basename = os.path.basename(name)
+            (mode, size, mtime, atime) = self._read_stats(name)
+            if self.preserve_times:
+                self._send_time(mtime, atime)
+            file_hdl = file(name, 'rb')
+            self.channel.sendall('C%s %d %s\n' % (mode, size, basename))
+            self._recv_confirm()
+            file_pos = 0
+            buff_size = self.buff_size
+            chan = self.channel
+            while file_pos < size:
+                chan.sendall(file_hdl.read(buff_size))
+                file_pos = file_hdl.tell()
+                if self.callback:
+                    self.callback(file_pos, size)
+            chan.sendall('\x00')
+            file_hdl.close()
+
+    def _send_recursive(self, files):
+        for base in files:
+            lastdir = base
+            for root, dirs, fls in os.walk(base):
+                # pop back out to the next dir in the walk
+                while lastdir != os.path.commonprefix([lastdir, root]):
+                    self._send_popd()
+                    lastdir = os.path.split(lastdir)[0]
+                self._send_pushd(root)
+                lastdir = root
+                self._send_files([os.path.join(root, f) for f in fls])
+        
+    def _send_pushd(self, directory):
+        (mode, size, mtime, atime) = self._read_stats(directory)
+        basename = os.path.basename(directory)
+        if self.preserve_times:
+            self._send_time(mtime, atime)
+        self.channel.sendall('D%s 0 %s\n' % (mode, basename))
+        self._recv_confirm()
+
+    def _send_popd(self):
+        self.channel.sendall('E\n')
+        self._recv_confirm()
+
+    def _send_time(self, mtime, atime):
+        self.channel.sendall('T%d 0 %d 0\n' % (mtime, atime))
+        self._recv_confirm()
+
+    def _recv_confirm(self):
+        # read scp response
+        msg = ''
+        try:
+            msg = self.channel.recv(512)
+        except SocketTimeout:
+            raise SCPException('Timout waiting for scp response')
+        if msg and msg[0] == '\x00':
+            return
+        elif msg and msg[0] == '\x01':
+            raise SCPException(msg[1:])
+        elif self.channel.recv_stderr_ready():
+            msg = self.channel.recv_stderr(512)
+            raise SCPException(msg)
+        elif not msg:
+            raise SCPException('No response from server')
+        else:
+            raise SCPException('Invalid response from server: ' + msg)
+    
+    def _recv_all(self):
+        # loop over scp commands, and recive as necessary
+        command = {'C': self._recv_file,
+                   'T': self._set_time,
+                   'D': self._recv_pushd,
+                   'E': self._recv_popd}
+        while not self.channel.closed:
+            # wait for command as long as we're open
+            self.channel.sendall('\x00')
+            msg = self.channel.recv(1024)
+            if not msg: # chan closed while recving
+                break
+            code = msg[0]
+            try:
+                command[code](msg[1:])
+            except KeyError:
+                raise SCPException(repr(msg))
+        # directory times can't be set until we're done writing files
+        self._set_dirtimes()
+    
+    def _set_time(self, cmd):
+        try:
+            times = cmd.split()
+            mtime = int(times[0])
+            atime = int(times[2]) or mtime
+        except:
+            self.channel.send('\x01')
+            raise SCPException('Bad time format')
+        # save for later
+        self._utime = (mtime, atime)
+
+    def _recv_file(self, cmd):
+        chan = self.channel
+        parts = cmd.split()
+        try:
+            mode = int(parts[0], 8)
+            size = int(parts[1])
+            path = os.path.join(self._recv_dir, parts[2])
+        except:
+            chan.send('\x01')
+            chan.close()
+            raise SCPException('Bad file format')
+        
+        try:
+            file_hdl = file(path, 'wb')
+        except IOError, e:
+            chan.send('\x01'+e.message)
+            chan.close()
+            raise
+
+        buff_size = self.buff_size
+        pos = 0
+        chan.send('\x00')
+        try:
+            while pos < size:
+                # we have to make sure we don't read the final byte
+                if size - pos <= buff_size:
+                    buff_size = size - pos
+                file_hdl.write(chan.recv(buff_size))
+                pos = file_hdl.tell()
+                if self.callback:
+                    self.callback(pos, size)
+            
+            msg = chan.recv(512)
+            if msg and msg[0] != '\x00':
+                raise SCPException(msg[1:])
+        except SocketTimeout:
+            chan.close()
+            raise SCPException('Error receiving, socket.timeout')
+
+        file_hdl.truncate()
+        try:
+            os.utime(path, self._utime)
+            self._utime = None
+            os.chmod(path, mode)
+            # should we notify the other end?
+        finally:
+            file_hdl.close()
+        # '\x00' confirmation sent in _recv_all
+
+    def _recv_pushd(self, cmd):
+        parts = cmd.split()
+        try:
+            mode = int(parts[0], 8)
+            path = os.path.join(self._recv_dir, parts[2])
+        except:
+            self.channel.send('\x01')
+            raise SCPException('Bad directory format')
+        try:
+            if not os.path.exists(path):
+                os.mkdir(path, mode)
+            elif os.path.isdir(path):
+                os.chmod(path, mode)
+            else:
+                raise SCPException('%s: Not a directory' % path)
+            self._dirtimes[path] = (self._utime)
+            self._utime = None
+            self._recv_dir = path
+        except (OSError, SCPException), e:
+            self.channel.send('\x01'+e.message)
+            raise
+
+    def _recv_popd(self, *cmd):
+        self._recv_dir = os.path.split(self._recv_dir)[0]
+        
+    def _set_dirtimes(self):
+        try:
+            for d in self._dirtimes:
+                os.utime(d, self._dirtimes[d])
+        finally:
+            self._dirtimes = {}
+
+
+class SCPException(Exception):
+    """SCP exception class"""
+    pass

Added: gnunet-planetlab/gplmt/gplmt/Tasks.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/Tasks.py                               (rev 0)
+++ gnunet-planetlab/gplmt/gplmt/Tasks.py       2012-08-03 14:01:14 UTC (rev 
23065)
@@ -0,0 +1,280 @@
+#!/usr/bin/python
+#
+#    This file is part of GNUnet.
+#    (C) 2010 Christian Grothoff (and other contributing authors)
+#
+#    GNUnet is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published
+#    by the Free Software Foundation; either version 2, or (at your
+#    option) any later version.
+#
+#    GNUnet is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with GNUnet; see the file COPYING.  If not, write to the
+#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+#
+# GNUnet Planetlab deployment and automation toolset 
+#
+# Nodes
+try: 
+    import xml
+    import sys
+    from xml.parsers import expat  
+    from minixsv import pyxsval as xsv 
+    from elementtree import ElementTree
+    elementtree_loaded = True 
+    from genxmlif import GenXmlIfError
+except ImportError: 
+    print "That's a bug! please check README" 
+    sys.exit(1)
+
+glogger = None
+
+supported_operations = ["run", "monitor", "get", "put"]
+
+class Taskresult:
+    unspecified = -1
+    success = 0
+    timeout = 1
+    fail = 2 
+    return_value_did_not_match = 3
+    output_did_not_match = 4
+    src_file_not_found = 5
+    
+
+class Operation:
+    none=0
+    run=1
+    monitor=2
+    get=3
+    put=4
+
+class Task:
+    def __init__(self):
+        self.id = -1
+        self.name = ""
+        self.type = Operation.none
+        self.command = ""
+        self.arguments = ""
+        self.timeout = 0
+        self.expected_return_code = -1
+        self.expected_output = None
+        self.stop_on_fail = False
+        self.set = None
+        self.src = None
+        self.dest = None
+    def log (self):
+        glogger.log ("Task " + str(self.id) + ": " + self.name)
+    def check (self):
+        if (Operation.none):
+            return False
+        if (self.type == Operation.run):                   
+            if ((self.id == -1) or (self.name == "") or (self.command == "")):
+                return False
+        if (self.type == Operation.put):                   
+            if ((self.id == -1) or (self.name == "") or 
+                (self.src == None) or (self.dest == None)):
+                return False
+        if (self.type == Operation.get):                   
+            if ((self.id == -1) or (self.name == "") or 
+                (self.src == None) or (self.dest == None)):
+                return False            
+        return True
+                        
+class Taskset:
+    def __init__(self):
+        self.set = list()
+
+
+def handle_task (elem, tasks):
+    t = Task ()
+    
+    if (None != elem.attrib.get("name")):
+        t.name = elem.attrib.get("name")
+
+    if (None != elem.attrib.get("id")):
+        t.id = elem.attrib.get("id")
+    
+    if (tasks.startid != -1):
+        if (tasks.startid == t.id):
+            tasks.startid_found = True
+            glogger.log ("Task " + str (t.id) + " '" + t.name + "' has start 
ID") 
+        if (tasks.startid_found == False):
+            glogger.log ("Task " + str (t.id) + " '" + t.name + "' skipped")
+            return None;
+    
+    if (None != elem.attrib.get("enabled")):
+        if ("FALSE" == str(elem.attrib.get("enabled")).upper()):
+            glogger.log ("Task " + str (t.id) + " '" + t.name + "' is 
disabled")
+            return
+    
+    if (elem.tag == "run"):     
+        t.type = Operation.run
+    elif (elem.tag == "monitor"):            
+        t.type = Operation.monitor
+    elif (elem.tag == "get"):            
+        t.type = Operation.get
+    elif (elem.tag == "put"):       
+        t.type = Operation.put
+    else:
+        t.type = Operation.none
+        
+    for child in elem:
+        if ((child.tag == "command") and (child.text != None)):
+            t.command = child.text
+        if ((child.tag == "arguments") and (child.text != None)):
+            t.arguments = child.text
+        if (child.tag == "timeout"):
+            try:
+                t.timeout = int(child.text)
+            except ValueError:
+                print "Invalid timeout '"+child.text+"' for task id " + str 
(t.id) + " name " + t.name
+        if (child.tag == "expected_return_code"):
+            try:
+                t.expected_return_code = int(child.text)
+            except ValueError:
+                print "Invalid expected return code '" +child.text+ "' for 
task id " + str (t.id) + " name " + t.name
+        if ((child.tag == "expected_output") and (child.text != None)):
+            t.expected_output = child.text                            
+        if ((child.tag == "stop_on_fail") and (child.text != None)):
+            if (str.upper(child.text) == "TRUE"):
+                t.stop_on_fail = True
+            else:
+                t.stop_on_fail = False        
+        if ((child.tag == "source") and (child.text != None)):
+            t.src = child.text
+        if ((child.tag == "destination") and (child.text != None)):
+            t.dest = child.text                
+
+    if (False == t.check()):
+        print "Parsed invalid task with id " + str (t.id) + " name '" + t.name 
+ "'"
+        return None 
+    else:
+        t.log ()
+        return t
+
+def handle_sequence (elem, tasks):
+    if (None != elem.attrib.get("enabled")):
+        if ("FALSE" == str(elem.attrib.get("enabled")).upper()):
+            glogger.log ("Element was disabled")
+            return
+    for child in elem:
+            handle_child (child, tasks)
+            
+def handle_parallel (elem, tasks):
+    glogger.log ("Found parallel execution with " + str(len(elem)) + " 
elements")
+    if (None != elem.attrib.get("enabled")):
+        if ("FALSE" == str(elem.attrib.get("enabled")).upper()):
+            glogger.log ("Element was disabled")
+            return
+    ptask = Taskset ()
+    for child in elem:
+        if (elem.tag in supported_operations):
+            t = handle_task (elem)
+            if (None != t):
+                ptask.set.append(t)
+                print "Added " + t.name + " to set"
+        elif (elem.tag == "parallel"):
+            glogger.log ("x")
+        #    handle_parallel (elem, l)
+        elif (elem.tag == "sequence"):
+            glogger.log ("x")
+        #        handle_sequence (elem, l)
+        else:
+            print "Invalid element in task file: " + elem.tag
+    tasks.l.append (ptask)            
+    
+def handle_child (elem, tasks):
+    global support_operations
+    if (elem.tag in supported_operations):
+        t = handle_task (elem, tasks)
+        if (None != t):
+            tasks.l.append(t)
+    elif (elem.tag == "parallel"):
+        handle_parallel (elem, tasks)
+    elif (elem.tag == "sequence"):
+        handle_sequence (elem, tasks)
+    else:
+        print "Invalid element in task file: " + elem.tag
+
+def print_sequence (l):
+    for i in l:
+        print "->",
+        if (i.__class__.__name__ == "Task"):
+            print i.name,
+        elif (i.__class__.__name__ == "Taskset"):
+            print "{",
+            print_sequence (i.set)
+            print "}",
+
+    
+
+class Tasks:
+    def __init__(self, filename, logger, startid):
+        assert (None != logger)
+        global glogger
+        glogger = logger
+        self.logger = logger
+        self.filename = filename
+        self.name = "<Undefined>"
+        self.l = list ()
+        self.startid = startid
+        self.startid_found = False
+    def load (self):        
+        self.logger.log ("Loading tasks file '" + self.filename + "'")
+        enabled = True
+        try:
+            xsv.parseAndValidate (self.filename)
+        except xsv.xsvalErrorHandler.XsvalError as e:
+            print "File '" + self.filename + "' does not validate against 
schema: \n" + str(e)
+            return False
+        except GenXmlIfError as e:
+            print "File '" + self.filename + "' is not well-formed: \n" + 
str(e)
+            return False
+        except IOError:
+            print "File '" + self.filename + "' not found \n"
+            return False
+        
+        try:
+            root = ElementTree.parse (self.filename).getroot()
+            if (None != root.attrib.get("name")):
+                self.name = root.attrib.get("name")
+            if (None != root.attrib.get("enabled")):
+                if (False == root.attrib.get("enabled")):
+                    enabled = False
+        except expat.ExpatError as e:
+            print "File '" + self.filename + "'is malformed: " + str(e)
+            return False                
+        except IOError:
+            print "File '" + self.filename + "' not found"
+            return False
+        if (enabled == True):
+            for child in root:
+                handle_child (child, self)
+        else:
+            print "Tasklist " + self.filename + " was disabled"
+        #print_sequence (self.l)
+        
+        return True
+
+        
+    def copy (self):
+        t = Tasks (self.filename, self.logger, -1)
+        # Create a copy of the task list as described in 
+        # http://docs.python.org/library/copy.html
+        t.filename = self.filename
+        t.name = self.name
+        t.l = self.l[:]
+        return t
+    def get (self):
+        if (len (self.l) > 0):
+            item = self.l[0]
+            self.l.remove(item)
+            return item
+        else:
+            return None

Added: gnunet-planetlab/gplmt/gplmt/Util.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/Util.py                                (rev 0)
+++ gnunet-planetlab/gplmt/gplmt/Util.py        2012-08-03 14:01:14 UTC (rev 
23065)
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+#
+#    This file is part of GNUnet.
+#    (C) 2010 Christian Grothoff (and other contributing authors)
+#
+#    GNUnet is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published
+#    by the Free Software Foundation; either version 2, or (at your
+#    option) any later version.
+#
+#    GNUnet is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with GNUnet; see the file COPYING.  If not, write to the
+#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+#
+# GNUnet Planetlab deployment and automation toolset 
+#
+# Utilities
+
+class Logger:
+
+    def __init__(self, verbose):
+        if (True == verbose):
+            self.verbose = True
+        else:
+            self.verbose = False
+    def log (self, message):
+        global main
+        if (True == self.verbose):
+            print (message)
\ No newline at end of file

Added: gnunet-planetlab/gplmt/gplmt/Worker.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt/Worker.py                              (rev 0)
+++ gnunet-planetlab/gplmt/gplmt/Worker.py      2012-08-03 14:01:14 UTC (rev 
23065)
@@ -0,0 +1,295 @@
+#!/usr/bin/python
+#
+#    This file is part of GNUnet.
+#    (C) 2010 Christian Grothoff (and other contributing authors)
+#
+#    GNUnet is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published
+#    by the Free Software Foundation; either version 2, or (at your
+#    option) any later version.
+#
+#    GNUnet is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#    General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with GNUnet; see the file COPYING.  If not, write to the
+#    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+#    Boston, MA 02111-1307, USA.
+#
+# GNUnet Planetlab deployment and automation toolset 
+#
+# Worker
+
+try:
+    import gplmt.Configuration as TransferMode
+    import gplmt.Tasks as Tasks
+
+    import threading
+    import socket
+    import os
+    import time
+    import sys
+    import select
+    from gplmt.SCP import SCPClient
+
+except ImportError: 
+    print "That's a bug! please check README" 
+    sys.exit(1)
+
+
+
+try:
+    import paramiko
+    from paramiko.ssh_exception import SSHException
+except ImportError:
+    pass
+
+# Global variables
+g_logger = None
+g_notifications = None
+g_configuration = None
+
+class NodeWorkerThread (threading.Thread):
+    def __init__(self, threadID, node, tasks):
+        threading.Thread.__init__(self)
+        self.threadID = threadID
+        self.node = node
+        self.tasks = tasks
+    def exec_run (self, task, transport):
+        try:
+            channel = transport.open_session()
+            channel.settimeout(1.0)
+            channel.get_pty ()
+            #print "CMD: " + task.command + " " + task.arguments
+            channel.exec_command(task.command + " " + task.arguments)
+            
+        except SSHException as e:
+            print self.node + " : Error while trying to connect: " + str(e)
+        
+        if (task.timeout > 0):
+            timeout = task.timeout
+        else:
+            timeout = -1
+        result = Tasks.Taskresult.success
+        exit_status = -1
+        start_time = time.time ()
+        
+        stdout_data = ""
+        stderr_data = ""
+        while 1:
+            if (timeout != -1):
+                delta = time.time() - start_time
+                if (delta > timeout):
+                    print "Timeout after " +str(delta) +" seconds"
+                    result = Tasks.Taskresult.timeout
+                    break
+            (r, w, e) = select.select([channel], [], [], 1)
+            if r:
+                got_data = False
+                if channel.recv_ready():
+                    data = r[0].recv(4096)
+                    if data:
+                        got_data = True
+                        #g_logger.log ('STDOUT: ' + data)
+                        stdout_data += data
+                if channel.recv_stderr_ready():
+                    data = r[0].recv_stderr(4096)
+                    if data:
+                        got_data = True
+                        #g_logger.log ('STDERR: ' + data)
+                        stderr_data += data
+                if not got_data:
+                    break
+        
+        if (result == Tasks.Taskresult.success):
+            exit_status = channel.recv_exit_status ()  
+        
+        if (result == Tasks.Taskresult.success):
+            if (task.expected_return_code != -1):                    
+                if (exit_status != task.expected_return_code):
+                    g_logger.log (self.node + " : Task '"+ task.name + "' 
completed after "+ str(time.time() - start_time) +" sec, but exit code " 
+str(exit_status)+ " was not as expected " + str(task.expected_return_code))
+                    g_logger.log (stdout_data)
+                    g_logger.log (stderr_data)
+                    result = Tasks.Taskresult.return_value_did_not_match
+                else:
+                    g_logger.log (self.node + " : Task '"+ task.name + "' 
completed after "+ str(time.time() - start_time) +" sec, exit code " 
+str(exit_status)+ " was as expected " + str(task.expected_return_code))
+            
+            if (task.expected_output != None):
+                output_contained = False
+                if (task.expected_output in stdout_data):
+                    output_contained = True
+                if (task.expected_output in stderr_data):
+                        output_contained = True                
+                if (output_contained == True):
+                    g_logger.log (self.node + " : Task '"+ task.name + "' 
expected output '"+task.expected_output+"' was found")
+                else:
+                    g_logger.log (self.node + " : Task '"+ task.name + "' 
expected output '"+task.expected_output+"' was not found")
+                    result = Tasks.Taskresult.output_did_not_match
+                    
+        if (result == Tasks.Taskresult.success):
+            g_logger.log (self.node + " : Task '"+ task.name + "' successful")
+        elif (result == Tasks.Taskresult.timeout):
+            g_logger.log (self.node + " : Task '"+ task.name + "' with 
timeout")
+        else: 
+            g_logger.log (self.node + " : Task '"+ task.name + "' failed")
+        return result
+    def exec_put (self, task, transport):
+        if (False == os.path.exists (task.src)):
+            return Tasks.Taskresult.src_file_not_found
+            
+        result = Tasks.Taskresult.success
+        try:
+            if (g_configuration.ssh_transfer == TransferMode.scp):
+                scp = SCPClient (transport)
+                scp.put (task.src, task.dest)
+            if (g_configuration.ssh_transfer == TransferMode.sftp):            
    
+                sftp = paramiko.SFTPClient.from_transport (transport)
+                sftp.put(task.src, task.dest)
+                sftp.close()
+        except paramiko.SSHException as e:
+            g_logger.log (self.node + " : Task '"+ task.name + "' :" + str(e))
+            result = Tasks.Taskresult.fail
+            pass
+        except (OSError, IOError) as e:
+            g_logger.log (self.node + " : Task '"+ task.name + "' : " + str(e))
+            result = Tasks.Taskresult.src_file_not_found 
+            pass           
+        return result
+            
+    def exec_get (self, task, transport):
+        result = Tasks.Taskresult.success
+        try:
+            if (g_configuration.ssh_transfer == TransferMode.scp): 
+                scp = SCPClient (transport)
+                scp.get (task.src, task.dest)
+            if (g_configuration.ssh_transfer == TransferMode.sftp):
+                sftp = paramiko.SFTPClient.from_transport (transport)
+                sftp.get (task.src, task.dest)
+                sftp.close()
+        except paramiko.SSHException as e:
+            g_logger.log (self.node + " : Task '"+ task.name + "' :" + str(e))
+            result = Tasks.Taskresult.fail
+            pass
+        except (OSError, IOError) as e:
+            g_logger.log (self.node + " : Task '"+ task.name + "' : " + str(e))
+            result = Tasks.Taskresult.src_file_not_found 
+            pass           
+        return result    
+          
+    def run(self):
+        g_logger.log (self.node + " : Starting tasklist " + self.tasks.name)
+        task = self.tasks.get()
+        try: 
+            ssh = paramiko.SSHClient()
+            if (g_configuration.ssh_use_known_hosts):
+                g_logger.log (self.node + " : Loading known hosts")
+                ssh.load_system_host_keys ()
+
+            # Automatically add new hostkeys
+            if (g_configuration.ssh_add_unkown_hostkeys == True):
+                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+            # check for private key existance
+            keyfile = None
+            if (g_configuration.ssh_keyfile != None): 
+                if (os.path.exists (g_configuration.ssh_keyfile)):
+                    g_logger.log (self.node + " : Found " + 
g_configuration.ssh_keyfile)
+                    keyfile = g_configuration.ssh_keyfile
+                else:
+                    g_logger.log (self.node + " : Not found " + 
g_configuration.ssh_keyfile)
+                
+            g_logger.log (self.node + " : Trying to connect to " + 
+                          g_configuration.pl_slicename + "@" + self.node + 
+                          " using password '" + g_configuration.ssh_password+ 
+                          "' and private keyfile '" +str(keyfile)+ "'")
+            ssh.connect (self.node, 
+                         username=g_configuration.pl_slicename, 
+                         password=g_configuration.ssh_password,
+                         timeout=10,
+                         key_filename=keyfile) 
+        except (IOError,
+                paramiko.SSHException,
+                paramiko.BadHostKeyException, 
+                paramiko.AuthenticationException,
+                socket.error) as e:  
+            print self.node + " : Error while trying to connect: " + str(e)
+            g_notifications.node_connected (self.node, False)
+            g_notifications.tasklist_completed (self.node, self.tasks, False)
+            return
+        
+        g_notifications.node_connected (self.node, True)
+        
+        transport = ssh.get_transport()        
+        success = True
+        result = Tasks.Taskresult.success
+        while (None != task):
+            g_logger.log (self.node + " : Running task id " +str(task.id)+" '" 
+ task.name + "'")
+            g_notifications.task_started (self.node, task)
+            if (task.__class__.__name__ == "Task"):
+                if (task.type == Tasks.Operation.run):
+                    result = self.exec_run (task, transport)
+                    g_notifications.task_completed (self.node, task, result)
+                elif (task.type == Tasks.Operation.put):
+                    result = self.exec_put (task, transport)
+                    g_notifications.task_completed (self.node, task, result)
+                elif (task.type == Tasks.Operation.get):
+                    result = self.exec_get (task, transport)
+                    g_notifications.task_completed (self.node, task, result)
+                else:
+                    print "FAIL"                    
+            elif (task.__class__.__name__ == "Taskset"):
+                g_logger.log (self.node + " : Running task set")
+            if ((task.stop_on_fail == True) and (result != 
Tasks.Taskresult.success)):
+                g_logger.log (self.node + " : Task failed and therefore 
execution is stopped")
+                transport.close()
+                success = False
+                break
+            task = self.tasks.get()
+        
+        ssh.close()
+        g_notifications.node_disconnected (self.node, True)
+        g_notifications.tasklist_completed (self.node, self.tasks, success)
+        g_logger.log (self.node + " : All tasks done for " + self.node)
+        
+
+
+class NodeWorker:
+    def __init__(self, node, tasks):
+        assert (None != node)
+        assert (None != tasks)
+        self.node = node
+        self.tasks = tasks
+        self.thread = None
+    def start (self):
+        g_logger.log ("Starting execution for node " + self.node)
+        g_notifications.tasklist_started (self.node, self.tasks)
+        self.thread = NodeWorkerThread (1, self.node, self.tasks)
+        self.thread.start()
+    
+class Worker:
+    def __init__(self, logger, configuration, nodes, tasks, notifications):
+        global g_logger;
+        global g_configuration;
+        global g_notifications;
+        assert (None != logger)
+        assert (None != nodes)
+        assert (None != tasks)
+        assert (None != notifications)
+        assert (hasattr(notifications, 'node_connected'))
+        assert (hasattr(notifications, 'node_disconnected'))        
+        assert (hasattr(notifications, 'tasklist_started'))
+        assert (hasattr(notifications, 'tasklist_completed'))
+        assert (hasattr(notifications, 'task_started'))
+        assert (hasattr(notifications, 'task_completed'))
+        self.nodes = nodes
+        self.tasks = tasks
+        g_configuration = configuration
+        g_notifications = notifications
+        g_logger = logger;
+    def start (self):
+        g_logger.log ("Starting execution")
+        for n in self.nodes.nodes:
+            nw = NodeWorker (n, self.tasks.copy())
+            nw.start()
+        

Modified: gnunet-planetlab/gplmt/gplmt.py
===================================================================
--- gnunet-planetlab/gplmt/gplmt.py     2012-08-03 14:00:04 UTC (rev 23064)
+++ gnunet-planetlab/gplmt/gplmt.py     2012-08-03 14:01:14 UTC (rev 23065)
@@ -40,18 +40,22 @@
 except ImportError: 
     minixsv_loaded = False 
 
+try:
+    import gplmt.Util as Util
+    import gplmt.Configuration as Configuration
+    import gplmt.Nodes as Nodes
+    import gplmt.Tasks as Tasks
+    import gplmt.Worker as Worker
+    import gplmt.Notifications as Notifications
 
-import getopt;
-import sys;
-import Util;
-import Configuration;
-import Nodes;
-import Tasks;
-import Worker;
-import Notifications;
+    import getopt, sys
+except ImportError: 
+    print "That's a bug! please check README"
+    sys.exit (1)
 
 
 
+
 def main():
     global main
     main = Main ()

Deleted: gnunet-planetlab/gplmt/tasklist_schema.xsd
===================================================================
--- gnunet-planetlab/gplmt/tasklist_schema.xsd  2012-08-03 14:00:04 UTC (rev 
23064)
+++ gnunet-planetlab/gplmt/tasklist_schema.xsd  2012-08-03 14:01:14 UTC (rev 
23065)
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
elementFormDefault="qualified">
-<xs:element name="tasklist" type="tasklist" />
-
-<xs:complexType name="tasklist">
-  <xs:sequence>
-    <xs:choice minOccurs="0" maxOccurs="unbounded">
-      <xs:element name="sequence" type="sequence" />
-      <xs:element name="parallel" type="parallel" />
-      <xs:element name="run" type="run" />
-      <xs:element name="monitor" type="monitor" />
-      <xs:element name="put" type="put" />
-      <xs:element name="get" type="get" />
-    </xs:choice>
-  </xs:sequence>
-  <xs:attribute name="name" type="xs:string"/>
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-<xs:complexType name="sequence">
-  <xs:sequence>
-    <xs:choice minOccurs="0" maxOccurs="unbounded">
-      <xs:element name="sequence" type="sequence" />
-      <xs:element name="parallel" type="parallel" />
-      <xs:element name="run" type="run" />
-      <xs:element name="monitor" type="monitor" />
-      <xs:element name="put" type="put" />
-      <xs:element name="get" type="get" />
-    </xs:choice>
-  </xs:sequence>
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-<xs:complexType name="parallel">
-  <xs:sequence>
-    <xs:choice minOccurs="0" maxOccurs="unbounded">
-      <xs:element name="sequence" type="sequence" />
-      <xs:element name="parallel" type="parallel" />
-      <xs:element name="run" type="run" />
-      <xs:element name="monitor" type="monitor" />
-      <xs:element name="put" type="put" />
-      <xs:element name="get" type="get" />
-    </xs:choice>
-  </xs:sequence>
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-<xs:complexType name="run">
-  <xs:sequence>
-    <xs:element name="command" type="xs:string"/>
-    <xs:element name="arguments" type="xs:string"/>
-    <xs:element name="timeout" type="xs:integer"/>
-    <xs:element name="expected_return_code"  type="xs:integer"/>
-    <xs:element name="expected_output" type="xs:string"/>
-    <xs:element name="stop_on_fail" type="xs:boolean"/>
-  </xs:sequence>
-  <xs:attribute name="id" type="xs:integer"/>  
-  <xs:attribute name="name" type="xs:string"/>
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-<xs:complexType name="monitor">
-  <xs:sequence>
-    <xs:element name="command" type="xs:string"/>
-    <xs:element name="arguments" type="xs:string"/>
-    <xs:element name="timeout" type="xs:integer"/>
-    <xs:element name="expected_return_code"  type="xs:integer"/>
-    <xs:element name="expected_output" type="xs:string"/>
-    <xs:element name="stop_on_fail" type="xs:boolean"/>
-  </xs:sequence>
-  <xs:attribute name="id" type="xs:integer"/>
-  <xs:attribute name="name" type="xs:string"/>  
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-<xs:complexType name="put">
-  <xs:sequence>
-    <xs:element name="source" type="xs:string"/>
-    <xs:element name="destination" type="xs:string"/>
-    <xs:element name="stop_on_fail" type="xs:boolean"/>
-  </xs:sequence>
-  <xs:attribute name="id" type="xs:integer"/>
-  <xs:attribute name="name" type="xs:string"/>
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-<xs:complexType name="get">
-  <xs:sequence>
-    <xs:element name="source" type="xs:string"/>
-    <xs:element name="destination" type="xs:string"/>
-    <xs:element name="stop_on_fail" type="xs:boolean"/>
-  </xs:sequence>
-  <xs:attribute name="id" type="xs:integer"/>
-  <xs:attribute name="name" type="xs:string"/>
-  <xs:attribute name="enabled" type="xs:boolean"/>
-</xs:complexType>
-
-</xs:schema>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]