Allow overwrite during init command

This commit is contained in:
Joshua Boniface 2021-05-30 23:59:17 -04:00
parent c7992000eb
commit a1969eb981
4 changed files with 62 additions and 12 deletions

View File

@ -260,17 +260,27 @@ api.add_resource(API_Logout, '/logout')
# /initialize # /initialize
class API_Initialize(Resource): class API_Initialize(Resource):
@RequestParser([ @RequestParser([
{'name': 'yes-i-really-mean-it', 'required': True, 'helptext': "Initialization is destructive; please confirm with the argument 'yes-i-really-mean-it'."} {'name': 'overwrite', 'required': False},
{'name': 'yes-i-really-mean-it', 'required': True, 'helptext': "Initialization is destructive; please confirm with the argument 'yes-i-really-mean-it'."},
]) ])
@Authenticator @Authenticator
def post(self, reqargs): def post(self, reqargs):
""" """
Initialize a new PVC cluster Initialize a new PVC cluster
Note: Normally used only once during cluster bootstrap; checks for the existence of the "/primary_node" key before proceeding and returns 400 if found
If the 'overwrite' option is not True, the cluster will return 400 if the `/primary_node` key is found. If 'overwrite' is True, the existing cluster
data will be erased and new, empty data written in its place.
All node daemons should be stopped before running this command, and the API daemon started manually to avoid undefined behavior.
--- ---
tags: tags:
- root - root
parameters: parameters:
- in: query
name: overwrite
type: bool
required: false
description: A flag to enable or disable (default) overwriting existing data
- in: query - in: query
name: yes-i-really-mean-it name: yes-i-really-mean-it
type: string type: string
@ -289,7 +299,10 @@ class API_Initialize(Resource):
400: 400:
description: Bad request description: Bad request
""" """
if api_helper.initialize_cluster(): if reqargs.get('overwrite', False):
overwrite_flag = True
if api_helper.initialize_cluster(overwrite=overwrite_flag):
return {"message": "Successfully initialized a new PVC cluster"}, 200 return {"message": "Successfully initialized a new PVC cluster"}, 200
else: else:
return {"message": "PVC cluster already initialized"}, 400 return {"message": "PVC cluster already initialized"}, 400

View File

@ -41,16 +41,41 @@ import daemon_lib.ceph as pvc_ceph
# Cluster base functions # Cluster base functions
# #
@ZKConnection(config) @ZKConnection(config)
def initialize_cluster(zkhandler): def initialize_cluster(zkhandler, overwrite=False):
""" """
Initialize a new cluster Initialize a new cluster
""" """
# Abort if we've initialized the cluster before # Abort if we've initialized the cluster before
if zkhandler.exists('/primary_node'): if zkhandler.exists('/primary_node') and not overwrite:
return False return False
if overwrite:
# Delete the existing keys; ignore any errors
status = zkhandler.delete([
'/primary_node',
'/upstream_ip',
'/maintenance',
'/nodes',
'/domains',
'/networks',
'/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 False
# Create the root keys # Create the root keys
zkhandler.write([ status = zkhandler.write([
('/primary_node', 'none'), ('/primary_node', 'none'),
('/upstream_ip', 'none'), ('/upstream_ip', 'none'),
('/maintenance', 'False'), ('/maintenance', 'False'),
@ -70,7 +95,7 @@ def initialize_cluster(zkhandler):
('/locks/primary_node', ''), ('/locks/primary_node', ''),
]) ])
return True return status
@ZKConnection(config) @ZKConnection(config)

View File

@ -25,16 +25,17 @@ import cli_lib.ansiprint as ansiprint
from cli_lib.common import call_api from cli_lib.common import call_api
def initialize(config): def initialize(config, overwrite=False):
""" """
Initialize the PVC cluster Initialize the PVC cluster
API endpoint: GET /api/v1/initialize API endpoint: GET /api/v1/initialize
API arguments: yes-i-really-mean-it API arguments: overwrite, yes-i-really-mean-it
API schema: {json_data_object} API schema: {json_data_object}
""" """
params = { params = {
'yes-i-really-mean-it': 'yes' 'yes-i-really-mean-it': 'yes',
'overwrite': overwrite
} }
response = call_api(config, 'post', '/initialize', params=params) response = call_api(config, 'post', '/initialize', params=params)

View File

@ -4304,15 +4304,26 @@ def task_restore(filename, confirm_flag):
# pvc task init # pvc task init
############################################################################### ###############################################################################
@click.command(name='init', short_help='Initialize a new cluster.') @click.command(name='init', short_help='Initialize a new cluster.')
@click.option(
'-o', '--overwite', 'overwrite_flag',
is_flag=True, default=False,
help='Remove and overwrite any existing data'
)
@click.option( @click.option(
'-y', '--yes', 'confirm_flag', '-y', '--yes', 'confirm_flag',
is_flag=True, default=False, is_flag=True, default=False,
help='Confirm the initialization' help='Confirm the initialization'
) )
@cluster_req @cluster_req
def task_init(confirm_flag): def task_init(confirm_flag, overwrite_flag):
""" """
Perform initialization of a new PVC cluster. Perform initialization of a new PVC cluster.
If the '-o'/'--overwrite' option is specified, all existing data in the cluster will be deleted
before new, empty data is written.
It is not advisable to do this against a running cluster - all node daemons should be stopped
first and the API daemon started manually before running this command.
""" """
if not confirm_flag and not config['unsafe']: if not confirm_flag and not config['unsafe']:
@ -4324,7 +4335,7 @@ def task_init(confirm_flag):
# Easter-egg # Easter-egg
click.echo("Some music while we're Layin' Pipe? https://youtu.be/sw8S_Kv89IU") click.echo("Some music while we're Layin' Pipe? https://youtu.be/sw8S_Kv89IU")
retcode, retmsg = pvc_cluster.initialize(config) retcode, retmsg = pvc_cluster.initialize(config, overwrite_flag)
cleanup(retcode, retmsg) cleanup(retcode, retmsg)