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.
This commit is contained in:
parent
495f5b558b
commit
9076f68f7b
2 changed files with 54 additions and 4 deletions
24
dnf-json
24
dnf-json
|
|
@ -5,6 +5,8 @@ import dnf
|
|||
import json
|
||||
import sys
|
||||
|
||||
DNF_ERROR_EXIT_CODE = 10
|
||||
|
||||
|
||||
def timestamp_to_rfc3339(timestamp):
|
||||
d = datetime.datetime.utcfromtimestamp(package.buildtime)
|
||||
|
|
@ -39,6 +41,11 @@ def create_base(repos):
|
|||
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", {})
|
||||
|
|
@ -63,8 +70,21 @@ if command == "dump":
|
|||
|
||||
elif command == "depsolve":
|
||||
base = create_base(arguments.get("repos", {}))
|
||||
base.install_specs(arguments["package-specs"])
|
||||
base.resolve()
|
||||
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({
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package rpmmd
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sort"
|
||||
|
|
@ -44,6 +46,15 @@ type RPMMD interface {
|
|||
Depsolve(specs []string, repos []RepoConfig) ([]PackageSpec, error)
|
||||
}
|
||||
|
||||
type DNFError struct {
|
||||
Kind string `json:"kind"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
func (err *DNFError) Error() string {
|
||||
return fmt.Sprintf("DNF error occured: %s: %s", err.Kind, err.Reason)
|
||||
}
|
||||
|
||||
func runDNF(command string, arguments interface{}, result interface{}) error {
|
||||
var call = struct {
|
||||
Command string `json:"command"`
|
||||
|
|
@ -77,12 +88,31 @@ func runDNF(command string, arguments interface{}, result interface{}) error {
|
|||
}
|
||||
stdin.Close()
|
||||
|
||||
err = json.NewDecoder(stdout).Decode(result)
|
||||
output, err := ioutil.ReadAll(stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cmd.Wait()
|
||||
err = cmd.Wait()
|
||||
|
||||
const DnfErrorExitCode = 10
|
||||
if runError, ok := err.(*exec.ExitError); ok && runError.ExitCode() == DnfErrorExitCode {
|
||||
var dnfError DNFError
|
||||
err = json.Unmarshal(output, &dnfError)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return &dnfError
|
||||
}
|
||||
|
||||
err = json.Unmarshal(output, result)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type rpmmdImpl struct{}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue