UP_SQL = """
|
CREATE UNIQUE INDEX host_queue_entries_job_id_and_host_id
|
ON host_queue_entries (job_id, host_id);
|
|
DROP INDEX host_queue_entries_job_id ON host_queue_entries;
|
"""
|
|
|
DOWN_SQL = """
|
CREATE INDEX host_queue_entries_job_id ON host_queue_entries (job_id);
|
|
DROP INDEX host_queue_entries_job_id_and_host_id ON host_queue_entries;
|
"""
|
|
|
def null_out_duplicate_hqes(manager, hqe_ids):
|
if not hqe_ids:
|
return
|
ids_to_null_string = ','.join(str(hqe_id) for hqe_id in hqe_ids)
|
|
# check if any of the HQEs we're going to null out are active. if so, it's
|
# too dangerous to proceed.
|
rows = manager.execute('SELECT id FROM host_queue_entries '
|
'WHERE active AND id IN (%s)' % ids_to_null_string)
|
if rows:
|
raise Exception('Active duplicate HQEs exist, cannot proceed. Please '
|
'manually abort these HQE IDs: %s' % ids_to_null_string)
|
|
# go ahead and null them out
|
print 'Nulling out duplicate HQE IDs: %s' % ids_to_null_string
|
manager.execute('UPDATE host_queue_entries '
|
'SET host_id = NULL, active = FALSE, complete = TRUE, '
|
'aborted = TRUE, status = "Aborted" '
|
'WHERE id IN (%s)' % ids_to_null_string)
|
|
|
def migrate_up(manager):
|
# cleanup duplicate host_queue_entries. rather than deleting them (and
|
# dealing with foreign key references), we'll just null out their host_ids
|
# and set them to aborted.
|
rows = manager.execute('SELECT GROUP_CONCAT(id), COUNT(1) AS count '
|
'FROM host_queue_entries '
|
'WHERE host_id IS NOT NULL '
|
'GROUP BY job_id, host_id HAVING count > 1')
|
# gather all the HQE IDs we want to null out
|
ids_to_null = []
|
for ids_string, _ in rows:
|
id_list = ids_string.split(',')
|
# null out all but the first one. this isn't terribly important, but
|
# the first one is the most likely to have actually executed, so might
|
# as well keep that one.
|
ids_to_null.extend(id_list[1:])
|
|
null_out_duplicate_hqes(manager, ids_to_null)
|
|
manager.execute_script(UP_SQL)
|