From a5f19ff5de1b43f845c21466b36196d325634f8e Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Dec 18 2017 16:20:06 +0000 Subject: drop migrateImage call The migrateImage call allows migrating pre-1.8 image builds from the old model (no build entry) to the new model (image build type). This call was added in 1.8 (4.5 years ago) as a one-time tool for migration. It is only available if the EnableImageMigration is set on the hub. See also: https://docs.pagure.org/koji/migrating_to_1.8/ Related: https://pagure.io/koji/issue/612 --- diff --git a/hub/kojihub.py b/hub/kojihub.py index d823f30..d4bab4a 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -6064,147 +6064,6 @@ def new_typed_build(build_info, btype): insert.execute() -def old_image_data(old_image_id): - """Return old image data for given id""" - - values = dict(img_id=old_image_id) - tables = ['imageinfo'] - fields = ['id', 'task_id', 'filename', 'filesize', 'arch', 'hash', 'mediatype'] - clauses = ['imageinfo.id = %(img_id)i'] - - query = QueryProcessor(columns=fields, tables=tables, clauses=clauses, - values=values) - ret = query.executeOne() - - if not ret: - raise koji.GenericError('no old image with ID: %i' % old_image_id) - return ret - -def check_old_image_files(old): - """Check for existence of files for old image data""" - - parts = [koji.pathinfo.topdir, 'images'] - if old['mediatype'] == 'LiveCD ISO': - parts.append('livecd') - else: - parts.append('appliance') - parts.extend([str(old['id'] % 10000), str(old['id'])]) - img_dir = os.path.join(*parts) - img_path = os.path.join(img_dir, old['filename']) - if not os.path.exists(img_path): - raise koji.GenericError("Image file is missing: %s" % img_path) - if os.path.islink(img_path): - raise koji.GenericError("Image file is a symlink: %s" % img_path) - if not os.path.isfile(img_path): - raise koji.GenericError("Not a regular file: %s" % img_path) - img_size = os.path.getsize(img_path) - if img_size != old['filesize']: - raise koji.GenericError("Size mismatch for %s (%i != %i)" % \ - (img_path, img_size, old['filesize'])) - # old images always used sha256 hashes - sha256sum = hashlib.sha256() - image_fo = open(img_path, 'r') - while True: - data = image_fo.read(1048576) - sha256sum.update(data) - if not len(data): - break - img_hash = sha256sum.hexdigest() - if img_hash != old['hash']: - raise koji.GenericError("Hash mismatch for %s (%i != %i)" % \ - (img_path, img_hash, old['hash'])) - # file looks ok - old['path'] = img_path - old['dir'] = img_dir - - # check for extra files, noting accompanying xml file - expected = [old['filename'], 'data'] - extra = [] - for out_file in os.listdir(img_dir): - if out_file in expected: - pass - elif out_file.endswith('.xml') and old['mediatype'] != 'LiveCD ISO': - if 'xmlfile' in old: - extra.append(out_file) - else: - old['xmlfile'] = out_file - else: - extra.append(out_file) - if extra: - raise koji.GenericError("Unexpected files under %s: %r" % (img_dir, extra)) - - -def import_old_image(old, name, version): - """Import old image data into the new data model""" - - # note: since this is a one-time migration tool, we are not triggering callbacks - # ^ XXX: except that some functions we call do - - # build entry - task = Task(old['task_id']) - binfo = dict(name=name, version=version) - binfo['release'] = get_next_release(binfo) - binfo['epoch'] = 0 - binfo['task_id'] = old['task_id'] - binfo['owner'] = task.getOwner() - binfo['state'] = koji.BUILD_STATES['COMPLETE'] - build_id = new_build(binfo) - binfo['id'] = build_id - new_image_build(binfo) - - # figure out buildroot id - # the old schema did not track buildroot directly, so we have to infer - # by task id. - # If the task had multiple buildroots, we chose the latest - query = QueryProcessor(columns=['buildroot_id'], tables=['standard_buildroot'], - clauses=['task_id=%(task_id)i'], values=old, - opts={'order': '-id', 'limit': 1}) - br_id = query.singleValue(strict=False) - - # archives - archives = [] - for fn in [old['filename'], old.get('xmlfile')]: - if not fn: - continue - fullpath = os.path.join(old['dir'], fn) - archivetype = get_archive_type(filename=fn) - logger.debug('image type we are migrating is: %s' % archivetype) - if not archivetype: - raise koji.BuildError('Unsupported image type') - imgdata = dict(arch=old['arch']) - archives.append(import_archive(fullpath, binfo, 'image', imgdata, buildroot_id=br_id)) - - # deal with contents listing - archive_id = archives[0]['id'] - logger.debug('root archive id is %s' % archive_id) - query = QueryProcessor(columns=['rpm_id'], tables=['imageinfo_listing'], - clauses=['archive_id=%(id)i'], values=old, - opts={'asList': True}) - rpm_ids = [r[0] for r in query.execute()] - insert = InsertProcessor('archive_rpm_components') - insert.set(archive_id=archive_id) - for rpm_id in rpm_ids: - insert.set(rpm_id=rpm_id) - insert.execute() - logger.info('updated archive_rpm_components') - - # grab old logs - old_log_dir = os.path.join(old['dir'], 'data', 'logs', old['arch']) - logdir = os.path.join(koji.pathinfo.build(binfo), 'data/logs/image') - for logfile in os.listdir(old_log_dir): - logsrc = os.path.join(old_log_dir, logfile) - koji.ensuredir(logdir) - final_path = os.path.join(logdir, logfile) - if os.path.exists(final_path): - raise koji.GenericError("Error importing build log. %s already exists." % final_path) - if os.path.islink(logsrc) or not os.path.isfile(logsrc): - raise koji.GenericError("Error importing build log. %s is not a regular file." % logsrc) - safer_move(logsrc, final_path) - os.symlink(final_path, logsrc) - - return binfo - - def import_archive(filepath, buildinfo, type, typeInfo, buildroot_id=None): """ Import an archive file and associate it with a build. The archive can @@ -8810,18 +8669,6 @@ class RootExports(object): return make_task('image', [name, version, arches, target, inst_tree, opts], **taskOpts) - def migrateImage(self, old_image_id, name, version): - """Migrate an old image to the new schema - - This call must be enabled via hub.conf (the EnableImageMigration setting) - """ - context.session.assertPerm('admin') - if not context.opts.get('EnableImageMigration'): - raise koji.GenericError('Image migration not enabled') - old = old_image_data(old_image_id) - check_old_image_files(old) - return import_old_image(old, name, version) - def hello(self, *args): return "Hello World" @@ -8845,9 +8692,6 @@ class RootExports(object): def winEnabled(self): return bool(context.opts.get('EnableWin')) - def imageMigrationEnabled(self): - return bool(context.opts.get('EnableImageMigration')) - def showSession(self): return "%s" % context.session diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 2307d59..f518da8 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -433,7 +433,6 @@ def load_config(environ): ['MissingPolicyOk', 'boolean', True], ['EnableMaven', 'boolean', False], ['EnableWin', 'boolean', False], - ['EnableImageMigration', 'boolean', False], ['RLIMIT_AS', 'string', None], ['RLIMIT_CORE', 'string', None],