def getRoleFilters(self, roles): cu = self.db.cursor() placeholders = ','.join('?' for x in roles) query = ("""SELECT userGroup, accept_flags, filter_flags FROM UserGroups WHERE userGroup in (%s)""" % placeholders) cu.execute(query, list(roles)) return dict( (x[0], (deps.ThawFlavor(x[1]), deps.ThawFlavor(x[2]))) for x in cu)
def fixTroveSig(self, repos, instanceId): cu = self.db.cursor() cu.execute( """ select Items.item as name, Versions.version, Flavors.flavor from Instances join Items using (itemId) join Versions on Instances.versionId = Versions.versionId join Flavors on Instances.flavorId = Flavors.flavorId where Instances.instanceId = ?""", instanceId) (name, version, flavor) = cu.fetchall()[0] # check the signature trv = repos.getTrove(name, versions.VersionFromString(version), deps.ThawFlavor(flavor)) if trv.verifyDigests(): return logMe(3, "updating trove sigs: %s %s %s" % (name, version, flavor)) trv.computeDigests() cu.execute( "delete from TroveInfo where instanceId = ? " "and infoType = ?", (instanceId, trove._TROVEINFO_TAG_SIGS)) cu.execute( "insert into TroveInfo (instanceId, infoType, data) " "values (?, ?, ?)", (instanceId, trove._TROVEINFO_TAG_SIGS, cu.binary(trv.troveInfo.sigs.freeze())))
def getTroves(cu, roleIds, name, version, mkUrl = None, thisHost = None): cu.execute(""" SELECT DISTINCT flavor FROM Instances JOIN Items USING (itemId) JOIN Versions ON (Instances.versionId = Versions.versionId) JOIN Flavors ON (Instances.flavorId = Flavors.flavorId) JOIN UserGroupInstancesCache AS ugi ON (instances.instanceId = ugi.instanceId AND ugi.userGroupId in (%s)) WHERE item = ? AND version = ? """ % ",".join( str(x) for x in roleIds), name, version) flavors = [ deps.ThawFlavor(x[0]) for x in cu ] commonFlavor = flavors[0] for flavor in flavors[1:]: commonFlavor = commonFlavor.intersection(flavor) troves = datamodel.TroveList() for flavor in flavors: troves.append(getTrove(cu, roleIds, name, version, str(flavor), mkUrl = mkUrl, thisHost = thisHost, displayFlavor = str(flavor.difference(commonFlavor)))) return troves
def testOptionalFlavor(self): depSet = deps.ThawFlavor('is:x86(i486 i586)') fs = OptionalFlavorStream() assert (fs.freeze() == '') fs.set(None) assert (fs.freeze() == '\0') fs.thaw('') assert (fs.freeze() == '') fs.thaw('\0') assert (fs.freeze() == '\0') fs.set(depSet) assert (fs.freeze() == 'is:x86(i486 i586)') fs2 = OptionalFlavorStream('\0') assert (fs2.freeze() == '\0') diff = fs2.diff(fs) newfs = fs.copy() newfs.twm(diff, newfs) assert (newfs == fs2) diff = fs.diff(fs2) newfs = fs2.copy() newfs.twm(diff, newfs) assert (newfs == fs)
def deleteJobs(self, jobIdList): cu = self.db.cursor() troveIdList = [] logHashes = set() for jobId in jobIdList: cu.execute( '''SELECT troveId, troveName, version, flavor, logPath FROM BuildTroves WHERE jobId=?''', jobId) for troveId, name, version, flavor, logPath in cu: version = versions.ThawVersion(version) flavor = deps.ThawFlavor(flavor) if logPath: logHashes.add(logPath) cu.execute('DELETE FROM BinaryTroves where troveId=?', troveId) for table in [ 'Jobs', 'JobConfig', 'Subscriber', 'BuildTroves', 'StateLogs', 'JobQueue' ]: cu.execute('DELETE FROM %s WHERE jobId=?' % table, jobId) cu.execute( '''DELETE FROM JobConfig WHERE key="jobContext" AND value=?''', jobId) if logHashes: # Prebuilt troves can refer to logs produced by previous builds. # Keep any logs that are still referenced by jobs not being # deleted. placeholders = ','.join('?' for x in logHashes) cu.execute( "SELECT logPath FROM BuildTroves WHERE logPath IN (%s)" % (placeholders, ), list(logHashes)) for logPath, in cu: logHashes.discard(logPath) return logHashes
def _rolesFromNames(self, cu, roleList): if not roleList: return {} where = [] args = [] if '*' in roleList: where.append('true') else: ids = set([x for x in roleList if isinstance(x, int)]) names = set([x for x in roleList if not isinstance(x, int)]) if ids: places = ', '.join('?' for x in ids) where.append('userGroupId IN ( %s )' % (places, )) args.extend(ids) if names: places = ', '.join('?' for x in names) where.append('userGroup IN ( %s )' % (places, )) args.extend(names) if not where: return {} where = ' OR '.join(where) query = ("SELECT userGroupId, accept_flags FROM UserGroups" " WHERE %s" % where) cu.execute(query, args) return dict((x[0], deps.ThawFlavor(x[1])) for x in cu)
def getId(self, flavorId): if flavorId == 0: return deps.Flavor() cu = self.db.cursor() cu.execute("SELECT flavor FROM Flavors WHERE flavorId = ?", flavorId) try: return deps.ThawFlavor(cu.next()[0]) except StopIteration: raise KeyError, flavorId
def _buildFlavorMap(self, cu): # need to rebuild flavormap logMe(2, "Recreating the FlavorMap table...") cu.execute("drop table FlavorMap") self.db.loadSchema() schema.createFlavors(self.db) cu.execute("select flavorId, flavor from Flavors") flavTable = flavors.Flavors(self.db) for (flavorId, flavorStr) in cu.fetchall(): flavor = deps.ThawFlavor(flavorStr) flavTable.createFlavorMap(flavorId, flavor, cu) return True
def _loadDepSolutions(self): if self.version < (2, 0): # Earlier versions were missing timestamps, which interferes with # dep solver tie-breaking. return depSolutionsList = self._loadPickle(self._depSolutionsPathId) for (sig, depSet, aResult) in depSolutionsList: depSet = deps.ThawDependencySet(depSet) allResults = [] for resultList in aResult: allResults.append([(x[0], versions.ThawVersion(x[1]), deps.ThawFlavor(x[2])) for x in resultList]) self.addDepSolution(sig, depSet, allResults)
def getAuthorizedRoles(self, cu, user, password, allowAnonymous=True, remoteIp=None): """ Given a user and password, return the list of roles that are authorized via these credentials. Returns a dictionary where the key is a role ID and the value is a Flavor object holding the role's accept flags. """ if isinstance(user, ValidUser): # Short-circuit for shim-using code that knows what roles # it wants. return self._rolesFromNames(cu, user.roles) cu.execute( """ SELECT Users.salt, Users.password, UserGroupMembers.userGroupId, Users.userName, UserGroups.canMirror, UserGroups.accept_flags FROM Users JOIN UserGroupMembers USING(userId) JOIN UserGroups USING(userGroupId) WHERE Users.userName = ? OR Users.userName = '******' """, user) result = cu.fetchall() if not result: return {} canMirror = (sum(x[4] for x in result) > 0) # each user can only appear once (by constraint), so we only # need to validate the password once. we don't validate the # password for 'anonymous'. Using a bad password still allows # anonymous access userPasswords = [x for x in result if x[3] != 'anonymous'] # mirror users do not have an anonymous fallback if userPasswords and canMirror: allowAnonymous = False if not allowAnonymous: result = userPasswords if userPasswords and not self._checkPassword( user, userPasswords[0][0].decode('hex'), userPasswords[0][1], password, remoteIp): result = [x for x in result if x[3] == 'anonymous'] return dict((x[2], deps.ThawFlavor(x[5])) for x in result)
def _loadDepSolutions(self): if self.version < (3, 0): # Version 1 was missing timestamps, which interferes with dep # solver tie-breaking. # Version 2 could have bogus unresolved dep solutions due to a bug # so the version was bumped to invalidate those. return depSolutionsList = self._loadPickle(self._depSolutionsPathId) for (sig, depSet, aResult) in depSolutionsList: depSet = deps.ThawDependencySet(depSet) allResults = [] for resultList in aResult: allResults.append([ (x[0], versions.ThawVersion(x[1]), deps.ThawFlavor(x[2])) for x in resultList]) self.addDepSolution(sig, depSet, allResults)
def thaw(self, data): del self[:] if not data: return l = data.split("\0") i = 0 while i < len(l): name = l[i] version = versions.ThawVersion(l[i + 1]) flavor = l[i + 2] flavor = deps.ThawFlavor(flavor) self.append((name, version, flavor)) i += 3
def doShow(dbfile, commitId): db = getDB(dbfile) cu = db.cursor() cu.execute( """ select item, version, flavor from CommitList join Items on CommitList.itemId = Items.itemId join Versions on CommitList.versionId = Versions.versionId join Flavors on CommitList.flavorId = Flavors.flavorId where commitId = ? """, commitId) for n, vStr, fStr in cu: if fStr: f = deps.ThawFlavor(fStr) print "%s=%s[%s]" % (n, vStr, deps.formatFlavor(f)) else: print "%s=%s" % (n, vStr) db.close()
def deleteJobs(self, jobIdList): cu = self.db.cursor() troveIdList = [] troveList = [] for jobId in jobIdList: cu.execute('''SELECT troveId, troveName, version, flavor FROM BuildTroves WHERE jobId=?''', jobId) for troveId, name, version, flavor in cu: version = versions.ThawVersion(version) flavor = deps.ThawFlavor(flavor) troveList.append((jobId, name, version, flavor)) cu.execute('DELETE FROM BinaryTroves where troveId=?', troveId) for table in ['Jobs', 'JobConfig', 'Subscriber', 'BuildTroves', 'StateLogs', 'JobQueue' ]: cu.execute('DELETE FROM %s WHERE jobId=?' % table, jobId) cu.execute('''DELETE FROM JobConfig WHERE key="jobContext" AND value=?''', jobId) return troveList
def files(self, auth, t, v, f): v = versions.ThawVersion(v) f = deps.ThawFlavor(f) parentTrove = self.repos.getTrove(t, v, f, withFiles=False) # non-source group troves only show contained troves if trove.troveIsGroup(t): troves = sorted(parentTrove.iterTroveList(strongRefs=True)) return self._write("group_contents", troveName=t, troves=troves) fileIters = [] for n, v, f in self.repos.walkTroveSet(parentTrove, withFiles=False): files = self.repos.iterFilesInTrove(n, v, f, withFiles=True, sortByPath=True) fileIters.append(files) return self._write("files", troveName=t, fileIters=itertools.chain(*fileIters))
def manageRoleForm(self, auth, roleName): users = self.repServer.auth.userAuth.getUserList() members = set(self.repServer.auth.getRoleMembers(roleName)) canMirror = self.repServer.auth.roleCanMirror(roleName) roleIsAdmin = self.repServer.auth.roleIsAdmin(roleName) flags = self.repServer.auth.getRoleFilters([roleName])[roleName] troveAccess = [ ((n, versions.VersionFromString(v), deps.ThawFlavor(f)), recursive) for ((n, v, f), recursive) in self.repServer.ri.listTroveAccess(roleName) ] return self._write( "add_role", role=roleName, users=users, members=members, canMirror=canMirror, roleIsAdmin=roleIsAdmin, modify=True, acceptFlags=flags[0], troveAccess=troveAccess, )
def _loadDeps(self): depList = self._loadPickle(self._depCachePathId) for (name, thawedVersion, frzFlavor, prov, req) in depList: version = versions.VersionFromString(thawedVersion) flavor = deps.ThawFlavor(frzFlavor) self.depCache[(name, version, flavor)] = (prov, req)
def _thawFlavor(flavor, withFrozenFlavor): if withFrozenFlavor: return deps.ThawFlavor(flavor) return deps.parseFlavor(flavor)
def getTrove(cu, roleIds, name, version, flavor, mkUrl = None, thisHost = None, displayFlavor = None, excludeCapsules = False): def buildTupleList(tuples, name, mkUrl = mkUrl): l = getattr(datamodel.SingleTrove, name)() for troveInfo in sorted(tuples.iter()): l.append(name = troveInfo.name(), version = troveInfo.version(), flavor = troveInfo.flavor(), mkUrl = mkUrl) return l def fileQuery(gfcu, filesInstanceId, dirName = None): # XXX restricing by dirName seems and obvious thing to do here, # but it actually slows things down?? # # the distinct here is unfortunate, but conary repositories had # a bug for about a year which caused it to store duplicate paths # if a path was committed for the first time duplicate times in # a single commit job gfcu.execute(""" SELECT DISTINCT dirName, basename, version, pathId, fileId FROM TroveFiles JOIN Versions USING (versionId) JOIN FileStreams ON (TroveFiles.streamId = FileStreams.streamId) JOIN FilePaths ON (TroveFiles.filePathId = FilePaths.filePathId) JOIN DirNames ON FilePaths.dirNameId = DirNames.dirNameId JOIN Basenames ON (FilePaths.baseNameId = Basenames.baseNameId) WHERE TroveFiles.instanceId = ? ORDER BY dirName, basename """, filesInstanceId) cu.execute(""" SELECT Instances.instanceId, Nodes.timeStamps FROM Instances JOIN Nodes USING (itemId, versionId) JOIN Items USING (itemId) JOIN Versions ON (Instances.versionId = Versions.versionId) JOIN Flavors ON (Instances.flavorId = Flavors.flavorId) JOIN UserGroupInstancesCache AS ugi ON (instances.instanceId = ugi.instanceId AND ugi.userGroupId in (%s)) WHERE item = ? AND version = ? AND flavor = ? """ % ",".join( str(x) for x in roleIds), name, version, deps.parseFlavor(flavor).freeze()) l = [ (x[0], x[1]) for x in cu ] if not l: return None instanceId, timeStamps = l[0] frzVer = versions.strToFrozen(version, timeStamps.split(":")) verobj = versions.ThawVersion(frzVer) tupleLists = [ ( trove._TROVEINFO_TAG_BUILDDEPS, 'builddeps' ), ( trove._TROVEINFO_TAG_POLICY_PROV, 'policyprovider' ), ( trove._TROVEINFO_TAG_LOADEDTROVES, 'loadedtroves' ), ( trove._TROVEINFO_TAG_COPIED_FROM, 'copiedfrom' ), ( trove._TROVEINFO_TAG_DERIVEDFROM, 'derivedfrom' ) ] cu.execute(""" SELECT infoType, data FROM TroveInfo WHERE instanceId = ? AND infoType IN (%s) """ % ",".join(str(x) for x in [ trove._TROVEINFO_TAG_SOURCENAME, trove._TROVEINFO_TAG_CLONEDFROM, trove._TROVEINFO_TAG_CLONEDFROMLIST, trove._TROVEINFO_TAG_BUILDTIME, trove._TROVEINFO_TAG_SIZE, trove._TROVEINFO_TAG_METADATA, trove._TROVEINFO_TAG_CAPSULE, ] + [ x[0] for x in tupleLists ] ), instanceId) troveInfo = {} for infoType, data in cu: data = cu.frombinary(data) infoClass = trove.TroveInfo.streamDict[infoType][1] troveInfo[infoType] = infoClass(data) kwargs = { 'name' : name, 'version' : verobj, 'flavor' : flavor } if displayFlavor is not None: kwargs['displayflavor'] = displayFlavor if trove._TROVEINFO_TAG_BUILDTIME in troveInfo: kwargs['buildtime'] = int(troveInfo[trove._TROVEINFO_TAG_BUILDTIME]()) if trove._TROVEINFO_TAG_SOURCENAME in troveInfo: kwargs['source'] = (troveInfo[trove._TROVEINFO_TAG_SOURCENAME](), verobj.getSourceVersion(), '') if trove._TROVEINFO_TAG_SIZE in troveInfo: kwargs['size'] = troveInfo[trove._TROVEINFO_TAG_SIZE]() if trove._TROVEINFO_TAG_METADATA in troveInfo: md = troveInfo[trove._TROVEINFO_TAG_METADATA].get() kwargs['shortdesc'] = md['shortDesc'] kwargs['longdesc'] = md['longDesc'] if md['licenses']: kwargs['license'] = [ x for x in md['licenses' ]] if md['crypto']: kwargs['crypto'] = [ x for x in md['crypto'] ] for (tag, tagName) in tupleLists: if tag in troveInfo: kwargs[tagName] = buildTupleList(troveInfo[tag], tagName, mkUrl = mkUrl) t = datamodel.SingleTrove(mkUrl = mkUrl, thisHost = thisHost, **kwargs) if trove._TROVEINFO_TAG_CLONEDFROMLIST in troveInfo: clonedFromList = troveInfo[trove._TROVEINFO_TAG_CLONEDFROMLIST] elif (trove._TROVEINFO_TAG_CLONEDFROM in troveInfo): clonedFromList = [ troveInfo[trove._TROVEINFO_TAG_CLONEDFROM]() ] else: clonedFromList = [] for ver in clonedFromList: t.addClonedFrom(name, ver, flavor, mkUrl = mkUrl) hasCapsule = False if trove._TROVEINFO_TAG_CAPSULE in troveInfo: if troveInfo[trove._TROVEINFO_TAG_CAPSULE].type(): hasCapsule = True fileQuery(cu, instanceId) for (dirName, baseName, fileVersion, pathId, fileId) in cu: dirName = cu.frombinary(dirName) baseName = cu.frombinary(baseName) if pathId == trove.CAPSULE_PATHID: isCapsule = 1 contentAvailable = not excludeCapsules else: isCapsule = None contentAvailable = not hasCapsule fileObj = datamodel.FileReference( path = os.path.join(dirName, baseName), version = fileVersion, pathId = md5ToString(cu.frombinary(pathId)), fileId = sha1ToString(cu.frombinary(fileId)), isCapsule = isCapsule, contentAvailable = contentAvailable, mkUrl = mkUrl, thisHost = thisHost) t.addFile(fileObj) cu.execute(""" SELECT item, version, flavor, TroveTroves.includedId, Nodes.timeStamps FROM TroveTroves JOIN Instances ON (Instances.instanceId = TroveTroves.includedId) JOIN Nodes USING (itemId, versionId) JOIN Items USING (itemId) JOIN Versions ON (Versions.versionId = Instances.versionId) JOIN Flavors ON (Flavors.flavorId = Instances.flavorId) WHERE TroveTroves.instanceId = ? AND (TroveTroves.flags & %d) = 0 ORDER BY item, version, flavor """ % schema.TROVE_TROVES_WEAKREF, instanceId) for (subName, subVersion, subFlavor, refInstanceId, subTS) in cu: subFlavor = str(deps.ThawFlavor(subFlavor)) frzVer = versions.strToFrozen(subVersion, [ x for x in subTS.split(":") ]) subV = versions.ThawVersion(frzVer) t.addReferencedTrove(subName, subV, subFlavor, mkUrl = mkUrl) # It would be far better to use file tags to identify these build # logs, but it's significantly slower as well because they're in # the file objects rather than the trove (and those file objects # could be stored on a different repository) if not subName.endswith(':debuginfo'): continue fileQuery(cu, refInstanceId, dirName = '/usr/src/debug/buildlogs') logHost = subV.getHost() for (dirName, baseName, fileVersion, pathId, fileId) in cu: if (dirName) != '/usr/src/debug/buildlogs': continue if baseName.endswith('-log.bz2'): t.setBuildLog(logHost, sha1ToString(fileId)) elif baseName.endswith('-xml.bz2'): t.setXMLBuildLog(logHost, sha1ToString(fileId)) return t
def searchTroves(cu, roleIds, label = None, filterSet = None, mkUrl = None, latest = True, start = 0, limit = None, name = None): d = { 'labelCheck' : '', 'nameCheck' : '' } args = [] regex = None if label: d['labelCheck'] = "label = ? AND" args.append(label) if name: if set('?.*[]\\()+') & set(name): # if only .* appears, replace them with '%' and use LIKE. this # code currently fails with \.* in the regex, but neither . # nor \* are valid trove names anyway likeName = name while '.*' in likeName: likeName = likeName.replace('.*', '%') if set('?.*[]\\()+') & set(name): regex = re.compile(name) else: d['nameCheck'] = "WHERE item LIKE ?" args.append(likeName) else: d['nameCheck' ] = "WHERE item = ?" args.append(name) d['roleIds'] = ",".join( str(x) for x in roleIds) if latest: cu.execute(""" SELECT item, version, flavor, ts FROM (SELECT DISTINCT Nodes.itemId AS itemId, Nodes.versionId AS versionId, flavorId, Nodes.timeStamps AS ts FROM Labels JOIN LabelMap USING (labelId) JOIN LatestCache USING (itemId, branchId) JOIN Nodes USING (itemId, versionId) WHERE %(labelCheck)s LatestCache.latestType = 1 AND LatestCache.userGroupId in (%(roleIds)s)) AS idTable JOIN Items USING (itemId) JOIN Versions ON (idTable.versionId = Versions.versionId) JOIN Flavors ON (idTable.flavorId = Flavors.flavorId) %(nameCheck)s ORDER BY item, version, flavor """ % d, *args) else: cu.execute(""" SELECT item, version, flavor, ts FROM (SELECT DISTINCT Instances.itemId AS itemId, Instances.versionId AS versionId, Instances.flavorId AS flavorId, Nodes.timeStamps AS ts FROM Labels JOIN LabelMap USING (labelId) JOIN Nodes USING (itemId, branchid) JOIN Instances USING (itemid, versionid) JOIN usergroupinstancescache AS ugi USING (instanceid) WHERE %(labelCheck)s ugi.userGroupId in (%(roleIds)s)) AS idTable JOIN Items USING (itemId) JOIN Versions ON (idTable.versionId = Versions.versionId) JOIN Flavors ON (idTable.flavorId = Flavors.flavorId) %(nameCheck)s ORDER BY item, version, flavor """ % d, *args) l = list(cu) filteredL = typeFilter(l, filterSet) if regex: filteredL = [ x for x in filteredL if regex.match(x[0]) ] if limit is None: limit = len(filteredL) - start troveList = datamodel.NamedTroveIdentList(total = len(filteredL), start = start) for (name, version, flavor, ts) in filteredL[start:start + limit]: flavor = str(deps.ThawFlavor(flavor)) frzVer = versions.strToFrozen(version, [ x for x in ts.split(":") ]) ver = versions.ThawVersion(frzVer) troveList.append(name = name, version = ver, flavor = flavor, mkUrl = mkUrl) return troveList
def _thawData(self, frzVersion, frzFlavor): version = versions.ThawVersion(frzVersion) flavor = deps.ThawFlavor(frzFlavor) return version, flavor
def getAuthorizedRoles(self, cu, serverName, remoteIp, entitlementClass, entitlement): """ Given an entitlement, return the list of roles that the credentials authorize. """ cacheEntry = sha1helper.sha1String( "%s%s%s" % (serverName, entitlementClass, entitlement)) roleIds, timeout, autoRetry = \ self.cache.get(cacheEntry, (None, None, None)) if (timeout is not None) and time.time() < timeout: return roleIds elif (timeout is not None): del self.cache[cacheEntry] if autoRetry is not True: raise errors.EntitlementTimeout([entitlement]) if self.entCheckUrl: if entitlementClass is not None: url = "%s?server=%s;class=%s;key=%s" \ % (self.entCheckUrl, urllib.quote(serverName), urllib.quote(entitlementClass), urllib.quote(entitlement)) else: url = "%s?server=%s;key=%s" \ % (self.entCheckUrl, urllib.quote(serverName), urllib.quote(entitlement)) if remoteIp is not None: url += ';remote_ip=%s' % urllib.quote(remoteIp) try: f = urllib2.urlopen(url) xmlResponse = f.read() except Exception: return set() p = conarycfg.EntitlementParser() try: p.parse(xmlResponse) except: return set() if p['server'] != serverName: return set() entitlementClass = p['class'] entitlement = p['key'] entitlementRetry = p['retry'] if p['timeout'] is None: entitlementTimeout = self.cacheTimeout else: entitlementTimeout = p['timeout'] if entitlementTimeout is None: entitlementTimeout = -1 # look up entitlements cu.execute( """ SELECT UserGroups.userGroupId, UserGroups.accept_flags FROM Entitlements JOIN EntitlementAccessMap USING (entGroupId) JOIN UserGroups USING (userGroupId) WHERE entitlement=? """, entitlement) roleIds = dict((x[0], deps.ThawFlavor(x[1])) for x in cu) if self.entCheckUrl: # cacheEntry is still set from the cache check above self.cache[cacheEntry] = (roleIds, time.time() + entitlementTimeout, entitlementRetry) return roleIds
def _checkLatestVersion(self, group): """ Check to make sure each specific conary version is the latest source and build count of the upstream version. """ # get names and versions troves = set() labels = set() for pkgKey, pkgData in group.iteritems(): name = str(pkgData.name) version = None if pkgData.version: version = versions.ThawVersion(pkgData.version) labels.add(version.branch().label()) # get upstream version revision = version.trailingRevision() upstreamVersion = revision.getVersion() # FIXME: This should probably be a fully formed version # as above. version = version.branch().label().asString( ) + '/' + upstreamVersion flavor = None # FIXME: At some point we might want to add proper flavor handling, # note that group flavor handling is different than what # findTroves normally does. #if pkgData.flavor: # flavor = deps.ThawFlavor(str(pkgData.flavor)) troves.add((name, version, flavor)) # Get flavors and such. foundTroves = dict([(x[0], y) for x, y in self._helper.findTroves( troves, labels=labels).iteritems()]) pkgs = {} for pkgKey, pkgData in group.iteritems(): name = str(pkgData.name) version = None if pkgData.version: version = versions.ThawVersion(pkgData.version) flavor = None if pkgData.flavor: flavor = deps.ThawFlavor(str(pkgData.flavor)) pkgs.setdefault(name, []).append((name, version, flavor)) assert len(pkgs) == len(foundTroves) # Get all old versions so that we can make sure any version conflicts # were introduced by old version handling. oldVersions = set() if self._cfg.platformSearchPath: qlabels = set(self._cfg.platformSearchPath) | labels else: qlabels = labels for nvfLst in self._cfg.useOldVersion.itervalues(): for nvf in nvfLst: srcMap = self._helper.getSourceVersionMapFromBinaryVersion( nvf, labels=qlabels, latest=False) oldVersions |= set(itertools.chain(*srcMap.itervalues())) errors = {} for name, found in foundTroves.iteritems(): assert name in pkgs # Make sure to dedup packages from the model since a name/version # pair can occure more than once. current = sorted(set(pkgs[name])) # FIXME: HACK to filter found for the versions in current. # Do to some issues early on with building pkgs with missing # flavors findTroves is returning some extra cruft. current_versions = [currentnvf[1] for currentnvf in current] found = [nvf for nvf in found if nvf[1] in current_versions] if len(current) > len(found): log.warn('found more packages in the model than in the ' 'repository, assuming that multiversion policy will ' 'catch this.') continue assert len(current) == 1 or len(found) == len(current) foundError = False for i, (n, v, f) in enumerate(found): if len(current) == 1: i = 0 cn, cv, cf = current[i] assert n == cn if v != cv: if (n, v, f) in oldVersions: log.info('found %s=%s[%s] in oldVersions exceptions' % (n, v, f)) continue # This is probably a flavor that we don't care about # anymore. if cv > v and cv in [x[1] for x in found]: log.warn( 'missing flavors found of %s that are not all ' 'included in the group, assuming this ' 'intentional.' % cn) continue foundError = True if foundError: log.error('found old version for %s' % name) errors[name] = (current, found) if errors: raise OldVersionsFoundError(pkgNames=errors.keys(), errors=errors)
def thawFlavor(self, flavor): return deps.ThawFlavor(flavor)