Move backup and restore into common
This commit is contained in:
parent
059230d369
commit
01c82f5d19
|
@ -45,89 +45,33 @@ def initialize_cluster(zkhandler, overwrite=False):
|
||||||
"""
|
"""
|
||||||
Initialize a new cluster
|
Initialize a new cluster
|
||||||
"""
|
"""
|
||||||
# Abort if we've initialized the cluster before
|
retflag, retmsg = pvc_cluster.cluster_initialize(zkhandler, overwrite)
|
||||||
if zkhandler.exists('/config/primary_node') and not overwrite:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if overwrite:
|
retmsg = {
|
||||||
# Delete the existing keys; ignore any errors
|
'message': retmsg
|
||||||
status = zkhandler.delete([
|
}
|
||||||
'/config'
|
if retflag:
|
||||||
'/nodes',
|
retcode = 200
|
||||||
'/domains',
|
else:
|
||||||
'/networks',
|
retcode = 400
|
||||||
'/ceph',
|
|
||||||
'/ceph/osds',
|
|
||||||
'/ceph/pools',
|
|
||||||
'/ceph/volumes',
|
|
||||||
'/ceph/snapshots',
|
|
||||||
'/cmd',
|
|
||||||
'/cmd/domains',
|
|
||||||
'/cmd/ceph',
|
|
||||||
'/locks',
|
|
||||||
'/locks/flush_lock',
|
|
||||||
'/locks/primary_node'
|
|
||||||
], recursive=True)
|
|
||||||
|
|
||||||
if not status:
|
return retmsg, retcode
|
||||||
return False
|
|
||||||
|
|
||||||
# Create the root keys
|
|
||||||
status = zkhandler.write([
|
|
||||||
('/config', ''),
|
|
||||||
('/config/primary_node', 'none'),
|
|
||||||
('/config/upstream_ip', 'none'),
|
|
||||||
('/config/maintenance', 'False'),
|
|
||||||
('/config/migration_target_selector', 'none'),
|
|
||||||
('/nodes', ''),
|
|
||||||
('/domains', ''),
|
|
||||||
('/networks', ''),
|
|
||||||
('/ceph', ''),
|
|
||||||
('/ceph/osds', ''),
|
|
||||||
('/ceph/pools', ''),
|
|
||||||
('/ceph/volumes', ''),
|
|
||||||
('/ceph/snapshots', ''),
|
|
||||||
('/cmd', ''),
|
|
||||||
('/cmd/domains', ''),
|
|
||||||
('/cmd/ceph', ''),
|
|
||||||
('/locks', ''),
|
|
||||||
('/locks/flush_lock', ''),
|
|
||||||
('/locks/primary_node', ''),
|
|
||||||
])
|
|
||||||
|
|
||||||
return status
|
|
||||||
|
|
||||||
|
|
||||||
@ZKConnection(config)
|
@ZKConnection(config)
|
||||||
def backup_cluster(zkhandler):
|
def backup_cluster(zkhandler):
|
||||||
# Dictionary of values to come
|
retflag, retdata = pvc_cluster.cluster_backup(zkhandler)
|
||||||
cluster_data = dict()
|
|
||||||
|
|
||||||
def get_data(path):
|
if retflag:
|
||||||
data = zkhandler.read(path)
|
retcode = 200
|
||||||
children = zkhandler.children(path)
|
retdata = json.dumps(retdata)
|
||||||
|
|
||||||
cluster_data[path] = data
|
|
||||||
|
|
||||||
if children:
|
|
||||||
if path == '/':
|
|
||||||
child_prefix = '/'
|
|
||||||
else:
|
else:
|
||||||
child_prefix = path + '/'
|
retcode = 400
|
||||||
|
retdata = {
|
||||||
|
'message': retdata
|
||||||
|
}
|
||||||
|
|
||||||
for child in children:
|
return retdata, retcode
|
||||||
if child_prefix + child == '/zookeeper':
|
|
||||||
# We must skip the built-in /zookeeper tree
|
|
||||||
continue
|
|
||||||
if child_prefix + child == '/patroni':
|
|
||||||
# We must skip the /patroni tree
|
|
||||||
continue
|
|
||||||
|
|
||||||
get_data(child_prefix + child)
|
|
||||||
|
|
||||||
get_data('/')
|
|
||||||
|
|
||||||
return json.dumps(cluster_data), 200
|
|
||||||
|
|
||||||
|
|
||||||
@ZKConnection(config)
|
@ZKConnection(config)
|
||||||
|
@ -135,21 +79,19 @@ def restore_cluster(zkhandler, cluster_data_raw):
|
||||||
try:
|
try:
|
||||||
cluster_data = json.loads(cluster_data_raw)
|
cluster_data = json.loads(cluster_data_raw)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"message": "Failed to parse JSON data: {}.".format(e)}, 400
|
return {'message': 'ERROR: Failed to parse JSON data: {}'.format(e)}, 400
|
||||||
|
|
||||||
# Build a key+value list
|
retflag, retdata = pvc_cluster.cluster_restore(zkhandler, cluster_data)
|
||||||
kv = []
|
|
||||||
for key in cluster_data:
|
|
||||||
data = cluster_data[key]
|
|
||||||
kv.append((key, data))
|
|
||||||
|
|
||||||
# Close the Zookeeper connection
|
retdata = {
|
||||||
result = zkhandler.write(kv)
|
'message': retdata
|
||||||
|
}
|
||||||
if result:
|
if retflag:
|
||||||
return {'message': 'Restore completed successfully.'}, 200
|
retcode = 200
|
||||||
else:
|
else:
|
||||||
return {'message': 'Restore failed.'}, 500
|
retcode = 400
|
||||||
|
|
||||||
|
return retdata, retcode
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -259,3 +259,77 @@ def get_info(zkhandler):
|
||||||
return True, cluster_information
|
return True, cluster_information
|
||||||
else:
|
else:
|
||||||
return False, 'ERROR: Failed to obtain cluster information!'
|
return False, 'ERROR: Failed to obtain cluster information!'
|
||||||
|
|
||||||
|
|
||||||
|
def cluster_initialize(zkhandler, overwrite=False):
|
||||||
|
# Abort if we've initialized the cluster before
|
||||||
|
if zkhandler.exists('base.config.primary_node') and not overwrite:
|
||||||
|
return False, 'ERROR: Cluster contains data and overwrite not set.'
|
||||||
|
|
||||||
|
if overwrite:
|
||||||
|
# Delete the existing keys; ignore any errors
|
||||||
|
status = zkhandler.delete(zkhandler.schema.keys('base'), recursive=True)
|
||||||
|
|
||||||
|
if not status:
|
||||||
|
return False, 'ERROR: Failed to delete data in cluster; running nodes perhaps?'
|
||||||
|
|
||||||
|
# Create the root keys
|
||||||
|
zkhandler.schema.apply(zkhandler)
|
||||||
|
|
||||||
|
return True, 'Successfully initialized cluster'
|
||||||
|
|
||||||
|
|
||||||
|
def cluster_backup(zkhandler):
|
||||||
|
# Dictionary of values to come
|
||||||
|
cluster_data = dict()
|
||||||
|
|
||||||
|
def get_data(path):
|
||||||
|
data = zkhandler.read(path)
|
||||||
|
children = zkhandler.children(path)
|
||||||
|
|
||||||
|
cluster_data[path] = data
|
||||||
|
|
||||||
|
if children:
|
||||||
|
if path == '/':
|
||||||
|
child_prefix = '/'
|
||||||
|
else:
|
||||||
|
child_prefix = path + '/'
|
||||||
|
|
||||||
|
for child in children:
|
||||||
|
if child_prefix + child == '/zookeeper':
|
||||||
|
# We must skip the built-in /zookeeper tree
|
||||||
|
continue
|
||||||
|
if child_prefix + child == '/patroni':
|
||||||
|
# We must skip the /patroni tree
|
||||||
|
continue
|
||||||
|
|
||||||
|
get_data(child_prefix + child)
|
||||||
|
|
||||||
|
try:
|
||||||
|
get_data('/')
|
||||||
|
except Exception as e:
|
||||||
|
return False, 'ERROR: Failed to obtain backup: {}'.format(e)
|
||||||
|
|
||||||
|
return True, cluster_data
|
||||||
|
|
||||||
|
|
||||||
|
def cluster_restore(zkhandler, cluster_data):
|
||||||
|
# Build a key+value list
|
||||||
|
kv = []
|
||||||
|
schema_version = None
|
||||||
|
for key in cluster_data:
|
||||||
|
if key == zkhandler.zkschema.path('base.schema.version'):
|
||||||
|
schema_version = cluster_data[key]
|
||||||
|
data = cluster_data[key]
|
||||||
|
kv.append((key, data))
|
||||||
|
|
||||||
|
if schema_version != zkhandler.schema.version:
|
||||||
|
return False, 'ERROR: Schema version of backup ({}) does not match cluster schema version ({}).'.format(schema_version, zkhandler.schema.version)
|
||||||
|
|
||||||
|
# Close the Zookeeper connection
|
||||||
|
result = zkhandler.write(kv)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
return True, 'Restore completed successfully.'
|
||||||
|
else:
|
||||||
|
return False, 'Restore failed.'
|
||||||
|
|
Loading…
Reference in New Issue