-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfetchbuild
executable file
·118 lines (101 loc) · 4.38 KB
/
fetchbuild
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
116
117
118
#!/usr/bin/python3
# fetchbuild - fetch entire builds from koji
import os
import koji
from koji_cli.lib import download_file, _format_size
def rpmpath(rpminfo):
return "{buildname}/{version}/{release}/{arch}/{name}-{version}-{release}.{arch}.rpm".format(**rpminfo)
class KojiWrapper(object):
def __init__(self, configname='koji'):
self.config = koji.read_config(configname)
self.session = koji.ClientSession(self.config['server'],
koji.grab_session_options(self.config))
self.pkgurl = self.config['topurl'].rstrip('/')+'/packages/'
def pkgid(self, pkgname):
return self.session.getPackageID(pkgname)
def listbuilds(self, pkgname):
pkgid = self.pkgid(pkgname)
if pkgid is None:
raise ValueError("Unknown package {}".format(pkgname))
return sorted(self.session.listBuilds(state=1, packageID=pkgid),
key=lambda b: b['completion_ts'])
def listrpms(self, build, arches=None):
rpms = self.session.listRPMs(buildID=build['build_id'], arches=arches)
for r in rpms:
r['buildname'] = build['name']
return rpms
def download_rpms(self, rpms, quiet=False, noprogress=False):
count = len(rpms)
for num,rpm in enumerate(rpms):
relpath = rpmpath(rpm)
size = rpm['size']
try:
existing_size = os.stat(relpath).st_size
except OSError:
existing_size = None
if existing_size and existing_size == size:
print("{} already downloaded, skipping".format(relpath))
else:
download_file(self.pkgurl+relpath, relpath, size=count, num=num+1,
quiet=quiet, noprogress=noprogress)
from argparse import ArgumentParser
def parse_args():
import re
from argparse import ArgumentParser
HOST_ARCH='x86_64' # FIXME
LATEST_VER='fc38' # FIXME ALSO
p = ArgumentParser(
prog="fetchbuild",
description="download builds from koji",
)
p.add_argument("packages", metavar="PKG", nargs="+",
help="package names to fetch")
p.add_argument("--version", metavar="REGEX",
type=re.compile, default='',
help="only download builds that match this version")
p.add_argument("--arch", metavar="ARCH", action="append", dest="arches",
default=[HOST_ARCH, 'noarch'],
help="package arches to fetch")
p.add_argument("--noarch", action="store_const", const=['noarch'],
help="only fetch `noarch` packages")
p.add_argument("--dist", metavar="DIST", action="append", dest="dists",
default=[LATEST_VER],
help="package dists to fetch")
p.add_argument("--dryrun", "-n", action="store_true",
help="look up packages but do not actually download")
args = p.parse_args()
return args
ANSI_RED="\x1b[91m"
ANSI_GREEN="\x1b[92m"
ANSI_END="\x1b[0m"
UNICODE_OK=f"{ANSI_GREEN}\N{heavy check mark}{ANSI_END}"
UNICODE_ERR=f"{ANSI_RED}\N{heavy ballot x}{ANSI_END}"
if __name__ == '__main__':
k = KojiWrapper()
dl_rpms = []
args = parse_args()
print("Finding builds for ({}), ({})".format(",".join(args.dists), ",".join(args.arches)))
for pkg in args.packages:
try:
builds = k.listbuilds(pkg)
except ValueError:
print("Skipping unknown package '{}'".format(pkg))
continue
print("Matching {} builds:".format(pkg))
for build in builds:
if any(build['release'].endswith(d) for d in args.dists):
verrel = "{version}-{release}".format(**build)
if args.version.match(verrel):
dl_rpms += k.listrpms(build, arches=args.arches)
end=UNICODE_OK
else:
end=UNICODE_ERR
print(" {version}-{release}".format(**build), end=end, flush=True)
print()
dl_size = sum(r['size'] for r in dl_rpms)
if args.dryrun:
print("Would download {} rpms ({}):".format(len(dl_rpms),_format_size(dl_size)))
print(*(" {nvr}.{arch}.rpm".format(**rpm) for rpm in dl_rpms), sep='\n')
else:
print("Downloading {} rpms ({})".format(len(dl_rpms),_format_size(dl_size)))
k.download_rpms(dl_rpms)