diff --git a/client-cli/pvc.py b/client-cli/pvc.py index 8a3d953d..8a8f63b2 100755 --- a/client-cli/pvc.py +++ b/client-cli/pvc.py @@ -579,13 +579,17 @@ def vm_info(domain, long_output): ) @click.option( '-t', '--target', 'target_node', default=None, - help='Limit list to specified node.' + help='Limit list to VMs on the specified node.' +) +@click.option( + '-s', '--state', 'target_state', default=None, + help='Limit list to VMs in the specified state.' ) @click.option( '-r', '--raw', 'raw', is_flag=True, default=False, - help='Display the raw list of VM names.' + help='Display the raw list of VM names only.' ) -def vm_list(target_node, limit, raw): +def vm_list(target_node, target_state, limit, raw): """ List all virtual machines in the cluster; optionally only match names matching regex LIMIT. @@ -593,7 +597,7 @@ def vm_list(target_node, limit, raw): """ zk_conn = pvc_common.startZKConnection(zk_host) - retcode, retmsg = pvc_vm.get_list(zk_conn, target_node, limit, raw) + retcode, retmsg = pvc_vm.get_list(zk_conn, target_node, target_state, limit, raw) cleanup(retcode, retmsg, zk_conn) ############################################################################### diff --git a/client-common/vm.py b/client-common/vm.py index 4e79d251..fd2808d2 100644 --- a/client-common/vm.py +++ b/client-common/vm.py @@ -494,11 +494,16 @@ def get_info(zk_conn, domain, long_output): return True, '' -def get_list(zk_conn, node, limit, raw): +def get_list(zk_conn, node, state, limit, raw): if node != None: # Verify node is valid common.verifyNode(zk_conn, node) + if state != None: + valid_states = [ 'start', 'restart', 'shutdown', 'stop', 'failed', 'migrate', 'unmigrate' ] + if not state in valid_states: + return False, 'VM state "{}" is not valid.'.format(state) + full_vm_list = zkhandler.listchildren(zk_conn, '/domains') vm_list = [] vm_list_output = [] @@ -529,35 +534,35 @@ def get_list(zk_conn, node, limit, raw): # Check we don't match the limit name = zkhandler.readdata(zk_conn, '/domains/{}'.format(vm)) vm_node[vm] = zkhandler.readdata(zk_conn, '/domains/{}/node'.format(vm)) + vm_state[vm] = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(vm)) # Handle limiting if limit != None: try: if re.match(limit, vm) != None: - if node == None: + if node == None and state == None: vm_list.append(vm) else: - if vm_node[vm] == node: + if vm_node[vm] == node or vm_state[vm] == state: vm_list.append(vm) if re.match(limit, name) != None: - if node == None: + if node == None and state == None: vm_list.append(vm) else: - if vm_node[vm] == node: + if vm_node[vm] == node or vm_state[vm] == state: vm_list.append(vm) except Exception as e: return False, 'Regex Error: {}'.format(e) else: # Check node to avoid unneeded ZK calls - if node == None: + if node == None and state == None: vm_list.append(vm) else: - if vm_node[vm] == node: + if vm_node[vm] == node or vm_state[vm] == state: vm_list.append(vm) # Gather information for printing for vm in vm_list: - vm_state[vm] = zkhandler.readdata(zk_conn, '/domains/{}/state'.format(vm)) vm_lastnode = zkhandler.readdata(zk_conn, '/domains/{}/lastnode'.format(vm)) if vm_lastnode != '': vm_migrated[vm] = 'from {}'.format(vm_lastnode)