|
|
b7ec20 |
commit 691faec2bed8457edd19b8ad5587768bfbe4c653
|
|
|
b7ec20 |
Author: Michal Domonkos <mdomonko@redhat.com>
|
|
|
b7ec20 |
Date: Mon May 28 16:49:10 2018 +0200
|
|
|
b7ec20 |
|
|
|
b7ec20 |
docs: fix versionlock
|
|
|
b7ec20 |
|
|
|
b7ec20 |
Fixes the formatting and clarifies the "exclude" subcommand (inspired
|
|
|
b7ec20 |
by: https://illiterat.livejournal.com/8221.html).
|
|
|
b7ec20 |
|
|
|
b7ec20 |
diff --git a/docs/yum-versionlock.1 b/docs/yum-versionlock.1
|
|
|
b7ec20 |
index f7cd467..e14bbd5 100644
|
|
|
b7ec20 |
--- a/docs/yum-versionlock.1
|
|
|
b7ec20 |
+++ b/docs/yum-versionlock.1
|
|
|
b7ec20 |
@@ -16,22 +16,17 @@ This allows you to protect packages from being updated by newer versions.
|
|
|
b7ec20 |
The plugin provides a command "versionlock" which allows you to view and edit
|
|
|
b7ec20 |
the list of locked packages easily.
|
|
|
b7ec20 |
.br
|
|
|
b7ec20 |
-.I \fR yum versionlock add <package-wildcard>...
|
|
|
b7ec20 |
-.PP
|
|
|
b7ec20 |
+.IP "\fByum versionlock add <package-wildcard>...\fR"
|
|
|
b7ec20 |
Add a versionlock for all of the packages in the rpmdb matching the given
|
|
|
b7ec20 |
wildcards.
|
|
|
b7ec20 |
-.I \fR yum versionlock exclude <package-wildcard>...
|
|
|
b7ec20 |
-.PP
|
|
|
b7ec20 |
-Add a exclude (within versionlock) for the latest versions of the
|
|
|
b7ec20 |
-packages in the available repos. matching the given wildcards.
|
|
|
b7ec20 |
-.I \fR yum versionlock list
|
|
|
b7ec20 |
-.PP
|
|
|
b7ec20 |
+.IP "\fByum versionlock exclude <package-wildcard>...\fR"
|
|
|
b7ec20 |
+Opposite; disallow currently available versions of the packages matching the
|
|
|
b7ec20 |
+given wildcards.
|
|
|
b7ec20 |
+.IP "\fByum versionlock list\fR"
|
|
|
b7ec20 |
List the current versionlock entries.
|
|
|
b7ec20 |
-.I \fR yum versionlock delete <entry-wildcard>...
|
|
|
b7ec20 |
-.PP
|
|
|
b7ec20 |
+.IP "\fByum versionlock delete <entry-wildcard>...\fR"
|
|
|
b7ec20 |
Remove any matching versionlock entries.
|
|
|
b7ec20 |
-.I \fR yum versionlock clear
|
|
|
b7ec20 |
-.PP
|
|
|
b7ec20 |
+.IP "\fByum versionlock clear\fR"
|
|
|
b7ec20 |
Remove all versionlock entries.
|
|
|
b7ec20 |
|
|
|
b7ec20 |
.SH FILES
|
|
|
b7ec20 |
commit f761392dc6209ec17e718291c2319ea011923880
|
|
|
b7ec20 |
Author: Michal Domonkos <mdomonko@redhat.com>
|
|
|
b7ec20 |
Date: Mon May 28 16:55:50 2018 +0200
|
|
|
b7ec20 |
|
|
|
b7ec20 |
versionlock: add hint and "status" subcommand. BZ 1497351
|
|
|
b7ec20 |
|
|
|
b7ec20 |
It is nice to be reminded of any versionlocks in effect when running yum
|
|
|
b7ec20 |
transactions (esp. when doing a "yum update" and wondering why no
|
|
|
b7ec20 |
updates were found). This commit adds the following message that is
|
|
|
b7ec20 |
printed in the excludes hook:
|
|
|
b7ec20 |
|
|
|
b7ec20 |
Excluding X updates due to versionlock (use "yum versionlock status"
|
|
|
b7ec20 |
to show them)
|
|
|
b7ec20 |
|
|
|
b7ec20 |
Since it would be too annoying to have all the excludes printed every
|
|
|
b7ec20 |
time, we only show their count (X) and provide the new "status"
|
|
|
b7ec20 |
subcommand that allows the user to list them if they are interested.
|
|
|
b7ec20 |
|
|
|
b7ec20 |
Note that even this short message might be annoying as it appears on
|
|
|
b7ec20 |
every yum run, so we're also adding an option to disable it.
|
|
|
b7ec20 |
|
|
|
b7ec20 |
diff --git a/docs/yum-versionlock.1 b/docs/yum-versionlock.1
|
|
|
b7ec20 |
index e14bbd5..6190fea 100644
|
|
|
b7ec20 |
--- a/docs/yum-versionlock.1
|
|
|
b7ec20 |
+++ b/docs/yum-versionlock.1
|
|
|
b7ec20 |
@@ -24,6 +24,10 @@ Opposite; disallow currently available versions of the packages matching the
|
|
|
b7ec20 |
given wildcards.
|
|
|
b7ec20 |
.IP "\fByum versionlock list\fR"
|
|
|
b7ec20 |
List the current versionlock entries.
|
|
|
b7ec20 |
+.IP "\fByum versionlock status\fR"
|
|
|
b7ec20 |
+List any available updates that are currently blocked by versionlock.
|
|
|
b7ec20 |
+That is, for each entry in the lock list, print the newest package available
|
|
|
b7ec20 |
+in the repos unless it is the particular locked/excluded version.
|
|
|
b7ec20 |
.IP "\fByum versionlock delete <entry-wildcard>...\fR"
|
|
|
b7ec20 |
Remove any matching versionlock entries.
|
|
|
b7ec20 |
.IP "\fByum versionlock clear\fR"
|
|
|
b7ec20 |
diff --git a/docs/yum-versionlock.conf.5 b/docs/yum-versionlock.conf.5
|
|
|
b7ec20 |
index 78a6e49..b5be24e 100644
|
|
|
b7ec20 |
--- a/docs/yum-versionlock.conf.5
|
|
|
b7ec20 |
+++ b/docs/yum-versionlock.conf.5
|
|
|
b7ec20 |
@@ -26,7 +26,7 @@ character to the version.
|
|
|
b7ec20 |
.B yum-versionlock.conf(5)
|
|
|
b7ec20 |
utilizes configuration options in the form of
|
|
|
b7ec20 |
.IP OPTION=VALUE
|
|
|
b7ec20 |
-.SH OPTION
|
|
|
b7ec20 |
+.SH OPTIONS
|
|
|
b7ec20 |
.IP follow_obsoletes
|
|
|
b7ec20 |
This option is a boolean flag which specifies if the versionlock plugin should
|
|
|
b7ec20 |
look at all the obsoletes, and see if any of the packages specified have an
|
|
|
b7ec20 |
@@ -36,13 +36,20 @@ excluded. This option is off by default, as
|
|
|
b7ec20 |
will take some time to do the obsoletes processing, and for non-rename
|
|
|
b7ec20 |
obsoletes any issues you had which kept you at a specific version of a package
|
|
|
b7ec20 |
should be different with another package.
|
|
|
b7ec20 |
-.SH OPTION
|
|
|
b7ec20 |
.IP locklist
|
|
|
b7ec20 |
This option is a string with points to the file which will have the versionlock
|
|
|
b7ec20 |
information in it. Note that the file
|
|
|
b7ec20 |
.B has
|
|
|
b7ec20 |
to exist (or the versionlock plugin will make yum exit). However it can be
|
|
|
b7ec20 |
empty.
|
|
|
b7ec20 |
+.IP show_hint
|
|
|
b7ec20 |
+This option is a boolean flag which specifies if the versionlock plugin should
|
|
|
b7ec20 |
+print a hint message whenever yum runs saying how many package updates
|
|
|
b7ec20 |
+available from the repos are being blocked due to versionlocks.
|
|
|
b7ec20 |
+This hint serves as a reminder that there are locks in effect and that you may
|
|
|
b7ec20 |
+want to reconsider them since newer versions of those packages have been
|
|
|
b7ec20 |
+released.
|
|
|
b7ec20 |
+Default is 1 (show the hint).
|
|
|
b7ec20 |
.SH AUTHOR
|
|
|
b7ec20 |
.RS
|
|
|
b7ec20 |
Chitlesh Goorah <chitlesh@fedoraproject.org>
|
|
|
b7ec20 |
diff --git a/plugins/versionlock/versionlock.conf b/plugins/versionlock/versionlock.conf
|
|
|
b7ec20 |
index 4e997da..42e05c9 100644
|
|
|
b7ec20 |
--- a/plugins/versionlock/versionlock.conf
|
|
|
b7ec20 |
+++ b/plugins/versionlock/versionlock.conf
|
|
|
b7ec20 |
@@ -1,5 +1,7 @@
|
|
|
b7ec20 |
[main]
|
|
|
b7ec20 |
enabled = 1
|
|
|
b7ec20 |
locklist = /etc/yum/pluginconf.d/versionlock.list
|
|
|
b7ec20 |
+# Show a hint when any locked packages have updates available
|
|
|
b7ec20 |
+show_hint = 1
|
|
|
b7ec20 |
# Uncomment this to lock out "upgrade via. obsoletes" etc. (slower)
|
|
|
b7ec20 |
# follow_obsoletes = 1
|
|
|
b7ec20 |
diff --git a/plugins/versionlock/versionlock.py b/plugins/versionlock/versionlock.py
|
|
|
b7ec20 |
index dfe4dd3..ad66855 100644
|
|
|
b7ec20 |
--- a/plugins/versionlock/versionlock.py
|
|
|
b7ec20 |
+++ b/plugins/versionlock/versionlock.py
|
|
|
b7ec20 |
@@ -42,6 +42,9 @@ _version_lock_excluder_B_nevr = set()
|
|
|
b7ec20 |
# _version_lock_excluder_pkgtup = set()
|
|
|
b7ec20 |
|
|
|
b7ec20 |
fileurl = None
|
|
|
b7ec20 |
+show_hint = True
|
|
|
b7ec20 |
+follow_obsoletes = False
|
|
|
b7ec20 |
+no_exclude = False
|
|
|
b7ec20 |
|
|
|
b7ec20 |
def _read_locklist():
|
|
|
b7ec20 |
locklist = []
|
|
|
b7ec20 |
@@ -73,6 +76,68 @@ def _match(ent, patterns):
|
|
|
b7ec20 |
return True
|
|
|
b7ec20 |
return False
|
|
|
b7ec20 |
|
|
|
b7ec20 |
+def _get_updates(base):
|
|
|
b7ec20 |
+ """Return packages that update or obsolete anything in our locklist.
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
+ Returns a dict of locked_name->X, where X is either a package object or a
|
|
|
b7ec20 |
+ list of them. If it's the former, it's the updating package. If it's the
|
|
|
b7ec20 |
+ latter, it's the obsoleting packages (since multiple packages may obsolete
|
|
|
b7ec20 |
+ the same name).
|
|
|
b7ec20 |
+ """
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
+ updates = {}
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
+ # Read in the locked versions
|
|
|
b7ec20 |
+ locks = {}
|
|
|
b7ec20 |
+ for ent in _read_locklist():
|
|
|
b7ec20 |
+ (n, v, r, e, a) = splitFilename(ent)
|
|
|
b7ec20 |
+ if e and e[0] == '!':
|
|
|
b7ec20 |
+ e = e[1:]
|
|
|
b7ec20 |
+ elif e == '':
|
|
|
b7ec20 |
+ e = '0'
|
|
|
b7ec20 |
+ locks.setdefault(n, []).append((e, v, r))
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
+ # Process regular updates
|
|
|
b7ec20 |
+ #
|
|
|
b7ec20 |
+ # We are using searchNames() + packagesNewestByName() here instead of just
|
|
|
b7ec20 |
+ # returnNewestByName() because the former way is much, much faster for big
|
|
|
b7ec20 |
+ # name lists.
|
|
|
b7ec20 |
+ #
|
|
|
b7ec20 |
+ # The problem with returnNewestByName() is that it may easily end up
|
|
|
b7ec20 |
+ # querying all the packages in pkgSack which is terribly slow (takes
|
|
|
b7ec20 |
+ # seconds); all it takes is a "-" in a package name and more than
|
|
|
b7ec20 |
+ # PATTERNS_MAX (8 by default) package names to trigger that.
|
|
|
b7ec20 |
+ #
|
|
|
b7ec20 |
+ # Since we know that we only ever deal with names, we can just go straight
|
|
|
b7ec20 |
+ # to searchNames() to avoid the full query.
|
|
|
b7ec20 |
+ pkgs = base.pkgSack.searchNames(locks.keys())
|
|
|
b7ec20 |
+ for p in packagesNewestByName(pkgs):
|
|
|
b7ec20 |
+ name = p.name
|
|
|
b7ec20 |
+ evr = p.returnEVR()
|
|
|
b7ec20 |
+ if (evr.epoch, evr.version, evr.release) in locks[name]:
|
|
|
b7ec20 |
+ # This one is either the locked or excluded version, skip
|
|
|
b7ec20 |
+ continue
|
|
|
b7ec20 |
+ updates[name] = p
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
+ # Process obsoletes
|
|
|
b7ec20 |
+ tups = base.up.getObsoletesTuples() if follow_obsoletes else []
|
|
|
b7ec20 |
+ for new, old in tups:
|
|
|
b7ec20 |
+ nname = new[0]
|
|
|
b7ec20 |
+ oname = old[0]
|
|
|
b7ec20 |
+ if oname not in locks:
|
|
|
b7ec20 |
+ # Not our package, skip
|
|
|
b7ec20 |
+ continue
|
|
|
b7ec20 |
+ if nname in locks and new[2:] in locks[nname]:
|
|
|
b7ec20 |
+ # This one is either the locked or excluded version, skip
|
|
|
b7ec20 |
+ continue
|
|
|
b7ec20 |
+ # Only record obsoletes for any given package name
|
|
|
b7ec20 |
+ if oname not in updates or not isinstance(updates[oname], list):
|
|
|
b7ec20 |
+ updates[oname] = []
|
|
|
b7ec20 |
+ p = base.getPackageObject(new)
|
|
|
b7ec20 |
+ updates[oname].append(p)
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
+ return updates
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
class VersionLockCommand:
|
|
|
b7ec20 |
created = 1247693044
|
|
|
b7ec20 |
|
|
|
b7ec20 |
@@ -80,7 +145,7 @@ class VersionLockCommand:
|
|
|
b7ec20 |
return ["versionlock"]
|
|
|
b7ec20 |
|
|
|
b7ec20 |
def getUsage(self):
|
|
|
b7ec20 |
- return '[add|exclude|list|delete|clear] [PACKAGE-wildcard]'
|
|
|
b7ec20 |
+ return '[add|exclude|list|status|delete|clear] [PACKAGE-wildcard]'
|
|
|
b7ec20 |
|
|
|
b7ec20 |
def getSummary(self):
|
|
|
b7ec20 |
return 'Control package version locks.'
|
|
|
b7ec20 |
@@ -93,7 +158,7 @@ class VersionLockCommand:
|
|
|
b7ec20 |
if extcmds:
|
|
|
b7ec20 |
if extcmds[0] not in ('add',
|
|
|
b7ec20 |
'exclude', 'add-!', 'add!', 'blacklist',
|
|
|
b7ec20 |
- 'list', 'del', 'delete', 'clear'):
|
|
|
b7ec20 |
+ 'list', 'status', 'del', 'delete', 'clear'):
|
|
|
b7ec20 |
cmd = 'add'
|
|
|
b7ec20 |
else:
|
|
|
b7ec20 |
cmd = {'del' : 'delete',
|
|
|
b7ec20 |
@@ -190,6 +255,19 @@ class VersionLockCommand:
|
|
|
b7ec20 |
os.rename(tmpfilename, filename)
|
|
|
b7ec20 |
return 0, ['versionlock deleted: ' + str(count)]
|
|
|
b7ec20 |
|
|
|
b7ec20 |
+ if cmd == 'status':
|
|
|
b7ec20 |
+ global no_exclude
|
|
|
b7ec20 |
+ no_exclude = True
|
|
|
b7ec20 |
+ updates = _get_updates(base)
|
|
|
b7ec20 |
+ for name, value in updates.iteritems():
|
|
|
b7ec20 |
+ if isinstance(value, list):
|
|
|
b7ec20 |
+ value = set(p.envr + '.*' for p in value)
|
|
|
b7ec20 |
+ for v in value:
|
|
|
b7ec20 |
+ print '%s (replacing %s)' % (v, name)
|
|
|
b7ec20 |
+ continue
|
|
|
b7ec20 |
+ print value.envr + '.*'
|
|
|
b7ec20 |
+ return 0, ['versionlock status done']
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
assert cmd == 'list'
|
|
|
b7ec20 |
for ent in _read_locklist():
|
|
|
b7ec20 |
print ent
|
|
|
b7ec20 |
@@ -201,8 +279,12 @@ class VersionLockCommand:
|
|
|
b7ec20 |
|
|
|
b7ec20 |
def config_hook(conduit):
|
|
|
b7ec20 |
global fileurl
|
|
|
b7ec20 |
+ global follow_obsoletes
|
|
|
b7ec20 |
+ global show_hint
|
|
|
b7ec20 |
|
|
|
b7ec20 |
fileurl = conduit.confString('main', 'locklist')
|
|
|
b7ec20 |
+ follow_obsoletes = conduit.confBool('main', 'follow_obsoletes', default=False)
|
|
|
b7ec20 |
+ show_hint = conduit.confBool('main', 'show_hint', default=True)
|
|
|
b7ec20 |
|
|
|
b7ec20 |
if hasattr(conduit._base, 'registerCommand'):
|
|
|
b7ec20 |
conduit.registerCommand(VersionLockCommand())
|
|
|
b7ec20 |
@@ -227,6 +309,9 @@ def _add_versionlock_blacklist(conduit):
|
|
|
b7ec20 |
ape(None, exid + str(3), 'exclude.marked')
|
|
|
b7ec20 |
|
|
|
b7ec20 |
def exclude_hook(conduit):
|
|
|
b7ec20 |
+ if no_exclude:
|
|
|
b7ec20 |
+ return
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
conduit.info(3, 'Reading version lock configuration')
|
|
|
b7ec20 |
|
|
|
b7ec20 |
if not fileurl:
|
|
|
b7ec20 |
@@ -250,8 +335,7 @@ def exclude_hook(conduit):
|
|
|
b7ec20 |
_version_lock_excluder_n.add(n)
|
|
|
b7ec20 |
_version_lock_excluder_nevr.add("%s-%s:%s-%s" % (n, e, v, r))
|
|
|
b7ec20 |
|
|
|
b7ec20 |
- if (_version_lock_excluder_n and
|
|
|
b7ec20 |
- conduit.confBool('main', 'follow_obsoletes', default=False)):
|
|
|
b7ec20 |
+ if (_version_lock_excluder_n and follow_obsoletes):
|
|
|
b7ec20 |
# If anything obsoletes something that we have versionlocked ... then
|
|
|
b7ec20 |
# remove all traces of that too.
|
|
|
b7ec20 |
for (pkgtup, instTup) in conduit._base.up.getObsoletesTuples():
|
|
|
b7ec20 |
@@ -259,6 +343,18 @@ def exclude_hook(conduit):
|
|
|
b7ec20 |
continue
|
|
|
b7ec20 |
_version_lock_excluder_n.add(pkgtup[0].lower())
|
|
|
b7ec20 |
|
|
|
b7ec20 |
+ total = len(_get_updates(conduit._base)) if show_hint else 0
|
|
|
b7ec20 |
+ if total:
|
|
|
b7ec20 |
+ if total > 1:
|
|
|
b7ec20 |
+ suffix = 's'
|
|
|
b7ec20 |
+ what = 'them'
|
|
|
b7ec20 |
+ else:
|
|
|
b7ec20 |
+ suffix = ''
|
|
|
b7ec20 |
+ what = 'it'
|
|
|
b7ec20 |
+ conduit.info(2, 'Excluding %d update%s due to versionlock '
|
|
|
b7ec20 |
+ '(use "yum versionlock status" to show %s)'
|
|
|
b7ec20 |
+ % (total, suffix, what))
|
|
|
b7ec20 |
+
|
|
|
b7ec20 |
if _version_lock_excluder_n:
|
|
|
b7ec20 |
_add_versionlock_whitelist(conduit)
|
|
|
b7ec20 |
if _version_lock_excluder_B_nevr:
|