Пример #1
0
    def getConflicts(self):
        """Check for conflicts in conflicts and obsoletes among currently
        installed packages.

        Return a HashList: RpmPackage =>
        [((name, RPMSENSE_* flags, EVR string), conflicting RpmPackage)]."""

        conflicts = HashList()

        if self.config.noconflicts:
            # conflicts turned off
            return conflicts

        if self.config.checkinstalled == 0:
            for r in self.installs:
                log.debug1("Checking for conflicts for %s", r.getNEVRA())
                self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"],
                                     conflicts)
            return conflicts

        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                log.debug1("Checking for conflicts for %s", r.getNEVRA())
                self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"],
                                     conflicts)
        return conflicts
Пример #2
0
    def getConflicts(self):
        """Check for conflicts in conflicts and obsoletes among currently
        installed packages.

        Return a HashList: RpmPackage =>
        [((name, RPMSENSE_* flags, EVR string), conflicting RpmPackage)]."""

        conflicts = HashList()

        if self.config.noconflicts:
            # conflicts turned off
            return conflicts

        if self.config.checkinstalled == 0:
            for r in self.installs:
                log.debug1("Checking for conflicts for %s", r.getNEVRA())
                self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"],
                                     conflicts)
            return conflicts

        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                log.debug1( "Checking for conflicts for %s", r.getNEVRA())
                self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"],
                                     conflicts)
        return conflicts
Пример #3
0
    def genRelations(self, rpms, operation, externaldb=None):
        # clear list to get to a sane state
        self.clear()

        # add relations for all packages
        for pkg in rpms:
            self[pkg] = RpmRelation()

        # Build a new resolver to list all dependencies between packages.
        if externaldb:
            db = RpmExternalSearchDB(externaldb, self.config, None)
        else:
            db = RpmMemoryDB(self.config, None)
        db.addPkgs(rpms)
        resolver = RpmResolver(self.config, db, nocheck=1)

        # Add dependencies:
        for pkg in db.getPkgs():
            log.debug1("Generating relations for %s", pkg.getNEVRA())
            resolved = resolver.getResolvedPkgDependencies(pkg)
            # ignore unresolved, we are only looking at the changes,
            # therefore not all symbols are resolvable in these changes
            for ((name, flag, version), s) in resolved:
                if name[:7] == "config(":
                    continue
                f = operationFlag(flag, operation)
                for pkg2 in s:
                    if pkg2 != pkg:
                        self.addRelation(pkg, pkg2, f)

        self.printRel()
Пример #4
0
    def genRelations(self, rpms, operation, externaldb=None):
        # clear list to get to a sane state
        self.clear()

        # add relations for all packages
        for pkg in rpms:
            self[pkg] = RpmRelation()

        # Build a new resolver to list all dependencies between packages.
        if externaldb:
            db = RpmExternalSearchDB(externaldb, self.config, None)
        else:
            db = RpmMemoryDB(self.config, None)
        db.addPkgs(rpms)
        resolver = RpmResolver(self.config, db, nocheck=1)

        # Add dependencies:
        for pkg in db.getPkgs():
            log.debug1("Generating relations for %s", pkg.getNEVRA())
            resolved = resolver.getResolvedPkgDependencies(pkg)
            # ignore unresolved, we are only looking at the changes,
            # therefore not all symbols are resolvable in these changes
            for ((name, flag, version), s) in resolved:
                if name[:7] == "config(":
                    continue
                f = operationFlag(flag, operation)
                for pkg2 in s:
                    if pkg2 != pkg:
                        self.addRelation(pkg, pkg2, f)

        self.printRel()
Пример #5
0
    def __arch_incompat(self, pkg, r):
        """Return True (and warn) if RpmPackage's pkg and r have different
        architectures, but the same base arch.

        Warn the user before returning True."""

        if pkg["arch"] != r["arch"] and archDuplicate(pkg["arch"], r["arch"]):
            log.debug1("%s does not match arch %s.", pkg.getNEVRA(), r["arch"])
            return 1
        return 0
