From 9a199992a15169cf3ade3365aeaae5f5189a5a49 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Tue, 13 Jul 2021 01:46:50 -0400 Subject: [PATCH] Add functions for manipulating VM tags Adds tags to schema (v3), to VM definition, adds function to modify tags, adds function to get tags, and adds tags to VM data output. Tags will enable more granular classification of VMs based either on administrator configuration or from automated system events. --- daemon-common/common.py | 11 +++++++++++ daemon-common/vm.py | 32 +++++++++++++++++++++++++++++++- daemon-common/zkhandler.py | 3 ++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/daemon-common/common.py b/daemon-common/common.py index f7e59a14..5cd9972e 100644 --- a/daemon-common/common.py +++ b/daemon-common/common.py @@ -306,6 +306,14 @@ def getDomainDiskList(zkhandler, dom_uuid): return disk_list +# +# Get a list of domain tags +# +def getDomainTags(zkhandler, dom_uuid): + tags = zkhandler.read(('domain.meta.tags', dom_uuid)).split(',') + return tags + + # # Get domain information from XML # @@ -352,6 +360,8 @@ def getInformationFromXML(zkhandler, uuid): else: stats_data = {} + domain_tags = getDomainTags(zkhandler, uuid) + domain_uuid, domain_name, domain_description, domain_memory, domain_vcpu, domain_vcputopo = getDomainMainDetails(parsed_xml) domain_networks = getDomainNetworks(parsed_xml, stats_data) @@ -378,6 +388,7 @@ def getInformationFromXML(zkhandler, uuid): 'node_selector': domain_node_selector, 'node_autostart': bool(strtobool(domain_node_autostart)), 'migration_method': domain_migration_method, + 'tags': domain_tags, 'description': domain_description, 'profile': domain_profile, 'memory': int(domain_memory), diff --git a/daemon-common/vm.py b/daemon-common/vm.py index 96eb67e0..60be1b6d 100644 --- a/daemon-common/vm.py +++ b/daemon-common/vm.py @@ -174,7 +174,7 @@ def flush_locks(zkhandler, domain): return success, message -def define_vm(zkhandler, config_data, target_node, node_limit, node_selector, node_autostart, migration_method=None, profile=None, initial_state='stop'): +def define_vm(zkhandler, config_data, target_node, node_limit, node_selector, node_autostart, migration_method=None, profile=None, tags=[], initial_state='stop'): # Parse the XML data try: parsed_xml = lxml.objectify.fromstring(config_data) @@ -246,6 +246,7 @@ def define_vm(zkhandler, config_data, target_node, node_limit, node_selector, no (('domain.meta.migrate_method', dom_uuid), migration_method), (('domain.meta.node_limit', dom_uuid), formatted_node_limit), (('domain.meta.node_selector', dom_uuid), node_selector), + (('domain.meta.tags', dom_uuid), ','.join(tags)), (('domain.migrate.sync_lock', dom_uuid), ''), ]) @@ -282,6 +283,35 @@ def modify_vm_metadata(zkhandler, domain, node_limit, node_selector, node_autost return True, 'Successfully modified PVC metadata of VM "{}".'.format(domain) +def modify_vm_tags(zkhandler, domain, action, tags): + dom_uuid = getDomainUUID(zkhandler, domain) + if not dom_uuid: + return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain) + + if action in ['replace']: + zkhandler.write([ + (('domain.meta.tags', dom_uuid), ','.join(tags)) + ]) + elif action in ['add']: + current_tags = zkhandler.read(('domain.meta.tags', dom_uuid)).split(',') + updated_tags = current_tags + tags + zkhandler.write([ + (('domain.meta.tags', dom_uuid), ','.join(updated_tags)) + ]) + elif action in ['remove']: + current_tags = zkhandler.read(('domain.meta.tags', dom_uuid)).split(',') + for tag in tags: + if tag in current_tags: + current_tags.remove(tag) + zkhandler.write([ + (('domain.meta.tags', dom_uuid), ','.join(current_tags)) + ]) + else: + return False, 'Specified tag action is not available.' + + return True, 'Successfully modified tags of VM "{}".'.format(domain) + + def modify_vm(zkhandler, domain, restart, new_vm_config): dom_uuid = getDomainUUID(zkhandler, domain) if not dom_uuid: diff --git a/daemon-common/zkhandler.py b/daemon-common/zkhandler.py index 5276fd40..80e155aa 100644 --- a/daemon-common/zkhandler.py +++ b/daemon-common/zkhandler.py @@ -466,7 +466,7 @@ class ZKHandler(object): # class ZKSchema(object): # Current version - _version = 2 + _version = 3 # Root for doing nested keys _schema_root = '' @@ -576,6 +576,7 @@ class ZKSchema(object): 'meta.migrate_method': '/migration_method', 'meta.node_selector': '/node_selector', 'meta.node_limit': '/node_limit', + 'meta.tags': '/tags', 'migrate.sync_lock': '/migrate_sync_lock' }, # The schema of an individual network entry (/networks/{vni})