Package buildbot :: Package changes :: Module pb
[frames] | no frames]

Source Code for Module buildbot.changes.pb

  1  # This file is part of Buildbot.  Buildbot is free software: you can 
  2  # redistribute it and/or modify it under the terms of the GNU General Public 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  5  # This program is distributed in the hope that it will be useful, but WITHOUT 
  6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 10  # You should have received a copy of the GNU General Public License along with 
 11  # this program; if not, write to the Free Software Foundation, Inc., 51 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 15   
 16   
 17  from twisted.python import log 
 18  from twisted.internet import defer 
 19   
 20  from buildbot.pbutil import NewCredPerspective 
 21  from buildbot.changes import base 
 22  from buildbot.util import epoch2datetime 
 23  from buildbot import config 
24 25 -class ChangePerspective(NewCredPerspective):
26
27 - def __init__(self, master, prefix):
28 self.master = master 29 self.prefix = prefix
30
31 - def attached(self, mind):
32 return self
33 - def detached(self, mind):
34 pass
35
36 - def perspective_addChange(self, changedict):
37 log.msg("perspective_addChange called") 38 39 if 'revlink' in changedict and not changedict['revlink']: 40 changedict['revlink'] = '' 41 if 'repository' in changedict and not changedict['repository']: 42 changedict['repository'] = '' 43 if 'project' in changedict and not changedict['project']: 44 changedict['project'] = '' 45 if 'files' not in changedict or not changedict['files']: 46 changedict['files'] = [] 47 48 # rename arguments to new names. Note that the client still uses the 49 # "old" names (who, when, and isdir), as they are not deprecated yet, 50 # although the master will accept the new names (author, 51 # when_timestamp, and is_dir). After a few revisions have passed, we 52 # can switch the client to use the new names. 53 if 'isdir' in changedict: 54 changedict['is_dir'] = changedict['isdir'] 55 del changedict['isdir'] 56 if 'who' in changedict: 57 changedict['author'] = changedict['who'] 58 del changedict['who'] 59 if 'when' in changedict: 60 when = None 61 if changedict['when'] is not None: 62 when = epoch2datetime(changedict['when']) 63 changedict['when_timestamp'] = when 64 del changedict['when'] 65 66 # turn any bytestring keys into unicode, assuming utf8 but just 67 # replacing unknown characters. Ideally client would send us unicode 68 # in the first place, but older clients do not, so this fallback is 69 # useful. 70 for key in changedict: 71 if type(changedict[key]) == str: 72 changedict[key] = changedict[key].decode('utf8', 'replace') 73 changedict['files'] = list(changedict['files']) 74 for i, file in enumerate(changedict.get('files', [])): 75 if type(file) == str: 76 changedict['files'][i] = file.decode('utf8', 'replace') 77 78 files = [] 79 for path in changedict['files']: 80 if self.prefix: 81 if not path.startswith(self.prefix): 82 # this file does not start with the prefix, so ignore it 83 continue 84 path = path[len(self.prefix):] 85 files.append(path) 86 changedict['files'] = files 87 88 if not files: 89 log.msg("No files listed in change... bit strange, but not fatal.") 90 91 if changedict.has_key('links'): 92 log.msg("Found links: "+repr(changedict['links'])) 93 del changedict['links'] 94 95 d = self.master.addChange(**changedict) 96 # since this is a remote method, we can't return a Change instance, so 97 # this just sets the return value to None: 98 d.addCallback(lambda _ : None) 99 return d
100
101 -class PBChangeSource(config.ReconfigurableServiceMixin, base.ChangeSource):
102 compare_attrs = ["user", "passwd", "port", "prefix", "port"] 103
104 - def __init__(self, user="change", passwd="changepw", port=None, 105 prefix=None):
106 107 self.user = user 108 self.passwd = passwd 109 self.port = port 110 self.prefix = prefix 111 self.registration = None 112 self.registered_port = None
113
114 - def describe(self):
115 portname = self.registered_port 116 d = "PBChangeSource listener on " + str(portname) 117 if self.prefix is not None: 118 d += " (prefix '%s')" % self.prefix 119 return d
120 121 @defer.inlineCallbacks
122 - def reconfigService(self, new_config):
123 # calculate the new port 124 port = self.port 125 if port is None: 126 port = new_config.slavePortnum 127 128 # and, if it's changed, re-register 129 if port != self.registered_port: 130 yield self._unregister() 131 self._register(port) 132 133 yield config.ReconfigurableServiceMixin.reconfigService( 134 self, new_config)
135
136 - def stopService(self):
137 d = defer.maybeDeferred(base.ChangeSource.stopService, self) 138 d.addCallback(lambda _ : self._unregister()) 139 return d
140
141 - def _register(self, port):
142 if not port: 143 log.msg("PBChangeSource has no port to listen on") 144 return 145 self.registered_port = port 146 self.registration = self.master.pbmanager.register( 147 port, self.user, self.passwd, 148 self.getPerspective)
149
150 - def _unregister(self):
151 self.registered_port = None 152 if self.registration: 153 return self.registration.unregister() 154 else: 155 return defer.succeed(None)
156
157 - def getPerspective(self, mind, username):
158 assert username == self.user 159 return ChangePerspective(self.master, self.prefix)
160