Пример #6
0
    def __arch_incompat(self, pkg, r):
        """Return True (and warn) if RpmPackage's pkg and r have different
        architectures, but the same base arch.

        Warn the user before returning True."""

        if pkg["arch"] != r["arch"] and archDuplicate(pkg["arch"], r["arch"]):
            log.debug1("%s does not match arch %s.", pkg.getNEVRA(), r["arch"])
            return 1
        return 0
Пример #7
0
    def getResolvedDependencies(self):
        """Get resolved dependencies.

        Return a HashList: RpmPackage =>
        [((name, RPMSENSE_* flags, EVR string),
          [relevant resolving RpmPackage's])]."""

        all_resolved = HashList()
        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                log.debug1("Checking dependencies for %s", r.getNEVRA())
                (unresolved, resolved) = self.getPkgDependencies(r)
                if len(resolved) > 0:
                    all_resolved.setdefault(r, [ ]).extend(resolved)
        return all_resolved
Пример #8
0
    def getResolvedDependencies(self):
        """Get resolved dependencies.

        Return a HashList: RpmPackage =>
        [((name, RPMSENSE_* flags, EVR string),
          [relevant resolving RpmPackage's])]."""

        all_resolved = HashList()
        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                log.debug1("Checking dependencies for %s", r.getNEVRA())
                (unresolved, resolved) = self.getPkgDependencies(r)
                if len(resolved) > 0:
                    all_resolved.setdefault(r, []).extend(resolved)
        return all_resolved
Пример #9
0
    def order(self):
        """Order operations.

        Return an ordered list of operations on success, with tuples of the
        form (operation, RpmPackage). The operation is one of OP_INSTALL,
        OP_UPDATE or OP_ERASE per package.
        If an error occurs, return None."""

        log.debug1("Start ordering")

        order = self.genOrder()
        if order == None:
            return None

        # generate operations
        return self.genOperations(order)
Пример #10
0
    def __install_check(self, r, pkg):
        """Check whether RpmPackage pkg can be installed when RpmPackage r
        with same %name is already in the current list.

        Return an RpmList error code (after warning the user)."""

        if r == pkg or r.isEqual(pkg):
            if self.isInstalled(r):
                log.debug1("%s: %s is already installed", pkg.getNEVRA(),
                           r.getNEVRA())
                return self.ALREADY_INSTALLED
            else:
                log.debug1("%s: %s was already added", pkg.getNEVRA(),
                           r.getNEVRA())
                return self.ALREADY_ADDED
        return self.OK
Пример #11
0
    def order(self):
        """Order operations.

        Return an ordered list of operations on success, with tuples of the
        form (operation, RpmPackage). The operation is one of OP_INSTALL,
        OP_UPDATE or OP_ERASE per package.
        If an error occurs, return None."""

        log.debug1("Start ordering")

        order = self.genOrder()
        if order == None:
            return None

        # generate operations
        return self.genOperations(order)
Пример #12
0
    def __install_check(self, r, pkg):
        """Check whether RpmPackage pkg can be installed when RpmPackage r
        with same %name is already in the current list.

        Return an RpmList error code (after warning the user)."""

        if r == pkg or r.isEqual(pkg):
            if self.isInstalled(r):
                log.debug1("%s: %s is already installed", pkg.getNEVRA(),
                           r.getNEVRA())
                return self.ALREADY_INSTALLED
            else:
                log.debug1("%s: %s was already added", pkg.getNEVRA(),
                           r.getNEVRA())
                return self.ALREADY_ADDED
        return self.OK
Пример #13
0
    def genOrder(self):
        """Order rpms in orderer.RpmRelations relations.

        Return an ordered list of RpmPackage's on success, None on error."""

        length = len(self)

        order = []

        connected_components = ConnectedComponentsDetector(self).detect(self)

        if connected_components:
            if log.isDebugLoggingHere(log.DEBUG1):
                # debug output the components
                log.debug1("-- STRONGLY CONNECTED COMPONENTS --")
                for i in xrange(len(connected_components)):
                    s = ", ".join([
                        pkg.getNEVRA() for pkg in connected_components[i].pkgs
                    ])
                    log.debug1("  %d: %s", i, s)

