qvm-template: factor filter_version() out of get_dl_list()
This allows reusing version filtering (getting only a single version per template) in other places. For equal versions packages, prefer the one from non-testing repository.
This commit is contained in:
parent
10bea1b77e
commit
86326b53c4
@ -263,6 +263,11 @@ class Template(typing.NamedTuple):
|
|||||||
summary: str
|
summary: str
|
||||||
description: str
|
description: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def evr(self):
|
||||||
|
"""Return a tuple of (EPOCH, VERSION, RELEASE)"""
|
||||||
|
return self.epoch, self.version, self.release
|
||||||
|
|
||||||
class DlEntry(typing.NamedTuple):
|
class DlEntry(typing.NamedTuple):
|
||||||
"""Information about a template to be downloaded."""
|
"""Information about a template to be downloaded."""
|
||||||
evr: typing.Tuple[str, str, str]
|
evr: typing.Tuple[str, str, str]
|
||||||
@ -634,6 +639,50 @@ def extract_rpm(name: str, path: str, target: str) -> bool:
|
|||||||
], stdin=rpm2cpio.stdout, stdout=subprocess.DEVNULL)
|
], stdin=rpm2cpio.stdout, stdout=subprocess.DEVNULL)
|
||||||
return rpm2cpio.wait() == 0 and cpio.wait() == 0
|
return rpm2cpio.wait() == 0 and cpio.wait() == 0
|
||||||
|
|
||||||
|
|
||||||
|
def filter_version(
|
||||||
|
query_res,
|
||||||
|
app: qubesadmin.app.QubesBase,
|
||||||
|
version_selector: VersionSelector = VersionSelector.LATEST):
|
||||||
|
"""Select only one version for given template name"""
|
||||||
|
# We only select one package for each distinct package name
|
||||||
|
results: typing.Dict[str, Template] = {}
|
||||||
|
|
||||||
|
for entry in query_res:
|
||||||
|
evr = (entry.epoch, entry.version, entry.release)
|
||||||
|
insert = False
|
||||||
|
if version_selector == VersionSelector.LATEST:
|
||||||
|
if entry.name not in results:
|
||||||
|
insert = True
|
||||||
|
if entry.name in results \
|
||||||
|
and rpm.labelCompare(results[entry.name].evr, evr) < 0:
|
||||||
|
insert = True
|
||||||
|
if entry.name in results \
|
||||||
|
and rpm.labelCompare(results[entry.name].evr, evr) == 0 \
|
||||||
|
and 'testing' not in entry.reponame:
|
||||||
|
# for the same-version matches, prefer non-testing one
|
||||||
|
insert = True
|
||||||
|
elif version_selector == VersionSelector.REINSTALL:
|
||||||
|
vm = get_managed_template_vm(app, entry.name)
|
||||||
|
cur_ver = query_local_evr(vm)
|
||||||
|
if rpm.labelCompare(evr, cur_ver) == 0:
|
||||||
|
insert = True
|
||||||
|
elif version_selector in [VersionSelector.LATEST_LOWER,
|
||||||
|
VersionSelector.LATEST_HIGHER]:
|
||||||
|
vm = get_managed_template_vm(app, entry.name)
|
||||||
|
cur_ver = query_local_evr(vm)
|
||||||
|
cmp_res = -1 \
|
||||||
|
if version_selector == VersionSelector.LATEST_LOWER \
|
||||||
|
else 1
|
||||||
|
if rpm.labelCompare(evr, cur_ver) == cmp_res:
|
||||||
|
if entry.name not in results \
|
||||||
|
or rpm.labelCompare(results[entry.name].evr, evr) < 0:
|
||||||
|
insert = True
|
||||||
|
if insert:
|
||||||
|
results[entry.name] = entry
|
||||||
|
|
||||||
|
return results.values()
|
||||||
|
|
||||||
def get_dl_list(
|
def get_dl_list(
|
||||||
args: argparse.Namespace,
|
args: argparse.Namespace,
|
||||||
app: qubesadmin.app.QubesBase,
|
app: qubesadmin.app.QubesBase,
|
||||||
@ -651,10 +700,6 @@ def get_dl_list(
|
|||||||
"""
|
"""
|
||||||
full_candid: typing.Dict[str, DlEntry] = {}
|
full_candid: typing.Dict[str, DlEntry] = {}
|
||||||
for template in args.templates:
|
for template in args.templates:
|
||||||
# This will be merged into `full_candid` later.
|
|
||||||
# It is separated so that we can check whether it is empty.
|
|
||||||
candid: typing.Dict[str, DlEntry] = {}
|
|
||||||
|
|
||||||
# Skip local RPMs
|
# Skip local RPMs
|
||||||
if template.endswith('.rpm'):
|
if template.endswith('.rpm'):
|
||||||
continue
|
continue
|
||||||
@ -662,35 +707,10 @@ def get_dl_list(
|
|||||||
query_res = qrexec_repoquery(args, app, PACKAGE_NAME_PREFIX + template)
|
query_res = qrexec_repoquery(args, app, PACKAGE_NAME_PREFIX + template)
|
||||||
|
|
||||||
# We only select one package for each distinct package name
|
# We only select one package for each distinct package name
|
||||||
for entry in query_res:
|
query_res = filter_version(query_res, app, version_selector)
|
||||||
ver = (entry.epoch, entry.version, entry.release)
|
|
||||||
insert = False
|
|
||||||
if version_selector == VersionSelector.LATEST:
|
|
||||||
if entry.name not in candid \
|
|
||||||
or rpm.labelCompare(candid[entry.name][0], ver) < 0:
|
|
||||||
insert = True
|
|
||||||
elif version_selector == VersionSelector.REINSTALL:
|
|
||||||
vm = get_managed_template_vm(app, entry.name)
|
|
||||||
cur_ver = query_local_evr(vm)
|
|
||||||
if rpm.labelCompare(ver, cur_ver) == 0:
|
|
||||||
insert = True
|
|
||||||
elif version_selector in [VersionSelector.LATEST_LOWER,
|
|
||||||
VersionSelector.LATEST_HIGHER]:
|
|
||||||
vm = get_managed_template_vm(app, entry.name)
|
|
||||||
cur_ver = query_local_evr(vm)
|
|
||||||
cmp_res = -1 \
|
|
||||||
if version_selector == VersionSelector.LATEST_LOWER \
|
|
||||||
else 1
|
|
||||||
if rpm.labelCompare(ver, cur_ver) == cmp_res:
|
|
||||||
if entry.name not in candid \
|
|
||||||
or rpm.labelCompare(candid[entry.name][0], ver) < 0:
|
|
||||||
insert = True
|
|
||||||
if insert:
|
|
||||||
candid[entry.name] = DlEntry(ver, entry.reponame, entry.dlsize)
|
|
||||||
|
|
||||||
# XXX: As it's possible to include version information in `template`,
|
# XXX: As it's possible to include version information in `template`,
|
||||||
# perhaps the messages can be improved
|
# perhaps the messages can be improved
|
||||||
if len(candid) == 0:
|
if len(query_res) == 0:
|
||||||
if version_selector == VersionSelector.LATEST:
|
if version_selector == VersionSelector.LATEST:
|
||||||
parser.error('Template \'%s\' not found.' % template)
|
parser.error('Template \'%s\' not found.' % template)
|
||||||
elif version_selector == VersionSelector.REINSTALL:
|
elif version_selector == VersionSelector.REINSTALL:
|
||||||
@ -707,10 +727,12 @@ def get_dl_list(
|
|||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
|
|
||||||
# Merge & choose the template with the highest version
|
# Merge & choose the template with the highest version
|
||||||
for name, dlentry in candid.items():
|
for entry in query_res:
|
||||||
if name not in full_candid \
|
if entry.name not in full_candid \
|
||||||
or rpm.labelCompare(full_candid[name].evr, dlentry.evr) < 0:
|
or rpm.labelCompare(full_candid[entry.name].evr,
|
||||||
full_candid[name] = dlentry
|
entry.evr) < 0:
|
||||||
|
full_candid[entry.name] = \
|
||||||
|
DlEntry(entry.evr, entry.reponame, entry.dlsize)
|
||||||
|
|
||||||
return full_candid
|
return full_candid
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user