libguestfs: Use python3 for builds and the Python PIP package.
[goaljobs-goals.git] / fedora.ml
index 82324ff..79a9678 100644 (file)
--- a/fedora.ml
+++ b/fedora.ml
@@ -5,11 +5,7 @@ open Printf
 
 open Goaljobs
 
-(* Repo dir, etc. *)
-let fedora_dir = Sys.getenv "HOME" // "d/fedora"
-let fedora_repo pkg branch = fedora_dir // pkg // branch
-let fedora_specfile pkg branch =
-  sprintf "%s/%s.spec" (fedora_repo pkg branch) pkg
+open Config
 
 (* Get the current version of a package. *)
 let fedora_verrel pkg branch =
@@ -69,37 +65,65 @@ let contains_substring substr str =
   try ignore (String.find str substr); true
   with Invalid_string -> false
 
-(* Check if a Koji (completed successfully) build exists. *)
 (* Not helped by the fact that the 'koji' tool actively
  * resists automation: RHBZ#760924.
  *)
-let koji_build_exists =
-  let state_complete = contains_substring "State: COMPLETE" in
-  let state_other = contains_substring "State: " in
+
+(* XXX koji_build_state verrel: If you do a build and it fails, then
+ * do another build without bumping the release field, 'koji buildinfo'
+ * seems to always return the failed build, at least until the second
+ * build completes.  This means the code below fails.  Unclear how it
+ * can be fixed, but best to always bump the release to avoid the
+ * problem.
+ *)
+
+(* Get build state. *)
+let rec koji_build_state verrel =
+  fst (koji_build_state_task verrel)
+
+(* Get build state and task ID. *)
+and koji_build_state_task =
+  let state = Pcre.regexp "State: (\\w+)" in
+  let task_id = Pcre.regexp "Task: (\\d+)" in
   let no_such_build = contains_substring "No such build" in
   fun verrel ->
-    (* Once a build is known to be complete, memoize it. *)
+    (* For speed, if a build is complete memoize it. *)
     let key = sprintf "koji_build_complete_%s" verrel in
     if memory_exists key then
-      true
+      `Complete, None
     else (
-      let rec loop () =
-        let out = shout "timeout 120 koji buildinfo %s 2>&1 ||:" verrel in
-        if state_complete out then
-          true
-        else if state_other out then
-          false
-        else if no_such_build out then
-          false
-        else (
-          eprintf "%s\n" out;
-          eprintf "koji_build_exists: unknown output\nretrying ...\n%!";
-          loop ()
-        )
-      in
-      let r = loop () in
-      memory_set key "1";
-      r
+      let out = shout "timeout 120 koji buildinfo %s 2>&1 ||:" verrel in
+      if no_such_build out then
+        `No_such_build, None
+      else (
+        let state =
+          try
+            let subs = Pcre.exec ~rex:state out in
+            match Pcre.get_substring subs 1 with
+            | "BUILDING" -> `Building
+            | "COMPLETE" -> `Complete
+            | "DELETED" -> `Deleted
+            | "FAILED" -> `Failed
+            | "CANCELED" -> `Canceled
+            | sub ->
+              failwith (sprintf "koji_build_state_task: %s: unknown build state '%s'"
+                          verrel sub)
+          with
+            Not_found ->
+              failwith (sprintf "koji_build_state_task: %s: no build state found"
+                          verrel) in
+        let task =
+          try
+            let subs = Pcre.exec ~rex:task_id out in
+            Some (int_of_string (Pcre.get_substring subs 1))
+          with
+            Not_found -> None in
+
+        if state == `Complete then
+          memory_set key "1";
+
+        state, task
+      )
     )
 
 (* Perform a Koji build and wait until it finishes.  If it fails,
@@ -111,31 +135,44 @@ let koji_build =
     contains_substring "Name or service not known" in
   let completed_successfully = contains_substring "completed successfully" in
   let failed = contains_substring "FAILED" in
-  fun pkg branch ->
+  fun ?(wait = true) ?side_tag pkg branch ->
     let repodir = fedora_repo pkg branch in
-    let out = shout "cd %s && fedpkg build 2>&1 ||:" repodir in
-    let task_id =
-      try
-        let subs = Pcre.exec ~rex:created_task out in
-        int_of_string (Pcre.get_substring subs 1)
-      with Not_found ->
-        failwith "could not find task ID in fedpkg build output" in
-    let rec loop out =
-      if name_or_service_not_known out then (
-        let out =
-          shout "cd %s && koji watch-task %d 2>&1 ||:" repodir task_id in
-        loop out
-      )
-      else if completed_successfully out then
-        ()
-      else if failed out then (
-        eprintf "%s\n%!" out;
-        failwith "koji build failed"
-      )
-      else
-        failwith (sprintf "koji_build: unknown output: %s" out)
+    let out =
+      shout "
+        cd %s
+        fedpkg build%s%s 2>&1
+      " repodir
+        (if not wait then " --nowait" else "")
+        (match side_tag with None -> "" | Some t -> " --target " ^ t)
     in
-    loop out
+    if not wait then (
+      (* Just check the task was created. *)
+      if not (Pcre.pmatch ~rex:created_task out) then (
+        failwith "fedpkg build: build failed to start"
+      )
+    ) else (
+      let task_id =
+        try
+          let subs = Pcre.exec ~rex:created_task out in
+          int_of_string (Pcre.get_substring subs 1)
+        with Not_found ->
+          failwith "could not find task ID in fedpkg build output" in
+      let rec loop out =
+        if name_or_service_not_known out then (
+          let out =
+            shout "cd %s && koji watch-task %d 2>&1 ||:" repodir task_id in
+          loop out
+        )
+        else if completed_successfully out then
+          ()
+        else if failed out then (
+          failwith "koji build failed"
+        )
+        else
+          failwith (sprintf "koji_build: unknown output: %s" out)
+      in
+      loop out
+    )
 
 let koji_wait_repo =
   let successfully_waited = contains_substring "Successfully waited" in