extras-buildsys/server CONFIG.py, 1.21, 1.21.2.1 Repo.py, 1.11, 1.11.2.1

Daniel Williams (dcbw) fedora-extras-commits at redhat.com
Fri Aug 19 18:48:46 UTC 2005


Author: dcbw

Update of /cvs/fedora/extras-buildsys/server
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv28405/server

Modified Files:
      Tag: STABLE_0_3
	CONFIG.py Repo.py 
Log Message:
2005-08-19  Dan Williams <dcbw at redhat.com>

    * server/Repo.py
      server/CONFIG.py
        - Add repo script capability, where a random script
            gets run after createrepo




Index: CONFIG.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/server/Attic/CONFIG.py,v
retrieving revision 1.21
retrieving revision 1.21.2.1
diff -u -r1.21 -r1.21.2.1
--- CONFIG.py	25 Jul 2005 19:47:15 -0000	1.21
+++ CONFIG.py	19 Aug 2005 18:48:43 -0000	1.21.2.1
@@ -7,6 +7,7 @@
 config_opts['make_cmd'] = "/usr/bin/make"
 config_opts['log_url'] = "http://foo.foo.org/logs/"
 config_opts['guest_allowed'] = True
+config_opts['repo_script'] = ''
 
 
 #


Index: Repo.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/server/Repo.py,v
retrieving revision 1.11
retrieving revision 1.11.2.1
diff -u -r1.11 -r1.11.2.1
--- Repo.py	18 Jul 2005 21:11:27 -0000	1.11
+++ Repo.py	19 Aug 2005 18:48:43 -0000	1.11.2.1
@@ -19,6 +19,9 @@
 import shutil
 import time
 import commands
+import popen2
+import fcntl
+import EmailUtils
 
 
 # Load in the config
@@ -44,6 +47,16 @@
         self._repo_additions = []
         self._lock_count = 0
         self._stop = False
+
+        self._pobj = None
+        self._repo_script_start = 0
+        try:
+            self._repo_script = config_opts['repo_script']
+            if len(self._repo_script):
+                self._repo_script = None
+        except KeyError:
+            self._repo_script = None
+
         threading.Thread.__init__(self)
 
     def target(self):
@@ -91,27 +104,96 @@
         if s != 0:
             print "Error: createrepo failed with exit status %d!  Output: '%s'" % (s, o)
 
+    def _run_repo_script(self):
+        cmd = "%s %s" % (self._repo_script, self._target)
+        print "Repo '%s': executing repository script %s" % (self._target, self._repo_script)
+        self._pobj = popen2.Popen4(cmd=cmd)
+        fcntl.fcntl(self._pobj.fromchild.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
+        self._repo_script_start = time.time()
+
+    def _email_repo_script_failure(self, subject):
+        admins = config_opts['admin_emails']
+        msg = self._get_repo_script_output()
+        for addr in admins:
+            EmailUtils.email_result(addr, msg, subject)
+
+    def _get_repo_script_output(self):
+        output = ""
+        while True:
+            try:
+                string = os.read(self._pobj.fromchild.fileno(), 1024)
+                if not len(string):
+                    break
+            except OSError, e:
+                break
+            output = output + string
+        return output
+
+    def _monitor_repo_script(self):
+        unlock = False
+        exit_status = self._pobj.poll()
+        if exit_status == 0:
+            print "Repo '%s': repo script %s done." % (self._target, self._repo_script)
+            unlock = True
+        elif exit_status > 0:
+            subj = "Repo '%s': repo script %s exited with error: %d." % (self._target, self._repo_script, exit_status)
+            self._email_repo_script_failure(subj)
+            print subj
+            unlock = True
+        else:
+            # If the repo script has been going for more than an hour, kill it
+            if time.time() > self._repo_script_start + (60 * 60):
+                try:
+                    os.kill(self._pobj.pid, 9)
+                except OSError:
+                    pass
+                subj = "Repo '%s': repo script %s timed out and was killed." % (self._target, self._repo_script)
+                self._email_repo_script_failure(subj)
+                print subj
+                unlock = True
+
+        if unlock:
+            self._repo_script_start = 0
+            self._lock_count = 0
+            self._pobj = None
 
     def run(self):
         while self._stop == False:
-            # We have 2 lock levels.  When the repo is in either, clients are prevented
-            # from starting their 'prep' state.  Clients may already be in the 'prep'
-            # state when we lock the repo, therefore we don't actually enter lock level
-            # 2 until all clients have finished their 'prep' state.  Only then do we
-            # copy RPMs to the repo and run createrepo on it.
+            # We have 3 lock levels:
+            #
+            # 0 - repo unlocked
+            # 1 - entered when jobs request packages to be copied to the repo;
+            #           builders blocked from entering the 'prep' state
+            # 2 - entered when no builders are currently in the 'prep' state;
+            #       packages copied to repo and createrepo is run
+            # 3 - entered when createrepo is done; repo script run
 
             prepping_builders = self._builder_manager.any_prepping_builders()
 
             self._lock.acquire()
 
-            # If the lock level is 2, update the repo
+            # Level 2: update the repo
             if self._lock_count == 2:
                 print "Repo '%s': updating repository metadata..." % self._target
                 self._update_repo()
                 print "Repo '%s': Done updating." % self._target
-                self._lock_count = 0
 
-            # Enter lock level 2 if there are no build clients in the
+                # If there's a repo script for this target, enter level 3
+                if self._repo_script:
+                    self._run_repo_script()
+                    self._lock_count = 3
+                else:
+                    self._lock_count = 0
+
+            # Level 3: monitor the repo script
+            if self._lock_count == 3:
+                if self._pobj:
+                    self._monitor_repo_script()
+                else:
+                    # If for some reason self._pobj is None, unlock the repo
+                    self._lock_count = 0
+
+            # Enter lock level 2 if there are no builders in the
             # 'prep' state and we are already at lock level 1
             if not prepping_builders and self._lock_count == 1:
                 self._lock_count = 2




More information about the scm-commits mailing list