def __init__(self, basedir, configFileName="master.cfg", umask=None): service.MultiService.__init__(self) self.setName("buildmaster") self.umask = umask self.basedir = basedir assert os.path.isdir(self.basedir) self.configFileName = configFileName # set up child services self.create_child_services() # loop for polling the db self.db_loop = None # db configured values self.configured_db_url = None self.configured_poll_interval = None # running multimaster mode self.configured_buildbotURL = None # configuration / reconfiguration handling self.config = config.MasterConfig() self.reconfig_active = False self.reconfig_requested = False self.reconfig_notifier = None self.is_changing_services = False self.change_service_lock = defer.DeferredLock() # this stores parameters used in the tac file, and is accessed by the # WebStatus to duplicate those values. self.log_rotation = LogRotation() # subscription points self._change_subs = \ subscription.SubscriptionPoint("changes") self._new_buildrequest_subs = \ subscription.SubscriptionPoint("buildrequest_additions") self._cancelled_buildrequest_subs = \ subscription.SubscriptionPoint("buildrequest_cancelled") self._new_buildset_subs = \ subscription.SubscriptionPoint("buildset_additions") self._complete_buildset_subs = \ subscription.SubscriptionPoint("buildset_completion") # local cache for this master's object ID self._object_id = None
def __init__(self, name, maxCount=1): super().__init__() # Name of the lock self.lockName = name # Current queue, tuples (waiter, LockAccess, deferred) self.waiting = [] # Current owners, tuples (owner, LockAccess) self.owners = [] # maximal number of counting owners self.maxCount = maxCount # current number of claimed exclusive locks (0 or 1), must match # self.owners self._claimed_excl = 0 # current number of claimed counting locks (0 to self.maxCount), must # match self.owners. Note that self.maxCount is not a strict limit, the # number of claimed counting locks may be higher than self.maxCount if # it was lowered by self._claimed_counting = 0 # subscriptions to this lock being released self.release_subs = subscription.SubscriptionPoint( f"{repr(self)} releases")
def __init__(self, name, maxCount=1): self.name = name # Name of the lock self.waiting = [] # Current queue, tuples (LockAccess, deferred) self.owners = [] # Current owners, tuples (owner, LockAccess) self.maxCount = maxCount # maximal number of counting owners # subscriptions to this lock being released self.release_subs = subscription.SubscriptionPoint("%r releases" % (self,))
def __init__(self, name, maxCount=1): # Name of the lock self.name = name # Current queue, tuples (waiter, LockAccess, deferred) self.waiting = [] # Current owners, tuples (owner, LockAccess) self.owners = [] # maximal number of counting owners self.maxCount = maxCount # current number of claimed exclusive locks (0 or 1), must match # self.owners self._claimed_excl = 0 # current number of claimed counting locks (0 to self.maxCount), must # match self.owners self._claimed_counting = 0 # subscriptions to this lock being released self.release_subs = subscription.SubscriptionPoint("%r releases" % (self, ))
def __init__(self, master, buildslave): self.master = master self.buildslave = buildslave name = buildslave.slavename self._disconnectSubs = subscription.SubscriptionPoint( "disconnections from %s" % name)
def attached(self, bot): """This is called when the slave connects. @return: a Deferred that fires when the attachment is complete """ # the botmaster should ensure this. assert not self.isConnected() metrics.MetricCountEvent.log("AbstractBuildSlave.attached_slaves", 1) # set up the subscription point for eventual detachment self.detached_subs = subscription.SubscriptionPoint("detached") # now we go through a sequence of calls, gathering information, then # tell the Botmaster that it can finally give this slave to all the # Builders that care about it. # we accumulate slave information in this 'state' dictionary, then # set it atomically if we make it far enough through the process state = {} # Reset graceful shutdown status self.slave_status.setGraceful(False) # We want to know when the graceful shutdown flag changes self.slave_status.addGracefulWatcher(self._gracefulChanged) self.slave_status.addPauseWatcher(self._pauseChanged) d = defer.succeed(None) @d.addCallback def _log_attachment_on_slave(res): d1 = bot.callRemote("print", "attached") d1.addErrback(lambda why: None) return d1 @d.addCallback def _get_info(res): d1 = bot.callRemote("getSlaveInfo") def _got_info(info): log.msg("Got slaveinfo from '%s'" % self.slavename) # TODO: info{} might have other keys state["admin"] = info.get("admin") state["host"] = info.get("host") state["access_uri"] = info.get("access_uri", None) state["slave_environ"] = info.get("environ", {}) state["slave_basedir"] = info.get("basedir", None) state["slave_system"] = info.get("system", None) def _info_unavailable(why): why.trap(pb.NoSuchMethod) # maybe an old slave, doesn't implement remote_getSlaveInfo log.msg("BuildSlave.info_unavailable") log.err(why) d1.addCallbacks(_got_info, _info_unavailable) return d1 d.addCallback(lambda _: self.startKeepaliveTimer()) @d.addCallback def _get_version(_): d = bot.callRemote("getVersion") def _got_version(version): state["version"] = version def _version_unavailable(why): why.trap(pb.NoSuchMethod) # probably an old slave state["version"] = '(unknown)' d.addCallbacks(_got_version, _version_unavailable) return d @d.addCallback def _get_commands(_): d1 = bot.callRemote("getCommands") def _got_commands(commands): state["slave_commands"] = commands def _commands_unavailable(why): # probably an old slave if why.check(AttributeError): return log.msg("BuildSlave.getCommands is unavailable - ignoring") log.err(why) d1.addCallbacks(_got_commands, _commands_unavailable) return d1 @d.addCallback def _accept_slave(res): self.slave_status.setConnected(True) self.slave_status.updateInfo( admin=state.get("admin"), host=state.get("host"), access_uri=state.get("access_uri"), version=state.get("version"), ) self.slave_commands = state.get("slave_commands") self.slave_environ = state.get("slave_environ") self.slave_basedir = state.get("slave_basedir") self.slave_system = state.get("slave_system") self.slave = bot if self.slave_system == "nt": self.path_module = namedModule("ntpath") else: # most everything accepts / as separator, so posix should be a # reasonable fallback self.path_module = namedModule("posixpath") log.msg("bot attached") self.messageReceivedFromSlave() self.stopMissingTimer() self.master.status.slaveConnected(self.slavename) d.addCallback(lambda _: self.updateSlave()) d.addCallback( lambda _: self.botmaster.maybeStartBuildsForSlave(self.slavename)) # Finally, the slave gets a reference to this BuildSlave. They # receive this later, after we've started using them. d.addCallback(lambda _: self) return d
def setUp(self): self.subpt = subscription.SubscriptionPoint('test_sub')
def __init__(self, master, worker): self.master = master self.worker = worker name = worker.workername self._disconnectSubs = subscription.SubscriptionPoint( "disconnections from %s" % name)
def __init__(self, name): self._disconnectSubs = subscription.SubscriptionPoint( "disconnections from {}".format(name))
def __init__(self, name): self._disconnectSubs = subscription.SubscriptionPoint( f"disconnections from {name}")
def __init__(self): self._disconnectSubs = subscription.SubscriptionPoint("disconnections from Fake")