Port VM on-node tasks to Celery worker system

Adds Celery versions of the flush_locks, device_attach, and
device_detach functions.
This commit is contained in:
2023-11-05 22:32:41 -05:00
parent f0c2e9d295
commit 89681d54b9
9 changed files with 577 additions and 174 deletions

View File

@ -24,6 +24,7 @@ import math
import time
import requests
import click
from ast import literal_eval
from urllib3 import disable_warnings
@ -199,3 +200,64 @@ def call_api(
# Return the response object
return response
def task_status(config, task_id=None, is_watching=False):
"""
Get information about Celery job {task_id}, or all tasks if None
API endpoint: GET /api/v1/tasks/{task_id}
API arguments:
API schema: {json_data_object}
"""
if task_id is not None:
response = call_api(config, "get", f"/tasks/{task_id}")
else:
response = call_api(config, "get", "/tasks")
if task_id is not None:
if response.status_code == 200:
retvalue = True
respjson = response.json()
if is_watching:
# Just return the raw JSON to the watching process instead of including value
return respjson
else:
return retvalue, respjson
else:
retvalue = False
retdata = response.json().get("message", "")
else:
retvalue = True
task_data_raw = response.json()
# Format the Celery data into a more useful data structure
task_data = list()
for task_type in ["active", "reserved", "scheduled"]:
try:
type_data = task_data_raw[task_type]
except Exception:
type_data = None
if not type_data:
type_data = dict()
for task_host in type_data:
for task_job in task_data_raw[task_type][task_host]:
task = dict()
if task_type == "reserved":
task["type"] = "pending"
else:
task["type"] = task_type
task["worker"] = task_host
task["id"] = task_job.get("id")
try:
task["args"] = literal_eval(task_job.get("args"))
except Exception:
task["args"] = task_job.get("args")
try:
task["kwargs"] = literal_eval(task_job.get("kwargs"))
except Exception:
task["kwargs"] = task_job.get("kwargs")
task_data.append(task)
retdata = task_data
return retvalue, retdata

View File

@ -152,7 +152,7 @@ def vm_device_attach(config, vm, xml):
data = {"xml": xml}
response = call_api(config, "post", "/vm/{vm}/device".format(vm=vm), data=data)
if response.status_code == 200:
if response.status_code in [200, 202]:
retstatus = True
else:
retstatus = False
@ -171,7 +171,7 @@ def vm_device_detach(config, vm, xml):
data = {"xml": xml}
response = call_api(config, "delete", "/vm/{vm}/device".format(vm=vm), data=data)
if response.status_code == 200:
if response.status_code in [200, 202]:
retstatus = True
else:
retstatus = False
@ -415,7 +415,7 @@ def vm_node(config, vm, target_node, action, force=False, wait=False, force_live
return retstatus, response.json().get("message", "")
def vm_locks(config, vm):
def vm_locks(config, vm, wait_flag=False):
"""
Flush RBD locks of (stopped) VM
@ -423,14 +423,23 @@ def vm_locks(config, vm):
API arguments:
API schema: {"message":"{data}"}
"""
response = call_api(config, "post", "/vm/{vm}/locks".format(vm=vm))
response = call_api(config, "post", f"/vm/{vm}/locks")
if response.status_code == 200:
retstatus = True
if response.status_code == 202:
retvalue = True
retjson = response.json()
if not wait_flag:
retdata = (
f"Task ID: {retjson['task_id']} assigned to node {retjson['run_on']}"
)
else:
# Just return the task JSON without formatting
retdata = response.json()
else:
retstatus = False
retvalue = False
retdata = response.json().get("message", "")
return retstatus, response.json().get("message", "")
return retvalue, retdata
def vm_backup(config, vm, backup_path, incremental_parent=None, retain_snapshot=False):