--- /dev/null
+all:
+ python -c "import compileall; compileall.compile_dir('.')"
+
+clean:
+ find -name '*.pyc' | xargs rm -f
--- /dev/null
+import os
+
+def chr_cmd(cmd):
+ return "sudo chroot /adm/chroot-i386 /bin/sh -c \"%s\"" % cmd
+ #return cmd
+
+def chr_popen(cmd):
+ f = os.popen(chr_cmd(cmd))
+ return f
+
+def chr_system(cmd):
+ os.system(chr_cmd(cmd))
--- /dev/null
+import string
+from chroot import *
+from util import *
+
+__all__ = ['compute_deps', 'remove_list']
+
+def compute_deps():
+ """Compute dependenecies between RPM installed on system.
+
+ Return dictionary from name of package to list of packages required by it.
+ Produce some warnings and progress information to stderr.
+ """
+ # pkg-name -> list of stuff returned by rpm -qR
+ rpm_req = {}
+ # --whatprovides ...
+ rpm_prov = {}
+ # list of required files
+ req_files = {}
+
+ def get_req():
+ msg("rpm-req... ")
+ f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{REQUIRENAME}\n]'")
+ cur_pkg = None
+ while 1:
+ l = f.readline()
+ if l == "": break
+ l = string.strip(l)
+ if l == "@":
+ cur_pkg = string.strip(f.readline())
+ rpm_req[cur_pkg] = []
+ continue
+ rpm_req[cur_pkg].append(l)
+ if l[0] == '/':
+ req_files[l] = 1
+ f.close()
+ msg("done\n")
+
+ def add_provides(pkg, what):
+ if rpm_prov.has_key(what):
+ msg("[%s: %s, %s] " % (what, rpm_prov[what], pkg))
+ else:
+ rpm_prov[what] = pkg
+
+ def get_prov():
+ msg("rpm-prov... ")
+ f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{PROVIDENAME}\n]'")
+ cur_pkg = None
+ while 1:
+ l = f.readline()
+ if l == "": break
+ l = string.strip(l)
+ if l == "@":
+ cur_pkg = string.strip(f.readline())
+ continue
+ add_provides(cur_pkg, l)
+ if l[0] == '/':
+ # already provided
+ del req_files[l]
+ f.close()
+ msg("done\n")
+
+ def get_prov_files():
+ msg("rpm-files... ")
+ f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{FILENAMES}\n]'")
+ cur_pkg = None
+ while 1:
+ l = f.readline()
+ if l == "": break
+ l = string.strip(l)
+ if l == "@":
+ cur_pkg = string.strip(f.readline())
+ continue
+ if req_files.has_key(l):
+ add_provides(cur_pkg, l)
+ f.close()
+ msg("done\n")
+
+ def compute():
+ msg("computing deps... ")
+ for pkg, reqs in rpm_req.items():
+ pkg_reqs = []
+ for req in reqs:
+ if req[0:7] == "rpmlib(": continue
+ if rpm_prov.has_key(req):
+ if rpm_prov[req] not in pkg_reqs:
+ pkg_reqs.append(rpm_prov[req])
+ else:
+ msg("[%s: %s] " % (pkg, req))
+ requires[pkg] = pkg_reqs
+ msg("done\n")
+
+ # map from pkg-name to list of pkg-names required by it
+ # this is result
+ requires = {}
+
+ get_req()
+ get_prov()
+ get_prov_files()
+ compute()
+ return requires
+
+def remove_list(req, need):
+ """List of packages scheduled for removal.
+
+ Given dependency information and list of needed packages compute list
+ of packages that don't need to be present.
+ """
+ need_m = {}
+ def close(n):
+ if need_m.has_key(n): return
+ need_m[n] = 1
+ if not req.has_key(n): return
+ for k in req[n]:
+ close(k)
+ for n in need: close(n)
+ rm = []
+ for p in req.keys():
+ if not need_m.has_key(p): rm.append(p)
+ return rm
--- /dev/null
+import re
+import string
+import xreadlines
+from util import *
+
+
+def get_build_requires(spec, bconds_with, bconds_without):
+ cond_rx = re.compile(r"%\{(\!\?|\?\!|\?)([a-zA-Z0-9_+]+)\s*:([^%\{\}]*)\}")
+
+ def expand_conds(l):
+ def expand_one(m):
+ if m.group(1) == "?":
+ if macros.has_key(m.group(2)):
+ return m.group(3)
+ else:
+ if not macros.has_key(m.group(2)):
+ return m.group(3)
+ return ""
+
+ for i in range(10):
+ l = cond_rx.sub(expand_one, l)
+ if len(l) > 1000: break
+
+ return l
+
+ macro_rx = re.compile(r"%\{([a-zA-Z0-9_+]+)\}")
+ def expand_macros(l):
+ def expand_one(m):
+ if macros.has_key(m.group(1)):
+ return string.strip(macros[m.group(1)])
+ else:
+ return m.group(0) # don't change
+
+ for i in range(10):
+ l = macro_rx.sub(expand_one, l)
+ if len(l) > 1000: break
+
+ return expand_conds(l)
+
+ simple_br_rx = re.compile(r"^BuildRequires\s*:\s*([^\s]+)", re.I)
+ bcond_rx = re.compile(r"^%bcond_(with|without)\s+([^\s]+)")
+ version_rx = re.compile(r"^Version\s*:\s*([^\s]+)", re.I)
+ release_rx = re.compile(r"^Release\s*:\s*([^\s]+)", re.I)
+ name_rx = re.compile(r"^Name\s*:\s*([^\s]+)", re.I)
+ define_rx = re.compile(r"^\%define\s+([a-zA-Z0-9_+]+)\s+(.*)", re.I)
+ any_br_rx = re.compile(r"BuildRequires", re.I)
+
+ macros = {}
+ for b in bconds_with:
+ macros["_with_%s" % b] = 1
+ for b in bconds_without:
+ macros["_without_%s" % b] = 1
+
+ macros["__perl"] = "/usr/bin/perl"
+ macros["_bindir"] = "/usr/bin"
+ macros["_sbindir"] = "/usr/bin"
+ macros["kgcc_package"] = "gcc"
+
+ build_req = []
+
+ f = open(spec)
+ for l in xreadlines.xreadlines(f):
+ l = string.strip(l)
+ if l == "%changelog": break
+
+ # %bcond_with..
+ m = bcond_rx.search(l)
+ if m:
+ bcond = m.group(2)
+ if m.group(1) == "with":
+ if macros.has_key("_with_%s" % bcond):
+ macros["with_%s" % bcond] = 1
+ else:
+ if not macros.has_key("_without_%s" % bcond):
+ macros["with_%s" % bcond] = 1
+ continue
+
+ # name,version,release
+ m = version_rx.search(l)
+ if m: macros["version"] = m.group(1)
+ m = release_rx.search(l)
+ if m: macros["release"] = m.group(1)
+ m = name_rx.search(l)
+ if m: macros["name"] = m.group(1)
+
+ # %define
+ m = define_rx.search(l)
+ if m: macros[m.group(1)] = m.group(2)
+
+ # *BuildRequires*
+ if any_br_rx.search(l):
+ l = expand_macros(l)
+ m = simple_br_rx.search(l)
+ if m:
+ build_req.append(m.group(1))
+ else:
+ if l <> "" and l[0] <> '#':
+ msg("spec error (%s): %s\n" % (spec, l))
+
+ for x in build_req:
+ print x
--- /dev/null
+import re
+import types
+import string
+import xreadlines
+
+from chroot import *
+from util import *
+
+
+def get_poldek_requires():
+ # precompile regexps
+ name_rx = re.compile(r"\d+\. ([^\s]+)-[^-]+-[^-]+\n")
+ req_rx = re.compile(r" req .* --> (.*)\n")
+ pkg_name_rx = re.compile(r"([^\s]+)-[^-]+-[^-]+")
+
+ def intersect(a, b):
+ r = []
+ for x in a:
+ if x in b: r.append(x)
+ return r
+
+ # add given req-list to cur_pkg_reqs
+ def add_req(reqs):
+ if len(reqs) == 1:
+ if reqs[0] not in cur_pkg_reqs:
+ cur_pkg_reqs.append(reqs[0])
+ else:
+ did = 0
+ for x in cur_pkg_reqs:
+ if type(x) is types.ListType:
+ i = intersect(x, reqs)
+ if len(i) == 0:
+ continue
+ did = 1
+ idx = cur_pkg_reqs.index(x)
+ if len(i) == 1:
+ if i[0] in cur_pkg_reqs:
+ del cur_pkg_reqs[idx]
+ else:
+ cur_pkg_reqs[idx] = i[0]
+ else:
+ cur_pkg_reqs[idx] = i
+ else:
+ if x in reqs:
+ return
+ if not did:
+ cur_pkg_reqs.append(reqs)
+
+ pkg_reqs = {}
+ cur_pkg_reqs = None
+ cur_pkg = None
+
+ f = chr_popen("poldek -v -v --verify --unique-pkg-names")
+ for l in xreadlines.xreadlines(f):
+ m = name_rx.match(l)
+ if m:
+ if cur_pkg:
+ pkg_reqs[cur_pkg] = cur_pkg_reqs
+ cur_pkg = m.groups(1)
+ if pkg_reqs.has_key(cur_pkg):
+ cur_pkg = None
+ cur_pkg_reqs = None
+ else:
+ cur_pkg_reqs = []
+ continue
+ m = req_rx.match(l)
+ if m:
+ reqs = []
+ for x in string.split(m.group(1)):
+ if x in ["RPMLIB_CAP", "NOT", "FOUND", "UNMATCHED"]: continue
+ m = pkg_name_rx.match(x)
+ if m:
+ reqs.append(m.group(1))
+ else:
+ msg("poldek_reqs: bad pkg name: %s\n" % x)
+ if len(reqs) != 0: add_req(reqs)
+
+ f.close()
+
+ if cur_pkg:
+ pkg_reqs[cur_pkg] = cur_pkg_reqs
+
+ return pkg_reqs
--- /dev/null
+import re
+import sys
+
+def pkg_name(nvr):
+ return re.match(r"(.+)-[^-]+-[^-]+", nvr).group(1)
+
+def msg(m):
+ sys.stderr.write(m)
--- /dev/null
+Zlecenie dla binary-builder:
+
+<group id="d30eb8ae-3c54-4103-9188-69b1114d6ac7">
+ <priority>2</priority>
+ <requester>malekith</requester>
+ <batch>
+ <src-rpm>foo-1.2-3.src.rpm</src-rpm>
+ <spec>foo.spec</spec>
+ <bcond>
+ <with>foo</with>
+ <without>bar</without>
+ </bcond>
+ <info>foo.spec -r DEVEL blah,blah</info>
+ <archs>
+ <arch>i386</arch>
+ <arch>i586</arch>
+ <arch>i686</arch>
+ <arch>ppc</arch>
+ </archs>
+ </batch>
+ <batch>
+ <src-rpm>bar-1.2-1.src.rpm</src-rpm>
+ <spec>bar.spec</spec>
+ <bcond>
+ <with>foo</with>
+ <without>bar</without>
+ </bcond>
+ <info>bar.spec -r HEAD blah,blah</info>
+ <archs>
+ <arch>i386</arch>
+ <arch>i586</arch>
+ <arch>i686</arch>
+ </archs>
+ </batch>
+</group>
+
+--------------------------------------------------------------------------
+Skrypt dla binary-builder, z crona.
+
+ 1. Je¶li ju¿ co¶ siê buduje lub za wysoki load to wyjd¼.
+
+ 2. Je¶li wewnêtrzna kolejka jest pusta, nie ma notyfikacji, ¿e ,,s±
+ nowe zlecenia'' (poczt±, od srcbuildera) i ostatnie sprawdzenie
+ pliku zleceñ na src-builderze by³o mniej ni¿ 10 minut temu to wyjd¼.
+
+ 3. Pobierz plik kolejki z srcbuildera.
+
+ 4. Wrzuæ wszystkie nie obs³u¿one jeszcze zlecenia do lokalnej kolejki.
+
+ 5. Z lokalnej kolejki wybierz grupê G o najwy¿szym priorytecie, która jest
+ najstarsza.
+
+ 6. Dla ka¿dego zlecenia Z w G:
+
+ a) ¦ci±gnij srpm.
+
+ b) Wyci±gnij spec z srpm
+
+ b) Je¶li mo¿na na raz budowaæ tylko jeden taki pakiet (co jest napisane
+ w specu), to MAX = 1, else MAX = z konfiguracji buildera (ew. z
+ uwzglêdnieniem aktualnego loadu)
+
+ c) Dla ka¿dej architektury sprawd¼ czy nale¿y budowaæ (czy jest zablokowany
+ i czy arch jest wymieniona w zleceniu)
+
+ d) build_rpm(Z, arch), nie wiêcej ni¿ MAX na raz.
+
+ 7. Wy¶lij raport o zakoñczeniu budowania.
+
+
+--------------------------------------------------------------------------
+
+build_rpm(Z, arch):
+
+ 1. Oblicz jakie pakiety s± wymagane do zbudowania Z.
+
+ 1,5. poldek --up w chroot.
+
+ 2. Wyinstaluj pakiety z chroot, które nie s± wymagane.
+
+ 3. Zrób poldek --uprade * w chroot.
+
+ 4. Zrób poldek --install (co jeszcze potrzebne do budowy) w chroot.
+
+ 5. Wrzuæ srpm do chroot.
+
+ 6. Uruchom rpmbuild w chroot, wyj¶cie zapmiêtuj±c w pliku.
+
+ 7. Wyci±gnij z chroot zbudowane rpm'y.
+
+ 8. Je¶li test-build(Z) to
+ po³ó¿ rpm'y w local-test/
+ w.p.p
+ po³ó¿ rpm'y w local-ready/
+ przegeneruj indexy poldeka w local-ready/
+
+ 9. po³ó¿ buildlogi w buildlogs/
+
+ 10. po³ó¿ zlecenie wys³anie tego wszystkiego w trasnfers/
+
+
+--------------------------------------------------------------------------
+
+Wysy³anie buildlogów i rpm'ów:
+
+ 1. Je¶li transfers/ puste -- wyjd¼.
+
+ 2. We¼ zlecenie z transfers/
+
+ 3. Wy¶lij rpm'y, buildlogi.
+
+ 4. Wys³ane pliki z buildlogs/ i local-test/ skasuj, local-ready/ jest
+ czyszczone z crona, pliki starsze ni¿ ile¶-tam wylatuj±.
+
+ 5. Wy¶lij powiadomienie do zlecaj±cego.
+
+--------------------------------------------------------------------------
+
+Konfiguracja poldka w chroot.
+
+source = local,pri=1 /.../local-ready
+source = ready,pri=2 ftp://.../ac/ready
+source = main-su,pri=3 ftp://.../updates/security
+source = main-gu,pri=4 ftp://.../updates/general
+source = main,pri=5 ftp://.../../RPMS
+
+keep_downloads = yes # + usuwanie z crona starych
+
+Dodatkowo poldek jest odpalany z -Q (tylko najnowsza wersja ka¿dego
+pakietu).
+
+--------------------------------------------------------------------------
+
+Na ró¿nych etapach mo¿na zrobiæ powiadamianie buildlogs (czy te¿ buildstats),
+¿e np. rozpoczê³o siê budowanie foobar etc. Mo¿na potem zrobiæ stronê z
+informacj± co siê gdzie aktualnie buduje.
+
+--------------------------------------------------------------------------
+
+Skrypt obs³ugi src-builder, zlecenia dostaje maile, procmail je kolejkuje.
+
+Z crona:
+
+1. We¼ zlecenie z kolejki
+
+2. Sprawd¼ autentykacjê (wynik login lub b³±d)
+
+3. Sprawd¼ czy login ma uprawnienia (je¶l nie to wypad)
+
+4. Uruchom w chroot ./builder -r BLAH -bs foo.spec
+
+5. Wyci±gnij z chroot srcrpm'a i wrzuæ na http
+
+6. Updajtnij kolejkê zleceñ
+
+--------------------------------------------------------------------------
+
+Wszêdzie s/arch/linia? builder? cokolwiek. My¶lê, ¿e mog³by byæ osobny
+,,arch'' do sec-updates, który by np. nie mia³ w ¼ród³ach w poldku local-ready/
+czy ready/.
+
--- /dev/null
+#!/usr/bin/python
+
+import sys
+from PLD_Builder.get_br import *
+
+for f in sys.argv[1:]:
+ get_build_requires(f, [], [])
--- /dev/null
+#!/usr/bin/python
+
+import sys
+from PLD_Builder.deps import *
+
+req = compute_deps()
+
+def main():
+ req = compute_deps()
+ m = {}
+ def close(p):
+ if m.has_key(p):
+ return
+ m[p] = 1
+ for x in req[p]:
+ close(x)
+ close("rpm-build")
+ for x in m.keys():
+ print x
+
+main()