]> git.pld-linux.org Git - projects/pld-builder.new.git/commitdiff
- first revision
authorMichal Moskal <michal@moskal.me>
Sat, 7 Jun 2003 22:55:21 +0000 (22:55 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    Makefile -> 1.1.1.1
    PLD_Builder/__init__.py -> 1.1.1.1
    PLD_Builder/chroot.py -> 1.1.1.1
    PLD_Builder/deps.py -> 1.1.1.1
    PLD_Builder/get_br.py -> 1.1.1.1
    PLD_Builder/poldek.py -> 1.1.1.1
    PLD_Builder/util.py -> 1.1.1.1
    architektura.txt -> 1.1.1.1
    go.py -> 1.1.1.1
    uninst.py -> 1.1.1.1

Makefile [new file with mode: 0644]
PLD_Builder/__init__.py [new file with mode: 0644]
PLD_Builder/chroot.py [new file with mode: 0644]
PLD_Builder/deps.py [new file with mode: 0644]
PLD_Builder/get_br.py [new file with mode: 0644]
PLD_Builder/poldek.py [new file with mode: 0644]
PLD_Builder/util.py [new file with mode: 0644]
architektura.txt [new file with mode: 0644]
go.py [new file with mode: 0755]
uninst.py [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..1b526f0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+all:
+       python -c "import compileall; compileall.compile_dir('.')"
+
+clean:
+       find -name '*.pyc' | xargs rm -f
diff --git a/PLD_Builder/__init__.py b/PLD_Builder/__init__.py
new file mode 100644 (file)
index 0000000..1bb8bf6
--- /dev/null
@@ -0,0 +1 @@
+# empty
diff --git a/PLD_Builder/chroot.py b/PLD_Builder/chroot.py
new file mode 100644 (file)
index 0000000..9675636
--- /dev/null
@@ -0,0 +1,12 @@
+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))
diff --git a/PLD_Builder/deps.py b/PLD_Builder/deps.py
new file mode 100644 (file)
index 0000000..4e39007
--- /dev/null
@@ -0,0 +1,119 @@
+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
diff --git a/PLD_Builder/get_br.py b/PLD_Builder/get_br.py
new file mode 100644 (file)
index 0000000..e810af3
--- /dev/null
@@ -0,0 +1,101 @@
+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
diff --git a/PLD_Builder/poldek.py b/PLD_Builder/poldek.py
new file mode 100644 (file)
index 0000000..1d6deeb
--- /dev/null
@@ -0,0 +1,83 @@
+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
diff --git a/PLD_Builder/util.py b/PLD_Builder/util.py
new file mode 100644 (file)
index 0000000..5c48a95
--- /dev/null
@@ -0,0 +1,8 @@
+import re
+import sys
+
+def pkg_name(nvr):
+  return re.match(r"(.+)-[^-]+-[^-]+", nvr).group(1)
+  
+def msg(m):
+  sys.stderr.write(m)
diff --git a/architektura.txt b/architektura.txt
new file mode 100644 (file)
index 0000000..a0913f9
--- /dev/null
@@ -0,0 +1,161 @@
+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/.
+
diff --git a/go.py b/go.py
new file mode 100755 (executable)
index 0000000..df87ccd
--- /dev/null
+++ b/go.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+
+import sys
+from PLD_Builder.get_br import *
+
+for f in sys.argv[1:]:
+  get_build_requires(f, [], [])
diff --git a/uninst.py b/uninst.py
new file mode 100755 (executable)
index 0000000..ca2d9cb
--- /dev/null
+++ b/uninst.py
@@ -0,0 +1,21 @@
+#!/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()
This page took 0.101111 seconds and 4 git commands to generate.