[Buildbot-commits] buildbot/buildbot/process step.py,1.103,1.104

Brian Warner warner at users.sourceforge.net
Fri Sep 15 14:49:02 UTC 2006


Update of /cvsroot/buildbot/buildbot/buildbot/process
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv21206/buildbot/process

Modified Files:
	step.py 
Log Message:
[project @ initial checkin of Albert's file-upload/download patch]

Original author: warner at lothar.com
Date: 2006-06-16 01:21:37

Index: step.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/process/step.py,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -d -r1.103 -r1.104
--- step.py	9 Sep 2006 06:20:50 -0000	1.103
+++ step.py	15 Sep 2006 14:49:00 -0000	1.104
@@ -1,5 +1,8 @@
 # -*- test-case-name: buildbot.test.test_steps -*-
 
+import time, random, types, re, warnings
+from email.Utils import formatdate
+
 from twisted.internet import reactor, defer, error
 from twisted.protocols import basic
 from twisted.spread import pb
@@ -1061,6 +1064,226 @@
         self.step_status.setText(self.getText(cmd, results))
         self.step_status.setText2(self.maybeGetText2(cmd, results))
 
+#
+# =================================================================
+#
+
+class FileIO(pb.Referenceable):
+    """
+    Helper base class that acts as remote-accessible file-object
+    """
+
+    def __init__(self,fp):
+        self.fp = fp
+    
+    def remote_close(self):
+        """
+        Called by remote slave to state that no more data will be transfered
+        """
+        if self.fp is not None:
+            self.fp.close()
+            self.fp = None
+
+class FileWriter(FileIO):
+    """
+    Helper class that acts as a file-object with write access
+    """
+
+    def __init__(self,fp, maxsize=None):
+        FileIO.__init__(self,fp)
+	self.maxsize = maxsize
+    
+    def remote_write(self,data):
+	"""
+	Called from remote slave to write L{data} to L{fp} within boundaries
+	of L{maxsize}
+
+	@type  data: C{string}
+	@param data: String of data to write
+	"""
+        if self.fp is not None:
+	    if self.maxsize is not None:
+		if len(data) > self.maxsize:
+		    data = data[:self.maxsize]
+                self.fp.write(data)
+		self.maxsize = self.maxsize - len(data)
+	    else:
+                self.fp.write(data)
+
+class FileReader(FileIO):
+    """
+    Helper class that acts as a file-object with read access
+    """
+
+    def remote_read(self,maxlength):
+	"""
+	Called from remote slave to read at most L{maxlength} bytes of data
+
+	@type  maxlength: C{integer}
+	@param maxlength: Maximum number of data bytes that can be returned
+
+        @return: Data read from L{fp}
+        @rtype: C{string} of bytes read from file
+	"""
+        if self.fp is None:
+            return ''
+        
+        data = self.fp.read(maxlength)
+        return data
+
+
+class StatusRemoteCommand(RemoteCommand):
+    def __init__(self, remote_command, args):
+        RemoteCommand.__init__(self, remote_command, args)
+
+        self.rc = None
+        self.stderr = ''
+
+    def remoteUpdate(self, update):
+        #log.msg('StatusRemoteCommand: update=%r' % update)
+        if 'rc' in update:
+            self.rc = update['rc']
+        if 'stderr' in update:
+            self.stderr = self.stderr + update['stderr'] + '\n'
+
+
+class FileUpload(BuildStep):
+    """
+    Build step to upload a file
+    arguments:
+
+    ['slavesrc']   filename of source file at slave
+    ['masterdest'] filename of destination file at master
+    ['workdir']    string with slave working directory relative to builder
+                   base dir, default 'build'
+    ['maxsize']    maximum size of the file, default None (=unlimited)
+    ['blocksize']  maximum size of each block being transfered
+
+    """
+
+    name = 'upload'
+
+    def __init__(self,build, **kwargs):
+        buildstep_kwargs = {}
+        for k in kwargs.keys()[:]:
+            if k in BuildStep.parms:
+                buildstep_kwargs[k] = kwargs[k]
+                del kwargs[k]
+            BuildStep.__init__(self,build,**buildstep_kwargs)
+
+        self.args = kwargs
+        self.fileWriter = None
+
+    def start(self):
+        log.msg("FileUpload started, from slave %r to master %r"
+                            % (self.args['slavesrc'],self.args['masterdest']))
+
+        self.step_status.setColor('yellow')
+        self.step_status.setText(['uploading', self.args['slavesrc']])
+
+        fp = open(self.args['masterdest'],'w')
+        self.fileWriter = FileWriter(fp)
+
+        a = self.args.copy()
+        a['writer'] = self.fileWriter
+
+        # add defaults for optional settings
+        for k,dv in [('maxsize',None),('blocksize',16*1024),('workdir','build')]:
+            if k not in a:
+                a[k] = dv
+
+        self.cmd = StatusRemoteCommand('uploadFile', a)
+        d = self.runCommand(self.cmd)
+        d.addCallback(self.finished).addErrback(self.failed)
+
+    def finished(self,result):
+        if self.cmd.stderr != '':
+            self.addCompleteLog('stderr', self.cmd.stderr)
+
+        self.fileWriter = None
+
+        if self.cmd.rc is None or self.cmd.rc == 0:
+            self.step_status.setColor('green')
+            return BuildStep.finished(self,SUCCESS)
+        self.step_status.setColor('red')
+        return BuildStep.finished(self,FAILURE)
+
+class FileDownload(BuildStep):
+    """
+    Build step to download a file
+    arguments:
+
+    ['mastersrc'] filename of source file at master
+    ['slavedest'] filename of destination file at slave
+    ['workdir']   string with slave working directory relative to builder
+                  base dir, default 'build'
+    ['maxsize']   maximum size of the file, default None (=unlimited)
+    ['blocksize'] maximum size of each block being transfered
+
+    """
+
+    name = 'download'
+
+    def __init__(self,build, **kwargs):
+        buildstep_kwargs = {}
+        for k in kwargs.keys()[:]:
+            if k in BuildStep.parms:
+                buildstep_kwargs[k] = kwargs[k]
+                del kwargs[k]
+            BuildStep.__init__(self,build,**buildstep_kwargs)
+
+        self.args = kwargs
+        self.fileReader = None
+
+    def start(self):
+        log.msg("FileDownload started, from master %r to slave %r"
+                            % (self.args['mastersrc'],self.args['slavedest']))
+
+        self.step_status.setColor('yellow')
+        self.step_status.setText(['downloading', self.args['slavedest']])
+
+        # If file does not exist, bail out with an error
+        if not os.path.isfile(self.args['mastersrc']):
+            self.addCompleteLog('stderr',
+                    'File %r not available at master' % self.args['mastersrc'])
+            reactor.callLater(0, self.reportFail)
+            return
+
+        # setup structures for reading the file
+        fp = open(self.args['mastersrc'],'r')
+        self.fileReader = FileReader(fp)
+
+        a = self.args.copy()
+        a['reader'] = self.fileReader
+
+        # add defaults for optional settings
+        for k,dv in [('maxsize',None),('blocksize',16*1024),('workdir','build')]:
+            if k not in a:
+                a[k] = dv
+
+        self.cmd = StatusRemoteCommand('downloadFile', a)
+        d = self.runCommand(self.cmd)
+        d.addCallback(self.finished).addErrback(self.failed)
+
+    def finished(self,result):
+        if self.cmd.stderr != '':
+            self.addCompleteLog('stderr', self.cmd.stderr)
+
+        self.fileReader = None
+
+        if self.cmd.rc is None or self.cmd.rc == 0:
+            self.step_status.setColor('green')
+            return BuildStep.finished(self,SUCCESS)
+        return self.reportFail()
+    
+    def reportFail(self):
+        self.step_status.setColor('red')
+        return BuildStep.finished(self,FAILURE)
+
+#
+# =================================================================
+#
+
 
 # legacy compatibility
 





More information about the Commits mailing list