From e7728b8375ae8ad8f0df6ad67502919b17d1b055 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 30 Jan 2020 11:45:46 -0500 Subject: [PATCH] Allow modification of a VM profile And fix some bugs around this. Fixes #76 --- client-api/api_lib/pvcapi_helper.py | 9 +++++++-- client-api/pvc-api.py | 9 ++++++++- client-cli/cli_lib/vm.py | 25 +++++++++---------------- client-cli/pvc.py | 10 +++++++--- client-common/vm.py | 7 ++++++- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/client-api/api_lib/pvcapi_helper.py b/client-api/api_lib/pvcapi_helper.py index 8273b718..715432db 100755 --- a/client-api/api_lib/pvcapi_helper.py +++ b/client-api/api_lib/pvcapi_helper.py @@ -478,12 +478,17 @@ def get_vm_meta(vm): return retdata, retcode -def update_vm_meta(vm, limit, selector, autostart): +def update_vm_meta(vm, limit, selector, autostart, provisioner_profile): """ Update metadata of a VM. """ zk_conn = pvc_common.startZKConnection(config['coordinators']) - retflag, retdata = pvc_vm.modify_vm_metadata(zk_conn, vm, limit, selector, bool(strtobool(autostart))) + if autostart is not None: + try: + autostart = bool(strtobool(autostart)) + except: + autostart = False + retflag, retdata = pvc_vm.modify_vm_metadata(zk_conn, vm, limit, selector, autostart, provisioner_profile) pvc_common.stopZKConnection(zk_conn) if retflag: diff --git a/client-api/pvc-api.py b/client-api/pvc-api.py index e37d7ede..923dba66 100755 --- a/client-api/pvc-api.py +++ b/client-api/pvc-api.py @@ -1165,6 +1165,7 @@ class API_VM_Metadata(Resource): { 'name': 'limit' }, { 'name': 'selector', 'choices': ('mem', 'vcpus', 'load', 'vms'), 'helptext': "A valid selector must be specified" }, { 'name': 'autostart' }, + { 'name': 'profile' }, ]) @Authenticator def post(self, vm, reqargs): @@ -1194,6 +1195,11 @@ class API_VM_Metadata(Resource): type: boolean required: false description: Whether to autostart the VM when its node returns to ready domain state + - in: query + name: profile + type: string + required: false + description: The PVC provisioner profile for the VM responses: 200: description: OK @@ -1210,7 +1216,8 @@ class API_VM_Metadata(Resource): vm, reqargs.get('limit', None), reqargs.get('selector', None), - reqargs.get('autostart', None) + reqargs.get('autostart', None), + reqargs.get('profile', None) ) api.add_resource(API_VM_Metadata, '/vm//meta') diff --git a/client-cli/cli_lib/vm.py b/client-cli/cli_lib/vm.py index deefeb93..cdf6eb0a 100644 --- a/client-cli/cli_lib/vm.py +++ b/client-cli/cli_lib/vm.py @@ -120,37 +120,30 @@ def vm_modify(config, vm, xml, restart): return retstatus, response.json()['message'] -def vm_metadata(config, vm, node_limit, node_selector, node_autostart): +def vm_metadata(config, vm, node_limit, node_selector, node_autostart, provisioner_profile): """ Modify PVC metadata of a VM API endpoint: GET /vm/{vm}/meta, POST /vm/{vm}/meta - API arguments: limit={node_limit}, selector={node_selector}, autostart={node_autostart} + API arguments: limit={node_limit}, selector={node_selector}, autostart={node_autostart}, profile={provisioner_profile} API schema: {"message":"{data}"} """ - response = call_api(config, 'get', '/vm/{vm}/meta'.format(vm=vm)) - - metadata = response.json() + params = dict() # Update any params that we've sent if node_limit is not None: - metadata['node_limit'] = node_limit - else: - # Collapse the existing list back down to a CSV - metadata['node_limit'] = ','.join(metadata['node_limit']) + params['limit'] = node_limit if node_selector is not None: - metadata['node_selector'] = node_selector + params['selector'] = node_selector if node_autostart is not None: - metadata['node_autostart'] = node_autostart + params['autostart'] = node_autostart + + if provisioner_profile is not None: + params['profile'] = provisioner_profile # Write the new metadata - params={ - 'limit': metadata['node_limit'], - 'selector': metadata['node_selector'], - 'autostart': metadata['node_autostart'] - } response = call_api(config, 'post', '/vm/{vm}/meta'.format(vm=vm), params=params) if response.status_code == 200: diff --git a/client-cli/pvc.py b/client-cli/pvc.py index 2ea61cd8..b03e772e 100755 --- a/client-cli/pvc.py +++ b/client-cli/pvc.py @@ -547,18 +547,22 @@ def vm_define(vmconfig, target_node, node_limit, node_selector, node_autostart): '-a/-A', '--autostart/--no-autostart', 'node_autostart', is_flag=True, default=None, help='Start VM automatically on next unflush/ready state of home node; unset by daemon once used.' ) +@click.option( + '-p', '--profile', 'provisioner_profile', default=None, show_default=False, + help='PVC provisioner profile name for VM.' +) @click.argument( 'domain' ) -def vm_meta(domain, node_limit, node_selector, node_autostart): +def vm_meta(domain, node_limit, node_selector, node_autostart, provisioner_profile): """ Modify the PVC metadata of existing virtual machine DOMAIN. At least one option to update must be specified. DOMAIN may be a UUID or name. """ - if node_limit is None and node_selector is None and node_autostart is None: + if node_limit is None and node_selector is None and node_autostart is None and provisioner_profile is None: cleanup(False, 'At least one metadata option must be specified to update.') - retcode, retmsg = pvc_vm.vm_metadata(config, domain, node_limit, node_selector, node_autostart) + retcode, retmsg = pvc_vm.vm_metadata(config, domain, node_limit, node_selector, node_autostart, provisioner_profile) cleanup(retcode, retmsg) ############################################################################### diff --git a/client-common/vm.py b/client-common/vm.py index 6ae83965..08b639ed 100644 --- a/client-common/vm.py +++ b/client-common/vm.py @@ -215,7 +215,7 @@ def define_vm(zk_conn, config_data, target_node, node_limit, node_selector, node return True, 'Added new VM with Name "{}" and UUID "{}" to database.'.format(dom_name, dom_uuid) -def modify_vm_metadata(zk_conn, domain, node_limit, node_selector, node_autostart): +def modify_vm_metadata(zk_conn, domain, node_limit, node_selector, node_autostart, provisioner_profile): dom_uuid = getDomainUUID(zk_conn, domain) if not dom_uuid: return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) @@ -235,6 +235,11 @@ def modify_vm_metadata(zk_conn, domain, node_limit, node_selector, node_autostar '/domains/{}/node_autostart'.format(dom_uuid): node_autostart }) + if provisioner_profile is not None: + zkhandler.writedata(zk_conn, { + '/domains/{}/profile'.format(dom_uuid): provisioner_profile + }) + return True, 'Successfully modified PVC metadata of VM "{}".'.format(domain) def modify_vm(zk_conn, domain, restart, new_vm_config):