#         weights = self.calculateWeights()
#         weight_keys = weights.keys()
#         weight_keys.sort()
#         weight_keys.reverse()

#         for key in weight_keys:
#             if key == -1: continue
#             for pkg in weights[key]:
#                 log.debug2("%s %s", key, pkg.getNEVRA())
#                 self.collect(pkg, order)

        self.processLeafNodes(order)

        if len(order) != length:
            log.error(
                "%d Packages of %d in order list! Number of connected "
                "components: %d ", len(order), length,
                len(connected_components))

        return order
Пример #14
0
    def checkDependencies(self):
        """Check dependencies, report errors.

        Return 1 if all dependencies are resolved, 0 if not (after warning the
        user)."""

        no_unresolved = 1

        if self.config.checkinstalled == 0:
            unresolved = self.getUnresolvedDependencies()
            for p in unresolved.keys():
                log.error("%s: unresolved dependencies:", p.getNEVRA())
                for u in unresolved[p]:
                    log.error("\t%s", depString(u))
            if unresolved:
                return 0
            return 1

        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                if self.config.checkinstalled == 0 and \
                       len(self.erases) == 0 and self.isInstalled(r):
                    # do not check installed packages if no packages
                    # are getting removed (by erase, update or obsolete)
                    continue
                log.debug1("Checking dependencies for %s", r.getNEVRA())
                (unresolved, resolved) = self.getPkgDependencies(r)
                if len(resolved) > 0:
                    log.debug2("%s: resolved dependencies:", r.getNEVRA())
                    for (u, s) in resolved:
                        s2 = ""
                        for r2 in s:
                            s2 += "%s " % r2.getNEVRA()
                        log.debug2("\t%s: %s", depString(u), s2)
                if len(unresolved) > 0:
                    no_unresolved = 0
                    log.error("%s: unresolved dependencies:", r.getNEVRA())
                    for u in unresolved:
                        log.erro("\t%s", depString(u))
        return no_unresolved
Пример #15
0
    def checkDependencies(self):
        """Check dependencies, report errors.

        Return 1 if all dependencies are resolved, 0 if not (after warning the
        user)."""

        no_unresolved = 1

        if self.config.checkinstalled == 0:
            unresolved = self.getUnresolvedDependencies()
            for p in unresolved.keys():
                log.error("%s: unresolved dependencies:", p.getNEVRA())
                for u in unresolved[p]:
                    log.error("\t%s", depString(u))
            if unresolved:
                return 0
            return 1

        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                if self.config.checkinstalled == 0 and \
                       len(self.erases) == 0 and self.isInstalled(r):
                    # do not check installed packages if no packages
                    # are getting removed (by erase, update or obsolete)
                    continue
                log.debug1("Checking dependencies for %s", r.getNEVRA())
                (unresolved, resolved) = self.getPkgDependencies(r)
                if len(resolved) > 0:
                    log.debug2("%s: resolved dependencies:", r.getNEVRA())
                    for (u, s) in resolved:
                        s2 = ""
                        for r2 in s:
                            s2 += "%s " % r2.getNEVRA()
                        log.debug2("\t%s: %s", depString(u), s2)
                if len(unresolved) > 0:
                    no_unresolved = 0
                    log.error("%s: unresolved dependencies:", r.getNEVRA())
                    for u in unresolved:
                        log.erro("\t%s", depString(u))
        return no_unresolved
Пример #16
0
    def genOrder(self):
        """Order rpms in orderer.RpmRelations relations.

        Return an ordered list of RpmPackage's on success, None on error."""

        length = len(self)

        order = [ ]

        connected_components = ConnectedComponentsDetector(self).detect(self)

        if connected_components:
            if log.isDebugLoggingHere(log.DEBUG1):
                # debug output the components
                log.debug1("-- STRONGLY CONNECTED COMPONENTS --")
                for i in xrange(len(connected_components)):
                    s = ", ".join([pkg.getNEVRA() for pkg in
                                   connected_components[i].pkgs])
                    log.debug1("  %d: %s", i, s)

