[Yum-devel] [PATCH 1/8] Add a metadata_expire_filter configuration, and use it in the shipped commands.
James Antill
james at and.org
Wed Jan 16 07:25:59 UTC 2013
In theory this is never needed because everyone always runs yum-cron
and repos. are always upto date. In practise everyone complains because
yum hits the network due to that not being the case. This allows the
user to control a lot better how much out of data info. they don't mind
having for simple "yum search" type commands etc.
Not sure how useful the past/present distinction is, but it's easier to
ignore/remove it that to add it back in later.
---
cli.py | 6 +++
docs/yum.conf.5 | 30 +++++++++++++
yum/config.py | 5 ++
yum/yumRepo.py | 23 +++++++++-
yumcommands.py | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/cli.py b/cli.py
index 9225d5a..01b21e6 100755
--- a/cli.py
+++ b/cli.py
@@ -509,6 +509,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
except yum.Errors.YumBaseError, e:
return 1, [exception2msg(e)]
+ cacheReq = 'write'
+ if hasattr(cmd, 'cacheRequirement'):
+ cacheReq = cmd.cacheRequirement(self, self.basecmd, self.extcmds)
+ for repo in self.repos.listEnabled():
+ repo._metadata_cache_req = cacheReq
+
return self.yum_cli_commands[self.basecmd].doCommand(self, self.basecmd, self.extcmds)
def doTransaction(self):
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 029fa75..30ac844 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -499,6 +499,31 @@ It's also possible to use the word "never", meaning that the metadata will
never expire. Note that when using a metalink file the metalink must always
be newer than the metadata for the repository, due to the validation, so this
timeout also applies to the metalink file.
+Also note that "never" does not override "yum clean expire-cache"
+
+.IP
+\fBmetadata_expire_filter \fR
+Filter the metadata_expire time, allowing a trade of speed for accuracy if
+a command doesn't require it. Each yum command can specify that it requires a
+certain level of timeliness quality from the remote repos. from "I'm about to
+install/upgrade, so this better be current" to "Anything that's available
+is good enough".
+
+'never' - Nothing is filtered, always obey metadata_expire.
+
+'read-only:past' - Commands that only care about past information
+are filtered from metadata expiring.
+Eg. yum history info (if history needs to lookup anything about a previous
+transaction, then by definition the remote package was available in the past).
+
+'read-only:present' - Commands that are balanced between past and future.
+This is the default.
+Eg. yum list yum
+
+'read-only:future' - Commands that are likely to result in running other
+commands which will require the latest metadata. Eg. yum check-update
+
+Note that this option does not override "yum clean expire-cache".
.IP
\fBmirrorlist_expire \fR
@@ -911,6 +936,11 @@ Overrides the \fBmetadata_expire\fR option from the [main] section for this
repository.
.IP
+\fBmetadata_expire_filter \fR
+Overrides the \fBmetadata_expire_filter\fR option from the [main] section for
+this repository.
+
+.IP
\fBmirrorlist_expire \fR
Overrides the \fBmirrorlist_expire\fR option from the [main] section for this
repository.
diff --git a/yum/config.py b/yum/config.py
index 74be397..3cdb0fd 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -792,6 +792,10 @@ class YumConf(StartupConf):
http_caching = SelectionOption('all', ('none', 'packages', 'all'))
metadata_expire = SecondsOption(60 * 60 * 6) # Time in seconds (6h).
+ metadata_expire_filter = SelectionOption('read-only:present',
+ ('never', 'read-only:future',
+ 'read-only:present',
+ 'read-only:past'))
# Time in seconds (1 day). NOTE: This isn't used when using metalinks
mirrorlist_expire = SecondsOption(60 * 60 * 24)
# XXX rpm_check_debug is unused, left around for API compatibility for now
@@ -944,6 +948,7 @@ class RepoConf(BaseConfig):
http_caching = Inherit(YumConf.http_caching)
metadata_expire = Inherit(YumConf.metadata_expire)
+ metadata_expire_filter = Inherit(YumConf.metadata_expire_filter)
mirrorlist_expire = Inherit(YumConf.mirrorlist_expire)
# NOTE: metalink expire _must_ be the same as metadata_expire, due to the
# checksumming of the repomd.xml.
diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index 4f5f7a6..09b2534 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -1068,7 +1068,7 @@ Insufficient space in download directory %s
self._metadataCurrent = False
return self._metadataCurrent
- def withinCacheAge(self, myfile, expiration_time):
+ def withinCacheAge(self, myfile, expiration_time, expire_req_filter=True):
"""check if any file is older than a certain amount of time. Used for
the cachecookie and the mirrorlist
return True if w/i the expiration time limit
@@ -1078,6 +1078,24 @@ Insufficient space in download directory %s
file. If any of them are newer then invalidate the cache
"""
+ # Never/write means we just skip this...
+ if (expire_req_filter and hasattr(self, '_metadata_cache_req') and
+ self._metadata_cache_req.startswith("read-only:") and
+ self.metadata_expire_filter.startswith("read-only:")):
+
+ cache_filt = self.metadata_expire_filter[len("read-only:"):]
+ cache_req = self._metadata_cache_req[len("read-only:"):]
+
+ if cache_filt == 'future':
+ assert cache_req in ('past', 'present', 'future')
+ expiration_time = -1
+ if cache_filt == 'present':
+ if cache_req in ('past', 'present'):
+ expiration_time = -1
+ if cache_filt == 'past':
+ if cache_req == 'past':
+ expiration_time = -1
+
# -1 is special and should never get refreshed
if expiration_time == -1 and os.path.exists(myfile):
return True
@@ -1850,7 +1868,8 @@ Insufficient space in download directory %s
fo = None
cacheok = False
- if self.withinCacheAge(self.mirrorlist_file, self.mirrorlist_expire):
+ if self.withinCacheAge(self.mirrorlist_file, self.mirrorlist_expire,
+ expire_req_filter=False):
cacheok = True
fo = open(self.mirrorlist_file, 'r')
url = 'file://' + self.mirrorlist_file # just to keep self._readMirrorList(fo,url) happy
diff --git a/yumcommands.py b/yumcommands.py
index a2e0b1b..14a1375 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -280,7 +280,35 @@ class YumCommand:
:return: True if a transaction set is needed, False otherwise
"""
return True
+
+ # Some of this is subjective, esp. between past/present, but roughly use:
+ #
+ # write = I'm using package data to alter the rpmdb in anyway.
+ # read-only:future = I'm providing data that is likely to result in a
+ # future write, so we might as well do it now.
+ # Eg. yum check-update && yum update -q -y
+ # read-only:present = I'm providing data about the present state of
+ # packages in the repo.
+ # Eg. yum list yum
+ # read-only:past = I'm providing context data about past writes, or just
+ # anything that is available is good enough for me
+ # (speed is much better than quality).
+ # Eg. yum history info
+ # Eg. TAB completion
+ #
+ # ...default is write, which does the same thing we always did (obey
+ # metadata_expire and live with it).
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'write'
+
class InstallCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
install command.
@@ -648,6 +676,19 @@ class InfoCommand(YumCommand):
return True
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ if len(extcmds) and extcmds[0] in ('updates', 'obsoletes'):
+ return 'read-only:future'
+ return 'read-only:present'
+
+
class ListCommand(InfoCommand):
"""A class containing methods needed by the cli to execute the
list command.
@@ -1349,6 +1390,17 @@ class ProvidesCommand(YumCommand):
except yum.Errors.YumBaseError, e:
return 1, [exception2msg(e)]
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:past'
+
+
class CheckUpdateCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
check-update command.
@@ -1440,6 +1492,17 @@ class CheckUpdateCommand(YumCommand):
else:
return result, []
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:future'
+
+
class SearchCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
search command.
@@ -1508,6 +1571,17 @@ class SearchCommand(YumCommand):
"""
return False
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:present'
+
+
class UpgradeCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
upgrade command.
@@ -1698,6 +1772,17 @@ class ResolveDepCommand(YumCommand):
except yum.Errors.YumBaseError, e:
return 1, [exception2msg(e)]
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:past'
+
+
class ShellCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
shell command.
@@ -1825,6 +1910,16 @@ class DepListCommand(YumCommand):
except yum.Errors.YumBaseError, e:
return 1, [exception2msg(e)]
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:past' # read-only ?
+
class RepoListCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
@@ -2141,6 +2236,16 @@ class RepoListCommand(YumCommand):
"""
return False
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:past'
+
class HelpCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
@@ -2583,6 +2688,16 @@ class VersionCommand(YumCommand):
return True
return vcmd in ('available', 'all', 'group-available', 'group-all')
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ return 'read-only:present'
+
class HistoryCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
@@ -2821,6 +2936,21 @@ class HistoryCommand(YumCommand):
vcmd = extcmds[0]
return vcmd in ('repeat', 'redo', 'undo', 'rollback')
+ def cacheRequirement(self, base, basecmd, extcmds):
+ """Return the cache requirements for the remote repos.
+
+ :param base: a :class:`yum.Yumbase` object
+ :param basecmd: the name of the command
+ :param extcmds: a list of arguments passed to *basecmd*
+ :return: Type of requirement: read-only:past, read-only:present, read-only:future, write
+ """
+ vcmd = 'list'
+ if extcmds:
+ vcmd = extcmds[0]
+ if vcmd in ('repeat', 'redo', 'undo', 'rollback'):
+ return 'write'
+ return 'read-only:past'
+
class CheckRpmdbCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
--
1.7.6.5
More information about the Yum-devel
mailing list