self.list()
-class ImportCommands(object):
- """Methods for importing Nova volumes to Cinder.
-
- EXPECTATIONS:
- These methods will do two things:
- 1. Import relevant Nova DB info in to Cinder
- 2. Import persistent tgt files from Nova to Cinder (see copy_tgt_files)
-
- If you're using VG's (local storage) for your backend YOU MUST install
- Cinder on the same node that you're migrating from.
- """
- def __init__(self):
- pass
-
- def _map_table(self, table):
- class Mapper(declarative_base()):
- __table__ = table
- return Mapper
-
- def _open_session(self, con_info):
- # Note(jdg): The echo option below sets whether to dispaly db command
- # debug info.
- engine = create_engine(con_info,
- convert_unicode=True,
- echo=False)
- session = sessionmaker(bind=engine)
- return (session(), engine)
-
- def _backup_cinder_db(self):
- #First, dump the dest_db as a backup incase this goes wrong
- cinder_dump = utils.execute('mysqldump', 'cinder')
- if 'Dump completed on' in cinder_dump[0]:
- with open('./cinder_db_bkup.sql', 'w+') as fo:
- for line in cinder_dump:
- fo.write(line)
- else:
- raise exception.InvalidResults()
-
- def _import_db(self, src_db, dest_db, backup_db):
- # Remember order matters due to FK's
- table_list = ['sm_flavors',
- 'sm_backend_config',
- 'snapshots',
- 'volume_types',
- 'volumes',
- 'iscsi_targets',
- 'sm_volume',
- 'volume_metadata',
- 'volume_type_extra_specs']
-
- quota_table_list = ['quota_classes',
- 'quota_usages',
- 'quotas',
- 'reservations']
-
- if backup_db > 0:
- if 'mysql:' not in dest_db:
- print (_('Sorry, only mysql backups are supported!'))
- raise exception.InvalidRequest()
- else:
- self._backup_cinder_db()
-
- (src, src_engine) = self._open_session(src_db)
- src_meta = MetaData(bind=src_engine)
- (dest, dest_engine) = self._open_session(dest_db)
-
- # First make sure nova is at Folsom
- table = Table('migrate_version', src_meta, autoload=True)
- if src.query(table).first().version < 132:
- print (_('ERROR: Specified Nova DB is not at a compatible '
- 'migration version!\nNova must be at Folsom or newer '
- 'to import into Cinder database.'))
- sys.exit(2)
-
- for table_name in table_list:
- print (_('Importing table %s...') % table_name)
- table = Table(table_name, src_meta, autoload=True)
- new_row = self._map_table(table)
- columns = table.columns.keys()
- for row in src.query(table).all():
- data = dict([(str(column), getattr(row, column))
- for column in columns])
- dest.add(new_row(**data))
- dest.commit()
-
- for table_name in quota_table_list:
- print (_('Importing table %s...') % table_name)
- table = Table(table_name, src_meta, autoload=True)
- new_row = self._map_table(table)
- columns = table.columns.keys()
- for row in src.query(table).all():
- if row.resource == 'gigabytes' or row.resource == 'volumes':
- data = dict([(str(column), getattr(row, column))
- for column in columns])
- dest.add(new_row(**data))
- dest.commit()
-
- @args('src', metavar='<Nova DB>',
- help='db-engine://db_user[:passwd]@db_host[:port]\t\t'
- 'example: mysql://root:secrete@192.168.137.1')
- @args('dest', metavar='<Cinder DB>',
- help='db-engine://db_user[:passwd]@db_host[:port]\t\t'
- 'example: mysql://root:secrete@192.168.137.1')
- @args('--backup', metavar='<0|1>', choices=[0, 1], default=1,
- help='Perform mysqldump of cinder db before writing to it'
- ' (default: %(default)d)')
- def import_db(self, src_db, dest_db, backup_db=1):
- """Import relevant volume DB entries from Nova into Cinder.
-
- NOTE:
- Your Cinder DB should be clean WRT volume entries.
-
- NOTE:
- We take an sqldump of the cinder DB before mods
- If you're not using mysql, set backup_db=0
- and create your own backup.
- """
- src_db = '%s/nova' % src_db
- dest_db = '%s/cinder' % dest_db
- self._import_db(src_db, dest_db, backup_db)
-
- @args('src',
- help='e.g. (login@src_host:]/opt/stack/nova/volumes/)')
- @args('dest', nargs='?', default=None,
- help='e.g. (login@src_host:/opt/stack/cinder/volumes/) '
- 'optional, if emitted, \'volume_dir\' in config will be used')
- def copy_ptgt_files(self, src_tgts, dest_tgts=None):
- """Copy persistent scsi tgt files from nova to cinder.
-
- Default destination is FLAGS.volume_dir or state_path/volumes/
-
- PREREQUISITES:
- Persistent tgts were introduced in Folsom. If you're running
- Essex or other release, this script is unnecessary.
-
- NOTE:
- If you're using local VG's and LVM for your nova volume backend
- there's no point in copying these files over. Leave them on
- your Nova system as they won't do any good here.
- """
- if dest_tgts is None:
- try:
- dest_tgts = FLAGS.volumes_dir
- except Exception:
- dest_tgts = '%s/volumes' % FLAGS.state_path
-
- utils.execute('rsync', '-avz', src_tgts, dest_tgts)
-
-
class VolumeCommands(object):
"""Methods for dealing with a cloud in an odd state."""
'sm': StorageManagerCommands,
'version': VersionCommands,
'volume': VolumeCommands,
- 'migrate': ImportCommands,
}