#         weights = self.calculateWeights()
#         weight_keys = weights.keys()
#         weight_keys.sort()
#         weight_keys.reverse()

#         for key in weight_keys:
#             if key == -1: continue
#             for pkg in weights[key]:
#                 log.debug2("%s %s", key, pkg.getNEVRA())
#                 self.collect(pkg, order)

        self.processLeafNodes(order)

        if len(order) != length:
            log.error("%d Packages of %d in order list! Number of connected "
                      "components: %d ",
                      len(order), length,
                      len(connected_components))

        return order
Пример #17
0
    def getFileConflicts(self):
        """Find file conflicts among packages in self.database.names.

        Return a HashList:
        RpmPackage => [(filename, conflicting RpmPackage)]."""

        conflicts = HashList()

        db = self.database

        if self.config.nofileconflicts:
            # file conflicts turned off
            return conflicts
        if self.config.checkinstalled == 0:
            # no conflicts if there is no new package
            for pkg in self.installs:
                for name in pkg.iterFilenames():
                    dups = db.searchFilenames(name)
                    if len(dups) == 1: continue
                    log.debug1("Checking for file conflicts for '%s'", name)
                    for p in dups:
                        if p is pkg: continue
                        if self._hasFileConflict(pkg, p, name):
                            conflicts.setdefault(pkg, [ ]).append(
                                (name, p))
            return conflicts

        # duplicates: { name: [(pkg, idx),..], .. }
        duplicates = self.database.getFileDuplicates()
        for name in duplicates:
            dups = duplicates[name]
            log.debug1("Checking for file conflicts for '%s'", name)
            for j in xrange(len(dups)):
                for k in xrange(j+1, len(dups)):
                    if not self._hasFileConflict(dups[j], dups[k], name):
                        continue
                    conflicts.setdefault(dups[j], [ ]).append((name, dups[k]))
                    conflicts.setdefault(dups[k], [ ]).append((name, dups[j]))
        return conflicts
Пример #18
0
    def getFileConflicts(self):
        """Find file conflicts among packages in self.database.names.

        Return a HashList:
        RpmPackage => [(filename, conflicting RpmPackage)]."""

        conflicts = HashList()

        db = self.database

        if self.config.nofileconflicts:
            # file conflicts turned off
            return conflicts
        if self.config.checkinstalled == 0:
            # no conflicts if there is no new package
            for pkg in self.installs:
                for name in pkg.iterFilenames():
                    dups = db.searchFilenames(name)
                    if len(dups) == 1: continue
                    log.debug1("Checking for file conflicts for '%s'", name)
                    for p in dups:
                        if p is pkg: continue
                        if self._hasFileConflict(pkg, p, name):
                            conflicts.setdefault(pkg, []).append((name, p))
            return conflicts

        # duplicates: { name: [(pkg, idx),..], .. }
        duplicates = self.database.getFileDuplicates()
        for name in duplicates:
            dups = duplicates[name]
            log.debug1("Checking for file conflicts for '%s'", name)
            for j in xrange(len(dups)):
                for k in xrange(j + 1, len(dups)):
                    if not self._hasFileConflict(dups[j], dups[k], name):
                        continue
                    conflicts.setdefault(dups[j], []).append((name, dups[k]))
                    conflicts.setdefault(dups[k], []).append((name, dups[j]))
        return conflicts
Пример #19
0
    def getObsoletes(self):
        """Check for obsoletes among packages in self.database.names.

        Return a HashList: RpmPackage =>
        [((name, RPMSENSE_* flags, EVR string), obsoleted RpmPackage)]."""

        obsoletes = HashList()

        if self.config.noconflicts:
            # conflicts turned off, obsoletes are also conflicts, but in an
            # other level
            return obsoletes
        if self.config.checkinstalled == 0:
            for r in self.installs:
                log.debug1("Checking for obsoletes for %s", r.getNEVRA())
                self.getPkgConflicts(r, r["obsoletes"], obsoletes)
            return obsoletes

        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                log.debug1(1, "Checking for obsoletes for %s" % r.getNEVRA())
                self.getPkgConflicts(r, r["obsoletes"], obsoletes)
        return obsoletes
