2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-01-11 18:42:29 +00:00

Fix up VM power handling

For both proxmox and vmware, properly model the 'oldstate' feature.

For proxmox, further:
- Wait for power change to actually take effect
- Change reset to a cycle, to help nodesetboot actually work correctly.
This commit is contained in:
Jarrod Johnson
2025-05-01 11:44:35 -04:00
parent b3ffd632a5
commit 5be99d995a
2 changed files with 32 additions and 5 deletions

View File

@@ -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))

View File

@@ -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))