debian-forge-composer/dnf-json
Ondřej Budai 9076f68f7b rpmmd: Add error reporting support to dnf-json
Previously dnf-json hasn't been able to report any reports. This commit
tries to fix it with introduction of somewhat flexible error format.
2019-11-13 14:54:02 +01:00

97 lines
2.7 KiB
Python

#!/usr/bin/python3
import datetime
import dnf
import json
import sys
DNF_ERROR_EXIT_CODE = 10
def timestamp_to_rfc3339(timestamp):
d = datetime.datetime.utcfromtimestamp(package.buildtime)
return d.strftime('%Y-%m-%dT%H:%M:%SZ')
def dnfrepo(desc, parent_conf=None):
"""Makes a dnf.repo.Repo out of a JSON repository description"""
repo = dnf.repo.Repo(desc["id"], parent_conf)
repo.name = desc["name"]
if "baseurl" in desc:
repo.baseurl = desc["baseurl"]
elif "metalink" in desc:
repo.metalink = desc["metalink"]
elif "mirrorlist" in desc:
repo.metalink = desc["mirrorlist"]
else:
assert False
return repo
def create_base(repos):
base = dnf.Base()
for repo in repos:
base.repos.add(dnfrepo(repo, base.conf))
base.fill_sack(load_system_repo=False)
return base
def exit_with_dnf_error(kind: str, reason: str):
json.dump({"kind": kind, "reason": reason}, sys.stdout)
sys.exit(DNF_ERROR_EXIT_CODE)
call = json.load(sys.stdin)
command = call["command"]
arguments = call.get("arguments", {})
if command == "dump":
base = create_base(arguments.get("repos", {}))
packages = []
for package in base.sack.query().available():
packages.append({
"name": package.name,
"summary": package.summary,
"description": package.description,
"url": package.url,
"epoch": package.epoch,
"version": package.version,
"release": package.release,
"arch": package.arch,
"buildtime": timestamp_to_rfc3339(package.buildtime),
"license": package.license
})
json.dump(packages, sys.stdout)
elif command == "depsolve":
base = create_base(arguments.get("repos", {}))
errors = []
for pkgspec in arguments["package-specs"]:
try:
base.install_specs([pkgspec])
except dnf.exceptions.MarkingError as e:
errors.append((pkgspec, str(e)))
if errors:
formatted_errors = ", ".join((f"{package} ({err})" for package, err in errors))
exit_with_dnf_error("MarkingError", f"The following package(s) had problems: {formatted_errors}")
try:
base.resolve()
except dnf.exceptions.DepsolveError as e:
exit_with_dnf_error("DepsolveError", f"There was a problem depsolving {arguments['package-specs']}: {e}")
packages = []
for package in base.transaction.install_set:
packages.append({
"name": package.name,
"epoch": package.epoch,
"version": package.version,
"release": package.release,
"arch": package.arch
})
json.dump(packages, sys.stdout)