From 9b68f47c96625fdafc9b3810de08563abe8e78be Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 16 May 2012 12:43:25 +0000 Subject: [PATCH] Move C module to newer version of libsolv. Many more improvements which should make the transaction check much faster. --- po/pakfire.pot | 155 ++++++++++++++------------ python/pakfire/actions.py | 10 +- python/pakfire/base.py | 36 ++++-- python/pakfire/builder.py | 3 +- python/pakfire/filelist.py | 13 +-- python/pakfire/packages/installed.py | 18 +-- python/pakfire/repository/database.py | 46 ++++---- python/pakfire/repository/index.py | 9 +- python/pakfire/repository/system.py | 50 +++++++-- python/pakfire/satsolver.py | 65 +++-------- python/pakfire/transaction.py | 49 ++++---- python/src/_pakfiremodule.c | 18 ++- python/src/repo.c | 31 ++++-- python/src/repo.h | 1 + python/src/request.c | 64 +++++------ python/src/request.h | 4 + python/src/solution.c | 8 +- python/src/solver.c | 88 +++++++++------ python/src/solver.h | 5 +- 19 files changed, 368 insertions(+), 305 deletions(-) diff --git a/po/pakfire.pot b/po/pakfire.pot index 4fd12e73e..db3a88f68 100644 --- a/po/pakfire.pot +++ b/po/pakfire.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-04-19 16:57+0200\n" +"POT-Creation-Date: 2012-05-16 12:33+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,13 +73,13 @@ msgid "Exception occured: %s" msgstr "" #: ../python/pakfire/actions.py:364 ../python/pakfire/actions.py:402 -#: ../python/pakfire/actions.py:425 ../python/pakfire/actions.py:448 -#: ../python/pakfire/actions.py:465 ../python/pakfire/actions.py:484 +#: ../python/pakfire/actions.py:424 ../python/pakfire/actions.py:446 +#: ../python/pakfire/actions.py:463 ../python/pakfire/actions.py:482 #, python-format msgid "Running transaction test for %s" msgstr "" -#: ../python/pakfire/actions.py:373 ../python/pakfire/actions.py:477 +#: ../python/pakfire/actions.py:373 msgid "Installing" msgstr "" @@ -87,63 +87,67 @@ msgstr "" msgid "Updating" msgstr "" -#: ../python/pakfire/actions.py:431 +#: ../python/pakfire/actions.py:430 msgid "Removing" msgstr "" #. Cleaning up leftover files and stuff. -#: ../python/pakfire/actions.py:455 +#: ../python/pakfire/actions.py:453 msgid "Cleanup" msgstr "" -#: ../python/pakfire/actions.py:493 +#: ../python/pakfire/actions.py:475 +msgid "Reinstalling" +msgstr "" + +#: ../python/pakfire/actions.py:491 msgid "Downgrading" msgstr "" -#: ../python/pakfire/base.py:315 +#: ../python/pakfire/base.py:320 msgid "Local install repository" msgstr "" -#: ../python/pakfire/base.py:372 +#: ../python/pakfire/base.py:377 #, python-format msgid "Could not find any installed package providing \"%s\"." msgstr "" -#: ../python/pakfire/base.py:378 +#: ../python/pakfire/base.py:383 #, python-format msgid "Multiple reinstall candidates for \"%(pattern)s\": %(pkgs)s" msgstr "" -#: ../python/pakfire/base.py:382 ../python/pakfire/base.py:450 -#: ../python/pakfire/base.py:487 ../python/pakfire/base.py:546 -#: ../python/pakfire/base.py:567 ../python/pakfire/transaction.py:396 +#: ../python/pakfire/base.py:387 ../python/pakfire/base.py:455 +#: ../python/pakfire/base.py:491 ../python/pakfire/base.py:553 +#: ../python/pakfire/base.py:574 ../python/pakfire/transaction.py:390 msgid "Nothing to do" msgstr "" -#: ../python/pakfire/base.py:407 +#: ../python/pakfire/base.py:412 #, python-format msgid "Could not find package %s in a remote repository." msgstr "" -#: ../python/pakfire/base.py:479 +#: ../python/pakfire/base.py:483 #, python-format msgid "Excluding %s." msgstr "" -#: ../python/pakfire/base.py:531 +#: ../python/pakfire/base.py:535 #, python-format msgid "\"%s\" package does not seem to be installed." msgstr "" -#: ../python/pakfire/base.py:681 +#: ../python/pakfire/base.py:688 msgid "Build command has failed." msgstr "" -#: ../python/pakfire/base.py:716 +#: ../python/pakfire/base.py:723 msgid "New repository" msgstr "" -#: ../python/pakfire/base.py:752 +#: ../python/pakfire/base.py:764 msgid "Everything is fine." msgstr "" @@ -199,72 +203,72 @@ msgstr "" msgid "Running installation test..." msgstr "" -#: ../python/pakfire/builder.py:766 +#: ../python/pakfire/builder.py:767 msgid "Installation test succeeded." msgstr "" #. Create a progressbar. -#: ../python/pakfire/builder.py:803 +#: ../python/pakfire/builder.py:804 msgid "Signing packages..." msgstr "" -#: ../python/pakfire/builder.py:837 +#: ../python/pakfire/builder.py:838 msgid "Dumping package information:" msgstr "" #. Walk through the whole tree and collect all files #. that are on the same disk (not crossing mountpoints). -#: ../python/pakfire/builder.py:867 +#: ../python/pakfire/builder.py:868 msgid "Creating filelist..." msgstr "" #. Create a nice progressbar. -#: ../python/pakfire/builder.py:886 +#: ../python/pakfire/builder.py:887 msgid "Compressing files..." msgstr "" -#: ../python/pakfire/builder.py:905 +#: ../python/pakfire/builder.py:906 #, python-format msgid "Cache file was successfully created at %s." msgstr "" -#: ../python/pakfire/builder.py:906 +#: ../python/pakfire/builder.py:907 #, python-format msgid " Containing %(files)s files, it has a size of %(size)s." msgstr "" #. Make a nice progress bar as always. -#: ../python/pakfire/builder.py:917 +#: ../python/pakfire/builder.py:918 msgid "Extracting files..." msgstr "" #. Update all packages. -#: ../python/pakfire/builder.py:937 +#: ../python/pakfire/builder.py:938 msgid "Updating packages from cache..." msgstr "" #. Package the result. #. Make all these little package from the build environment. -#: ../python/pakfire/builder.py:1075 +#: ../python/pakfire/builder.py:1076 msgid "Creating packages:" msgstr "" #. Execute the buildscript of this stage. -#: ../python/pakfire/builder.py:1089 +#: ../python/pakfire/builder.py:1090 #, python-format msgid "Running stage %s:" msgstr "" -#: ../python/pakfire/builder.py:1107 +#: ../python/pakfire/builder.py:1108 #, python-format msgid "Could not remove static libraries: %s" msgstr "" -#: ../python/pakfire/builder.py:1113 +#: ../python/pakfire/builder.py:1114 msgid "Compressing man pages did not complete successfully." msgstr "" -#: ../python/pakfire/builder.py:1133 +#: ../python/pakfire/builder.py:1134 msgid "Extracting debuginfo did not complete with success. Aborting build." msgstr "" @@ -416,7 +420,7 @@ msgstr "" msgid "Give name of at least one package to check." msgstr "" -#: ../python/pakfire/cli.py:348 ../python/pakfire/transaction.py:405 +#: ../python/pakfire/cli.py:348 ../python/pakfire/transaction.py:399 msgid "Repository" msgstr "" @@ -740,7 +744,7 @@ msgid "Job: %(name)s" msgstr "" #: ../python/pakfire/cli.py:1078 ../python/pakfire/packages/base.py:107 -#: ../python/pakfire/transaction.py:404 +#: ../python/pakfire/transaction.py:398 msgid "Arch" msgstr "" @@ -992,7 +996,7 @@ msgstr "" msgid "Running pakfire-build in a pakfire container?" msgstr "" -#: ../python/pakfire/errors.py:94 ../python/pakfire/transaction.py:475 +#: ../python/pakfire/errors.py:94 ../python/pakfire/transaction.py:469 msgid "Transaction test was not successful" msgstr "" @@ -1085,7 +1089,7 @@ msgstr "" msgid "Name" msgstr "" -#: ../python/pakfire/packages/base.py:110 ../python/pakfire/transaction.py:404 +#: ../python/pakfire/packages/base.py:110 ../python/pakfire/transaction.py:398 msgid "Version" msgstr "" @@ -1093,7 +1097,7 @@ msgstr "" msgid "Release" msgstr "" -#: ../python/pakfire/packages/base.py:115 ../python/pakfire/transaction.py:405 +#: ../python/pakfire/packages/base.py:115 ../python/pakfire/transaction.py:399 msgid "Size" msgstr "" @@ -1173,7 +1177,7 @@ msgstr "" msgid "Not set" msgstr "" -#: ../python/pakfire/packages/base.py:528 +#: ../python/pakfire/packages/base.py:534 #, python-format msgid "Config file saved as %s." msgstr "" @@ -1243,16 +1247,16 @@ msgstr "" msgid "Building source package %s:" msgstr "" -#: ../python/pakfire/repository/database.py:116 +#: ../python/pakfire/repository/database.py:123 msgid "The format of the database is not supported by this version of pakfire." msgstr "" -#: ../python/pakfire/repository/database.py:224 +#: ../python/pakfire/repository/database.py:231 #, python-format msgid "Cannot use database with version greater than %s." msgstr "" -#: ../python/pakfire/repository/database.py:226 +#: ../python/pakfire/repository/database.py:233 #, python-format msgid "Migrating database from format %(old)s to %(new)s." msgstr "" @@ -1320,33 +1324,38 @@ msgstr "" msgid "Trying an other mirror." msgstr "" -#: ../python/pakfire/satsolver.py:230 ../python/pakfire/satsolver.py:256 +#. Create a progressbar. +#: ../python/pakfire/repository/system.py:66 +msgid "Loading installed packages" +msgstr "" + +#: ../python/pakfire/satsolver.py:199 ../python/pakfire/satsolver.py:225 msgid "The solver returned one problem:" msgstr "" #. Ask the user if he or she want to modify the request. If not, just exit. -#: ../python/pakfire/satsolver.py:272 +#: ../python/pakfire/satsolver.py:241 msgid "Do you want to manually alter the request?" msgstr "" -#: ../python/pakfire/satsolver.py:275 +#: ../python/pakfire/satsolver.py:244 msgid "You can now try to satisfy the solver by modifying your request." msgstr "" -#: ../python/pakfire/satsolver.py:280 +#: ../python/pakfire/satsolver.py:249 msgid "Which problem to you want to resolve?" msgstr "" -#: ../python/pakfire/satsolver.py:282 +#: ../python/pakfire/satsolver.py:251 msgid "Press enter to try to re-solve the request." msgstr "" -#: ../python/pakfire/satsolver.py:313 +#: ../python/pakfire/satsolver.py:282 #, python-format msgid " Solution: %s" msgstr "" -#: ../python/pakfire/satsolver.py:322 +#: ../python/pakfire/satsolver.py:291 msgid " Solutions:" msgstr "" @@ -1354,110 +1363,110 @@ msgstr "" msgid "Could not be determined" msgstr "" -#: ../python/pakfire/transaction.py:95 +#: ../python/pakfire/transaction.py:94 #, python-format msgid "file %(name)s from %(pkg1)s conflicts with file from package %(pkg2)s" msgstr "" -#: ../python/pakfire/transaction.py:101 +#: ../python/pakfire/transaction.py:100 #, python-format msgid "file %(name)s from %(pkg)s conflicts with files from %(pkgs)s" msgstr "" -#: ../python/pakfire/transaction.py:109 +#: ../python/pakfire/transaction.py:108 #, python-format msgid "" "There is not enough space left on %(name)s. Need at least %(size)s to " "perform transaction." msgstr "" -#: ../python/pakfire/transaction.py:327 +#: ../python/pakfire/transaction.py:321 #, python-format msgid "Not enough space to download %s of packages." msgstr "" -#: ../python/pakfire/transaction.py:330 +#: ../python/pakfire/transaction.py:324 msgid "Downloading packages:" msgstr "" -#: ../python/pakfire/transaction.py:404 +#: ../python/pakfire/transaction.py:398 msgid "Package" msgstr "" -#: ../python/pakfire/transaction.py:409 +#: ../python/pakfire/transaction.py:403 msgid "Installing:" msgstr "" -#: ../python/pakfire/transaction.py:410 +#: ../python/pakfire/transaction.py:404 msgid "Reinstalling:" msgstr "" -#: ../python/pakfire/transaction.py:411 +#: ../python/pakfire/transaction.py:405 msgid "Updating:" msgstr "" -#: ../python/pakfire/transaction.py:412 +#: ../python/pakfire/transaction.py:406 msgid "Downgrading:" msgstr "" -#: ../python/pakfire/transaction.py:413 +#: ../python/pakfire/transaction.py:407 msgid "Removing:" msgstr "" -#: ../python/pakfire/transaction.py:419 +#: ../python/pakfire/transaction.py:413 msgid "Transaction Summary" msgstr "" -#: ../python/pakfire/transaction.py:426 +#: ../python/pakfire/transaction.py:420 msgid "package" msgstr "" -#: ../python/pakfire/transaction.py:432 +#: ../python/pakfire/transaction.py:426 #, python-format msgid "Total download size: %s" msgstr "" -#: ../python/pakfire/transaction.py:436 +#: ../python/pakfire/transaction.py:430 #, python-format msgid "Installed size: %s" msgstr "" -#: ../python/pakfire/transaction.py:439 +#: ../python/pakfire/transaction.py:433 #, python-format msgid "Freed size: %s" msgstr "" -#: ../python/pakfire/transaction.py:450 +#: ../python/pakfire/transaction.py:444 msgid "Is this okay?" msgstr "" -#: ../python/pakfire/transaction.py:456 +#: ../python/pakfire/transaction.py:450 msgid "Running Transaction Test" msgstr "" -#: ../python/pakfire/transaction.py:468 +#: ../python/pakfire/transaction.py:462 msgid "Transaction Test Succeeded" msgstr "" #. Make a nice progressbar. -#: ../python/pakfire/transaction.py:501 +#: ../python/pakfire/transaction.py:495 msgid "Verifying signatures..." msgstr "" -#: ../python/pakfire/transaction.py:533 +#: ../python/pakfire/transaction.py:527 #, python-format msgid "Found %s signature error(s)!" msgstr "" -#: ../python/pakfire/transaction.py:538 +#: ../python/pakfire/transaction.py:532 msgid "Going on because we are running in permissive mode." msgstr "" -#: ../python/pakfire/transaction.py:539 +#: ../python/pakfire/transaction.py:533 msgid "This is dangerous!" msgstr "" -#: ../python/pakfire/transaction.py:560 +#: ../python/pakfire/transaction.py:554 msgid "Running transaction" msgstr "" diff --git a/python/pakfire/actions.py b/python/pakfire/actions.py index cdc277891..9fda2613e 100644 --- a/python/pakfire/actions.py +++ b/python/pakfire/actions.py @@ -417,7 +417,6 @@ class ActionRemove(Action): def __init__(self, *args, **kwargs): Action.__init__(self, *args, **kwargs) - # XXX This is ugly, but works for the moment. self.pkg = self.local.db.get_package_from_solv(self.pkg_solv) assert self.pkg @@ -431,7 +430,7 @@ class ActionRemove(Action): self.pkg.cleanup(_("Removing"), prefix=self.pakfire.path) # Remove package from the database. - self.local.rem_package(self.pkg) + self.local.rem_package(self.pkg_solv) class ActionCleanup(Action): @@ -440,7 +439,6 @@ class ActionCleanup(Action): def __init__(self, *args, **kwargs): Action.__init__(self, *args, **kwargs) - # XXX This is ugly, but works for the moment. self.pkg = self.local.db.get_package_from_solv(self.pkg_solv) assert self.pkg @@ -455,7 +453,7 @@ class ActionCleanup(Action): self.pkg.cleanup(_("Cleanup"), prefix=self.pakfire.path) # Remove package from the database. - self.local.rem_package(self.pkg) + self.local.rem_package(self.pkg_solv) class ActionReinstall(Action): @@ -471,10 +469,10 @@ class ActionReinstall(Action): def run(self): # Remove package from the database and add it afterwards. # Sounds weird, but fixes broken entries in the database. - self.local.rem_package(self.pkg) + self.local.rem_package(self.pkg_solv) self.local.add_package(self.pkg) - self.pkg.extract(_("Installing"), prefix=self.pakfire.path) + self.pkg.extract(_("Reinstalling"), prefix=self.pakfire.path) class ActionDowngrade(Action): diff --git a/python/pakfire/base.py b/python/pakfire/base.py index 6e2e52e7d..54485a517 100644 --- a/python/pakfire/base.py +++ b/python/pakfire/base.py @@ -132,7 +132,7 @@ class Pakfire(object): return ret - def create_request(self, builder=False, install=None, remove=None, update=None): + def create_request(self, builder=False, install=None, remove=None, update=None, updateall=False): request = satsolver.Request(self.pool) # Add multiinstall information. @@ -151,6 +151,11 @@ class Pakfire(object): for req in self.expand_requires(update): request.update(req) + # Configure the request to update all packages + # if requested. + if updateall: + request.updateall() + # Return the request. return request @@ -467,12 +472,11 @@ class Pakfire(object): # If there are given any packets on the command line, we will # only update them. Otherwise, we update the whole system. + updateall = True if pkgs: - update = False - else: - update = True + updateall = False - request = self.create_request(update=pkgs) + request = self.create_request(update=pkgs, updateall=updateall) # Exclude packages that should not be updated. for exclude in excludes or []: @@ -481,7 +485,7 @@ class Pakfire(object): exclude = self.create_relation(exclude) request.lock(exclude) - solver = self.solv(request, logger=logger, update=update, **kwargs) + solver = self.solv(request, logger=logger, **kwargs) if not solver.status: logger.info(_("Nothing to do")) @@ -534,8 +538,11 @@ class Pakfire(object): request.install(rel) # Solve the request. - solver = self.solv(request, allow_downgrade=True, allow_vendorchange=allow_vendorchange, - allow_archchange=allow_archchange) + solver = self.solv(request, + allow_downgrade=True, + allow_vendorchange=allow_vendorchange, + allow_archchange=allow_archchange, + ) assert solver.status is True # Create the transaction. @@ -556,7 +563,7 @@ class Pakfire(object): request = self.create_request(remove=pkgs) # Solve the request. - solver = self.solv(request, uninstall=True) + solver = self.solv(request, allow_uninstall=True) assert solver.status is True # Create the transaction. @@ -737,7 +744,7 @@ class Pakfire(object): # Clean up repository caches. self.repos.clean() - def check(self, downgrade=True, uninstall=True): + def check(self, allow_downgrade=True, allow_uninstall=True): """ Try to fix any errors in the system. """ @@ -745,8 +752,13 @@ class Pakfire(object): # For that we create an empty request and solver and try to solve # something. request = self.create_request() - solver = self.solv(request, fix_system=True, allow_downgrade=downgrade, - uninstall=uninstall) + request.verify() + + solver = self.solv( + request, + allow_downgrade=allow_downgrade, + allow_uninstall=allow_uninstall, + ) if solver.status is False: log.info(_("Everything is fine.")) diff --git a/python/pakfire/builder.py b/python/pakfire/builder.py index 494049e01..863ade324 100644 --- a/python/pakfire/builder.py +++ b/python/pakfire/builder.py @@ -761,7 +761,8 @@ class BuildEnviron(object): # Install all packages that were built. self.install(self.find_result_packages(), - uninstall=True, signatures_mode="disabled") + allow_vendorchange=True, allow_archchange=True, + allow_uninstall=True, signatures_mode="disabled") self.log.info(_("Installation test succeeded.")) self.log.info("") diff --git a/python/pakfire/filelist.py b/python/pakfire/filelist.py index ef7ee35f4..4bac6eff7 100644 --- a/python/pakfire/filelist.py +++ b/python/pakfire/filelist.py @@ -74,13 +74,12 @@ class File(_File): class FileDatabase(_File): - def __init__(self, pakfire, db, row_id): + def __init__(self, pakfire, db, row_id, row=None): _File.__init__(self, pakfire) self.db = db self.row_id = row_id - - self.__row = None + self.__row = row @property def row(self): @@ -91,13 +90,7 @@ class FileDatabase(_File): c = self.db.cursor() c.execute("SELECT * FROM files WHERE id = ? LIMIT 1", (self.row_id,)) - # Check if we got the same row. - #assert c.lastrowid == self.row_id - - for row in c: - self.__row = row - break - + self.__row = c.fetchone() c.close() return self.__row diff --git a/python/pakfire/packages/installed.py b/python/pakfire/packages/installed.py index 5a7763b61..33c241d0c 100644 --- a/python/pakfire/packages/installed.py +++ b/python/pakfire/packages/installed.py @@ -39,6 +39,7 @@ class DatabasePackage(Package): self.db = db self._data = {} + self._filelist = None for key in data.keys(): self._data[key] = data[key] @@ -169,20 +170,21 @@ class DatabasePackage(Package): @property def filename(self): - return self.metadata.get("filename") # XXX basename? + return self.metadata.get("filename") @property def filelist(self): - filelist = [] + if self._filelist is None: + self._filelist = [] - c = self.db.cursor() - c.execute("SELECT id FROM files WHERE pkg = ?", (self.id,)) + c = self.db.cursor() + c.execute("SELECT * FROM files WHERE pkg = ?", (self.id,)) - for id in c: - file = pakfire.filelist.FileDatabase(self.pakfire, self.db, id[0]) - filelist.append(file) + for row in c.fetchall(): + file = pakfire.filelist.FileDatabase(self.pakfire, self.db, row["id"], row) + self._filelist.append(file) - return filelist + return self._filelist @property def configfiles(self): diff --git a/python/pakfire/repository/database.py b/python/pakfire/repository/database.py index 6f8f39750..a5e5b858b 100644 --- a/python/pakfire/repository/database.py +++ b/python/pakfire/repository/database.py @@ -53,6 +53,13 @@ class Database(object): self._db.close() self._db = None + @property + def db(self): + if self._db is None: + self.open() + + return self._db + def create(self): pass @@ -338,11 +345,11 @@ class DatabaseLocal(Database): #c.execute("SELECT id FROM packages WHERE name = ? AND epoch = ? AND version = ?" # " AND release = ? LIMIT 1", (pkg.name, pkg.epoch, pkg.version, pkg.release,)) - id = None - for row in c: - id = row["id"] - break - assert id + row = c.fetchone() + if not row: + return + + id = row["id"] # First, delete all files from the database and then delete the pkg itself. c.execute("DELETE FROM files WHERE pkg = ?", (id,)) @@ -364,34 +371,29 @@ class DatabaseLocal(Database): @property def packages(self): - c = self.cursor() + c = self.db.execute("SELECT * FROM packages ORDER BY name") - c.execute("SELECT * FROM packages ORDER BY name") - - for row in c: + for row in c.fetchall(): yield packages.DatabasePackage(self.pakfire, self.repo, self, row) c.close() def get_filelist(self): - c = self.cursor() - c.execute("SELECT DISTINCT name FROM files") - - ret = [] - for row in c: - ret.append(row["name"]) - - c.close() + c = self.db.execute("SELECT name FROM files") - return ret + return [r["name"] for r in c.fetchall()] def get_package_from_solv(self, solv_pkg): - c = self.cursor() - c.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,)) + assert solv_pkg.uuid + + c = self.db.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,)) try: - for row in c: - return packages.DatabasePackage(self.pakfire, self.repo, self, row) + row = c.fetchone() + if row is None: + return + + return packages.DatabasePackage(self.pakfire, self.repo, self, row) finally: c.close() diff --git a/python/pakfire/repository/index.py b/python/pakfire/repository/index.py index fac1c2f00..7620b3897 100644 --- a/python/pakfire/repository/index.py +++ b/python/pakfire/repository/index.py @@ -24,6 +24,7 @@ import os import logging log = logging.getLogger("pakfire") +import pakfire.packages as packages import pakfire.satsolver as satsolver class Index(object): @@ -147,8 +148,12 @@ class Index(object): solvable.add_provides(rel) def rem_package(self, pkg): - # XXX delete the solvable from the index. - pass # TODO + """ + Delete the solvable from the index. + """ + assert isinstance(pkg, packages.SolvPackage) + + self.solver_repo.rem_solv(pkg) def clear(self): """ diff --git a/python/pakfire/repository/system.py b/python/pakfire/repository/system.py index ce3e97993..386f25255 100644 --- a/python/pakfire/repository/system.py +++ b/python/pakfire/repository/system.py @@ -19,9 +19,17 @@ # # ############################################################################### +import os + import base import database +import pakfire.packages as packages +import pakfire.util as util + +from pakfire.constants import * +from pakfire.i18n import _ + class RepositorySystem(base.RepositoryFactory): def __init__(self, pakfire): base.RepositoryFactory.__init__(self, pakfire, "@system", "Local repository") @@ -32,6 +40,10 @@ class RepositorySystem(base.RepositoryFactory): # Tell the solver, that these are the installed packages. self.pool.set_installed(self.solver_repo) + @property + def cache_file(self): + return os.path.join(self.pakfire.path, PACKAGES_SOLV) + @property def priority(self): """ @@ -40,14 +52,35 @@ class RepositorySystem(base.RepositoryFactory): return 10 def update(self, force=False, offline=False): - if not force: - force = len(self) == 0 + # XXX using the cache is currently disabled + #if not force: + # if os.path.exists(self.cache_file): + # self.index.read(self.cache_file) + # + # force = len(self) == 0 + + force = True if force: + # Create a progressbar. + pb = util.make_progress(_("Loading installed packages"), len(self.db)) + + # Remove all data from the current index. self.index.clear() + + i = 0 for pkg in self.db.packages: + if pb: + i += 1 + pb.update(i) + self.index.add_package(pkg) + self.index.optimize() + + if pb: + pb.finish() + def commit(self): # Commit the database to disk. self.db.commit() @@ -55,20 +88,23 @@ class RepositorySystem(base.RepositoryFactory): # Make sure that all data in the index is accessable. self.index.optimize() + # Write the content of the index to a file + # for fast parsing. + # XXX this is currently disabled + #self.index.write(self.cache_file) + def add_package(self, pkg): # Add package to the database. self.db.add_package(pkg) self.index.add_package(pkg) def rem_package(self, pkg): + assert isinstance(pkg, packages.SolvPackage), pkg + # Remove package from the database. self.db.rem_package(pkg) self.index.rem_package(pkg) @property def filelist(self): - # XXX ugly? - - for pkg in self.db.packages: - for file in pkg.filelist: - yield file + return self.db.get_filelist() diff --git a/python/pakfire/satsolver.py b/python/pakfire/satsolver.py index c3629cee8..48c6d0dee 100644 --- a/python/pakfire/satsolver.py +++ b/python/pakfire/satsolver.py @@ -111,6 +111,13 @@ class Request(_pakfire.Request): class Solver(object): + option2flag = { + "allow_archchange" : SOLVER_FLAG_ALLOW_ARCHCHANGE, + "allow_downgrade" : SOLVER_FLAG_ALLOW_DOWNGRADE, + "allow_uninstall" : SOLVER_FLAG_ALLOW_UNINSTALL, + "allow_vendorchange" : SOLVER_FLAG_ALLOW_VENDORCHANGE, + } + def __init__(self, pakfire, request, logger=None): if logger is None: logger = logging.getLogger("pakfire") @@ -119,27 +126,6 @@ class Solver(object): self.pakfire = pakfire self.pool = self.pakfire.pool - # Default settings. - self.settings = { - # Update all installed packages? - "update" : False, - - # Allow to uninstall any packages? - "uninstall" : False, - - # Allow to downgrade any packages? - "allow_downgrade" : False, - - # Allow packages to change their vendors? - "allow_vendorchange" : False, - - # Allow packages to change their arch? - "allow_archchange" : False, - - # Fix system? - "fix_system" : False, - } - self.request = request assert self.request, "Empty request?" @@ -159,40 +145,23 @@ class Solver(object): self.__problems = None self.__transaction = None - def set(self, key, value): - assert self.settings.has_key(key), "Unknown configuration setting: %s" % key - assert value in (True, False), "Invalid value: %s" % value - + def set(self, option, value): try: - self.settings[key] = value + flag = self.option2flag[option] except KeyError: - pass + raise Exception, "Unknown configuration setting: %s" % option + self.solver.set_flag(flag, value) - def get(self, key): - assert self.settings.has_key(key), "Unknown configuration setting: %s" % key - - return self.settings.get(key) + def get(self, option): + try: + flag = self.option2flag[option] + except KeyError: + raise Exception, "Unknown configuration setting: %s" % option + return self.solver.get_flag(flag) def solve(self): assert self.status is None, "Solver did already solve something." - # Apply solver configuration. - self.solver.set_fix_system(self.get("fix_system")) - self.solver.set_allow_uninstall(self.get("uninstall")) - self.solver.set_allow_downgrade(self.get("allow_downgrade")) - - # Optionally allow packages to change their vendors. - # This is not recommended because it may have weird effects. - self.solver.set_allow_vendorchange(self.get("allow_vendorchange")) - - # Optionally allow packages ot change their architecture. - self.solver.set_allow_archchange(self.get("allow_archchange")) - - # Configure the solver for an update. - if self.get("update"): - self.solver.set_updatesystem(True) - self.solver.set_do_split_provides(True) - # Actually solve the request. start_time = time.time() self.status = self.solver.solve(self.request) diff --git a/python/pakfire/transaction.py b/python/pakfire/transaction.py index 58b52c697..10a1277c2 100644 --- a/python/pakfire/transaction.py +++ b/python/pakfire/transaction.py @@ -59,15 +59,16 @@ class TransactionCheck(object): @property def error_files(self): - ret = {} + ret = [] - for name, files in self.filelist.items(): - if len(files) <= 1: - continue + for name, count in self.filelist.items(): + if count > 1: + ret.append(name) - ret[name] = files + return sorted(ret) - return ret + def provides_file(self, name): + return [] # XXX TODO @property def successful(self): @@ -85,18 +86,16 @@ class TransactionCheck(object): if logger is None: logger = logging.getLogger("pakfire") - for name, files in sorted(self.error_files.items()): - assert len(files) >= 2 - - pkgs = [f.pkg.friendly_name for f in files] + for file in self.error_files: + pkgs = self.provides_file(file) - if len(files) == 2: + if len(pkgs) == 2: logger.critical( _("file %(name)s from %(pkg1)s conflicts with file from package %(pkg2)s") % \ { "name" : name, "pkg1" : pkgs[0], "pkg2" : pkgs[1] } ) - elif len(files) >= 3: + elif len(pkgs) >= 3: logger.critical( _("file %(name)s from %(pkg)s conflicts with files from %(pkgs)s") % \ { "name" : name, "pkg" : pkgs[0], "pkgs" : i18n.list(pkgs[1:])} @@ -113,7 +112,7 @@ class TransactionCheck(object): filelist = {} for file in self.pakfire.repos.local.filelist: - filelist[file.name] = [file,] + filelist[file] = 1 return filelist @@ -122,11 +121,10 @@ class TransactionCheck(object): if file.is_dir(): continue - if self.filelist.has_key(file.name): - self.filelist[file.name].append(file) - - else: - self.filelist[file.name] = [file,] + try: + self.filelist[file.name] += 1 + except KeyError: + self.filelist[file.name] = 1 # Add all filesize data to mountpoints. self.mountpoints.add_pkg(pkg) @@ -136,14 +134,10 @@ class TransactionCheck(object): if file.is_dir(): continue - if not self.filelist.has_key(file.name): - continue - - for f in self.filelist[file.name]: - if not f.pkg == pkg: - continue - - self.filelist[file.name].remove(f) + try: + self.filelist[file.name] -= 1 + except KeyError: + pass # Remove all filesize data from mountpoints. self.mountpoints.rem_pkg(pkg) @@ -562,8 +556,11 @@ class Transaction(object): for action in self.actions: try: action.run() + except ActionError, e: logger.error("Action finished with an error: %s - %s" % (action, e)) + #except Exception, e: + # logger.error(_("An unforeseen error occoured: %s") % e) logger.info("") diff --git a/python/src/_pakfiremodule.c b/python/src/_pakfiremodule.c index d4ea688d4..8e80468fd 100644 --- a/python/src/_pakfiremodule.c +++ b/python/src/_pakfiremodule.c @@ -80,6 +80,9 @@ static PyMethodDef Request_methods[] = { {"noobsoletes_solvable", (PyCFunction)Request_noobsoletes_solvable, METH_VARARGS, NULL}, {"noobsoletes_relation", (PyCFunction)Request_noobsoletes_relation, METH_VARARGS, NULL}, {"noobsoletes_name", (PyCFunction)Request_noobsoletes_name, METH_VARARGS, NULL}, + {"updateall", (PyCFunction)Request_updateall, METH_NOARGS, NULL}, + {"distupgrade", (PyCFunction)Request_distupgrade, METH_NOARGS, NULL}, + {"verify", (PyCFunction)Request_verify, METH_NOARGS, NULL}, { NULL, NULL, 0, NULL } }; @@ -99,6 +102,7 @@ static PyMethodDef Repo_methods[] = { {"internalize", (PyCFunction)Repo_internalize, METH_NOARGS, NULL}, {"clear", (PyCFunction)Repo_clear, METH_NOARGS, NULL}, {"get_all", (PyCFunction)Repo_get_all, METH_NOARGS, NULL}, + {"rem_solv", (PyCFunction)Repo_rem_solv, METH_VARARGS, NULL}, { NULL, NULL, 0, NULL } }; @@ -152,10 +156,8 @@ static PyMethodDef Solution_methods[] = { static PyMethodDef Solver_methods[] = { {"solve", (PyCFunction)Solver_solve, METH_VARARGS, NULL}, - {"get_fix_system", (PyCFunction)Solver_get_fix_system, METH_NOARGS, NULL}, - {"set_fix_system", (PyCFunction)Solver_set_fix_system, METH_VARARGS, NULL}, - {"get_allow_downgrade", (PyCFunction)Solver_get_allow_downgrade, METH_NOARGS, NULL}, - {"set_allow_downgrade", (PyCFunction)Solver_set_allow_downgrade, METH_VARARGS, NULL}, + {"get_flag", (PyCFunction)Solver_get_flag, METH_VARARGS, NULL}, + {"set_flag", (PyCFunction)Solver_set_flag, METH_VARARGS, NULL}, {"get_allow_archchange", (PyCFunction)Solver_get_allow_archchange, METH_NOARGS, NULL}, {"set_allow_archchange", (PyCFunction)Solver_set_allow_archchange, METH_VARARGS, NULL}, {"get_allow_vendorchange", (PyCFunction)Solver_get_allow_vendorchange, METH_NOARGS, NULL}, @@ -307,4 +309,12 @@ void init_pakfire(void) { PyDict_SetItemString(d, "SOLVER_RULE_FEATURE", Py_BuildValue("i", SOLVER_RULE_FEATURE)); PyDict_SetItemString(d, "SOLVER_RULE_LEARNT", Py_BuildValue("i", SOLVER_RULE_LEARNT)); PyDict_SetItemString(d, "SOLVER_RULE_CHOICE", Py_BuildValue("i", SOLVER_RULE_CHOICE)); + + /* Solver flags */ + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_DOWNGRADE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_DOWNGRADE)); + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_ARCHCHANGE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_ARCHCHANGE)); + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_VENDORCHANGE", Py_BuildValue("i", SOLVER_FLAG_ALLOW_VENDORCHANGE)); + PyDict_SetItemString(d, "SOLVER_FLAG_ALLOW_UNINSTALL", Py_BuildValue("i", SOLVER_FLAG_ALLOW_UNINSTALL)); + PyDict_SetItemString(d, "SOLVER_FLAG_NO_UPDATEPROVIDE", Py_BuildValue("i", SOLVER_FLAG_NO_UPDATEPROVIDE)); + PyDict_SetItemString(d, "SOLVER_FLAG_SPLITPROVIDES", Py_BuildValue("i", SOLVER_FLAG_SPLITPROVIDES)); } diff --git a/python/src/repo.c b/python/src/repo.c index 6621c3bff..4bc112ad8 100644 --- a/python/src/repo.c +++ b/python/src/repo.c @@ -47,7 +47,6 @@ PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { const char *name; if (!PyArg_ParseTuple(args, "Os", &pool, &name)) { - /* XXX raise exception */ return NULL; } @@ -67,7 +66,6 @@ PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { } PyObject *Repo_dealloc(RepoObject *self) { - // repo_free(self->_repo, 0); self->ob_type->tp_free((PyObject *)self); Py_RETURN_NONE; @@ -97,7 +95,6 @@ PyObject *Repo_set_enabled(RepoObject *self, PyObject *args) { bool enabled; if (!PyArg_ParseTuple(args, "b", &enabled)) { - /* XXX raise exception */ return NULL; } @@ -132,13 +129,12 @@ PyObject *Repo_write(RepoObject *self, PyObject *args) { char exception[STRING_SIZE]; if (!PyArg_ParseTuple(args, "s", &filename)) { - /* XXX raise exception */ + return NULL; } // Prepare the pool and internalize all attributes. - _Pool_prepare(self->_repo->pool); + //_Pool_prepare(self->_repo->pool); - // XXX catch if file cannot be opened FILE *fp = NULL; if ((fp = fopen(filename, "wb")) == NULL) { snprintf(exception, STRING_SIZE - 1, "Could not open file for writing: %s (%s).", @@ -147,8 +143,7 @@ PyObject *Repo_write(RepoObject *self, PyObject *args) { return NULL; } - repo_write(self->_repo, fp, NULL, NULL, 0); - + repo_write(self->_repo, fp); fclose(fp); Py_RETURN_NONE; @@ -158,14 +153,12 @@ PyObject *Repo_read(RepoObject *self, PyObject *args) { const char *filename; if (!PyArg_ParseTuple(args, "s", &filename)) { - /* XXX raise exception */ + return NULL; } // XXX catch if file cannot be opened FILE *fp = fopen(filename, "rb"); - - repo_add_solv(self->_repo, fp); - + repo_add_solv(self->_repo, fp, 0); fclose(fp); Py_RETURN_NONE; @@ -209,3 +202,17 @@ PyObject *Repo_get_all(RepoObject *self) { return list; } + +PyObject *Repo_rem_solv(RepoObject *self, PyObject *args) { + Repo *repo = self->_repo; + SolvableObject *solv; + + if (!PyArg_ParseTuple(args, "O", &solv)) { + return NULL; + } + + Solvable *s = pool_id2solvable(repo->pool, solv->_id); + repo_free_solvable(repo, s - repo->pool->solvables, 1); + + Py_RETURN_NONE; +} diff --git a/python/src/repo.h b/python/src/repo.h index 9de636f57..3ef96df0e 100644 --- a/python/src/repo.h +++ b/python/src/repo.h @@ -44,6 +44,7 @@ extern PyObject *Repo_read(RepoObject *self, PyObject *args); extern PyObject *Repo_internalize(RepoObject *self); extern PyObject *Repo_clear(RepoObject *self); extern PyObject *Repo_get_all(RepoObject *self); +extern PyObject *Repo_rem_solv(RepoObject *self, PyObject *args); extern PyTypeObject RepoType; diff --git a/python/src/request.c b/python/src/request.c index 168b455a0..7d7c5b200 100644 --- a/python/src/request.c +++ b/python/src/request.c @@ -64,29 +64,25 @@ PyObject *Request_dealloc(RequestObject *self) { } void _Request_solvable(RequestObject *self, Id what, Id solvable) { - queue_push(&self->_queue, what|SOLVER_SOLVABLE); - queue_push(&self->_queue, solvable); + queue_push2(&self->_queue, what|SOLVER_SOLVABLE, solvable); } void _Request_relation(RequestObject *self, Id what, Id relation) { - queue_push(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES); - queue_push(&self->_queue, relation); + queue_push2(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES, relation); } void _Request_name(RequestObject *self, Id what, Id provides) { - queue_push(&self->_queue, what|SOLVER_SOLVABLE_NAME); - queue_push(&self->_queue, provides); + queue_push2(&self->_queue, what|SOLVER_SOLVABLE_NAME, provides); } PyObject *Request_install_solvable(RequestObject *self, PyObject *args) { SolvableObject *solv; if (!PyArg_ParseTuple(args, "O", &solv)) { - /* XXX raise exception */ + return NULL; } _Request_solvable(self, SOLVER_INSTALL, solv->_id); - Py_RETURN_NONE; } @@ -94,11 +90,10 @@ PyObject *Request_install_relation(RequestObject *self, PyObject *args) { RelationObject *rel; if (!PyArg_ParseTuple(args, "O", &rel)) { - /* XXX raise exception */ + return NULL; } _Request_relation(self, SOLVER_INSTALL, rel->_id); - Py_RETURN_NONE; } @@ -106,7 +101,7 @@ PyObject *Request_install_name(RequestObject *self, PyObject *args) { const char *name; if (!PyArg_ParseTuple(args, "s", &name)) { - /* XXX raise exception */ + return NULL; } Id _name = pool_str2id(self->_pool, name, 1); @@ -119,11 +114,10 @@ PyObject *Request_remove_solvable(RequestObject *self, PyObject *args) { SolvableObject *solv; if (!PyArg_ParseTuple(args, "O", &solv)) { - /* XXX raise exception */ + return NULL; } _Request_solvable(self, SOLVER_ERASE, solv->_id); - Py_RETURN_NONE; } @@ -131,11 +125,10 @@ PyObject *Request_remove_relation(RequestObject *self, PyObject *args) { RelationObject *rel; if (!PyArg_ParseTuple(args, "O", &rel)) { - /* XXX raise exception */ + return NULL; } _Request_relation(self, SOLVER_ERASE, rel->_id); - Py_RETURN_NONE; } @@ -143,7 +136,7 @@ PyObject *Request_remove_name(RequestObject *self, PyObject *args) { const char *name; if (!PyArg_ParseTuple(args, "s", &name)) { - /* XXX raise exception */ + return NULL; } Id _name = pool_str2id(self->_pool, name, 1); @@ -156,11 +149,10 @@ PyObject *Request_update_solvable(RequestObject *self, PyObject *args) { SolvableObject *solv; if (!PyArg_ParseTuple(args, "O", &solv)) { - /* XXX raise exception */ + return NULL; } _Request_solvable(self, SOLVER_UPDATE, solv->_id); - Py_RETURN_NONE; } @@ -168,11 +160,10 @@ PyObject *Request_update_relation(RequestObject *self, PyObject *args) { RelationObject *rel; if (!PyArg_ParseTuple(args, "O", &rel)) { - /* XXX raise exception */ + return NULL; } _Request_relation(self, SOLVER_UPDATE, rel->_id); - Py_RETURN_NONE; } @@ -180,7 +171,7 @@ PyObject *Request_update_name(RequestObject *self, PyObject *args) { const char *name; if (!PyArg_ParseTuple(args, "s", &name)) { - /* XXX raise exception */ + return NULL; } Id _name = pool_str2id(self->_pool, name, 1); @@ -193,11 +184,10 @@ PyObject *Request_lock_solvable(RequestObject *self, PyObject *args) { SolvableObject *solv; if (!PyArg_ParseTuple(args, "O", &solv)) { - /* XXX raise exception */ + return NULL; } _Request_solvable(self, SOLVER_LOCK, solv->_id); - Py_RETURN_NONE; } @@ -205,11 +195,10 @@ PyObject *Request_lock_relation(RequestObject *self, PyObject *args) { RelationObject *rel; if (!PyArg_ParseTuple(args, "O", &rel)) { - /* XXX raise exception */ + return NULL; } _Request_relation(self, SOLVER_LOCK, rel->_id); - Py_RETURN_NONE; } @@ -217,7 +206,7 @@ PyObject *Request_lock_name(RequestObject *self, PyObject *args) { const char *name; if (!PyArg_ParseTuple(args, "s", &name)) { - /* XXX raise exception */ + return NULL; } Id _name = pool_str2id(self->_pool, name, 1); @@ -230,11 +219,10 @@ PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *args) { SolvableObject *solv; if (!PyArg_ParseTuple(args, "O", &solv)) { - /* XXX raise exception */ + return NULL; } _Request_solvable(self, SOLVER_NOOBSOLETES, solv->_id); - Py_RETURN_NONE; } @@ -242,11 +230,10 @@ PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args) { RelationObject *rel; if (!PyArg_ParseTuple(args, "O", &rel)) { - /* XXX raise exception */ + return NULL; } _Request_relation(self, SOLVER_NOOBSOLETES, rel->_id); - Py_RETURN_NONE; } @@ -254,7 +241,7 @@ PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) { const char *name; if (!PyArg_ParseTuple(args, "s", &name)) { - /* XXX raise exception */ + return NULL; } Id _name = pool_str2id(self->_pool, name, 1); @@ -262,3 +249,18 @@ PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) { Py_RETURN_NONE; } + +PyObject *Request_updateall(RequestObject *self, PyObject *args) { + queue_push2(&self->_queue, SOLVER_UPDATE|SOLVER_SOLVABLE_ALL, 0); + Py_RETURN_NONE; +} + +PyObject *Request_distupgrade(RequestObject *self, PyObject *args) { + queue_push2(&self->_queue, SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL, 0); + Py_RETURN_NONE; +} + +PyObject *Request_verify(RequestObject *self, PyObject *args) { + queue_push2(&self->_queue, SOLVER_VERIFY|SOLVER_SOLVABLE_ALL, 0); + Py_RETURN_NONE; +} diff --git a/python/src/request.h b/python/src/request.h index b9368015d..aa7927433 100644 --- a/python/src/request.h +++ b/python/src/request.h @@ -59,6 +59,10 @@ extern PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *arg extern PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args); extern PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args); +extern PyObject *Request_updateall(RequestObject *self, PyObject *args); +extern PyObject *Request_distupgrade(RequestObject *self, PyObject *args); +extern PyObject *Request_verify(RequestObject *self, PyObject *args); + extern PyTypeObject RequestType; #endif diff --git a/python/src/solution.c b/python/src/solution.c index b52a1b595..7360a3781 100644 --- a/python/src/solution.c +++ b/python/src/solution.c @@ -82,7 +82,7 @@ PyObject *Solution_string(SolutionObject *self) { switch (how & SOLVER_JOBMASK) { case SOLVER_INSTALL: - if (select == SOLVER_SOLVABLE && solver->installed && pool->solvables[what].repo == solver->installed) + if (select == SOLVER_SOLVABLE && pool->installed && pool->solvables[what].repo == pool->installed) snprintf(str, STRING_SIZE - 1, _("do not keep %s installed"), pool_solvid2str(pool, what)); else if (select == SOLVER_SOLVABLE_PROVIDES) @@ -94,7 +94,7 @@ PyObject *Solution_string(SolutionObject *self) { break; case SOLVER_ERASE: - if (select == SOLVER_SOLVABLE && !(solver->installed && pool->solvables[what].repo == solver->installed)) + if (select == SOLVER_SOLVABLE && !(pool->installed && pool->solvables[what].repo == pool->installed)) snprintf(str, STRING_SIZE - 1, _("do not forbid installation of %s"), pool_solvid2str(pool, what)); else if (select == SOLVER_SOLVABLE_PROVIDES) @@ -122,7 +122,7 @@ PyObject *Solution_string(SolutionObject *self) { } else if (p == SOLVER_SOLUTION_INFARCH) { s = pool->solvables + rp; - if (solver->installed && s->repo == solver->installed) + if (pool->installed && s->repo == pool->installed) snprintf(str, STRING_SIZE - 1, _("keep %s despite the inferior architecture"), pool_solvable2str(pool, s)); else @@ -131,7 +131,7 @@ PyObject *Solution_string(SolutionObject *self) { } else if (p == SOLVER_SOLUTION_DISTUPGRADE) { s = pool->solvables + rp; - if (solver->installed && s->repo == solver->installed) + if (pool->installed && s->repo == pool->installed) snprintf(str, STRING_SIZE - 1, _("keep obsolete %s"), pool_solvable2str(pool, s)); else diff --git a/python/src/solver.c b/python/src/solver.c index 50795104c..54e12947d 100644 --- a/python/src/solver.c +++ b/python/src/solver.c @@ -53,6 +53,9 @@ PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { } } + /* enable splitprovides by default */ + solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, 1); + return (PyObject *)self; } @@ -63,138 +66,150 @@ PyObject *Solver_dealloc(SolverObject *self) { Py_RETURN_NONE; } -PyObject *Solver_get_fix_system(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->fixsystem); +PyObject *Solver_get_flag(SolverObject *self, PyObject *args) { + int flag = 0; + + if (!PyArg_ParseTuple(args, "i", &flag)) { + return NULL; + } + + int val = solver_get_flag(self->_solver, flag); + return Py_BuildValue("i", val); } -PyObject *Solver_set_fix_system(SolverObject *self, PyObject *args) { - int val; +PyObject *Solver_set_flag(SolverObject *self, PyObject *args) { + int flag = 0, val = 0; - if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + if (!PyArg_ParseTuple(args, "ii", &flag, &val)) { + return NULL; } - self->_solver->fixsystem = val; - + solver_set_flag(self->_solver, flag, val); Py_RETURN_NONE; } PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->allowdowngrade); + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE); + + return Py_BuildValue("i", val); } PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args) { int val; if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + return NULL; } - self->_solver->allowdowngrade = val; - + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE, val); Py_RETURN_NONE; } PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->allowarchchange); + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE); + + return Py_BuildValue("i", val); } PyObject *Solver_set_allow_archchange(SolverObject *self, PyObject *args) { int val; if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + return NULL; } - self->_solver->allowarchchange = val; - + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE, val); Py_RETURN_NONE; } PyObject *Solver_get_allow_vendorchange(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->allowvendorchange); + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE); + + return Py_BuildValue("i", val); } PyObject *Solver_set_allow_vendorchange(SolverObject *self, PyObject *args) { int val; if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + return NULL; } - self->_solver->allowvendorchange = val; - + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE, val); Py_RETURN_NONE; } PyObject *Solver_get_allow_uninstall(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->allowuninstall); + int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL); + + return Py_BuildValue("i", val); } PyObject *Solver_set_allow_uninstall(SolverObject *self, PyObject *args) { int val; if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + return NULL; } - self->_solver->allowuninstall = val; - + solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL, val); Py_RETURN_NONE; } PyObject *Solver_get_updatesystem(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->updatesystem); + //return Py_BuildValue("i", self->_solver->updatesystem); + Py_RETURN_NONE; } PyObject *Solver_set_updatesystem(SolverObject *self, PyObject *args) { - int val; + /*int val; if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + return NULL; } - self->_solver->updatesystem = val; + self->_solver->updatesystem = val; */ Py_RETURN_NONE; } PyObject *Solver_get_do_split_provides(SolverObject *self, PyObject *args) { - return Py_BuildValue("i", self->_solver->dosplitprovides); + int val = solver_get_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES); + + return Py_BuildValue("i", val); } PyObject *Solver_set_do_split_provides(SolverObject *self, PyObject *args) { int val; if (!PyArg_ParseTuple(args, "i", &val)) { - /* XXX raise exception */ + return NULL; } - self->_solver->dosplitprovides = val; - + solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, val); Py_RETURN_NONE; } PyObject *Solver_solve(SolverObject *self, PyObject *args) { RequestObject *request; + int res = 0; if (!PyArg_ParseTuple(args, "O", &request)) { - /* XXX raise exception */ + return NULL; } // Make sure, the pool is prepared. _Pool_prepare(self->_solver->pool); - solver_solve(self->_solver, &request->_queue); + res = solver_solve(self->_solver, &request->_queue); #ifdef DEBUG solver_printallsolutions(self->_solver); #endif - if (self->_solver->problems.count == 0) { + if (res == 0) { Py_RETURN_TRUE; } - Py_RETURN_FALSE; } @@ -202,7 +217,6 @@ PyObject *Solver_get_problems(SolverObject *self, PyObject *args) { RequestObject *request; if (!PyArg_ParseTuple(args, "O", &request)) { - /* XXX raise exception */ return NULL; } diff --git a/python/src/solver.h b/python/src/solver.h index 604cb83ad..8a4478b2d 100644 --- a/python/src/solver.h +++ b/python/src/solver.h @@ -34,8 +34,9 @@ typedef struct { extern PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds); extern PyObject *Solver_dealloc(SolverObject *self); -extern PyObject *Solver_get_fix_system(SolverObject *self, PyObject *args); -extern PyObject *Solver_set_fix_system(SolverObject *self, PyObject *args); +extern PyObject *Solver_get_flag(SolverObject *self, PyObject *args); +extern PyObject *Solver_set_flag(SolverObject *self, PyObject *args); + extern PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args); extern PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args); extern PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args); -- 2.39.5