From 6a509182b36799776de93a57f23dc74e1e81c57e Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 6 Aug 2011 15:49:50 +0200 Subject: [PATCH] Add support for --offline mode. --- pakfire/base.py | 14 +++- pakfire/cli.py | 12 +++ pakfire/config.py | 9 ++ pakfire/downloader.py | 4 + pakfire/errors.py | 5 ++ pakfire/repository/index.py | 45 ++++++---- pakfire/repository/remote.py | 6 ++ po/pakfire.pot | 155 ++++++++++++++++++++++------------- 8 files changed, 175 insertions(+), 75 deletions(-) diff --git a/pakfire/base.py b/pakfire/base.py index f0f609b4e..eb8d315b6 100644 --- a/pakfire/base.py +++ b/pakfire/base.py @@ -28,10 +28,10 @@ class Pakfire(object): def __init__(self, mode=None, path="/", configs=[], enable_repos=None, disable_repos=None, - distro_config=None): + distro_config=None, **kwargs): # Set the mode. - assert mode in ("normal", "builder", "repo", "server", "master") + assert mode in ("normal", "builder", "server",) self.mode = mode # Check if we are operating as the root user. @@ -53,6 +53,9 @@ class Pakfire(object): self.config = config.Config(type=mode) for filename in configs: self.config.read(filename) + # Assume, that all other keyword arguments are configuration + # parameters. + self.config.update(kwargs) # Setup the logger logger.setup_logging(self.config) @@ -105,6 +108,13 @@ class Pakfire(object): def supported_arches(self): return self.config.supported_arches + @property + def offline(self): + """ + A shortcut that indicates if the system is running in offline mode. + """ + return self.config.get("offline", False) + def check_root_user(self): if not os.getuid() == 0 or not os.getgid() == 0: raise Exception, "You must run pakfire as the root user." diff --git a/pakfire/cli.py b/pakfire/cli.py index 8a7333b77..774b2f569 100644 --- a/pakfire/cli.py +++ b/pakfire/cli.py @@ -76,6 +76,9 @@ class Cli(object): if hasattr(self.args, "enable_repo"): ret["enable_repos"] = self.args.enable_repo + if hasattr(self.args, "offline"): + ret["offline"] = self.args.offline + return ret def parse_common_arguments(self): @@ -91,6 +94,9 @@ class Cli(object): self.parser.add_argument("--enabled-repo", nargs="*", metavar="REPO", help=_("Enable a repository temporarily.")) + self.parser.add_argument("--offline", action="store_true", + help=_("Run pakfire in offline mode.")) + def parse_command_install(self): # Implement the "install" command. sub_install = self.sub_commands.add_parser("install", @@ -312,6 +318,9 @@ class CliBuilder(Cli): if hasattr(self.args, "enable_repo"): ret["enable_repos"] = self.args.enable_repo + if hasattr(self.args, "offline"): + ret["offline"] = self.args.offline + return ret def parse_command_update(self): @@ -458,6 +467,9 @@ class CliServer(Cli): def pakfire_args(self): ret = { "mode" : "server" } + if hasattr(self.args, "offline"): + ret["offline"] = self.args.offline + return ret def parse_command_build(self): diff --git a/pakfire/config.py b/pakfire/config.py index e0f884977..74280d856 100644 --- a/pakfire/config.py +++ b/pakfire/config.py @@ -96,8 +96,17 @@ class Config(object): return self._config.get(key, default) def set(self, key, val): + logging.debug("Updating configuration parameter: %s = %s" % (key, val)) self._config[key] = val + def update(self, values): + """ + This function takes a dictionary which configuration + parameters and applies them to the configuration. + """ + for key, val in values.items(): + self.set(key, val) + def get_repos(self): return self._config_repos.items() diff --git a/pakfire/downloader.py b/pakfire/downloader.py index b57f0978d..3401c6b86 100644 --- a/pakfire/downloader.py +++ b/pakfire/downloader.py @@ -27,6 +27,10 @@ class PakfireGrabber(URLGrabber): else: config = pakfire.config + if config.get("offline"): + raise + raise OfflineModeError, "Cannot use %s in offline mode." % self.__class__.__name__ + # Set throttle setting. bandwidth_throttle = config.get("bandwidth_throttle") if bandwidth_throttle: diff --git a/pakfire/errors.py b/pakfire/errors.py index 183e8e0ee..3c5b9fe16 100644 --- a/pakfire/errors.py +++ b/pakfire/errors.py @@ -40,6 +40,11 @@ class FileNotFoundError(Error): class NotAnIPFireSystemError(Error): pass +class OfflineModeError(Error): + message = _("The requested action cannot be done on offline mode.\n" + "Please connect your system to the network, remove --offline from the" + " command line and try again.") + class PakfireError(Error): pass diff --git a/pakfire/repository/index.py b/pakfire/repository/index.py index cccf339ad..0155a18b9 100644 --- a/pakfire/repository/index.py +++ b/pakfire/repository/index.py @@ -196,26 +196,39 @@ class IndexSolv(Index): old_metadata = metadata.Metadata(self.pakfire, self, self.cache.abspath(filename)) + # If no metadata was downloaded and we are in offline mode. + elif self.pakfire.offline: + raise OfflineModeError, _("There is no metadata for the repository '%s' and" + " we cannot download any because we are running in offline mode." + " Connect to a network or disable this repository.") % self.repo.name + + elif force and self.pakfire.offline: + raise OfflineModeError, _("I cannot be forced to re-download the metadata for" + " the repository '%s' when running in offline mode.") % self.repo.name + if download: - logging.debug("Going to (re-)download the repository metadata.") + # We are supposed to download new metadata, but we are running in + # offline mode. That's okay. Just doing nothing. + if not self.pakfire.offline: + logging.debug("Going to (re-)download the repository metadata.") - # Initialize a grabber for download. - grabber = downloader.MetadataDownloader(self.pakfire) - grabber = self.repo.mirrors.group(grabber) + # Initialize a grabber for download. + grabber = downloader.MetadataDownloader(self.pakfire) + grabber = self.repo.mirrors.group(grabber) - data = grabber.urlread(filename, limit=METADATA_DOWNLOAD_LIMIT) + data = grabber.urlread(filename, limit=METADATA_DOWNLOAD_LIMIT) - # Parse new metadata for comparison. - new_metadata = metadata.Metadata(self.pakfire, self, metadata=data) + # Parse new metadata for comparison. + new_metadata = metadata.Metadata(self.pakfire, self, metadata=data) - if old_metadata and new_metadata < old_metadata: - logging.warning("The downloaded metadata was less recent than the current one. Trashing that.") + if old_metadata and new_metadata < old_metadata: + logging.warning("The downloaded metadata was less recent than the current one. Trashing that.") - else: - # We explicitely rewrite the metadata if it is equal to have - # a new timestamp and do not download it over and over again. - with self.cache.open(filename, "w") as o: - o.write(data) + else: + # We explicitely rewrite the metadata if it is equal to have + # a new timestamp and do not download it over and over again. + with self.cache.open(filename, "w") as o: + o.write(data) # Parse the metadata that we just downloaded or load it from cache. self.metadata = metadata.Metadata(self.pakfire, self, @@ -226,6 +239,10 @@ class IndexSolv(Index): filename = os.path.join(METADATA_DOWNLOAD_PATH, self.metadata.database) if not self.cache.exists(filename): + if self.pakfire.offline: + raise OfflineModeError, _("Your repository metadata is outdated " + " and a new version needs to be downloaded.") + # Initialize a grabber for download. grabber = downloader.DatabaseDownloader( self.pakfire, diff --git a/pakfire/repository/remote.py b/pakfire/repository/remote.py index 09fd7c5af..a00293eb1 100644 --- a/pakfire/repository/remote.py +++ b/pakfire/repository/remote.py @@ -9,6 +9,7 @@ import index import pakfire.downloader as downloader from pakfire.constants import * +from pakfire.i18n import _ class RepositorySolv(base.RepositoryFactory): def __init__(self, pakfire, name, description, url, mirrorlist, gpgkey, enabled=True): @@ -81,6 +82,11 @@ class RepositorySolv(base.RepositoryFactory): if download: logging.debug("Going to download %s" % filename) + # If we are in offline mode, we cannot download any files. + if self.pakfire.offline and not self.url.startswith("file://"): + raise OfflineModeError, _("Cannot download this file in offline mode: %s") \ + % filename + # Make sure filename is of type string (and not unicode) filename = str(filename) diff --git a/po/pakfire.pot b/po/pakfire.pot index bc0aa6744..9925c7dc7 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: 2011-08-06 14:14+0200\n" +"POT-Creation-Date: 2011-08-06 15:48+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -38,16 +38,16 @@ msgstr "" msgid "Downgrading" msgstr "" -#: ../pakfire/base.py:157 ../pakfire/base.py:199 ../pakfire/base.py:230 -#: ../pakfire/base.py:252 +#: ../pakfire/base.py:167 ../pakfire/base.py:209 ../pakfire/base.py:240 +#: ../pakfire/base.py:262 msgid "Nothing to do" msgstr "" -#: ../pakfire/base.py:185 +#: ../pakfire/base.py:195 msgid "There are no packages to install." msgstr "" -#: ../pakfire/base.py:448 +#: ../pakfire/base.py:458 msgid "Everything is fine." msgstr "" @@ -64,207 +64,211 @@ msgstr "" msgid "The path where pakfire should operate in." msgstr "" -#: ../pakfire/cli.py:83 +#: ../pakfire/cli.py:86 msgid "Enable verbose output." msgstr "" -#: ../pakfire/cli.py:86 +#: ../pakfire/cli.py:89 msgid "Path to a configuration file to load." msgstr "" -#: ../pakfire/cli.py:89 +#: ../pakfire/cli.py:92 msgid "Disable a repository temporarily." msgstr "" -#: ../pakfire/cli.py:92 +#: ../pakfire/cli.py:95 msgid "Enable a repository temporarily." msgstr "" -#: ../pakfire/cli.py:97 +#: ../pakfire/cli.py:98 +msgid "Run pakfire in offline mode." +msgstr "" + +#: ../pakfire/cli.py:103 msgid "Install one or more packages to the system." msgstr "" -#: ../pakfire/cli.py:99 +#: ../pakfire/cli.py:105 msgid "Give name of at least one package to install." msgstr "" -#: ../pakfire/cli.py:105 +#: ../pakfire/cli.py:111 msgid "Install one or more packages from the filesystem." msgstr "" -#: ../pakfire/cli.py:107 +#: ../pakfire/cli.py:113 msgid "Give filename of at least one package." msgstr "" -#: ../pakfire/cli.py:113 +#: ../pakfire/cli.py:119 msgid "Remove one or more packages from the system." msgstr "" -#: ../pakfire/cli.py:115 +#: ../pakfire/cli.py:121 msgid "Give name of at least one package to remove." msgstr "" -#: ../pakfire/cli.py:121 +#: ../pakfire/cli.py:127 msgid "Update the whole system or one specific package." msgstr "" -#: ../pakfire/cli.py:123 +#: ../pakfire/cli.py:129 msgid "Give a name of a package to update or leave emtpy for all." msgstr "" -#: ../pakfire/cli.py:129 +#: ../pakfire/cli.py:135 msgid "Print some information about the given package(s)." msgstr "" -#: ../pakfire/cli.py:131 +#: ../pakfire/cli.py:137 msgid "Give at least the name of one package." msgstr "" -#: ../pakfire/cli.py:137 +#: ../pakfire/cli.py:143 msgid "Search for a given pattern." msgstr "" -#: ../pakfire/cli.py:139 +#: ../pakfire/cli.py:145 msgid "A pattern to search for." msgstr "" -#: ../pakfire/cli.py:145 +#: ../pakfire/cli.py:151 msgid "Get a list of packages that provide a given file or feature." msgstr "" -#: ../pakfire/cli.py:147 +#: ../pakfire/cli.py:153 msgid "File or feature to search for." msgstr "" -#: ../pakfire/cli.py:153 +#: ../pakfire/cli.py:159 msgid "Get list of packages that belong to the given group." msgstr "" -#: ../pakfire/cli.py:155 +#: ../pakfire/cli.py:161 msgid "Group name to search for." msgstr "" -#: ../pakfire/cli.py:161 +#: ../pakfire/cli.py:167 msgid "Install all packages that belong to the given group." msgstr "" -#: ../pakfire/cli.py:163 +#: ../pakfire/cli.py:169 msgid "Group name." msgstr "" -#: ../pakfire/cli.py:169 +#: ../pakfire/cli.py:175 msgid "List all currently enabled repositories." msgstr "" -#: ../pakfire/cli.py:173 +#: ../pakfire/cli.py:179 msgid "Cleanup commands." msgstr "" -#: ../pakfire/cli.py:181 +#: ../pakfire/cli.py:187 msgid "Cleanup all temporary files." msgstr "" -#: ../pakfire/cli.py:187 +#: ../pakfire/cli.py:193 msgid "Check the system for any errors." msgstr "" -#: ../pakfire/cli.py:247 ../pakfire/transaction.py:175 +#: ../pakfire/cli.py:253 ../pakfire/transaction.py:175 msgid "Repository" msgstr "" -#: ../pakfire/cli.py:247 +#: ../pakfire/cli.py:253 msgid "Enabled" msgstr "" -#: ../pakfire/cli.py:247 +#: ../pakfire/cli.py:253 msgid "Priority" msgstr "" -#: ../pakfire/cli.py:247 +#: ../pakfire/cli.py:253 msgid "Packages" msgstr "" -#: ../pakfire/cli.py:259 +#: ../pakfire/cli.py:265 msgid "Cleaning up everything..." msgstr "" -#: ../pakfire/cli.py:270 +#: ../pakfire/cli.py:276 msgid "Pakfire builder command line interface." msgstr "" -#: ../pakfire/cli.py:320 +#: ../pakfire/cli.py:329 msgid "Update the package indexes." msgstr "" -#: ../pakfire/cli.py:326 +#: ../pakfire/cli.py:335 msgid "Build one or more packages." msgstr "" -#: ../pakfire/cli.py:328 +#: ../pakfire/cli.py:337 msgid "Give name of at least one package to build." msgstr "" -#: ../pakfire/cli.py:332 +#: ../pakfire/cli.py:341 msgid "Build the package for the given architecture." msgstr "" -#: ../pakfire/cli.py:334 ../pakfire/cli.py:360 +#: ../pakfire/cli.py:343 ../pakfire/cli.py:369 msgid "Path were the output files should be copied to." msgstr "" -#: ../pakfire/cli.py:336 ../pakfire/cli.py:349 +#: ../pakfire/cli.py:345 ../pakfire/cli.py:358 msgid "Mode to run in. Is either 'release' or 'development' (default)." msgstr "" -#: ../pakfire/cli.py:341 +#: ../pakfire/cli.py:350 msgid "Go into a shell." msgstr "" -#: ../pakfire/cli.py:343 +#: ../pakfire/cli.py:352 msgid "Give name of a package." msgstr "" -#: ../pakfire/cli.py:347 +#: ../pakfire/cli.py:356 msgid "Emulated architecture in the shell." msgstr "" -#: ../pakfire/cli.py:354 +#: ../pakfire/cli.py:363 msgid "Generate a source package." msgstr "" -#: ../pakfire/cli.py:356 +#: ../pakfire/cli.py:365 msgid "Give name(s) of a package(s)." msgstr "" -#: ../pakfire/cli.py:432 +#: ../pakfire/cli.py:441 msgid "Pakfire server command line interface." msgstr "" -#: ../pakfire/cli.py:466 +#: ../pakfire/cli.py:478 msgid "Request a build job from the server." msgstr "" -#: ../pakfire/cli.py:472 +#: ../pakfire/cli.py:484 msgid "Send a keepalive to the server." msgstr "" -#: ../pakfire/cli.py:479 +#: ../pakfire/cli.py:491 msgid "Update all repositories." msgstr "" -#: ../pakfire/cli.py:485 +#: ../pakfire/cli.py:497 msgid "Repository management commands." msgstr "" -#: ../pakfire/cli.py:493 +#: ../pakfire/cli.py:505 msgid "Create a new repository index." msgstr "" -#: ../pakfire/cli.py:494 +#: ../pakfire/cli.py:506 msgid "Path to the packages." msgstr "" -#: ../pakfire/cli.py:495 +#: ../pakfire/cli.py:507 msgid "Path to input packages." msgstr "" @@ -276,6 +280,13 @@ msgstr "" msgid "One or more dependencies could not been resolved." msgstr "" +#: ../pakfire/errors.py:44 +msgid "" +"The requested action cannot be done on offline mode.\n" +"Please connect your system to the network, remove --offline from the command " +"line and try again." +msgstr "" + #: ../pakfire/packages/base.py:70 msgid "Name" msgstr "" @@ -344,22 +355,48 @@ msgstr "" msgid "Requires" msgstr "" -#: ../pakfire/repository/index.py:232 +#: ../pakfire/repository/index.py:201 +#, python-format +msgid "" +"There is no metadata for the repository '%s' and we cannot download any " +"because we are running in offline mode. Connect to a network or disable this " +"repository." +msgstr "" + +#: ../pakfire/repository/index.py:206 +#, python-format +msgid "" +"I cannot be forced to re-download the metadata for the repository '%s' when " +"running in offline mode." +msgstr "" + +#: ../pakfire/repository/index.py:243 +msgid "" +"Your repository metadata is outdated and a new version needs to be " +"downloaded." +msgstr "" + +#: ../pakfire/repository/index.py:249 #, python-format msgid "%s: package database" msgstr "" #. Create progress bar. -#: ../pakfire/repository/index.py:320 +#: ../pakfire/repository/index.py:337 #, python-format msgid "Loading from %s" msgstr "" #. Add all packages from the database to the index. -#: ../pakfire/repository/index.py:373 +#: ../pakfire/repository/index.py:390 msgid "Loading installed packages" msgstr "" +#: ../pakfire/repository/remote.py:87 +#, python-format +msgid "Cannot download this file in offline mode: %s" +msgstr "" + #: ../pakfire/satsolver.py:129 msgid "The solver returned one problem:" msgstr "" -- 2.39.5