def getCML(self, *args): cfg = mock.MockObject() cfg._mock.set(installLabelPath = ['a@b:c', 'd@e:f' ]) cfg._mock.set(flavor = deps.parseFlavor('')) cfg._mock.set(root = self.rootDir) cfg._mock.set(modelPath = '/etc/conary/system-model') return cml.CML(cfg, *args)
def getSystemModel(self, *args): cfg = mock.MockObject() cfg._mock.set(installLabelPath=['a@b:c', 'd@e:f']) cfg._mock.set(flavor=deps.parseFlavor('')) cfg._mock.set(root=self.rootDir) model = cml.CML(cfg) return systemmodel.SystemModelFile(model, *args)
def _update_model(self, opargs): ''' Updated system model from current system model @param opargs: a list of tuples of operation and a tuple of packages that go with the operation ie: [ ('install'('lynx', 'joe')), ('remove', ('httpd')), ('update', ('wget')), ] @type opargs: list of tuples [(op, args)] @param op: a conary system model operation 'install', 'update', 'erase' @type op: string @param args: a tuple of conary packages for an operation @type args: ( pkg1, pkg2 ) @param pkg: a name of a conary package @type pkg: string @return: conary SystemModelFile object ''' # FIXME # This should append to the current system-model # need a dictionary of { op : arg } to parse cfg = self.conaryCfg model = cml.CML(cfg) model.setVersion(str(time.time())) # I think this is how it should work # Take some uglies from stdin and append them # to current system model # apparently in the most ugly way I can for op, args in opargs.items(): arg = ' '.join([x for x in args]) model.appendOpByName(op, arg) newmodel = SystemModel(self._modelFile(model)) return newmodel
def _system_model_update(self, cfg, op, args, callback, dry_run=False): ''' conary update action for a system model op can be 'update'||'updateall'||'install'||'erase'. args is a list of packages. dry_run == True, return UpdateJob, suggMap ''' updated = False updJob, suggMap = None, {} model = cml.CML(cfg) modelFile = systemmodel.SystemModelFile(model) model.appendOpByName(op, args) modelFile.writeSnapshot() try: updJob, suggMap = self._buildUpdateJob(model) #not sure i got this right... need to just run an update #_model_build_update_job(cfg, model, modelFile, callback) if not dry_run: self._applyUpdateJob(updJob, callback) updated = True except: pass if updated: modelFile.write() modelFile.closeSnapshot() return updJob, suggMap
def testSystemModelRollbacks(self): sm = self.cfg.root + '/etc/conary/system-model' foo = self.cfg.root + '/foo' util.mkdirChain(self.cfg.root + '/etc/conary') self.addComponent('foo:runtime', '1', fileContents = [ ( '/foo', '1') ]) self.addComponent('foo:runtime', '2', fileContents = [ ( '/foo', '2') ]) self.addComponent('foo:runtime', '3', fileContents = [ ( '/foo', '3') ]) model = cml.CML(self.cfg) modelFile = systemmodel.SystemModelFile(model) file(sm, 'w').write('') self.updatePkg('foo:runtime=1', modelFile=modelFile) file(sm, 'a').write('install foo:runtime=1\n') self.updatePkg('foo:runtime=2', modelFile=modelFile) file(sm, 'a').write('install foo:runtime=2\n') self.updatePkg('foo:runtime=3', modelFile=modelFile) file(sm, 'a').write('install foo:runtime=3\n') rbsm = self.cfg.root + '/var/lib/conarydb/rollbacks/%d/system-model' self.verifyFile(rbsm % 0, '') self.verifyFile(rbsm % 1, 'install foo:runtime=1\n' ) self.verifyFile(rbsm % 2, 'install foo:runtime=1\n' 'install foo:runtime=2\n', ) self.verifyFile(sm, 'install foo:runtime=1\n' 'install foo:runtime=2\n' 'install foo:runtime=3\n', ) self.verifyFile(foo, '3') self.rollback(self.rootDir, 2) self.verifyFile(sm, 'install foo:runtime=1\n' 'install foo:runtime=2\n', ) self.verifyFile(foo, '2') self.rollback(self.rootDir, 1) self.verifyFile(sm, 'install foo:runtime=1\n' ) self.verifyFile(foo, '1') self.rollback(self.rootDir, 0) self.verifyFile(sm, '') assert(not os.path.exists(foo))
def getSystemModel(self): """ Returns the Conary system model, or None if the system is not modeled @rtype: SystemModel or None """ model = cml.CML(self.cfg) modelFile = systemmodel.SystemModelFile(model) if modelFile.exists(): return modelFile else: return None
def includeAction(self, data): if self.resultSet: self.outSet._setInstall(self.resultSet._getInstallSet()) self.outSet._setOptional(self.resultSet._getOptionalSet()) return True assert (not self.includeSet._getOptionalSet()) assert (not self.includeSet._getInstallSet() == 1) nvf = list(self.includeSet._getInstallSet())[0] if not trove.troveIsComponent(nvf[0]): assert (trove.troveIsPackage(nvf[0])) # getTrove is sometimes disabled to prevent one at a time calls # can't be helped here trv = data.troveCache.getTroves([nvf], withFiles=False)[0] found = None for subNVF in trv.iterTroveList(strongRefs=True): if subNVF[0].endswith(':cml'): found = subNVF break if not found: raise IncludeException('Package %s=%s[%s] does not contain a ' 'cml component for inclusion' % nvf) nvf = found elif nvf[0].split(':')[1] not in ['cml', 'source']: raise IncludeException('Include only supports source and cml ' 'components') if nvf in self.outSet.g.included: raise IncludeException( 'Include loop detected involving %s=%s[%s]' % nvf) self.outSet.g.included.add(nvf) cmlFileLines = self.getCML(data.troveCache, nvf) model = cml.CML(None, context=nvf[0]) model.parse(fileData=cmlFileLines) self.resultSet = self.compiler.augment(model, self.searchSet, self.primaryTroveSet) self.outSet.g.addEdge(self.resultSet, self.outSet) self.outSet.finalSearchSet.setTroveSetList( self.outSet.finalSearchSet.fetch([self.resultSet.searchPath])) return False
def __init__(self, client): log.debug("loading system model cache") troveCache = trovecache.TroveCache(None) troveCache.load(client.cfg.dbPath + '/modelcache') model = cml.CML(client.cfg) troveSet = client.cmlGraph(model) troveSet.g.realize( modelupdate.CMLActionData(troveCache, client.cfg.flavor[0], client.getRepos(), client.cfg)) self.troveTups = set() for withFiles, trv in troveCache.cache.values(): for nvf in trv.iterTroveList(strongRefs=True, weakRefs=True): self.troveTups.add(nvf)
def _model_do_conary_updateall(cfg, callback, dry_run=False): '''Perform a conary updatell If dry_run is True, return (UpdateJob, suggMap) which contains information about the install. ''' model = cml.CML(cfg) modelFile = systemmodel.SystemModelFile(model) model.refreshVersionSnapshots() ret = _model_build_update_job(cfg, model, modelFile, callback) if not dry_run: _model_apply_update_job(ret[0], cfg, modelFile, callback) return ret
def _startNew(self): ''' Start a new model with a mostly blank cfg ''' # TODO # DO we really need this? newFileExt = '.new' fileName = self._cfg.modelPath + newFileExt self._new_cfg = conarycfg.ConaryConfiguration(False) self._new_cfg.initializeFlavors() self._new_cfg.dbPath = self._cfg.dbPath self._new_cfg.flavor = self._cfg.flavor self._new_cfg.configLine('updateThreshold 1') self._new_cfg.buildLabel = self._cfg.buildLabel self._new_cfg.installLabelPath = self._cfg.installLabelPath self._new_cfg.modelPath = fileName model = cml.CML(self._new_cfg) model.setVersion(str(time.time())) return model
def _model_do_conary_update(cfg, op, args, callback, dry_run=False): '''Perform a conary update action op can be 'install'/'erase'. args is a list of packages. If dry_run is True, return (UpdateJob, suggMap) which contains information about the install. ''' # Copy of conary/cmds/conarycmd.py:_UpdateCommand and # conary/cmds/updatecmd.py:doModelUpdate model = cml.CML(cfg) modelFile = systemmodel.SystemModelFile(model) model.appendOpByName(op, args) ret = _model_build_update_job(cfg, model, modelFile, callback) if not dry_run: _model_apply_update_job(ret[0], cfg, modelFile, callback) return ret
def testSystemModelRollbackRace(self): util.mkdirChain(self.cfg.root + '/etc/conary') sm = self.cfg.root + '/etc/conary/system-model' open(sm, 'w') self.addComponent('foo:runtime=1', fileContents = [ ( '/foo', '1') ]) self.addCollection('foo=1', [ ':runtime' ]) # does not conflict self.addComponent('aaa:runtime=1', fileContents = [ ( '/aaa', '1') ]) self.addCollection('aaa=1', [ ':runtime' ]) # intentional file conflict with foo:runtime self.addComponent('bar:runtime=1', fileContents = [ ( '/foo', 'conflict!!!') ]) self.addCollection('bar=1', [ ':runtime' ]) model = cml.CML(self.cfg) modelFile = systemmodel.SystemModelFile(model) updatecmd.doModelUpdate(self.cfg, model, modelFile, [ '+foo:runtime=localhost@rpl:linux/1' ], updateByDefault = False) self.assertRaises(update.UpdateError, updatecmd.doModelUpdate, self.cfg, model, modelFile, [ '+bar:runtime=localhost@rpl:linux/1' ], updateByDefault = False) self.verifyNoFile(sm+'.next') # force aaa (no conflict) and bar (conflict) into separate jobs self.cfg.updateThreshold = 1 self.assertRaises(update.UpdateError, updatecmd.doModelUpdate, self.cfg, model, modelFile, [ '+aaa:runtime=localhost@rpl:linux/1', '+bar:runtime=localhost@rpl:linux/1' ], updateByDefault = False) self.verifyFile(sm+'.next', 'install foo:runtime=localhost@rpl:linux/1\n' 'install bar:runtime=localhost@rpl:linux/1\n' 'install aaa:runtime=localhost@rpl:linux/1' ' bar:runtime=localhost@rpl:linux/1\n')
def test08_OverlapConflict(self): osA1 = self.addRPMComponent("overlap-same-A:rpm=1.0", 'overlap-same-A-1.0-1.i386.rpm') self.addCollection('overlap-same-A', '1.0', [ ':rpm' ]) osB1 = self.addRPMComponent("overlap-conflict:rpm", 'overlap-conflict-1.0-1.i386.rpm') self.addCollection('overlap-conflict', '1.0', [ ':rpm' ]) self.updatePkg('overlap-same-A:rpm=1.0') self.assertRaises(update.UpdateError, self.updatePkg, 'overlap-conflict:rpm=1.0', raiseError=True) self.updatePkg('overlap-conflict:rpm=1.0', replaceFiles = True) self.checkOwners('/file', [ osB1 ]) self.rollback(1) self.checkOwners('/file', [ osA1 ]) # now test that allowing overlaps via groups pathConflicts is OK # in system model self.addCollection('group-dist', '1.0', [ ('overlap-same-A:rpm', '1.0'), ('overlap-conflict:rpm', '1.0')], pathConflicts=['/file']) root = self.cfg.root util.mkdirChain(root+'/etc/conary') file(root+'/etc/conary/system-model', 'w').write( 'install group-dist=localhost@rpl:linux/1.0\n') model = cml.CML(self.cfg) modelFile = systemmodel.SystemModelFile(model) updatecmd.doModelUpdate(self.cfg, model, modelFile, [], keepExisting=True) self.resetRoot() self.updatePkg(['overlap-same-A:rpm', 'overlap-conflict:rpm=1.0'], replaceFiles = True) self.rollback(0)
def _applyModel(self, modelList, addSearchLabel=True, apply=True, useCache=None): cachePath = os.path.join(self.workDir, 'modelcache') from conary import callbacks client = conaryclient.ConaryClient( self.cfg, updateCallback=callbacks.UpdateCallback()) model = cml.CML(self.cfg) cache = modelupdate.CMLTroveCache(client.getDatabase(), client.getRepos()) if useCache and os.path.exists(cachePath): cache.load(cachePath) if addSearchLabel: updatedModel = list(modelList) updatedModel.insert(0, 'search localhost@rpl:linux') else: updatedModel = modelList model.parse(updatedModel) updJob = client.newUpdateJob() ts = client.cmlGraph(model) suggMap = client._updateFromTroveSetGraph(updJob, ts, cache) if useCache: cache.save(cachePath) if not apply: return ts client.applyUpdateJob(updJob) return updJob, suggMap