removed volumes from bin scripts
This commit is contained in:
parent
468b5bfe3f
commit
0016763230
@ -57,11 +57,11 @@ if __name__ == '__main__':
|
||||
servers = []
|
||||
# manila-api
|
||||
try:
|
||||
servers.append(service.WSGIService('osapi_volume'))
|
||||
servers.append(service.WSGIService('osapi_share'))
|
||||
except (Exception, SystemExit):
|
||||
LOG.exception(_('Failed to load osapi_volume'))
|
||||
LOG.exception(_('Failed to load osapi_share'))
|
||||
|
||||
for binary in ['manila-volume', 'manila-scheduler']:
|
||||
for binary in ['manila-share', 'manila-scheduler']:
|
||||
try:
|
||||
servers.append(service.Service.create(binary=binary))
|
||||
except (Exception, SystemExit):
|
||||
|
@ -236,352 +236,6 @@ class VersionCommands(object):
|
||||
self.list()
|
||||
|
||||
|
||||
class ImportCommands(object):
|
||||
"""Methods for importing Nova volumes to manila.
|
||||
|
||||
EXPECTATIONS:
|
||||
These methods will do two things:
|
||||
1. Import relevant Nova DB info in to manila
|
||||
2. Import persistent tgt files from Nova to manila (see copy_tgt_files)
|
||||
|
||||
If you're using VG's (local storage) for your backend YOU MUST install
|
||||
manila 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_manila_db(self):
|
||||
#First, dump the dest_db as a backup incase this goes wrong
|
||||
manila_dump = utils.execute('mysqldump', 'manila')
|
||||
if 'Dump completed on' in manila_dump[0]:
|
||||
with open('./manila_db_bkup.sql', 'w+') as fo:
|
||||
for line in manila_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_manila_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 manila 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='<manila 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 manila 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 manila.
|
||||
|
||||
NOTE:
|
||||
Your manila DB should be clean WRT volume entries.
|
||||
|
||||
NOTE:
|
||||
We take an sqldump of the manila 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/manila' % 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/manila/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 manila.
|
||||
|
||||
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."""
|
||||
|
||||
@args('volume_id',
|
||||
help='Volume ID to be deleted')
|
||||
def delete(self, volume_id):
|
||||
"""Delete a volume, bypassing the check that it
|
||||
must be available."""
|
||||
ctxt = context.get_admin_context()
|
||||
volume = db.volume_get(ctxt, param2id(volume_id))
|
||||
host = volume['host']
|
||||
|
||||
if not host:
|
||||
print "Volume not yet assigned to host."
|
||||
print "Deleting volume from database and skipping rpc."
|
||||
db.volume_destroy(ctxt, param2id(volume_id))
|
||||
return
|
||||
|
||||
if volume['status'] == 'in-use':
|
||||
print "Volume is in-use."
|
||||
print "Detach volume from instance and then try again."
|
||||
return
|
||||
|
||||
rpc.cast(ctxt,
|
||||
rpc.queue_get_for(ctxt, FLAGS.volume_topic, host),
|
||||
{"method": "delete_volume",
|
||||
"args": {"volume_id": volume['id']}})
|
||||
|
||||
@args('volume_id',
|
||||
help='Volume ID to be reattached')
|
||||
def reattach(self, volume_id):
|
||||
"""Re-attach a volume that has previously been attached
|
||||
to an instance. Typically called after a compute host
|
||||
has been rebooted."""
|
||||
ctxt = context.get_admin_context()
|
||||
volume = db.volume_get(ctxt, param2id(volume_id))
|
||||
if not volume['instance_id']:
|
||||
print "volume is not attached to an instance"
|
||||
return
|
||||
instance = db.instance_get(ctxt, volume['instance_id'])
|
||||
host = instance['host']
|
||||
rpc.cast(ctxt,
|
||||
rpc.queue_get_for(ctxt, FLAGS.compute_topic, host),
|
||||
{"method": "attach_volume",
|
||||
"args": {"instance_id": instance['id'],
|
||||
"volume_id": volume['id'],
|
||||
"mountpoint": volume['mountpoint']}})
|
||||
|
||||
|
||||
class StorageManagerCommands(object):
|
||||
"""Class for mangaging Storage Backends and Flavors."""
|
||||
|
||||
@args('flavor', nargs='?',
|
||||
help='flavor to be listed')
|
||||
def flavor_list(self, flavor=None):
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
try:
|
||||
if flavor is None:
|
||||
flavors = db.sm_flavor_get_all(ctxt)
|
||||
else:
|
||||
flavors = db.sm_flavor_get(ctxt, flavor)
|
||||
except exception.NotFound as ex:
|
||||
print "error: %s" % ex
|
||||
sys.exit(2)
|
||||
|
||||
print "%-18s\t%-20s\t%s" % (_('id'),
|
||||
_('Label'),
|
||||
_('Description'))
|
||||
|
||||
for flav in flavors:
|
||||
print "%-18s\t%-20s\t%s" % (
|
||||
flav['id'],
|
||||
flav['label'],
|
||||
flav['description'])
|
||||
|
||||
@args('label', help='flavor label')
|
||||
@args('desc', help='flavor description')
|
||||
def flavor_create(self, label, desc):
|
||||
# TODO(renukaapte) flavor name must be unique
|
||||
try:
|
||||
db.sm_flavor_create(context.get_admin_context(),
|
||||
dict(label=label,
|
||||
description=desc))
|
||||
except exception.DBError, e:
|
||||
_db_error(e)
|
||||
|
||||
@args('label', help='label of flavor to be deleted')
|
||||
def flavor_delete(self, label):
|
||||
try:
|
||||
db.sm_flavor_delete(context.get_admin_context(), label)
|
||||
|
||||
except exception.DBError, e:
|
||||
_db_error(e)
|
||||
|
||||
def _splitfun(self, item):
|
||||
i = item.split("=")
|
||||
return i[0:2]
|
||||
|
||||
@args('backend_conf_id', nargs='?', default=None)
|
||||
def backend_list(self, backend_conf_id=None):
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
try:
|
||||
if backend_conf_id is None:
|
||||
backends = db.sm_backend_conf_get_all(ctxt)
|
||||
else:
|
||||
backends = db.sm_backend_conf_get(ctxt, backend_conf_id)
|
||||
|
||||
except exception.NotFound as ex:
|
||||
print "error: %s" % ex
|
||||
sys.exit(2)
|
||||
|
||||
print "%-5s\t%-10s\t%-40s\t%-10s\t%s" % (_('id'),
|
||||
_('Flavor id'),
|
||||
_('SR UUID'),
|
||||
_('SR Type'),
|
||||
_('Config Parameters'),)
|
||||
|
||||
for b in backends:
|
||||
print "%-5s\t%-10s\t%-40s\t%-10s\t%s" % (b['id'],
|
||||
b['flavor_id'],
|
||||
b['sr_uuid'],
|
||||
b['sr_type'],
|
||||
b['config_params'],)
|
||||
|
||||
@args('flavor_label')
|
||||
@args('sr_type')
|
||||
@args('args', nargs='*')
|
||||
def backend_add(self, flavor_label, sr_type, *args):
|
||||
# TODO(renukaapte) Add backend_introduce.
|
||||
ctxt = context.get_admin_context()
|
||||
params = dict(map(self._splitfun, args))
|
||||
sr_uuid = uuid.uuid4()
|
||||
|
||||
if flavor_label is None:
|
||||
print "error: backend needs to be associated with flavor"
|
||||
sys.exit(2)
|
||||
|
||||
try:
|
||||
flavors = db.sm_flavor_get(ctxt, flavor_label)
|
||||
|
||||
except exception.NotFound as ex:
|
||||
print "error: %s" % ex
|
||||
sys.exit(2)
|
||||
|
||||
config_params = " ".join(
|
||||
['%s=%s' % (key, params[key]) for key in params])
|
||||
|
||||
if 'sr_uuid' in params:
|
||||
sr_uuid = params['sr_uuid']
|
||||
try:
|
||||
backend = db.sm_backend_conf_get_by_sr(ctxt, sr_uuid)
|
||||
except exception.DBError, e:
|
||||
_db_error(e)
|
||||
|
||||
if backend:
|
||||
print 'Backend config found. Would you like to recreate this?'
|
||||
print '(WARNING:Recreating will destroy all VDIs on backend!!)'
|
||||
c = raw_input('Proceed? (y/n) ')
|
||||
if c == 'y' or c == 'Y':
|
||||
try:
|
||||
db.sm_backend_conf_update(
|
||||
ctxt, backend['id'],
|
||||
dict(created=False,
|
||||
flavor_id=flavors['id'],
|
||||
sr_type=sr_type,
|
||||
config_params=config_params))
|
||||
except exception.DBError, e:
|
||||
_db_error(e)
|
||||
return
|
||||
|
||||
else:
|
||||
print 'Backend config not found. Would you like to create it?'
|
||||
|
||||
print '(WARNING: Creating will destroy all data on backend!!!)'
|
||||
c = raw_input('Proceed? (y/n) ')
|
||||
if c == 'y' or c == 'Y':
|
||||
try:
|
||||
db.sm_backend_conf_create(ctxt,
|
||||
dict(flavor_id=flavors['id'],
|
||||
sr_uuid=sr_uuid,
|
||||
sr_type=sr_type,
|
||||
config_params=config_params))
|
||||
except exception.DBError, e:
|
||||
_db_error(e)
|
||||
|
||||
@args('backend_conf_id')
|
||||
def backend_remove(self, backend_conf_id):
|
||||
try:
|
||||
db.sm_backend_conf_delete(context.get_admin_context(),
|
||||
backend_conf_id)
|
||||
|
||||
except exception.DBError, e:
|
||||
_db_error(e)
|
||||
|
||||
|
||||
class ConfigCommands(object):
|
||||
"""Class for exposing the flags defined by flag_file(s)."""
|
||||
|
||||
@ -671,17 +325,13 @@ class ServiceCommands(object):
|
||||
|
||||
|
||||
CATEGORIES = {
|
||||
'backup': BackupCommands,
|
||||
'config': ConfigCommands,
|
||||
'db': DbCommands,
|
||||
'host': HostCommands,
|
||||
'logs': GetLogCommands,
|
||||
'service': ServiceCommands,
|
||||
'shell': ShellCommands,
|
||||
'sm': StorageManagerCommands,
|
||||
'version': VersionCommands,
|
||||
'volume': VolumeCommands,
|
||||
'migrate': ImportCommands,
|
||||
'version': VersionCommands
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user