From 17cd01ab8683080ac208b4903bcd65930d4e91ef Mon Sep 17 00:00:00 2001 From: Fabian Holler Date: Thu, 27 Sep 2012 12:07:35 +0200 Subject: [PATCH] use new db layout + bugfixes --- add_liveboot_request.py | 151 +++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 41 deletions(-) diff --git a/add_liveboot_request.py b/add_liveboot_request.py index a3fad10..cf01955 100644 --- a/add_liveboot_request.py +++ b/add_liveboot_request.py @@ -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 " @@ -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:]) -- 2.39.5