introspection data backend: migration tool
This patch provides a simple tool to help with migrating introspection data between two introspection data storages. Story: 1726713 Task: 11373 Change-Id: I2a930dbad2178e3dde6725e2620d8099e4e21d78
This commit is contained in:
parent
68a4829c01
commit
1d94e534b9
128
ironic_inspector/cmd/migration.py
Normal file
128
ironic_inspector/cmd/migration.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""Migrate introspected data between Swift and database."""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log
|
||||||
|
from oslo_utils import encodeutils
|
||||||
|
import six
|
||||||
|
|
||||||
|
from ironic_inspector.common.i18n import _
|
||||||
|
from ironic_inspector.conf import opts
|
||||||
|
from ironic_inspector import node_cache
|
||||||
|
from ironic_inspector.plugins import base as plugins_base
|
||||||
|
from ironic_inspector import utils
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
_AVAILABLE_STORAGES = [('database', _('The database storage backend')),
|
||||||
|
('swift', _('The Swift storage backend'))]
|
||||||
|
_OPTS = [
|
||||||
|
cfg.StrOpt('from',
|
||||||
|
dest='source_storage',
|
||||||
|
required=True,
|
||||||
|
choices=_AVAILABLE_STORAGES,
|
||||||
|
help=_('The source storage where the introspected data will be '
|
||||||
|
'read from.')),
|
||||||
|
cfg.StrOpt('to',
|
||||||
|
dest='target_storage',
|
||||||
|
required=True,
|
||||||
|
choices=_AVAILABLE_STORAGES,
|
||||||
|
help=_('The target storage where the introspected data will be '
|
||||||
|
'saved to.'))
|
||||||
|
]
|
||||||
|
|
||||||
|
# Migration result
|
||||||
|
RESULT_NOCONTENT = 'no content'
|
||||||
|
RESULT_FAILED = 'failed'
|
||||||
|
RESULT_SUCCESS = 'success'
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_logger(args=None):
|
||||||
|
args = [] if args is None else args
|
||||||
|
log.register_options(CONF)
|
||||||
|
opts.set_config_defaults()
|
||||||
|
opts.parse_args(args)
|
||||||
|
log.setup(CONF, 'ironic_inspector')
|
||||||
|
|
||||||
|
|
||||||
|
class MigrationTool(object):
|
||||||
|
|
||||||
|
def _migrate_one(self, node, processed):
|
||||||
|
LOG.debug('Starting to migrate introspection data for node '
|
||||||
|
'%(node)s (processed %(processed)s)',
|
||||||
|
{'node': node.uuid, 'processed': processed})
|
||||||
|
try:
|
||||||
|
data = self.ext_src.get(node.uuid, processed=processed,
|
||||||
|
get_json=True)
|
||||||
|
if not data:
|
||||||
|
return RESULT_NOCONTENT
|
||||||
|
self.ext_tgt.save(node.uuid, data, processed=processed)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Migrate introspection data failed for node '
|
||||||
|
'%(node)s (processed %(processed)s), error: '
|
||||||
|
'%(error)s', {'node': node.uuid, 'processed': processed,
|
||||||
|
'error': e})
|
||||||
|
return RESULT_FAILED
|
||||||
|
|
||||||
|
return RESULT_SUCCESS
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
CONF.register_cli_opts(_OPTS)
|
||||||
|
_setup_logger(sys.argv[1:])
|
||||||
|
|
||||||
|
if CONF.source_storage == CONF.target_storage:
|
||||||
|
raise utils.Error(_('Source and destination can not be the same.'))
|
||||||
|
|
||||||
|
introspection_data_manager = plugins_base.introspection_data_manager()
|
||||||
|
self.ext_src = introspection_data_manager[CONF.source_storage].obj
|
||||||
|
self.ext_tgt = introspection_data_manager[CONF.target_storage].obj
|
||||||
|
|
||||||
|
nodes = node_cache.get_node_list()
|
||||||
|
migration_list = [(n, p) for n in nodes for p in [True, False]]
|
||||||
|
failed_records = []
|
||||||
|
for node, processed in migration_list:
|
||||||
|
result = self._migrate_one(node, processed)
|
||||||
|
if result == RESULT_FAILED:
|
||||||
|
failed_records.append((node.uuid, processed))
|
||||||
|
|
||||||
|
msg = ('Finished introspection data migration, total records: %d. '
|
||||||
|
% len(migration_list))
|
||||||
|
if failed_records:
|
||||||
|
msg += 'Failed to migrate:\n' + '\n'.join([
|
||||||
|
'%s(processed=%s)' % (record[0], record[1])
|
||||||
|
for record in failed_records])
|
||||||
|
elif len(migration_list) > 0:
|
||||||
|
msg += 'all records are migrated successfully.'
|
||||||
|
print(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
try:
|
||||||
|
MigrationTool().main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print(_("... terminating migration tool"), file=sys.stderr)
|
||||||
|
return 130
|
||||||
|
except Exception as e:
|
||||||
|
print(encodeutils.safe_encode(six.text_type(e)), file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds a migration tool ``ironic-inspector-migrate-data`` to facilitate the
|
||||||
|
introspection data migration between supported introspection data storage
|
||||||
|
backends. Currently the available introspection data storage backends are:
|
||||||
|
``database`` and ``swift``. For example, to migrate existing introspection
|
||||||
|
data stored in the swift to database, execute following command:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ ironic-inspector-migrate-data --from swift --to database --config-file /etc/ironic-inspector/inspector.conf
|
||||||
|
|
||||||
|
Storage backends involved in the migration should have been properly
|
||||||
|
configured in the ironic inspector configuration file. Before the
|
||||||
|
introspection data migration can be started. The ironic inspector database
|
||||||
|
should be upgraded to have the latest schema.
|
@ -28,6 +28,7 @@ console_scripts =
|
|||||||
ironic-inspector = ironic_inspector.cmd.all:main
|
ironic-inspector = ironic_inspector.cmd.all:main
|
||||||
ironic-inspector-dbsync = ironic_inspector.dbsync:main
|
ironic-inspector-dbsync = ironic_inspector.dbsync:main
|
||||||
ironic-inspector-rootwrap = oslo_rootwrap.cmd:main
|
ironic-inspector-rootwrap = oslo_rootwrap.cmd:main
|
||||||
|
ironic-inspector-migrate-data = ironic_inspector.cmd.migration:main
|
||||||
ironic_inspector.hooks.processing =
|
ironic_inspector.hooks.processing =
|
||||||
scheduler = ironic_inspector.plugins.standard:SchedulerHook
|
scheduler = ironic_inspector.plugins.standard:SchedulerHook
|
||||||
validate_interfaces = ironic_inspector.plugins.standard:ValidateInterfacesHook
|
validate_interfaces = ironic_inspector.plugins.standard:ValidateInterfacesHook
|
||||||
|
Loading…
Reference in New Issue
Block a user