# Copyright (C) 2016-2024 RhodeCode GmbH # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License, version 3 # (only), as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # This program is dual-licensed. If you wish to learn more about the # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ import sys import logging import click from rhodecode.lib.pyramid_utils import bootstrap from rhodecode.lib.ext_json import json from rhodecode.model.db import FileStore from rhodecode.apps.file_store import utils as store_utils log = logging.getLogger(__name__) @click.command() @click.argument('ini_path', type=click.Path(exists=True)) @click.argument('file_uid') @click.option( '--source-backend-conf', type=click.Path(exists=True, dir_okay=False, readable=True), help='Source backend config file path in a json format' ) @click.option( '--dest-backend-conf', type=click.Path(exists=True, dir_okay=False, readable=True), help='Source backend config file path in a json format' ) def main(ini_path, file_uid, source_backend_conf, dest_backend_conf): return command(ini_path, file_uid, source_backend_conf, dest_backend_conf) _source_settings = {} _dest_settings = {} def command(ini_path, file_uid, source_backend_conf, dest_backend_conf): with bootstrap(ini_path, env={'RC_CMD_SETUP_RC': '1'}) as env: migrate_func(env, file_uid, source_backend_conf, dest_backend_conf) def migrate_func(env, file_uid, source_backend_conf=None, dest_backend_conf=None): """ Example usage:: from rhodecode.lib.rc_commands import migrate_artifact migrate_artifact._source_settings = { 'file_store.backend.type': 'filesystem_v1', 'file_store.filesystem_v1.storage_path': '/var/opt/rhodecode_data/file_store', } migrate_artifact._dest_settings = { 'file_store.backend.type': 'objectstore', 'file_store.objectstore.url': 'http://s3-minio:9000', 'file_store.objectstore.bucket': 'rhodecode-file-store', 'file_store.objectstore.key': 's3admin', 'file_store.objectstore.secret': 's3secret4', 'file_store.objectstore.region': 'eu-central-1', } for db_obj in FileStore.query().all(): migrate_artifact.migrate_func({}, db_obj.file_uid) """ try: from rc_ee.api.views.store_api import _store_file except ImportError: click.secho('ERROR: Unable to import store_api. ' 'store_api is only available in EE edition of RhodeCode', fg='red') sys.exit(-1) source_settings = _source_settings if source_backend_conf: source_settings = json.loads(open(source_backend_conf).read()) dest_settings = _dest_settings if dest_backend_conf: dest_settings = json.loads(open(dest_backend_conf).read()) if file_uid.isnumeric(): file_store_db_obj = FileStore().query() \ .filter(FileStore.file_store_id == file_uid) \ .scalar() else: file_store_db_obj = FileStore().query() \ .filter(FileStore.file_uid == file_uid) \ .scalar() if not file_store_db_obj: click.secho(f'ERROR: Unable to fetch artifact from database file_uid={file_uid}', fg='red') sys.exit(-1) uid_filename = file_store_db_obj.file_uid org_filename = file_store_db_obj.file_display_name click.secho(f'Attempting to migrate artifact {uid_filename}, filename: {org_filename}', fg='green') # get old version of f_store based on the data. origin_f_store = store_utils.get_filestore_backend(source_settings, always_init=True) reader, metadata = origin_f_store.fetch(uid_filename) target_f_store = store_utils.get_filestore_backend(dest_settings, always_init=True) target_f_store.import_to_store(reader, org_filename, uid_filename, metadata) click.secho(f'Migrated artifact {uid_filename}, filename: {org_filename} into {target_f_store} storage', fg='green')