| |
@@ -0,0 +1,94 @@
|
| |
+ # -*- encoding: utf-8 -*-
|
| |
+
|
| |
+ import argparse
|
| |
+ import collections
|
| |
+ import json
|
| |
+ import os
|
| |
+
|
| |
+ import productmd.common
|
| |
+ import productmd.compose
|
| |
+
|
| |
+
|
| |
+ def get_package_version(compose, pkg):
|
| |
+ """Find all SRPMs with given name."""
|
| |
+ kernels = set()
|
| |
+ for variant in compose.rpms.rpms:
|
| |
+ for arch in compose.rpms.rpms[variant]:
|
| |
+ for build in compose.rpms.rpms[variant][arch]:
|
| |
+ n, v, r = build.rsplit("-", 2)
|
| |
+ if n == pkg:
|
| |
+ kernels.add(build.replace(".src", ""))
|
| |
+ if kernels:
|
| |
+ return "%s: %s" % (pkg.capitalize(), ", ".join(sorted(kernels)))
|
| |
+
|
| |
+
|
| |
+ def get_containers(compose):
|
| |
+ """Get details about containers built in OSBS: the NVR, name label and
|
| |
+ registry where it can be retrieved from.
|
| |
+ """
|
| |
+ metadata_uri = os.path.join(compose.compose_path, "metadata/osbs.json")
|
| |
+ try:
|
| |
+ # This should probably be exposed by productmd in some better way.
|
| |
+ # Unlike regular open(), this will handle HTTP urls transaprently.
|
| |
+ with productmd.common._open_file_obj(metadata_uri) as f:
|
| |
+ metadata = json.load(f)
|
| |
+ except IOError:
|
| |
+ # Failed to open metadata, there are no containers.
|
| |
+ return None
|
| |
+ containers = collections.defaultdict(list)
|
| |
+ for variant in metadata:
|
| |
+ for arch in metadata[variant]:
|
| |
+ for container in metadata[variant][arch]:
|
| |
+ containers[
|
| |
+ (
|
| |
+ container["nvr"],
|
| |
+ container["docker"]["config"]["config"]["Labels"]["name"],
|
| |
+ )
|
| |
+ ].append(container["docker"]["repositories"][0])
|
| |
+ if containers:
|
| |
+ return "Containers:\n" + "\n".join(
|
| |
+ _format_container(c[0], c[1], r) for c, r in containers.items()
|
| |
+ )
|
| |
+
|
| |
+
|
| |
+ def _format_container(nvr, name, repos):
|
| |
+ return " * %s (%s)\n%s" % (nvr, name, "\n".join(" - %s" % r for r in repos))
|
| |
+
|
| |
+
|
| |
+ def get_images(compose, types=["qcow2"]):
|
| |
+ """Get list of image filenames for given types."""
|
| |
+ images = set()
|
| |
+ for variant in compose.images.images:
|
| |
+ for arch in compose.images.images[variant]:
|
| |
+ for image in compose.images.images[variant][arch]:
|
| |
+ if image.type in types:
|
| |
+ images.add(os.path.basename(image.path))
|
| |
+ if images:
|
| |
+ return "Images:\n%s" % "\n".join(" * %s" % x for x in sorted(images))
|
| |
+
|
| |
+
|
| |
+ def get_essentials(compose_path):
|
| |
+ compose = productmd.compose.Compose(compose_path)
|
| |
+ return filter(
|
| |
+ None,
|
| |
+ [
|
| |
+ get_package_version(compose, "kernel"),
|
| |
+ get_package_version(compose, "lorax"),
|
| |
+ get_package_version(compose, "anaconda"),
|
| |
+ get_containers(compose),
|
| |
+ get_images(compose)
|
| |
+ ],
|
| |
+ )
|
| |
+
|
| |
+
|
| |
+ def print_details(details):
|
| |
+ for detail in details:
|
| |
+ print(detail)
|
| |
+
|
| |
+
|
| |
+ def main(args=None):
|
| |
+ parser = argparse.ArgumentParser()
|
| |
+ parser.add_argument("COMPOSE", help="compose to inspect")
|
| |
+ opts = parser.parse_args(args)
|
| |
+ details = get_essentials(opts.COMPOSE)
|
| |
+ print_details(details)
|
| |
It will print kernel version, plus information about qcow images and containers.