def checkResults(self, callData, name, version, flavorList, wait): flavorList = tuple(flavorList) if (name, version, flavorList) in self._results: results = self._results[name, version, flavorList] else: timeSpent = 0 buildInfo = self._buildInfo[name, version, flavorList] while True: results = cook.getResults(*buildInfo) if results: break elif wait and timeSpent < wait: time.sleep(.1) timeSpent += .1 else: return '' del self._buildInfo[name, version, flavorList] return freeze(cook.CookResults, results)
class ChrootServer(apirpc.XMLApiServer): def _setProcessTitle(self, name): pass @api(version=1) @api_parameters(1, 'BuildConfiguration') @api_return(1, None) def storeConfig(self, callData, buildCfg): buildCfg = self._updateConfig(buildCfg) path = '%s/tmp/conaryrc' % self.cfg.root util.mkdirChain(os.path.dirname(path)) conaryrc = open(path, 'w') conaryrc.write('# This is the actual conary configuration used when\n' '# building.\n') buildCfg.storeConaryCfg(conaryrc) conaryrc.close() path = '%s/tmp/rmakemacros' % self.cfg.root util.mkdirChain(os.path.dirname(path)) macrosrc = open(path, 'w') macrosrc.write('# This file contains macros; some of which may not' ' be included in /etc/conaryrc\n' + buildCfg.getMacros()) macrosrc.close() def _updateConfig(self, buildCfg): buildCfg.root = self.cfg.root buildCfg.buildPath = self.cfg.root + '/tmp/rmake/builds' buildCfg.lookaside = self.cfg.root + '/tmp/rmake/cache' buildCfg.dbPath = '/var/lib/conarydb' if not buildCfg.copyInConary: buildCfg.resetToDefault('policyDirs') if not buildCfg.copyInConfig: for option in buildCfg._dirsToCopy + buildCfg._pathsToCopy: buildCfg.resetToDefault(option) conaryCfg = conarycfg.ConaryConfiguration(True) buildCfg.strictMode = False buildCfg.useConaryConfig(conaryCfg) buildCfg.strictMode = True if self.cfg.root: # test path - we don't have a way to have managed policy # in this case. buildCfg.enforceManagedPolicy = False return buildCfg def _getRepos(self, buildCfg, caching=True): repos = conaryclient.ConaryClient(buildCfg).getRepos() if caching: repos = repocache.CachingTroveSource(repos, self.cfg.root + '/tmp/cscache', readOnly=True) return repos @api(version=1) @api_parameters(1, 'BuildConfiguration', 'str', 'version') def checkoutPackage(self, callData, buildCfg, troveName, troveVersion): buildCfg = self._updateConfig(buildCfg) repos = self._getRepos(buildCfg, caching=True) workDir = buildCfg.root + '/tmp/rmake' troveName = troveName.split(':')[0] checkoutPath = '%s/%s-checkout' % (workDir, troveName) util.mkdirChain(workDir) # make sure we don't set the context during checkout, as # the context doesn't exist at this point. buildCfg.context = None checkin.checkout(repos, buildCfg, checkoutPath, ['%s=%s' % (troveName, troveVersion)]) os.chmod(checkoutPath, 0775) @api(version=1) @api_parameters(1, 'BuildConfiguration', 'label', 'str', 'version', 'flavorList', 'LoadSpecsList', 'troveTupleList', None, 'troveTupleList', 'troveTupleList') @api_return(1, None) def buildTrove(self, callData, buildCfg, targetLabel, name, version, flavorList, loadSpecsList, builtTroves, logData, buildReqs, crossReqs): buildCfg = self._updateConfig(buildCfg) flavorList = tuple(flavorList) repos = self._getRepos(buildCfg, caching=not name.startswith('group-')) logPath, pid, buildInfo = cook.cookTrove(buildCfg, repos, self._logger, name, version, flavorList, targetLabel, loadSpecsList, logData, buildReqs, crossReqs) pid = buildInfo[1] self._buildInfo[name, version, flavorList] = buildInfo return logPath, pid @api(version=1) @api_parameters(1, 'str', 'version', 'flavorList', 'float') @api_return(1, None) def checkResults(self, callData, name, version, flavorList, wait): flavorList = tuple(flavorList) if (name, version, flavorList) in self._results: results = self._results[name, version, flavorList] else: timeSpent = 0 buildInfo = self._buildInfo[name, version, flavorList] while True: results = cook.getResults(*buildInfo) if results: break elif wait and timeSpent < wait: time.sleep(.1) timeSpent += .1 else: return '' del self._buildInfo[name, version, flavorList] return freeze(cook.CookResults, results) @api(version=1) @api_parameters(1, 'str', 'version', 'flavorList') @api_return(1, 'int') def subscribeToBuild(self, callData, name, version, flavorList): flavorList = tuple(flavorList) if not (name, version, flavorList) in self._buildInfo: return 0 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 0)) port = s.getsockname()[1] s.listen(1) self._unconnectedSubscribers[s] = name, version, flavorList return port @api(version=1) @api_parameters(1) @api_return(1, None) def stop(self, callData): self._results = [] self._halt = True return @api(version=1) @api_parameters(1, 'str', 'str') @api_return(1, 'int') def startSession(self, callData, command, ports): if os.path.exists('/tmp/rmake'): workDir = '/tmp/rmake' else: workDir = '/' ports = tuple(ports) t = telnetserver.TelnetServerForCommand(('', ports), command, workDir=workDir) port = t.server_address[1] pid = self._fork('Telnet session') if pid: # Note that when this session dies, the server will die. # This is in recognition of the fact that this chroot server, # while made to handle multiple commands, in fact only ever # receives one command and then dies when it finishes. # Perhaps we should get rid of this daemon and instead # make it a simple program? t.server_close() self._sessionPid = pid return port try: self._try('Telnet session', t.handle_request) finally: os._exit(1) def _serveLoopHook(self): try: ready = select.select(self._unconnectedSubscribers, [], [], 0.1)[0] except select.error, err: ready = [] for socket in ready: troveTup = self._unconnectedSubscribers.pop(socket) socket, caddr = socket.accept() self._subscribers.setdefault(troveTup, []).append(socket) for troveInfo, buildInfo in self._buildInfo.items(): results = cook.getResults(*buildInfo) if not results: continue self._results[troveInfo] = results for socket in self._subscribers.get(troveInfo, []): socket.close() del self._buildInfo[troveInfo] self._collectChildren()
def _wait(self, buildInfo): for i in range(10000): result = cook.getResults(*buildInfo) if result: return result time.sleep(.1)