Пример #20
0
    def getObsoletes(self):
        """Check for obsoletes among packages in self.database.names.

        Return a HashList: RpmPackage =>
        [((name, RPMSENSE_* flags, EVR string), obsoleted RpmPackage)]."""

        obsoletes = HashList()

        if self.config.noconflicts:
            # conflicts turned off, obsoletes are also conflicts, but in an
            # other level
            return obsoletes
        if self.config.checkinstalled == 0:
            for r in self.installs:
                log.debug1("Checking for obsoletes for %s", r.getNEVRA())
                self.getPkgConflicts(r, r["obsoletes"], obsoletes)
            return obsoletes

        for name in self.database.getNames():
            for r in self.database.getPkgsByName(name):
                log.debug1(1, "Checking for obsoletes for %s" % r.getNEVRA())
                self.getPkgConflicts(r, r["obsoletes"], obsoletes)
        return obsoletes
Пример #21
0
    def update(self, pkg):
        name = pkg["name"]

        # get obsoletes
        # Valid only during OP_UPDATE: list of RpmPackage's that will be
        # obsoleted by the current update
        self.pkg_obsoletes = set()
        for u in pkg["obsoletes"]:
            s = self.database.searchDependency(u[0], u[1], u[2])
            for r in s:
                if r["name"] != pkg["name"]:
                    self.pkg_obsoletes.add(r)

        # update package

        # Valid only during OP_UPDATE: list of RpmPackage's that will be
        # removed by the current update
        self.pkg_updates = [ ]
        for r in self.database.getPkgsByName(name):
            ret = pkgCompare(r, pkg)
            if ret > 0: # old_ver > new_ver
                if self.config.oldpackage == 0:
                    if self.isInstalled(r):
                        msg = "%s: A newer package is already installed"
                    else:
                        msg = "%s: A newer package was already added"
                    log.debug1(msg, pkg.getNEVRA())
                    del self.pkg_updates
                    return self.OLD_PACKAGE
                else:
                    # old package: simulate a new package
                    ret = -1
            if ret < 0: # old_ver < new_ver
                if self.config.exactarch == 1 and \
                       self.__arch_incompat(pkg, r):
                    del self.pkg_updates
                    return self.ARCH_INCOMPAT

                if archDuplicate(pkg["arch"], r["arch"]) or \
                       pkg["arch"] == "noarch" or r["arch"] == "noarch":
                    self.pkg_updates.append(r)
            else: # ret == 0, old_ver == new_ver
                if self.config.exactarch == 1 and \
                       self.__arch_incompat(pkg, r):
                    del self.pkg_updates
                    return self.ARCH_INCOMPAT

                ret = self.__install_check(r, pkg) # Fails for same NEVRAs
                if ret != self.OK:
                    del self.pkg_updates
                    return ret

                if archDuplicate(pkg["arch"], r["arch"]):
                    if archCompat(pkg["arch"], r["arch"]):
                        if self.isInstalled(r):
                            msg = "%s: Ignoring due to installed %s"
                            ret = self.ALREADY_INSTALLED
                        else:
                            msg = "%s: Ignoring due to already added %s"
                            ret = self.ALREADY_ADDED
                        log.debug1(msg, pkg.getNEVRA(), r.getNEVRA())
                        del self.pkg_updates
                        return ret
                    else:
                        self.pkg_updates.append(r)

        ret = self.install(pkg, operation=OP_UPDATE)
        if ret != self.OK:
            del self.pkg_updates
            return ret

        for r in self.pkg_updates:
            if self.isInstalled(r):
                log.debug1("%s was already installed, replacing with %s",
                           r.getNEVRA(), pkg.getNEVRA())
            else:
                log.debug1("%s was already added, replacing with %s",
                           r.getNEVRA(), pkg.getNEVRA())
            if self._pkgUpdate(pkg, r) != self.OK: # Currently can't fail
                del self.pkg_updates
                return self.UPDATE_FAILED

        del self.pkg_updates

        # handle obsoletes
        for r in self.pkg_obsoletes:
            # package is not the same and has not the same name
            if self.isInstalled(r):
                fmt = "%s obsoletes installed %s, removing %s"
            else:
                fmt = "%s obsoletes added %s, removing %s"
            log.debug1(fmt, pkg.getNEVRA(), r.getNEVRA(), r.getNEVRA())
            if self._pkgObsolete(pkg, r) != self.OK:
                del self.pkg_obsoletes
                return self.OBSOLETE_FAILED

        del self.pkg_obsoletes

        return self.OK
