Compare commits
4 Commits
16544227eb
...
1cf8706a52
Author | SHA1 | Date |
---|---|---|
Joshua Boniface | 1cf8706a52 | |
Joshua Boniface | dd8f07526f | |
Joshua Boniface | 5a5e5da663 | |
Joshua Boniface | 739b60b91e |
|
@ -1868,6 +1868,7 @@ class API_VM_State(Resource):
|
||||||
"helptext": "A valid state must be specified",
|
"helptext": "A valid state must be specified",
|
||||||
"required": True,
|
"required": True,
|
||||||
},
|
},
|
||||||
|
{"name": "force"},
|
||||||
{"name": "wait"},
|
{"name": "wait"},
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -1890,6 +1891,10 @@ class API_VM_State(Resource):
|
||||||
- stop
|
- stop
|
||||||
- restart
|
- restart
|
||||||
- disable
|
- disable
|
||||||
|
- in: query
|
||||||
|
name: force
|
||||||
|
type: boolean
|
||||||
|
description: Whether to force stop instead of shutdown VM during disable
|
||||||
- in: query
|
- in: query
|
||||||
name: wait
|
name: wait
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -1907,6 +1912,7 @@ class API_VM_State(Resource):
|
||||||
id: Message
|
id: Message
|
||||||
"""
|
"""
|
||||||
state = reqargs.get("state", None)
|
state = reqargs.get("state", None)
|
||||||
|
force = bool(strtobool(reqargs.get("force", "false")))
|
||||||
wait = bool(strtobool(reqargs.get("wait", "false")))
|
wait = bool(strtobool(reqargs.get("wait", "false")))
|
||||||
|
|
||||||
if state == "start":
|
if state == "start":
|
||||||
|
@ -1918,7 +1924,7 @@ class API_VM_State(Resource):
|
||||||
if state == "restart":
|
if state == "restart":
|
||||||
return api_helper.vm_restart(vm, wait)
|
return api_helper.vm_restart(vm, wait)
|
||||||
if state == "disable":
|
if state == "disable":
|
||||||
return api_helper.vm_disable(vm)
|
return api_helper.vm_disable(vm, force)
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -719,11 +719,11 @@ def vm_start(zkhandler, name):
|
||||||
|
|
||||||
|
|
||||||
@ZKConnection(config)
|
@ZKConnection(config)
|
||||||
def vm_restart(zkhandler, name, wait):
|
def vm_restart(zkhandler, name, wait=False):
|
||||||
"""
|
"""
|
||||||
Restart a VM in the PVC cluster.
|
Restart a VM in the PVC cluster.
|
||||||
"""
|
"""
|
||||||
retflag, retdata = pvc_vm.restart_vm(zkhandler, name, wait)
|
retflag, retdata = pvc_vm.restart_vm(zkhandler, name, wait=wait)
|
||||||
|
|
||||||
if retflag:
|
if retflag:
|
||||||
retcode = 200
|
retcode = 200
|
||||||
|
@ -767,11 +767,11 @@ def vm_stop(zkhandler, name):
|
||||||
|
|
||||||
|
|
||||||
@ZKConnection(config)
|
@ZKConnection(config)
|
||||||
def vm_disable(zkhandler, name):
|
def vm_disable(zkhandler, name, force=False):
|
||||||
"""
|
"""
|
||||||
Disable a (stopped) VM in the PVC cluster.
|
Disable (shutdown or force stop if required)a VM in the PVC cluster.
|
||||||
"""
|
"""
|
||||||
retflag, retdata = pvc_vm.disable_vm(zkhandler, name)
|
retflag, retdata = pvc_vm.disable_vm(zkhandler, name, force=force)
|
||||||
|
|
||||||
if retflag:
|
if retflag:
|
||||||
retcode = 200
|
retcode = 200
|
||||||
|
|
|
@ -116,16 +116,20 @@ class ErrorResponse(requests.Response):
|
||||||
|
|
||||||
|
|
||||||
def call_api(
|
def call_api(
|
||||||
config, operation, request_uri, headers={}, params=None, data=None, files=None
|
config,
|
||||||
|
operation,
|
||||||
|
request_uri,
|
||||||
|
headers={},
|
||||||
|
params=None,
|
||||||
|
data=None,
|
||||||
|
files=None,
|
||||||
|
timeout=3,
|
||||||
):
|
):
|
||||||
# Craft the URI
|
# Craft the URI
|
||||||
uri = "{}://{}{}{}".format(
|
uri = "{}://{}{}{}".format(
|
||||||
config["api_scheme"], config["api_host"], config["api_prefix"], request_uri
|
config["api_scheme"], config["api_host"], config["api_prefix"], request_uri
|
||||||
)
|
)
|
||||||
|
|
||||||
# Default timeout is 3 seconds
|
|
||||||
timeout = 3
|
|
||||||
|
|
||||||
# Craft the authentication header if required
|
# Craft the authentication header if required
|
||||||
if config["api_key"]:
|
if config["api_key"]:
|
||||||
headers["X-Api-Key"] = config["api_key"]
|
headers["X-Api-Key"] = config["api_key"]
|
||||||
|
|
|
@ -369,7 +369,7 @@ def vm_remove(config, vm, delete_disks=False):
|
||||||
return retstatus, response.json().get("message", "")
|
return retstatus, response.json().get("message", "")
|
||||||
|
|
||||||
|
|
||||||
def vm_state(config, vm, target_state, wait=False):
|
def vm_state(config, vm, target_state, force=False, wait=False):
|
||||||
"""
|
"""
|
||||||
Modify the current state of VM
|
Modify the current state of VM
|
||||||
|
|
||||||
|
@ -377,8 +377,14 @@ def vm_state(config, vm, target_state, wait=False):
|
||||||
API arguments: state={state}, wait={wait}
|
API arguments: state={state}, wait={wait}
|
||||||
API schema: {"message":"{data}"}
|
API schema: {"message":"{data}"}
|
||||||
"""
|
"""
|
||||||
params = {"state": target_state, "wait": str(wait).lower()}
|
params = {
|
||||||
response = call_api(config, "post", "/vm/{vm}/state".format(vm=vm), params=params)
|
"state": target_state,
|
||||||
|
"force": str(force).lower(),
|
||||||
|
"wait": str(wait).lower(),
|
||||||
|
}
|
||||||
|
response = call_api(
|
||||||
|
config, "post", "/vm/{vm}/state".format(vm=vm), params=params, timeout=120
|
||||||
|
)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
retstatus = True
|
retstatus = True
|
||||||
|
|
|
@ -1308,15 +1308,22 @@ def vm_stop(domain, confirm_flag):
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@click.command(name="disable", short_help="Mark a virtual machine as disabled.")
|
@click.command(name="disable", short_help="Mark a virtual machine as disabled.")
|
||||||
@click.argument("domain")
|
@click.argument("domain")
|
||||||
|
@click.option(
|
||||||
|
"--force",
|
||||||
|
"force",
|
||||||
|
is_flag=True,
|
||||||
|
default=False,
|
||||||
|
help="Forcibly stop the VM instead of waiting for shutdown.",
|
||||||
|
)
|
||||||
@cluster_req
|
@cluster_req
|
||||||
def vm_disable(domain):
|
def vm_disable(domain, force):
|
||||||
"""
|
"""
|
||||||
Prevent stopped virtual machine DOMAIN from being counted towards cluster health status. DOMAIN may be a UUID or name.
|
Shut down virtual machine DOMAIN and mark it as disabled. DOMAIN may be a UUID or name.
|
||||||
|
|
||||||
Use this option for VM that are stopped intentionally or long-term and which should not impact cluster health if stopped. A VM can be started directly from disable state.
|
Disabled VMs will not be counted towards a degraded cluster health status, unlike stopped VMs. Use this option for a VM that will remain off for an extended period.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retcode, retmsg = pvc_vm.vm_state(config, domain, "disable")
|
retcode, retmsg = pvc_vm.vm_state(config, domain, "disable", force=force)
|
||||||
cleanup(retcode, retmsg)
|
cleanup(retcode, retmsg)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -837,21 +837,29 @@ def stop_vm(zkhandler, domain):
|
||||||
return True, 'Forcibly stopping VM "{}".'.format(domain)
|
return True, 'Forcibly stopping VM "{}".'.format(domain)
|
||||||
|
|
||||||
|
|
||||||
def disable_vm(zkhandler, domain):
|
def disable_vm(zkhandler, domain, force=False):
|
||||||
# Validate that VM exists in cluster
|
# Validate that VM exists in cluster
|
||||||
dom_uuid = getDomainUUID(zkhandler, domain)
|
dom_uuid = getDomainUUID(zkhandler, domain)
|
||||||
if not dom_uuid:
|
if not dom_uuid:
|
||||||
return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain)
|
return False, 'ERROR: Could not find VM "{}" in the cluster!'.format(domain)
|
||||||
|
|
||||||
# Get state and verify we're OK to proceed
|
# Get state and perform a shutdown/stop if VM is online
|
||||||
current_state = zkhandler.read(("domain.state", dom_uuid))
|
current_state = zkhandler.read(("domain.state", dom_uuid))
|
||||||
if current_state != "stop":
|
if current_state in ["start"]:
|
||||||
return False, 'ERROR: VM "{}" must be stopped before disabling!'.format(domain)
|
if force:
|
||||||
|
change_state(zkhandler, dom_uuid, "stop")
|
||||||
|
# Wait for the command to be registered by the node
|
||||||
|
time.sleep(0.5)
|
||||||
|
else:
|
||||||
|
change_state(zkhandler, dom_uuid, "shutdown")
|
||||||
|
# Wait for the shutdown to complete
|
||||||
|
while zkhandler.read(("domain.state", dom_uuid)) != "stop":
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
# Set the VM to disable
|
# Set the VM to disable
|
||||||
change_state(zkhandler, dom_uuid, "disable")
|
change_state(zkhandler, dom_uuid, "disable")
|
||||||
|
|
||||||
return True, 'Marked VM "{}" as disable.'.format(domain)
|
return True, 'Disabled VM "{}".'.format(domain)
|
||||||
|
|
||||||
|
|
||||||
def update_vm_sriov_nics(zkhandler, dom_uuid, source_node, target_node):
|
def update_vm_sriov_nics(zkhandler, dom_uuid, source_node, target_node):
|
||||||
|
|
|
@ -6680,6 +6680,12 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "Whether to force stop instead of shutdown VM during disable",
|
||||||
|
"in": "query",
|
||||||
|
"name": "force",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Whether to block waiting for the state change to complete",
|
"description": "Whether to block waiting for the state change to complete",
|
||||||
"in": "query",
|
"in": "query",
|
||||||
|
|
Loading…
Reference in New Issue