]> Frank Brehm's Git Trees - profitbricks/jenkins-build-scripts.git/commitdiff
use new db layout + bugfixes
authorFabian Holler <fabian.holler@profitbricks.com>
Thu, 27 Sep 2012 10:07:35 +0000 (12:07 +0200)
committerHolger Levsen <holger@layer-acht.org>
Thu, 27 Sep 2012 10:10:57 +0000 (12:10 +0200)
add_liveboot_request.py

index a3fad104bf0beac808c8bf05a3f05db4a15073e7..cf0195574f3852fd9a56a20228ff3f7369b289b0 100644 (file)
@@ -3,12 +3,6 @@
 """ This script creates a new liveboot build request when a new version of
     .deb package is available
 
-    If the package is included in the default pkg list for liveboot, the
-    version of this pkg in the default package list will be updates.
-
-
-    It updates the default pkg list for the liveboot in the database with the
-    create
 """
 
 __author__ = "Fabian Holler <fabian.holler@profitbricks.com>"
@@ -20,6 +14,9 @@ import logging
 import pwd
 
 
+logger = logging.getLogger()
+
+
 def get_default_pkg_list_id(con):
     """ Returns the package_list_id for the default package_list. """
 
@@ -31,15 +28,18 @@ def get_default_pkg_list_id(con):
         logger.error("Error: default_package_list_id doesn't exist in"
               " liveboot_settings table")
         return None
-    return int(result[0])
+    result = int(result[0])
+    logger.debug("Default package list id: %s" % result)
+    return result
 
 
 def get_deb_pkg_id(con, deb_package_instance_id):
     """ Return the deb_package_id for a given deb_package_instance_id. """
 
     cur = con.cursor()
