]> git.pld-linux.org Git - projects/pld-builder.new.git/commitdiff
- rpm builder actually did something (immortal alien.spec) ;-)
authorMichal Moskal <michal@moskal.me>
Wed, 11 Jun 2003 00:03:29 +0000 (00:03 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    PLD_Builder/chroot.py -> 1.5
    PLD_Builder/config.py -> 1.6
    PLD_Builder/log.py -> 1.3
    PLD_Builder/path.py -> 1.7
    PLD_Builder/rpm_builder.py -> 1.1
    PLD_Builder/srpm_builder.py -> 1.8
    PLD_Builder/util.py -> 1.4
    bin/rpm-builder.sh -> 1.1
    doc/README -> 1.3

PLD_Builder/chroot.py
PLD_Builder/config.py
PLD_Builder/log.py
PLD_Builder/path.py
PLD_Builder/rpm_builder.py [new file with mode: 0644]
PLD_Builder/srpm_builder.py
PLD_Builder/util.py
bin/rpm-builder.sh [new file with mode: 0644]
doc/README

index 0be6188c04441f4cc452df78dea2ac8d8547c43f..25f5a003505199b4f66503f00e7fb36911eb8a2e 100644 (file)
@@ -11,8 +11,8 @@ def command(cmd, user = "builder"):
 def command_sh(cmd):
   return "sudo chroot %s /bin/sh -c \"export LC_ALL=C; %s\"" % (config.chroot, quote(cmd))
 
-def popen(cmd, user = "builder"):
-  f = os.popen(command(cmd, user))
+def popen(cmd, user = "builder", mode = "r"):
+  f = os.popen(command(cmd, user), mode)
   return f
   
 def run(cmd, user = "builder", logfile = None):
index 3ae22ab0cf5706c38a1f731dc74f3f1aaa74ceae..e69195028e240c650d421f9541e66530c8d66bfe 100644 (file)
@@ -8,6 +8,7 @@ import status
 
 class Builder_Conf:
   def __init__(self):
+    self.done = 0
     pass
 
   def read(self, builder):
@@ -34,11 +35,13 @@ class Builder_Conf:
     self.job_slots = int(get("job_slots"))
     self.max_load = float(get("max_load"))
     self.control_url = get("control_url")
+    self.done = 1
 
 config = Builder_Conf()
 
 def init_conf(builder):
   os.environ['LC_ALL'] = "C"
   status.push("reading builder config")
+  log.builder = builder
   config.read(builder)
   status.pop()
index 512ff4021118853efa7fcbc4efb54781ad7e4860..c82eaa6ef6bba2e44457d61d9c8997c6636879ce 100644 (file)
@@ -1,7 +1,9 @@
 import sys
 
+builder = ""
+
 def log(s):
-  sys.stderr.write("LOG: %s\n" % s)
+  sys.stderr.write("LOG[%s]: %s\n" % (builder, s))
   
 def alert(s):
   log("alert: %s" % s) 
index 36c96923b7aee00bf0af6a5db075bc3643b0aea5..c8282fe356e1db92837c0d678ce2216324e795c6 100644 (file)
@@ -16,6 +16,7 @@ processed_ids_file = spool_dir + "processed_ids"
 buildlogs_queue_dir = spool_dir + "buildlogs/"
 ftp_queue_dir = spool_dir + "ftp/"
 last_req_no_file = spool_dir + "last_req_no"
+got_lock_file = spool_dir + "got_lock"
 
 # www/
 srpms_dir = www_dir + "srpms/"
diff --git a/PLD_Builder/rpm_builder.py b/PLD_Builder/rpm_builder.py
new file mode 100644 (file)
index 0000000..bdd4e8a
--- /dev/null
@@ -0,0 +1,161 @@
+import sys
+import os
+import atexit
+import time
+import urllib
+
+from config import config, init_conf
+from bqueue import B_Queue
+from acl import acl
+import lock
+import util
+import path
+import status
+import log
+import chroot
+import ftp
+import buildlogs
+
+# this code is duplicated in srpm_builder, but we
+# might want to handle some cases differently here
+def pick_request(q):
+  def mycmp(r1, r2):
+    if r1.kind != 'group' or r2.kind != 'group':
+      raise "non-group requests"
+    pri_diff = cmp(r1.priority, r2.priority)
+    if pri_diff == 0:
+      return cmp(r1.time, r2.time)
+    else:
+      return pri_diff
+  q.requests.sort(mycmp)
+  ret = q.requests[0]
+  q.requests = q.requests[1:]
+  return ret
+
+def handle_request(r):
+  def log_line(l):
+    log.notice(l)
+    util.append_to(spec_log, l)
+  
+  def fetch_src(b):
+    src_url = config.control_url + "/srpms/" + r.id + "/" + b.src_rpm
+    log_line("fetching %s" % src_url)
+    start = time.time()
+    f = urllib.urlopen(src_url)
+    o = chroot.popen("cat > %s" % b.src_rpm, mode = "w")
+    bytes = util.sendfile(f, o)
+    f.close()
+    o.close()
+    t = time.time() - start
+    if t == 0:
+      log_line("fetched %d bytes" % bytes)
+    else:
+      log_line("fetched %d bytes, %.1f K/s" % (bytes, bytes / 1024.0 / t))
+
+  def build_rpm(b):
+    global spec_log
+    spec_log = tmp + b.spec + ".log"
+    status.push("building %s" % b.spec)
+    fetch_src(b)
+    res = chroot.run("rpm -U %s && rm -f %s" % (b.src_rpm, b.src_rpm), 
+                     logfile = spec_log)
+    if res:
+      log_line("error: installing src rpm failed")
+    else:
+      cmd = "cd rpm/SPECS; rpmbuild -bb %s" % b.spec
+      log_line("Building RPM using: %s" % cmd)
+      res = chroot.run(cmd, logfile = spec_log)
+      files = util.collect_files(spec_log)
+      if len(files) > 0:
+        all_files.extend(files)
+      else:
+        # FIXME: is it error?
+        log_line("error: No files produced.")
+        res = 1
+    buildlogs.add(logfile = spec_log, failed = res)
+    status.pop()
+    return res
+
+  tmp = path.spool_dir + r.id + "/"
+  os.mkdir(tmp)
+  atexit.register(util.clean_tmp, tmp)
+  user = acl.user(r.requester)
+  log.notice("started processing %s" % r.id)
+  all_files = []
+  for batch in r.batches:
+    log.notice("building %s" % batch.spec)
+    if build_rpm(batch):
+      # clean up
+      log.notice("building %s failed" % batch.spec)
+      chroot.run("rm -f %s" % string.join(all_files))
+      m = user.message_to()
+      m.set_headers(subject = "Binary: %s failed" % batch.spec)
+      # FIXME: write about other specs from group
+      m.write("Building RPM failed for %s.\nAttached log:\n" % batch.spec)
+      m.append_log(spec_log)
+      m.send()
+      buildlogs.flush()
+      return
+    log.notice("building %s finished" % batch.spec)
+  for f in all_files:
+    local = tmp + os.path.basename(f)
+    chroot.run("cat %s; rm -f %s" % (f, f), logfile = local)
+    ftp.add(local)
+
+  # FIXME: send notification?
+  buildlogs.flush()
+  ftp.flush()
+
+def check_load():
+  try:
+    f = open("/proc/loadavg")
+    if float(string.split(f.readline())[2]) > config.max_load:
+      sys.exit(0)
+  except:
+    pass
+
+def main():
+  if len(sys.argv) < 2:
+    raise "fatal: need to have builder name as first arg"
+  init_conf(sys.argv[1])
+  # allow only one build in given builder at once
+  if not lock.lock("building-rpm-for-%s" % config.builder, non_block = 1):
+    return
+  # don't kill server
+  check_load()
+  # not more then job_slots builds at once
+  locked = 0
+  for slot in range(config.job_slots):
+    if lock.lock("building-rpm-slot-%d" % slot, non_block = 1):
+      locked = 1
+      break
+  if not locked:
+    return
+
+  status.push("picking request for %s" % config.builder)
+  q = B_Queue(path.queue_file + "-" + config.builder)
+  q.lock(0)
+  q.read()
+  if q.requests == []:
+    return
+  r = pick_request(q)
+  q.write()
+  q.unlock()
+  status.pop()
+
+  # record fact that we got lock for this builder, load balancer
+  # will use it for fair-queuing
+  l = lock.lock("got-lock")
+  f = open(path.got_lock_file, "a")
+  f.write(config.builder + "\n")
+  f.close()
+  l.close()
+  
+  msg = "handling request %s (%d) for %s from %s" \
+        % (r.id, r.no, config.builder, r.requester)
+  log.notice(msg)
+  status.push(msg)
+  handle_request(r)
+  status.pop()
+  
+util.wrap(main)
index 8078398822d8d08ddba8dc68c19954d2bd5801ad..c29acef92fb5415f10be17ae77a52c5f29190ac3 100644 (file)
@@ -37,16 +37,6 @@ def pick_request(q):
   q.requests = q.requests[1:]
   return ret
 
-def collect_files(log):
-  f = open(log)
-  rx = re.compile(r"^Wrote: (/home.*\.rpm)$")
-  files = []
-  for l in f.xreadlines():
-    m = rx.search(l)
-    if m:
-      files.append(m.group(1))
-  return files
-
 def handle_request(r):
   def build_srpm(b):
     status.push("building %s" % b.spec)
@@ -57,7 +47,7 @@ def handle_request(r):
     spec_log = tmp + b.spec + ".log"
     util.append_to(spec_log, "Building SRPM using: %s\n" % cmd)
     res = chroot.run(cmd, logfile = spec_log)
-    files = collect_files(spec_log)
+    files = util.collect_files(spec_log)
     if len(files) > 0:
       if len(files) > 1:
         util.append_to(spec_log, "error: More then one file produced: %s" % files)
index 37a946a3738b65e961b16a0c4b949e6859a88884..a2d68172fa6530d0ce6fd25ba48b15bf92de07a9 100644 (file)
@@ -15,10 +15,13 @@ def msg(m):
   sys.stderr.write(m)
 
 def sendfile(src, dst):
+  cnt = 0
   while 1:
     s = src.read(10000)
     if s == "": break
+    cnt += len(s)
     dst.write(s)
+  return cnt
 
 def append_to(log, msg):
   f = open(log, "a")
@@ -49,3 +52,13 @@ def wrap(main):
     log.alert("fatal python exception during: %s" % status.get())
     log.alert(s.getvalue())
     sys.exit(1)
+
+def collect_files(log):
+  f = open(log)
+  rx = re.compile(r"^Wrote: (/home.*\.rpm)$")
+  files = []
+  for l in f.xreadlines():
+    m = rx.search(l)
+    if m:
+      files.append(m.group(1))
+  return files
diff --git a/bin/rpm-builder.sh b/bin/rpm-builder.sh
new file mode 100644 (file)
index 0000000..38d306d
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cd ~/pld-builder.new
+python PLD_Builder/rpm_builder.py $1
index 8a5761db0ef8a9ad1c6a2c691bd3dd8723c1fc68..ee6c13c4ed519a1f033529afecbcce12f6e57d27 100644 (file)
@@ -8,8 +8,6 @@ Roadmap:
 
   architektura.txt -- docs, in Polish.
 
-  binary_builder/ -- scripts for binary builder
-
   client/ -- scripts for clients, i.e. developers sending requests
 
   config/ -- configuration
@@ -28,6 +26,16 @@ Roadmap:
       builders in spool/req_queue (which is mirrored in www/ directory,
       signed and compressed). SRPMS and buildlogs are queued for transmission.
 
+  binary_builder/ -- scripts for binary builder
+
+    request-fetcher.sh
+      Fetch queue.gz from src-builder, and distribute requests for all
+      builders hosted on given account (to spool/queue-<builder> files).
+
+    rpm-builder.sh <builder>
+      Tries to aquire locks for <builder> and for job-slot. If that suceeds, 
+      proccess one request from spool/queue-<builder>.
+  
 Working directories:
   lock/
   spool/
This page took 0.128026 seconds and 4 git commands to generate.