blob: 4ec343efacae836cc1c6d504266662126981d668 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#!/usr/bin/env python3
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
import sys
import dnf
import hawkey
import signal
import os
import json
base = None
def get_sack():
global base
if base is None:
base = dnf.Base()
conf = base.conf
conf.read()
conf.installroot = '/'
conf.assumeyes = True
subst = conf.substitutions
subst.update_from_etc(conf.installroot)
try:
base.init_plugins()
base.pre_configure_plugins()
except AttributeError:
pass
base.read_all_repos()
try:
base.configure_plugins()
except AttributeError:
pass
base.fill_sack(load_system_repo='auto')
return base.sack
# FIXME: leaks memory and does not work
def flushcache():
try:
os.remove('/var/cache/dnf/@System.solv')
except OSError:
pass
get_sack().load_system_repo(build_cache=True)
def versioncompare(versions):
sack = get_sack()
if (versions[0] is None) or (versions[1] is None):
sys.stdout.write('0\n')
else:
evr_comparison = sack.evr_cmp(versions[0], versions[1])
sys.stdout.write('{}\n'.format(evr_comparison))
def query(command):
sack = get_sack()
subj = dnf.subject.Subject(command['provides'])
q = subj.get_best_query(sack, with_provides=True)
if command['action'] == "whatinstalled":
q = q.installed()
if command['action'] == "whatavailable":
q = q.available()
if 'epoch' in command:
q = q.filterm(epoch=int(command['epoch']))
if 'version' in command:
q = q.filterm(version__glob=command['version'])
if 'release' in command:
q = q.filterm(release__glob=command['release'])
if 'arch' in command:
q = q.filterm(arch__glob=command['arch'])
# only apply the default arch query filter if it returns something
archq = q.filter(arch=[ 'noarch', hawkey.detect_arch() ])
if len(archq.run()) > 0:
q = archq
pkgs = q.latest(1).run()
if not pkgs:
sys.stdout.write('{} nil nil\n'.format(command['provides'].split().pop(0)))
else:
# make sure we picked the package with the highest version
pkgs.sort
pkg = pkgs.pop()
sys.stdout.write('{} {}:{}-{} {}\n'.format(pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch))
# the design of this helper is that it should try to be 'brittle' and fail hard and exit in order
# to keep process tables clean. additional error handling should probably be added to the retry loop
# on the ruby side.
def exit_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, exit_handler)
signal.signal(signal.SIGHUP, exit_handler)
signal.signal(signal.SIGPIPE, exit_handler)
while 1:
# kill self if we get orphaned (tragic)
ppid = os.getppid()
if ppid == 1:
sys.exit(0)
line = sys.stdin.readline()
command = json.loads(line)
if command['action'] == "whatinstalled":
query(command)
elif command['action'] == "whatavailable":
query(command)
elif command['action'] == "flushcache":
flushcache()
elif command['action'] == "versioncompare":
versioncompare(command['versions'])
else:
raise RuntimeError("bad command")
|