def testStart(self): raise testhelp.SkipTestException('Failing test in bamboo') startFile = self.workDir + '/startFile' if os.path.exists(startFile): os.remove(startFile) stopFile = self.workDir + '/stopFile' #sys.argv[0] = 'python ./testsuite.py' #sys.argv[0] = 'daemontest.py' self.rmakeCfg.pluginDirs = resources.get_plugin_dirs() self.rmakeCfg.usePlugins = False self.rmakeCfg.usePlugin['multinode'] = False reposPort, proxyPort = sock_utils.findPorts(2) self.rmakeCfg.reposUrl = 'http://LOCAL:%s' % reposPort self.rmakeCfg.proxyUrl = 'http://LOCAL:%s' % proxyPort util.mkdirChain(self.rmakeCfg.lockDir) util.mkdirChain(self.rmakeCfg.buildDir) pid = os.fork() if not pid: self.rmakeCfg.writeToFile(self.workDir + '/rmakecfg') daemon.rMakeDaemon.configClass.getSocketPath = lambda x: self.rootDir + '/socket' daemon.rMakeDaemon.configClass.getServerUri = lambda x: 'unix://' + self.rootDir + '/socket' logFile = logfile.LogFile(startFile) logFile.redirectOutput() try: try: daemon.main([ 'rmake-server', 'start', '-n', '--skip-default-config', '--config-file', self.workDir + '/rmakecfg' ]) except SystemExit, err: if err.code == 0: os._exit(0) finally: os._exit(1) timeSlept = 0 while timeSlept < 5: if os.path.exists(startFile): log = open(startFile).read() if 'Started rMake Server at pid %s' % pid in log: break time.sleep(.1) timeSlept += .1 assert (timeSlept < 5) # wait for fail current jobs process to stop. time.sleep(1) try: logFile = logfile.LogFile(stopFile) logFile.redirectOutput() daemon.main([ 'rmake-server', 'stop', '--skip-default-config', '--config-file', self.workDir + '/rmakecfg' ]) except SystemExit, err: if err.code: raise
def testFakeChroot(self): groupRecipe = """ class SimpleGroup(GroupRecipe): name = 'group-foo' version = '1' clearBuildReqs() def setup(r): r.add('foo:lib') """ trv = self.addComponent('group-foo:source=1', [('group-foo.recipe', groupRecipe)]) self.addComponent('foo:lib') mgr = rootmanager.ChrootManager(self.rmakeCfg) trv = self.newBuildTrove(1, *trv.getNameVersionFlavor()) factory = mgr.getRootFactory(self.buildCfg, [], [], [], trv) factory.create() logFile = logfile.LogFile(self.workDir + '/rmake.out') logFile.redirectOutput() chroot = factory.start() try: chroot.buildTrove(self.buildCfg, versions.Label('localhost@rpl:branch'), *trv.getNameVersionFlavor()) results = chroot.checkResults(wait=30, *trv.getNameVersionFlavor()) assert(results.isBuildSuccess()) finally: chroot.stop() factory.clean() assert(factory.root != '/tmp/rmake') assert(not os.path.exists('/tmp/rmake/builds/group-foo'))
def testBuildImages(self): rbuildServer = self.startMockRbuilder() oldSleep = time.sleep self.mock(time, 'sleep', lambda x: oldSleep(.1)) self.addComponent('foo:run') trv = self.addCollection('group-foo', ['foo:run']) db = self.openRmakeDatabase() job = self.newJob() trv = self.newImageTrove(job.jobId, productName='product', imageType='imageType', imageOptions={}, *trv.getNameVersionFlavor()) trv.setConfig(self.buildCfg) job.addBuildTrove(trv) job.setBuildTroves([trv]) b = builder.Builder(self.rmakeCfg, job) self.logFilter.add() logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() try: b.build() except Exception: b.worker.stopAllCommands() raise log = db.getTroveBuildLog(1, job.troves.values()[0].getNameVersionFlavor(), 0)[1] expectedLog = '''\ 0: Working: 51 0: Working: 101 0: Working: 151 0: Finished. ''' assert(expectedLog in log)
def testLogFile(self): # test logging to fd path = self.workDir + '/logfile' fd = os.open(path, os.O_CREAT | os.O_APPEND | os.O_WRONLY) logFile = logfile.LogFile(fd) logFile.redirectOutput() print 'foo!' logFile.close() assert (open(path).read() == 'foo!\n') assert (self.captureOutput(sys.stdout.write, 'bar\n')[1] == 'bar\n')
def startProxy(cfg, fork=True, logger=None): global conaryDir baseDir = cfg.getProxyDir() proxyPort = cfg.getProxyInfo()[1] util.mkdirChain('%s/repos' % baseDir) if os.path.exists(cfg.getProxyConfigPath()): os.unlink(cfg.getProxyConfigPath()) serverCfg = server.ServerConfig(cfg.getProxyConfigPath()) serverCfg.serverName = [] serverCfg.proxyDB = ('sqlite', cfg.getProxyPath()) serverCfg.changesetCacheDir = cfg.getProxyChangesetPath() serverCfg.proxyContentsDir = cfg.getProxyContentsPath() serverCfg.port = proxyPort serverCfg.logFile = None # Transfer SSL settings from rMake config object if hasattr(server, 'SSL') and server.SSL: # The server supports starting in SSL mode serverCfg.useSSL = cfg.proxyRequiresSsl() serverCfg.sslCert = cfg.sslCertPath serverCfg.sslKey = cfg.sslCertPath if fork: pid = os.fork() if pid: try: pingServer(cfg, cfg.getProxyUrl()) except: killServer(pid) raise if logger: logger.info('Started proxy on port %s (pid %s)' % (proxyPort, pid)) return pid elif hasattr(logger, 'close'): logger.close() try: util.mkdirChain(cfg.getProxyDir()) os.chdir(cfg.getProxyDir()) serverrc = open(cfg.getProxyConfigPath(), 'w') serverCfg.store(serverrc, includeDocs=False) util.mkdirChain(os.path.dirname(cfg.getProxyLogPath())) util.mkdirChain(cfg.getProxyContentsPath()) logFile = logfile.LogFile(cfg.getProxyLogPath()) logFile.redirectOutput(close=True) serverrc.close() os.execv('%s/server/server.py' % conaryDir, [ '%s/server/server.py' % conaryDir, '--config-file', cfg.getProxyConfigPath() ]) except Exception, err: print >> sys.stderr, 'Could not start proxy server: %s' % err os._exit(1)
def testPerlReqs(self): self.openRmakeRepository() repos = self.openRepository() trvname = "perl-dummy" perl = self.addComponent('perl:lib', provides='perl: CGI perl: strict') trv = self.makeSourceTrove(trvname, testPerlRecipe) troveTup = repos.findTrove(self.cfg.buildLabel, (trvname + ':source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) logFile = logfile.LogFile(self.workDir + '/chrootlog') logFile.redirectOutput() mgr, factory, cfg, client = self._createRoot([perl], buildTrove, start=True) logPath = client.buildTrove(cfg, cfg.getTargetLabel(troveTup[1]), *troveTup) result = client.checkResults(wait=20, *troveTup) client.stop() logFile.restoreOutput() assert (result) assert (result.isBuildSuccess()) cs = changeset.ChangeSetFromFile(result.getChangeSetFile()) trvHash = {} for trv in cs.iterNewTroveList(): trvHash[trv.getName()] = trv # this also checks to make sure build logging is turned on if len(trvHash) < 3: raise RuntimeError('logging turned off!') self.failUnless(trvname in trvHash) self.failUnless(trvname + ':data' in trvHash) self.failUnless(trvname + ':debuginfo' in trvHash) trv = trvHash[trvname + ':data'] dps = [(d[0].tagName, d[1].getName()) for d in trv.getRequires().iterDeps()] dps.sort() self.failUnlessEqual(dps, [('perl', ('CGI', )), ('perl', ('strict', ))])
def getLogFile(self): if self._logFile is not None: return self._logFile try: logPath = os.path.join(self.cfg.logDir, "%s.log" % self.name) self._logFile = logfile.LogFile(logPath) return self._logFile except OSError, err: self.error('error opening logfile "%s" for writing: %s', logPath, err.strerror) sys.exit(1)
def testMultipleContexts(self): config = """ [nossl] buildFlavor !ssl """ repos = self.openRepository() trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', basicRecipe + '\tif Use.ssl:pass')]) self.openRmakeRepository() self.writeFile(self.workDir + '/config', config) self.buildCfg.read(self.workDir + '/config') uri = 'unix://%s/socket' % self.rootDir self.buildCfg.strictMode = True srv = server.rMakeServer(#None, uri, self.rmakeCfg, None, quiet=True) rmakeClient = client.rMakeClient(uri) pid = os.fork() if pid: srv._close() try: helper = self.getRmakeHelper(rmakeClient.uri) troveSpec = '%s=%s[%s]' % trv.getNameVersionFlavor() troveSpec2 = '%s=%s[%s]{nossl}' % trv.getNameVersionFlavor() jobId = helper.buildTroves([troveSpec, troveSpec2]) buildCfg = rmakeClient.getJobConfig(jobId) self.assertEquals(buildCfg.buildTroveSpecs, [cmdline.parseTroveSpec(troveSpec)]) helper.waitForJob(jobId) job = helper.getJob(jobId) # make sure a trove can actually be found if job.isFailed(): raise RuntimeError('Job Failed: %s' % job.getFailureReason()) trvs = job.findTrovesWithContext(None, [('testcase:source', None, None, None)]) assert(len(trvs) == 1) self.assertEquals(len(trvs.values()[0]), 2) finally: os.kill(pid, signal.SIGTERM) self.waitThenKill(pid) else: try: sys.stdin = open('/dev/null') lf = logfile.LogFile(self.rootDir + '/srv.log') lf.redirectOutput() srv.serve_forever() finally: os._exit(1)
def testTee(self): def _redirect(logFile): logFile.teeOutput() print 'foo' logFile.close() path = self.workDir + '/logfile' logFile = logfile.LogFile(path) assert (self.captureOutput(_redirect, logFile)[1] == 'foo\n') assert (open(path).read() == 'foo\n') assert (self.captureOutput(sys.stdout.write, 'bar\n')[1] == 'bar\n') assert (open(path).read() == 'foo\n')
def testFilesetRecipe(self): self.openRmakeRepository() self.addComponent('orig:run', '1', ['/bin/foo']) self.addCollection('orig', '1', [':run']) trv = self.addComponent('fileset-foo:source', '1.0-1', '', [('fileset-foo.recipe', filesetRecipe)]) troveList = [ trv.getNameVersionFlavor() ] job = self.newJob(*troveList) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert b.job.isBuilt(), b.job.troves.values()[0].getFailureReason()
def testInfoRecipe(self): self.openRmakeRepository() db = self.openRmakeDatabase() trv = self.addComponent('info-sys:source', '1.0-1', '', [('info-sys.recipe', infoRecipe)]) troveList = [ trv.getNameVersionFlavor() ] job = self.newJob(*troveList) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert(b.job.isBuilt())
def testGroupRecipe(self): if compat.ConaryVersion().conaryVersion[0:2] == [1,2]: raise testhelp.SkipTestException('test fails on 1.2') repos = self.openRmakeRepository() db = self.openRmakeDatabase() self.buildCfg.shortenGroupFlavors = True self.buildCfg.setSection('foo') # add context foo self.buildCfg.configLine('buildFlavor desktop is:x86') self.buildCfg.setSection('bar') self.buildCfg.configLine('buildFlavor !desktop is:x86') simple = self.addComponent('simple:runtime', '1.0-1-1', '') other1 = self.addComponent('other:runtime', '1.0-1-1', '!desktop', filePrimer=1) other2 = self.addComponent('other:runtime', '1.0-1-1', 'desktop', filePrimer=1) # Prevent the desktop flag from being pre-filtered out recipe = groupRecipe + '\n if Use.desktop: pass\n' trv = self.addComponent('group-foo:source', '/localhost@rpl:linux//rmakehost@local:linux/1:1.0-1', [('group-foo.recipe', recipe)]) troveList = [ trv.getNameVersionFlavor() + ('foo',), trv.getNameVersionFlavor() + ('bar',), ] job = self.newJob(*troveList) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert b.job.isBuilt(), str(b.job.getFailureReason()) assert len(b.job.getBuiltTroveList()) == 2, b.job.getBuiltTroveList() for tup in b.job.getBuiltTroveList(): groupTrove = repos.getTrove(*tup) # this is just a very basic test of builder -> group build. # tests of the group cook code's ability to include the right # version in particular cases should be in cooktest.py if '!desktop' in str(groupTrove.getFlavor()): other = other1 else: other = other2 self.assertEqual(sorted(groupTrove.iterTroveList(strongRefs=True)), [other.getNameVersionFlavor(), simple.getNameVersionFlavor()])
def testMacrosRecipe(self): self.openRmakeRepository() db = self.openRmakeDatabase() trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', macrosRecipe)]) self.buildCfg.configLine('macros foo readline') self.buildCfg.macros['multi'] = 'line1\nline2' job = self.newJob(trv) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert(b.job.isBuilt())
def testBasic(self): repos = self.openRepository() trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', basicRecipe)]) self.openRmakeRepository() uri = 'unix://%s/socket' % self.rootDir srv = server.rMakeServer(#None, uri, self.rmakeCfg, None, quiet=True) self.buildCfg.uuid = self.genUUID('foo') self.buildCfg.strictMode = True #client = server.rMakeClient(srv) #client = server.rMakeClient('http://*****:*****@local:linux', None), self.buildCfg.flavor) finally: os.kill(pid, signal.SIGTERM) self.waitThenKill(pid) else: try: sys.stdin = open('/dev/null') lf = logfile.LogFile(self.rootDir + '/srv.log') lf.redirectOutput() srv.serve_forever() finally: os._exit(1)
def testRedirectToPort(self): path = self.workDir + '/logfile' outpath = self.workDir + '/logfile2' p = PortLogger(outpath) pid = os.fork() if not pid: p.serveThenDie() try: logFile = logfile.LogFile(path) logFile.logToPort('localhost', p.port) print "foo", finally: logFile.close() pid, status = self.waitThenKill(pid) assert (pid) assert (open(path).read() == 'foo') assert (open(outpath).read() == 'foo')
def __init__(self, serverCfg, job, jobContext=None, db=None): self.serverCfg = serverCfg self.buildCfg = job.getMainConfig() self.logger = BuildLogger(job.jobId, serverCfg.getBuildLogPath(job.jobId)) self.logFile = logfile.LogFile( serverCfg.getBuildLogPath(job.jobId)) self.repos = self.getRepos() self.job = job self.jobId = job.jobId self.db = db self.dh = None self.worker = worker.Worker(serverCfg, self.logger, serverCfg.slots) self.eventHandler = EventHandler(job, self.worker) if jobContext: self.setJobContext(jobContext) else: self.jobContext = [] self.initialized = False
def testRedirectRecipe(self): self.openRmakeRepository() db = self.openRmakeDatabase() self.addComponent('redirect:run', '1') self.addCollection('redirect', '1', [':run']) self.addComponent('target:run', '1') self.addCollection('target', '1', [':run']) # simulate building a checkout trv = self.addComponent( 'redirect:source=/localhost@rpl:linux//rmakehost@local:linux/1.0-1', [('redirect.recipe', redirectRecipe)]) os.chdir(self.workDir) troveList = [ trv.getNameVersionFlavor() ] job = self.newJob(*troveList) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert b.job.isBuilt(), b.job.getFailureReason()
def testBasic(self): trv = self.addComponent('nocross:source', '1.0-1', '', [('nocross.recipe', nocrossRecipe)]) trv2 = self.addComponent('crosstool:source', '1.0-1', '', [('crosstool.recipe', crosstoolRecipe)]) ccRoot = self.rmakeCfg.buildDir + '/chroots/crosscompiled' trv3 = self.addComponent( 'crosscompiled:source', '1.0-1', '', [('crosscompiled.recipe', crosscompiledRecipe % (ccRoot, ccRoot))]) self.openRmakeRepository() troveList = [(trv.getName(), trv.getVersion(), deps.parseFlavor('!cross target: x86_64')), (trv2.getName(), trv2.getVersion(), deps.parseFlavor('cross target: x86_64')), (trv3.getName(), trv3.getVersion(), deps.parseFlavor('!cross target: x86_64'))] db = self.openRmakeDatabase() self.buildCfg.flavor = [ deps.overrideFlavor( self.buildCfg.flavor[0], deps.parseFlavor('~cross is:x86 target:x86_64')) ] job = self.newJob(*troveList) db.subscribeToJob(job) b = builder.Builder(self.rmakeCfg, job) self.logFilter.add() logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() try: b.build() except Exception: b.worker.stopAllCommands() raise logFile.restoreOutput() assert (set([x.getName() for x in b.dh.depState.getBuiltTroves() ]) == set([trv.getName(), trv2.getName(), trv3.getName()]))
def testPerlReqsScriptCopy(self): self.openRmakeRepository() repos = self.openRepository() trvname = "perl-dummy" perl = self.addComponent('perl:lib', provides='perl: CGI perl: strict') trv = self.makeSourceTrove(trvname, testPerlRecipe) troveTup = repos.findTrove(self.cfg.buildLabel, (trvname + ':source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) logFile = logfile.LogFile(self.workDir + '/chrootlog') logFile.redirectOutput() mgr, factory, cfg, _ = self._createRoot([perl], buildTrove, start=False) logFile.restoreOutput() # Is the scripts directory copied? conaryDir = os.path.dirname(sys.modules['conary'].__file__) scriptsDir = os.path.realpath(os.path.join(conaryDir, '../scripts')) if not os.path.exists(scriptsDir): raise testsuite.SkipTestException( 'Cant test copy in conary when scripts dir doesnt exist') rootfact = factory.chroot self.failUnless(scriptsDir in [x[0] for x in rootfact.dirsToCopy]) perlreqs = os.path.join(scriptsDir, 'perlreqs.pl') self.failUnless(perlreqs in [x[0] for x in rootfact.filesToCopy])
def testMultipleDelayedRecipes(self): self.openRmakeRepository() db = self.openRmakeDatabase() trv = self.addComponent('redirect:source', '1.0-1', '', [('redirect.recipe', redirectRecipe)]) trv2 = self.addComponent('fileset-foo:source', '1.0-1', '', [('fileset-foo.recipe', filesetRecipe)]) troveList = [ trv.getNameVersionFlavor(), trv2.getNameVersionFlavor() ] job = self.newJob(*troveList) db.subscribeToJob(job) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert(b.job.isFailed()) failedTroves = list(b.job.iterFailedTroves()) assert(len(failedTroves) == 2) group = [ x for x in failedTroves if x.getName() == trv.getName()][0] assert(str(group.getFailureReason()) == 'Trove failed sanity check: redirect and fileset packages must be alone in their own job') assert(str(b.job.getFailureReason()) == 'Job failed sanity check: redirect and fileset packages must be alone in their own job: fileset-foo, redirect')
def start(self): pid = os.fork() if pid: self.server = xmlrpclib.ServerProxy(self.url) self.pid = pid def checkPid(): if os.waitpid(pid, os.WNOHANG)[0]: raise RuntimeError('Mock Rbuilder Died!') self.ping(checkFn=checkPid) else: try: from rmake.lib import logfile self.logFile = logfile.LogFile(self.logPath) self.logFile.redirectOutput() server = SimpleXMLRPCServer.SimpleXMLRPCServer( ("localhost", self.port), MockRbuilderHandler) server.register_instance(MockRbuilderServer()) server.serve_forever() finally: os._exit(0)
def testDerivedRecipe(self): self.openRmakeRepository() db = self.openRmakeDatabase() trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', workingRecipe)]) self.addComponent('testcase:run', '1.0-1-1', ['/foo', '/bar']) self.addCollection('testcase', '1.0-1-1', [':run']) trv = self.addComponent('testcase:source', '/localhost@rpl:linux//branch/1.0-1', [('testcase.recipe', workingRecipe)]) trv = self.addComponent('testcase:source', '/localhost@rpl:linux//branch/1.0-1.1', [('testcase.recipe', derivedRecipe)]) troveList = [ trv.getNameVersionFlavor() ] job = self.newJob(*troveList) b = builder.Builder(self.rmakeCfg, job) logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() assert(b.job.isBuilt())
def testCopyInPolicy(self): trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', workingRecipe)]) self.openRmakeRepository() troveList = [ trv.getNameVersionFlavor() ] db = self.openRmakeDatabase() buildCfg = copy.deepcopy(self.buildCfg) buildCfg.strictMode = False buildCfg.copyInConary = True fakePolicyPath = resources.get_archive('policy') buildCfg.policyDirs = buildCfg.policyDirs + [ fakePolicyPath ] job = self.newJob(buildConfig=buildCfg, *troveList) b = builder.Builder(self.rmakeCfg, job) self.logFilter.add() logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() b.build() logFile.restoreOutput() trove = b.job.troves.values()[0] assert(str(trove.getFailureReason()).endswith( 'This fake policy always breaks.'))
def testBuildReqs(self): self.addComponent('foo:runtime[!cross]') self.addComponent('foo:runtime=2[cross]', filePrimer=1) trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', buildReqsRecipe)]) self.openRmakeRepository() db = self.openRmakeDatabase() job = self.newJob(trv.getNameVersionFlavor()) db.subscribeToJob(job) b = builder.Builder(self.rmakeCfg, job) self.logFilter.add() logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() try: b.build() except Exception: b.worker.stopAllCommands() raise logFile.restoreOutput() assert b.job.isBuilt(), b.job.troves.values()[0].getFailureReason().getTraceback() trv = self.findAndGetTrove('testcase=rmakehost@local:linux') buildReqs = trv.getBuildRequirements() assert len(buildReqs) == 2, "Got cross req twice!"
def startRepository(cfg, fork=True, logger=None): global conaryDir baseDir = cfg.serverDir if logger is None: logger = log reposDir = '%s/repos' % baseDir util.mkdirChain(reposDir) if not cfg.reposUser: passwordFile = reposDir + '/password' if os.path.exists(passwordFile): password = open(passwordFile).readline()[:-1] else: password = ''.join( [chr(random.randrange(ord('a'), ord('z'))) for x in range(10)]) open(passwordFile, 'w').write(password + '\n') os.chmod(reposDir + '/password', 0700) cfg.reposUser.addServerGlob(cfg.reposName, 'rmake', password) serverConfig = os.path.join(cfg.getReposDir(), 'serverrc') if os.path.exists(serverConfig): os.unlink(serverConfig) serverCfg = server.ServerConfig(os.path.join(cfg.getReposDir(), 'serverrc')) serverCfg.repositoryDB = ('sqlite', cfg.getReposDbPath()) serverCfg.contentsDir = cfg.getContentsPath() serverCfg.port = cfg.getReposInfo()[1] serverCfg.configKey('serverName', cfg.reposName) # this works with either # 1.0.16 or 1.0.17+ serverCfg.logFile = cfg.getReposDir() + '/repos.log' serverCfg.logFile = None # Transfer SSL settings from rMake config object if hasattr(server, 'SSL') and server.SSL: # The server supports starting in SSL mode serverCfg.useSSL = cfg.reposRequiresSsl() serverCfg.sslCert = cfg.sslCertPath serverCfg.sslKey = cfg.sslCertPath elif cfg.reposRequiresSsl(): raise errors.RmakeError( 'Tried to start repository at %s, but missing ssl server library: Please install m2crypto' % (cfg.getRepositoryUrl(), )) (driver, database) = serverCfg.repositoryDB db = dbstore.connect(database, driver) # Note - this will automatically migrate this repository! # Since this is a throwaway repos anyway, I think that's # acceptable. compat.ConaryVersion().loadServerSchema(db) db.commit() db.close() user, password = cfg.reposUser.find(cfg.reposName) addUser(serverCfg, user, password, write=True) if not serverCfg.useSSL: # allow anonymous access if we're not securing this repos # by using SSL - no use securing access if it's all going to be # viewable via tcpdump. addUser(serverCfg, 'anonymous', 'anonymous') if fork: pid = os.fork() if pid: try: pingServer(cfg) except: killServer(pid) raise logger.info('Started repository "%s" on port %s (pid %s)' % (cfg.reposName, serverCfg.port, pid)) return pid elif hasattr(logger, 'close'): logger.close() try: os.chdir(cfg.getReposDir()) serverrc = open(cfg.getReposConfigPath(), 'w') serverCfg.store(serverrc, includeDocs=False) util.mkdirChain(os.path.dirname(cfg.getReposLogPath())) logFile = logfile.LogFile(cfg.getReposLogPath()) logFile.redirectOutput(close=True) serverrc.close() os.execv('%s/server/server.py' % conaryDir, [ '%s/server/server.py' % conaryDir, '--config-file', cfg.getReposConfigPath() ]) except Exception, err: print >> sys.stderr, 'Could not start repository server: %s' % err os._exit(1)
def testChrootFactory2(self): self.openRmakeRepository() repos = self.openRepository() self.addComponent('test1:source', '1.0', '', [('test1.recipe', test1Recipe)]) self.addComponent( 'test1:source', '2.0', '', [('test1.recipe', test1Recipe.replace('1.0', '2.0'))]) rootDir = self.rmakeCfg.getChrootDir() + '/testBuildReqs' self.makeSourceTrove('testBuildReqs', testBuildReqsRecipe % dict(rootDir=rootDir)) troveTup = repos.findTrove(self.cfg.buildLabel, ('testBuildReqs:source', None, None), None)[0] cookFlavor = deps.parseFlavor('readline,ssl,X') troveTup = (troveTup[0], troveTup[1], cookFlavor) db = self.openRmakeDatabase() job = self.newJob(troveTup) buildTrove = buildtrove.BuildTrove(job.jobId, *troveTup) buildTrove.setPublisher(job.getPublisher()) cfg = buildcfg.BuildConfiguration(False, conaryConfig=self.cfg, root=self.cfg.root, serverConfig=self.rmakeCfg) cfg.defaultBuildReqs = [] trv1 = self.addComponent( 'test1:runtime', '1.0', '', [('/usr/bin/test1', rephelp.RegularFile(contents='#!/bin/sh', perms=0755))]) trv2 = self.addCollection('test1', '1.0', [':runtime']) trv3 = self.addComponent( 'test2:runtime', '1.0', '', [('/usr/bin/test2', rephelp.RegularFile(contents='#!/bin/sh', perms=0755))]) trv4 = self.addComponent('testunreadable:runtime', '1.0', '', [ ('/usr/untraverseable', rephelp.Directory(perms=0700)), ('/usr/symlink', rephelp.Symlink(target='/usr/untraverseable')), ('/usr/untraverseable/unreadable', rephelp.RegularFile(perms=0600)) ]) self.rmakeCfg.chrootUser = '******' mgr = rootmanager.ChrootManager(self.rmakeCfg) jobList = [ (x[0], (None, None), (x[1], x[2]), False) for x in (trv1.getNameVersionFlavor(), trv2.getNameVersionFlavor(), trv3.getNameVersionFlavor(), trv4.getNameVersionFlavor()) ] logFile = logfile.LogFile(self.workDir + '/chrootlog') logFile.redirectOutput() factory = mgr.getRootFactory(cfg, jobList, [], [], buildTrove) factory.create() chrootClient = factory.start() try: logPath = chrootClient.buildTrove(cfg, cfg.getTargetLabel(troveTup[1]), *troveTup) result = chrootClient.checkResults(wait=20, *troveTup) logFile.restoreOutput() assert (result) assert result.isBuildSuccess(), repr(result.getFailureReason()) untraverseable = mgr.baseDir + '/testBuildReqs/usr/untraverseable' self.assertEquals(stat.S_IMODE(os.stat(untraverseable).st_mode), 0705) unreadable = untraverseable + '/unreadable' self.assertEquals(stat.S_IMODE(os.stat(unreadable).st_mode), 0604) cs = changeset.ChangeSetFromFile(result.getChangeSetFile()) trvCs = [ x for x in cs.iterNewTroveList() if x.getName() == 'testBuildReqs:runtime' ][0] trv = trove.Trove(trvCs) files = [x[1] for x in trv.iterFileList()] # make sure the loadInstalled picked the recipe that # matches the installed package. assert ('/foo/1.0' in files) finally: chrootClient.stop()
def cookTrove(cfg, repos, logger, name, version, flavorList, targetLabel, loadSpecsList=None, logData=None, buildReqs=None, crossReqs=None): if not isinstance(flavorList, (tuple, list)): flavorList = [flavorList] util.mkdirChain(cfg.root + '/tmp') fd, csFile = tempfile.mkstemp(dir=cfg.root + '/tmp', prefix='rmake-%s-' % name, suffix='.ccs') os.chmod(csFile, 0644) os.close(fd) logPath = cfg.root + '/tmp/rmake/%s-%s.log' % (name, version.trailingRevision()) logFile = logfile.LogFile(logPath) os.chmod(logPath, 0664) os.chmod(cfg.root + '/tmp/rmake', 0775) results = CookResults(name, version, flavorList) # ignore child output problems signal.signal(signal.SIGTTOU, signal.SIG_IGN) inF, outF = pipereader.makePipes() pid = os.fork() if not pid: try: try: signal.signal(signal.SIGTERM, signal.SIG_DFL) os.close(inF) os.setpgid(0, 0) # don't accidentally make world writable files os.umask(0022) # don't allow us to create core dumps resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) log.setVerbosity(log.DEBUG) log.info("Cook process started (pid %s)" % os.getpid()) _cookTrove(cfg, repos, name, version, flavorList, targetLabel, loadSpecsList, csFile, buildReqs=buildReqs, crossReqs=crossReqs, failureFd=outF, logger=logger) except Exception, msg: if len(flavorList) > 1: errMsg = 'Error cooking %s=%s with flavors %s: %s' % \ (name, version, ', '.join([str(x) for x in flavorList]), str(msg)) else: errMsg = str(msg) _buildFailed(outF, errMsg, traceback.format_exc()) logFile.close() os._exit(1) else: logFile.close() os._exit(0)
def testBasic(self): # FIXME: this is really slow - ~20 seconds. # Perhaps we need to make hooks to make this test faster? trv = self.addComponent('testcase:source', '1.0-1', '', [('testcase.recipe', workingRecipe)]) trv2 = self.addComponent('testcase2:source', '1.0-1', '', [('testcase2.recipe', failingRecipe)]) trv3 = self.addComponent('testcase3:source', '1.0-1', '', [('testcase3.recipe', failedSetupRecipe)]) trv4 = self.addComponent('testcase4:source', '1.0-1', '', [('testcase4.recipe', failedLoadRecipe)]) trv5 = self.addComponent('testcase5:source', '1.0-1', '', [('testcase5.recipe', failedBuildReqRecipe)]) self.openRmakeRepository() troveList = [ (trv.getName(), trv.getVersion(), deps.parseFlavor('!ssl')), trv2.getNameVersionFlavor(), trv3.getNameVersionFlavor(), trv4.getNameVersionFlavor(), trv5.getNameVersionFlavor(), ] db = self.openRmakeDatabase() job = self.newJob(*troveList) db.subscribeToJob(job) b = builder.Builder(self.rmakeCfg, job) self.logFilter.add() logFile = logfile.LogFile(self.workDir + '/buildlog') logFile.redirectOutput() try: b.build() except Exception: b.worker.stopAllCommands() raise logFile.restoreOutput() assert(set([x.getName() for x in b.dh.depState.getFailedTroves()]) == set([trv2.getName(), trv3.getName(), trv4.getName(), trv5.getName()])) repos = self.openRepository() results = repos.findTrove(None, ('testcase', 'rmakehost@local:linux', deps.parseFlavor('!ssl')), self.buildCfg.flavor) assert(len(results) == 1) assert(results[0][2] == deps.parseFlavor('~!ssl')) troveDict = dict((x.getName(), x) for x in db.getJob(1).iterFailedTroves()) assert(len(troveDict) == 4) trv2 = troveDict['testcase2:source'] failureReason = str(trv2.getFailureReason()) # remove the arch-specific flavor here, we're not testing that failureReason = re.sub(r'\[.*\]', '[FLAVOR]', failureReason) assert(str(failureReason) == 'Failed while building: Error building recipe testcase2:source=/localhost@rpl:linux/1.0-1[FLAVOR]: Shell command "exit 1" exited with exit code 1') trv3 = troveDict['testcase3:source'] assert(str(trv3.getFailureReason()) == "Failed while loading recipe: global name 'b' is not defined") trv4 = troveDict['testcase4:source'] failureReason = str(trv4.getFailureReason()) failureReason = re.sub('/tmp.*\.recipe', 'TEMP.recipe', failureReason) failureReason = re.sub('temp-testcase4.*\.recipe', 'testcase4.recipe', failureReason) errStr = '''\ Failed while loading recipe: unable to load recipe file /varTEMP.recipe: Error in recipe file "testcase4.recipe": Traceback (most recent call last): File "/varTEMP.recipe", line 1, in ? class TestRecipe(PackageRecipe): File "/varTEMP.recipe", line 4, in TestRecipe a = b # NameError NameError: name 'b' is not defined ''' if sys.version_info > (2, 5): errStr = errStr.replace('?', '<module>') self.assertEquals(failureReason, errStr) trv5 = troveDict['testcase5:source'] self.assertEquals(str(trv5.getFailureReason()), 'Could not satisfy build requirements: bbbbbbb:devel=[]') assert(str(b.job.getFailureReason()) == """\ Failed while building: Build job had failures: * testcase2:source: Error building recipe testcase2:source=/localhost@rpl:linux/1.0-1[%s]: Shell command "exit 1" exited with exit code 1 * testcase3:source: Failed while loading recipe * testcase4:source: Failed while loading recipe * testcase5:source: Could not satisfy build requirements: bbbbbbb:devel=[] """ % self.getArchFlavor())