diff --git a/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py b/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py index 33771544..bbe4ae9c 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py @@ -12,6 +12,7 @@ import confluent.interface.console as conapi import io import urllib.parse as urlparse import eventlet.green.ssl as ssl +import eventlet try: @@ -282,17 +283,38 @@ class PmxApiClient: def set_vm_power(self, vm, state): host, guest = self.get_vm(vm) + current = None + newstate = '' + targstate = state + if targstate == 'boot': + targstate = 'on' if state == 'boot': current = self.get_vm_power(vm) if current == 'on': state = 'reset' + newstate = 'reset' else: state = 'start' elif state == 'on': state = 'start' elif state == 'off': state = 'stop' - rsp = self.wc.grab_json_response_with_status(f'/api2/json/nodes/{host}/{guest}/status/{state}', method='POST') + if state == 'reset': # check for pending config + cfg = self.wc.grab_json_response(f'/api2/json/nodes/{host}/{guest}/pending') + for datum in cfg['data']: + if datum['key'] == 'boot' and 'pending' in datum: + self.set_vm_power(vm, 'off') + self.set_vm_power(vm, 'on') + state = '' + newstate = 'reset' + if state: + rsp = self.wc.grab_json_response_with_status(f'/api2/json/nodes/{host}/{guest}/status/{state}', method='POST') + if state and state != 'reset': + newstate = self.get_vm_power(vm) + while newstate != targstate: + eventlet.sleep(0.1) + newstate = self.get_vm_power(vm) + return newstate, current def set_vm_bootdev(self, vm, bootdev): host, guest = self.get_vm(vm) @@ -370,8 +392,8 @@ def update(nodes, element, configmanager, inputdata): for node in nodes: currclient = clientsbynode[node] if element == ['power', 'state']: - currclient.set_vm_power(node, inputdata.powerstate(node)) - yield msg.PowerState(node, currclient.get_vm_power(node)) + newstate, oldstate = currclient.set_vm_power(node, inputdata.powerstate(node)) + yield msg.PowerState(node, newstate, oldstate) elif element == ['boot', 'nextdevice']: currclient.set_vm_bootdev(node, inputdata.bootdevice(node)) yield msg.BootDevice(node, currclient.get_vm_bootdev(node)) diff --git a/confluent_server/confluent/plugins/hardwaremanagement/vcenter.py b/confluent_server/confluent/plugins/hardwaremanagement/vcenter.py index e7140d7a..00f6c2bc 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/vcenter.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/vcenter.py @@ -265,18 +265,23 @@ class VmwApiClient: raise Exception("Unknown response {}".format(repr(rsp))) def set_vm_power(self, vm, state): + current = None + targstate = state vm = self.index_vm(vm) if state == 'boot': current = self.get_vm_power(vm) if current == 'on': state = 'reset' + targstate = state else: + targstate = 'on' state = 'start' elif state == 'on': state = 'start' elif state == 'off': state = 'stop' rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/power?action={state}', method='POST') + return targstate, current def set_vm_bootdev(self, vm, bootdev): @@ -356,8 +361,8 @@ def update(nodes, element, configmanager, inputdata): for node in nodes: currclient = clientsbynode[node] if element == ['power', 'state']: - currclient.set_vm_power(node, inputdata.powerstate(node)) - yield msg.PowerState(node, currclient.get_vm_power(node)) + newstate, oldstate = currclient.set_vm_power(node, inputdata.powerstate(node)) + yield msg.PowerState(node, newstate, oldstate) elif element == ['boot', 'nextdevice']: currclient.set_vm_bootdev(node, inputdata.bootdevice(node)) yield msg.BootDevice(node, currclient.get_vm_bootdev(node))