""" 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>"
import pwd
+logger = logging.getLogger()
+
+
def get_default_pkg_list_id(con):
""" Returns the package_list_id for the default package_list. """
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:
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,
""" 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.
"""
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:])