More gracefully handle none selectors

Allow selection of "none" as the node selector, and handle this by
always using the cluster default instead of writing it in.
This commit is contained in:
Joshua Boniface 2021-06-01 11:05:15 -04:00
parent a0b9087167
commit a48bf2d71e
6 changed files with 29 additions and 21 deletions

View File

@ -1102,7 +1102,7 @@ class API_VM_Root(Resource):
@RequestParser([ @RequestParser([
{'name': 'limit'}, {'name': 'limit'},
{'name': 'node'}, {'name': 'node'},
{'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms'), 'helptext': "A valid selector must be specified"}, {'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms', 'none'), 'helptext': "A valid selector must be specified"},
{'name': 'autostart'}, {'name': 'autostart'},
{'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"}, {'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"},
{'name': 'xml', 'required': True, 'helptext': "A Libvirt XML document must be specified"}, {'name': 'xml', 'required': True, 'helptext': "A Libvirt XML document must be specified"},
@ -1172,7 +1172,7 @@ class API_VM_Root(Resource):
reqargs.get('xml'), reqargs.get('xml'),
reqargs.get('node', None), reqargs.get('node', None),
reqargs.get('limit', None), reqargs.get('limit', None),
reqargs.get('selector', 'mem'), reqargs.get('selector', 'none'),
bool(strtobool(reqargs.get('autostart', 'false'))), bool(strtobool(reqargs.get('autostart', 'false'))),
reqargs.get('migration_method', 'none') reqargs.get('migration_method', 'none')
) )
@ -1206,7 +1206,7 @@ class API_VM_Element(Resource):
@RequestParser([ @RequestParser([
{'name': 'limit'}, {'name': 'limit'},
{'name': 'node'}, {'name': 'node'},
{'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms'), 'helptext': "A valid selector must be specified"}, {'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms', 'none'), 'helptext': "A valid selector must be specified"},
{'name': 'autostart'}, {'name': 'autostart'},
{'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"}, {'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"},
{'name': 'xml', 'required': True, 'helptext': "A Libvirt XML document must be specified"}, {'name': 'xml', 'required': True, 'helptext': "A Libvirt XML document must be specified"},
@ -1247,6 +1247,7 @@ class API_VM_Element(Resource):
- vcpus - vcpus
- load - load
- vms - vms
- none (cluster default)
- in: query - in: query
name: autostart name: autostart
type: boolean type: boolean
@ -1278,7 +1279,7 @@ class API_VM_Element(Resource):
reqargs.get('xml'), reqargs.get('xml'),
reqargs.get('node', None), reqargs.get('node', None),
reqargs.get('limit', None), reqargs.get('limit', None),
reqargs.get('selector', 'mem'), reqargs.get('selector', 'none'),
bool(strtobool(reqargs.get('autostart', 'false'))), bool(strtobool(reqargs.get('autostart', 'false'))),
reqargs.get('migration_method', 'none') reqargs.get('migration_method', 'none')
) )
@ -1407,7 +1408,7 @@ class API_VM_Metadata(Resource):
@RequestParser([ @RequestParser([
{'name': 'limit'}, {'name': 'limit'},
{'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms'), 'helptext': "A valid selector must be specified"}, {'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms', 'none'), 'helptext': "A valid selector must be specified"},
{'name': 'autostart'}, {'name': 'autostart'},
{'name': 'profile'}, {'name': 'profile'},
{'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"}, {'name': 'migration_method', 'choices': ('live', 'shutdown', 'none'), 'helptext': "A valid migration_method must be specified"},

View File

@ -53,9 +53,6 @@ def initialize_cluster(zkhandler, overwrite=False):
# Delete the existing keys; ignore any errors # Delete the existing keys; ignore any errors
status = zkhandler.delete([ status = zkhandler.delete([
'/config' '/config'
'/config/primary_node',
'/config/upstream_ip',
'/config/maintenance',
'/nodes', '/nodes',
'/domains', '/domains',
'/networks', '/networks',
@ -81,6 +78,7 @@ def initialize_cluster(zkhandler, overwrite=False):
('/config/primary_node', 'none'), ('/config/primary_node', 'none'),
('/config/upstream_ip', 'none'), ('/config/upstream_ip', 'none'),
('/config/maintenance', 'False'), ('/config/maintenance', 'False'),
('/config/migration_target_selector', 'none'),
('/nodes', ''), ('/nodes', ''),
('/domains', ''), ('/domains', ''),
('/networks', ''), ('/networks', ''),

View File

@ -219,6 +219,9 @@ def create_template_system(name, vcpu_count, vram_mb, serial=False, vnc=False, v
retcode = 400 retcode = 400
return retmsg, retcode return retmsg, retcode
if node_selector == 'none':
node_selector = None
query = "INSERT INTO system_template (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart, migration_method, ova) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" query = "INSERT INTO system_template (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart, migration_method, ova) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);"
args = (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart, migration_method, ova) args = (name, vcpu_count, vram_mb, serial, vnc, vnc_bind, node_limit, node_selector, node_autostart, migration_method, ova)
@ -414,6 +417,9 @@ def modify_template_system(name, vcpu_count=None, vram_mb=None, serial=None, vnc
fields.append({'field': 'node_limit', 'data': node_limit}) fields.append({'field': 'node_limit', 'data': node_limit})
if node_selector is not None: if node_selector is not None:
if node_selector == 'none':
node_selector = 'None'
fields.append({'field': 'node_selector', 'data': node_selector}) fields.append({'field': 'node_selector', 'data': node_selector})
if node_autostart is not None: if node_autostart is not None:

View File

@ -618,8 +618,8 @@ def cli_vm():
) )
@click.option( @click.option(
'-s', '--selector', 'node_selector', default='mem', show_default=True, '-s', '--selector', 'node_selector', default='mem', show_default=True,
type=click.Choice(['mem', 'load', 'vcpus', 'vms']), type=click.Choice(['mem', 'load', 'vcpus', 'vms', 'none']),
help='Method to determine optimal target node during autoselect; saved with VM.' help='Method to determine optimal target node during autoselect; "none" will use the default for the cluster.'
) )
@click.option( @click.option(
'-a/-A', '--autostart/--no-autostart', 'node_autostart', is_flag=True, default=False, '-a/-A', '--autostart/--no-autostart', 'node_autostart', is_flag=True, default=False,
@ -664,8 +664,8 @@ def vm_define(vmconfig, target_node, node_limit, node_selector, node_autostart,
) )
@click.option( @click.option(
'-s', '--selector', 'node_selector', default=None, show_default=False, '-s', '--selector', 'node_selector', default=None, show_default=False,
type=click.Choice(['mem', 'load', 'vcpus', 'vms']), type=click.Choice(['mem', 'load', 'vcpus', 'vms', 'none']),
help='Method to determine optimal target node during autoselect.' help='Method to determine optimal target node during autoselect; "none" will use the default for the cluster.'
) )
@click.option( @click.option(
'-a/-A', '--autostart/--no-autostart', 'node_autostart', is_flag=True, default=None, '-a/-A', '--autostart/--no-autostart', 'node_autostart', is_flag=True, default=None,
@ -2895,9 +2895,9 @@ def provisioner_template_system_list(limit):
) )
@click.option( @click.option(
'--node-selector', 'node_selector', '--node-selector', 'node_selector',
type=click.Choice(['mem', 'vcpus', 'vms', 'load'], case_sensitive=False), type=click.Choice(['mem', 'vcpus', 'vms', 'load', 'none'], case_sensitive=False),
default=None, # Use cluster default default='none',
help='Use this selector to determine the optimal node during migrations.' help='Method to determine optimal target node during autoselect; "none" will use the default for the cluster.'
) )
@click.option( @click.option(
'--node-autostart', 'node_autostart', '--node-autostart', 'node_autostart',
@ -2973,8 +2973,8 @@ def provisioner_template_system_add(name, vcpus, vram, serial, vnc, vnc_bind, no
) )
@click.option( @click.option(
'--node-selector', 'node_selector', '--node-selector', 'node_selector',
type=click.Choice(['mem', 'vcpus', 'vms', 'load'], case_sensitive=False), type=click.Choice(['mem', 'vcpus', 'vms', 'load', 'none'], case_sensitive=False),
help='Use this selector to determine the optimal node during migrations.' help='Method to determine optimal target node during autoselect; "none" will use the default for the cluster.'
) )
@click.option( @click.option(
'--node-autostart', 'node_autostart', '--node-autostart', 'node_autostart',

View File

@ -430,7 +430,11 @@ def findTargetNode(zkhandler, dom_uuid):
try: try:
search_field = zkhandler.read('/domains/{}/node_selector'.format(dom_uuid)) search_field = zkhandler.read('/domains/{}/node_selector'.format(dom_uuid))
except Exception: except Exception:
search_field = 'mem' search_field = None
# If our search field is invalid, use the default
if search_field is None or search_field == 'None':
search_field = zkhandler.read('/config/migration_target_selector')
# Execute the search # Execute the search
if search_field == 'mem': if search_field == 'mem':

View File

@ -160,10 +160,9 @@ def findTargetNode(zk_conn, config, logger, dom_uuid):
except Exception: except Exception:
search_field = None search_field = None
# If our search field is invalid, use and set the default (for next time) # If our search field is invalid, use the default
if search_field is None or search_field == 'None': if search_field is None or search_field == 'None':
search_field = config['migration_target_selector'] search_field = zkhandler.readdata(zk_conn, '/config/migration_target_selector')
zkhandler.writedata(zk_conn, {'/domains/{}/node_selector'.format(dom_uuid): config['migration_target_selector']})
if config['debug']: if config['debug']:
logger.out('Migrating VM {} with selector {}'.format(dom_uuid, search_field), state='d', prefix='node-flush') logger.out('Migrating VM {} with selector {}'.format(dom_uuid, search_field), state='d', prefix='node-flush')