-    cur.execute("SELECT dp.id FROM deb_package AS dp JOIN deb_package_instance"
-            " AS dpi ON (dpi.deb_package_id = dp.id) WHERE dpi.id =%s",
+    cur.execute("SELECT dp.id FROM deb_package AS dp JOIN"
+            " deb_package_instance AS dpi ON (dpi.deb_package_id = dp.id)"
+            " WHERE dpi.id =%s",
             (deb_package_instance_id,))
     result = cur.fetchone()
     if not result:
@@ -49,14 +49,41 @@ def get_deb_pkg_id(con, deb_package_instance_id):
     return int(result[0])
 
 
+def lock_table(con, table_name):
+    cur = con.cursor()
+    cur.execute("LOCK TABLE %s IN EXCLUSIVE MODE" % table_name)
+    # no unlock table cmd exists, tables are unlocked at transaction end
+
+
 def get_deb_pkg_instance_ids(con, deb_package_id):
     """ Returns all deb_package_instance ids for a given deb_package_id. """
 
     cur = con.cursor()
-    cur.execute("SELECT id FROM deb_package_instance AS dpi"
+    cur.execute("SELECT dpi.id FROM deb_package_instance AS dpi"
         " JOIN deb_package AS dp ON (dpi.deb_package_id = dp.id)"
         " WHERE dp.id=%s", (deb_package_id,))
-    return cur.fetchall()
+    result = cur.fetchall()
+    return tuple([ i[0] for i in result ])
+
+
+def duplicate_pkg_list(con, deb_package_list_id):
+    """ Duplicates a deb_package_list and returns the id of the new list.
+
+        Creates a new deb_package_list that contains the same package that the
+        list with the passed deb_package_list_id.
+    """
+
+    cur = con.cursor()
+    cur.execute("INSERT INTO package_list(id) VALUES("
+        " (SELECT nextval('package_list_id_seq'))) RETURNING ID")
+    new_pkg_list_id = cur.fetchone()[0]
+    cur.execute("INSERT INTO package_list_deb_package_instance"
+        "(package_list_id, deb_package_instance_id)"
+        "  SELECT '%s' AS package_list_id, deb_package_instance_id FROM"
+        " package_list_deb_package_instance WHERE package_list_id=%s",
+        (new_pkg_list_id, deb_package_list_id))
+
+    return new_pkg_list_id
 
 
 def update_default_package_list(con, def_package_list_id,
@@ -64,9 +91,14 @@ def update_default_package_list(con, def_package_list_id,
     """ Updates a deb_package_id field in deb_package_list.
 
         @param def_package_list_id ID of the deb_package_list
-        @param new_deb_package_instance_id ID of the deb_package_list
-        @param old_deb_package_instance_ids List of deb_package_ids that
-            should be changed to new_deb_package_instance_id
+        @param new_deb_package_instance_id deb_package_instance that should
+            be included in the package_list.
+        @param old_deb_package_instance_ids All deb_package_instance IDs for
+            the deb_package of new_deb_packge_instance_ids.
+            All package_instances in the package_list that have one of these
+            IDs are changed to new_deb_package_instance_id
+        @type old_deb_package_instance_ids: List of int
+
         @return True If at least one record was updated.
         @return False If no record was updated.
     """
@@ -74,43 +106,80 @@ def update_default_package_list(con, def_package_list_id,
     cur = con.cursor()
     cur.execute("UPDATE package_list_deb_package_instance AS pldpi"
         " SET deb_package_instance_id = %s WHERE pldpi.package_list_id = %s"
-        " AND pldpi.deb_package_instance_id IN %s RETURNING package_list_id",
-        (new_deb_package_instance_id, def_package_list_id,
-            old_deb_package_instance_ids))
+        " AND pldpi.deb_package_instance_id IN %s"
+        " RETURNING package_list_id", (new_deb_package_instance_id,
+            def_package_list_id, old_deb_package_instance_ids))
 
     result = cur.fetchall()
-    return(True and result)
+    return(len(result) != 0)
 
 
 def insert_liveboot_request(con, owner_uid, package_list_id):
+    """ Inserts a new record in the liveboot_request table. """
     cur = con.cursor()
     cur.execute("INSERT INTO liveboot_request(owner_uid, package_list_id)"
-        " VALUES(%s)", (owner_uid, package_list_id))
+        " VALUES(%s, %s)", (owner_uid, package_list_id))
 
-def add_liveboot_request(deb_pkg_instance_id):
-    logging.basicConfig()
-    logger = logging.getLogger()
+
+def add_liveboot_request(deb_pkg_instance_ids):
+    """ Creates a new liveboot request.
+
+        If none of the passed packages are included in the default package
+        list nothing is done.
+
+        If the passed packages are included in the default pkg list for the
+        liveboot the default list will be modified to include the passed
+        package instances. Afterwards a new liveboot request for the default
+        package list will be created.
+
+        @type deb_pkg_instance_ids List of str
+    """
 
     con = db_connect()
-    # If the package is included in the default package list, update the list
-    # to include newest version of the package
-    deb_pkg_id = get_deb_pkg_id(con, deb_pkg_instance_id)
-    def_pkg_list_id = get_default_pkg_list(con)
-
-    # This can't return None with the used db constraints
-    deb_pkg_instance_ids = get_deb_pkg_instance_ids(con, deb_pkg_id)
-
-    updated = update_default_package_list(con, def_pkg_list_id,
-        deb_pkg_instance_id, deb_pkg_instance_ids)
-    con.commit()
-    logger.info("Updated default package list successfully")
-
-    if not updated:
-        logger.info("deb_package with id %s doesn't exist in default package"
-            " list, no liveboot request will be created")
-    else:
+
+    def_pkg_list_id = get_default_pkg_list_id(con)
+
+    def_pkg_list_updated = False  # is set to True if at least one
+                                  # package_instance_id is included in the
+                                  # default package list
+
+    # make sure the default pkg list isn't changed while we are creating a new
+    # liveboot request
+    lock_table(con, "package_list_deb_package_instance")
+
+    for deb_pkg_instance_id in deb_pkg_instance_ids:
+        # If the package is included in the default package list, update the
+        # default pkg list to include newest version of the package
+        deb_pkg_id = get_deb_pkg_id(con, deb_pkg_instance_id)
+
+        # Get all deb_package_instances for a debian package
+        instance_ids = get_deb_pkg_instance_ids(con, deb_pkg_id)
+
+        if (update_default_package_list(con, def_pkg_list_id,
+            deb_pkg_instance_id, instance_ids)):
+            def_pkg_list_updated = True
+        else:
+            logger.info("deb_pkg_instance_id %s isn't included in the liveboot"
+                " request because it isn't member of the default package list")
+
+    if def_pkg_list_updated:
+        pkg_list = duplicate_pkg_list(con, def_pkg_list_id)
         # create a new liveboot request with the updated default package list
-        jenkins_uid = pwd.getpwnam("jenkins").pw_uid
+        try:
+            jenkins_uid = pwd.getpwnam("jenkins").pw_uid
+        except Exception as e:
+            logger.warning("User jenkins can't be found, liveboot_request uid is"
+            " unspecified")
+            jenkins_uid = None
+
         insert_liveboot_request(con, jenkins_uid, def_pkg_list_id)
         con.commit()
-    return
+        logger.info("New liveboot request created sucessfully")
+    else:
+        logger.info("Package isn't in the default package_list, no liveboot"
+            " request was created")
+
+
+if __name__ == "__main__":
+    logging.basicConfig(level=logging.DEBUG)
+    add_liveboot_request(sys.argv[1:])