Пример #22
0
    def update(self, pkg):
        name = pkg["name"]

        # get obsoletes
        # Valid only during OP_UPDATE: list of RpmPackage's that will be
        # obsoleted by the current update
        self.pkg_obsoletes = set()
        for u in pkg["obsoletes"]:
            s = self.database.searchDependency(u[0], u[1], u[2])
            for r in s:
                if r["name"] != pkg["name"]:
                    self.pkg_obsoletes.add(r)

        # update package

        # Valid only during OP_UPDATE: list of RpmPackage's that will be
        # removed by the current update
        self.pkg_updates = []
        for r in self.database.getPkgsByName(name):
            ret = pkgCompare(r, pkg)
            if ret > 0:  # old_ver > new_ver
                if self.config.oldpackage == 0:
                    if self.isInstalled(r):
                        msg = "%s: A newer package is already installed"
                    else:
                        msg = "%s: A newer package was already added"
                    log.debug1(msg, pkg.getNEVRA())
                    del self.pkg_updates
                    return self.OLD_PACKAGE
                else:
                    # old package: simulate a new package
                    ret = -1
            if ret < 0:  # old_ver < new_ver
                if self.config.exactarch == 1 and \
                       self.__arch_incompat(pkg, r):
                    del self.pkg_updates
                    return self.ARCH_INCOMPAT

                if archDuplicate(pkg["arch"], r["arch"]) or \
                       pkg["arch"] == "noarch" or r["arch"] == "noarch":
                    self.pkg_updates.append(r)
            else:  # ret == 0, old_ver == new_ver
                if self.config.exactarch == 1 and \
                       self.__arch_incompat(pkg, r):
                    del self.pkg_updates
                    return self.ARCH_INCOMPAT

                ret = self.__install_check(r, pkg)  # Fails for same NEVRAs
                if ret != self.OK:
                    del self.pkg_updates
                    return ret

                if archDuplicate(pkg["arch"], r["arch"]):
                    if archCompat(pkg["arch"], r["arch"]):
                        if self.isInstalled(r):
                            msg = "%s: Ignoring due to installed %s"
                            ret = self.ALREADY_INSTALLED
                        else:
                            msg = "%s: Ignoring due to already added %s"
                            ret = self.ALREADY_ADDED
                        log.debug1(msg, pkg.getNEVRA(), r.getNEVRA())
                        del self.pkg_updates
                        return ret
                    else:
                        self.pkg_updates.append(r)

        ret = self.install(pkg, operation=OP_UPDATE)
        if ret != self.OK:
            del self.pkg_updates
            return ret

        for r in self.pkg_updates:
            if self.isInstalled(r):
                log.debug1("%s was already installed, replacing with %s",
                           r.getNEVRA(), pkg.getNEVRA())
            else:
                log.debug1("%s was already added, replacing with %s",
                           r.getNEVRA(), pkg.getNEVRA())
            if self._pkgUpdate(pkg, r) != self.OK:  # Currently can't fail
                del self.pkg_updates
                return self.UPDATE_FAILED

        del self.pkg_updates

        # handle obsoletes
        for r in self.pkg_obsoletes:
            # package is not the same and has not the same name
            if self.isInstalled(r):
                fmt = "%s obsoletes installed %s, removing %s"
            else:
                fmt = "%s obsoletes added %s, removing %s"
            log.debug1(fmt, pkg.getNEVRA(), r.getNEVRA(), r.getNEVRA())
            if self._pkgObsolete(pkg, r) != self.OK:
                del self.pkg_obsoletes
                return self.OBSOLETE_FAILED

        del self.pkg_obsoletes

        return self.OK