Deploy show implement

This commit add some changes to deploy show endpoint, the name was
changed to just deploy with GET verb and also changes the deploy to
be saved as a list of dict to attend the API requirements. Now the
api accepts from_release and to_release as optional params, in case
it is provided the endpoint will return a dict otherwise will return
a list of dict.

Test Plan:
PASS: Create deploy
PASS: Update deploy
PASS: Software deploy start
PASS: Software deploy show

Story: 2010676
Task: 49645

Change-Id: I68d243c05da88c7eecf2d866c7202c3c7be51a2b
Signed-off-by: Luis Eduardo Bonatti <LuizEduardo.Bonatti@windriver.com>
This commit is contained in:
Luis Eduardo Bonatti 2024-02-22 16:55:32 -03:00
parent 88e95d5c1f
commit 98cd083cff
5 changed files with 78 additions and 36 deletions

View File

@ -1011,7 +1011,7 @@ def deploy_complete_req(args):
def deploy_show_req(args):
url = "http://%s/v1/software/deploy_show" % api_addr
url = "http://%s/v1/software/deploy" % api_addr
headers = {}
append_auth_token_if_required(headers)
req = requests.get(url, headers=headers)
@ -1023,10 +1023,11 @@ def deploy_show_req(args):
print("Respond code %d. Error: %s" % (req.status_code, req.reason))
return 1
data = json.loads(req.text)
data = req.json().get("data")
if not data:
print("No deploy in progress.\n")
print("No deploy in progress.")
else:
data = data[0]
data["reboot_required"] = "Yes" if data.get("reboot_required") else "No"
data_list = [[k, v] for k, v in data.items()]
transposed_data_list = list(zip(*data_list))

View File

@ -10,6 +10,7 @@ import os
from oslo_log import log
from pecan import expose
from pecan import request
from pecan import Response
import shutil
from software.exceptions import SoftwareError
@ -132,15 +133,13 @@ class SoftwareAPIController(object):
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def deploy_show(self):
try:
result = sc.software_deploy_show_api()
except SoftwareError as e:
return dict(error="Error: %s" % str(e))
return result
@expose('json', method="GET")
def deploy(self):
from_release = request.GET.get("from_release")
to_release = request.GET.get("to_release")
result = dict(data=sc.software_deploy_show_api(from_release, to_release))
response_data = json.dumps(result)
return Response(body=response_data, status_code=200)
@expose('json')
@expose('query.xml', content_type='application/xml')

View File

@ -37,10 +37,17 @@ class SoftwareAPI:
self.deploy_handler.create(from_release, to_release, reboot_required)
self.end_update()
def get_deploy(self):
def get_deploy(self, from_release, to_release):
self.begin_update()
try:
return self.deploy_handler.query()
return self.deploy_handler.query(from_release, to_release)
finally:
self.end_update()
def get_deploy_all(self):
self.begin_update()
try:
return self.deploy_handler.query_all()
finally:
self.end_update()

View File

@ -2627,9 +2627,13 @@ class PatchController(PatchService):
return dict(info=msg_info, warning=msg_warning, error=msg_error)
def software_deploy_show_api(self):
def software_deploy_show_api(self, from_release=None, to_release=None):
# Retrieve deploy state from db
return self.db_api_instance.get_deploy()
if from_release and to_release:
return self.db_api_instance.get_deploy(from_release, to_release)
else:
# Retrieve deploy state from db in list format
return self.db_api_instance.get_deploy_all()
def software_deploy_host_api(self, host_ip, force, async_req=False):
msg_info = ""
@ -2902,7 +2906,11 @@ class PatchController(PatchService):
def deploy_host_list(self):
query_hosts = self.query_host_cache()
deploy_hosts = self.db_api_instance.get_deploy_host()
deploy = self.db_api_instance.get_deploy()
deploy = self.db_api_instance.get_deploy_all()
if not deploy:
return None
deploy = deploy[0]
# If there's a hostname missing, add it to query hosts.
hostnames = []

View File

@ -138,7 +138,7 @@ class Deploy(ABC):
"""
Create a new deployment entry.
:param from_release: The source release version.
:param from_release: The current release version.
:param to_release: The target release version.
:param reboot_required: If is required to do host reboot.
:param state: The state of the deployment.
@ -149,10 +149,11 @@ class Deploy(ABC):
check_instances([state], DEPLOY_STATES)
@abstractmethod
def query(self):
def query(self, from_release, to_release):
"""
Get deployments based on source and target release versions.
Get deployments based on current and target release versions.
"""
validate_versions([from_release, to_release])
pass
@abstractmethod
@ -160,7 +161,7 @@ class Deploy(ABC):
"""
Update a deployment entry.
:param state: The state of the deployment.
:param new_state: The state of the deployment.
"""
check_instances([new_state], DEPLOY_STATES)
@ -168,7 +169,7 @@ class Deploy(ABC):
@abstractmethod
def delete(self):
"""
Delete a deployment entry based on source and target release versions.
Delete a deployment entry based on current and target release versions.
"""
pass
@ -236,13 +237,13 @@ class DeployHandler(Deploy):
def create(self, from_release, to_release, reboot_required, state=DEPLOY_STATES.START):
"""
Create a new deploy with given from and to release version
:param from_release: The source release version.
:param from_release: The current release version.
:param to_release: The target release version.
:param reboot_required: If is required to do host reboot.
:param state: The state of the deployment.
"""
super().create(from_release, to_release, reboot_required, state)
deploy = self.query()
deploy = self.query(from_release, to_release)
if deploy:
raise DeployAlreadyExist("Error to create. Deploy already exists.")
new_deploy = {
@ -253,18 +254,39 @@ class DeployHandler(Deploy):
}
try:
self.data["deploy"] = new_deploy
deploy_data = self.data.get("deploy", [])
if not deploy_data:
deploy_data = {
"deploy": []
}
deploy_data["deploy"].append(new_deploy)
self.data.update(deploy_data)
else:
deploy_data.append(new_deploy)
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
except Exception:
self.data["deploy"] = {}
self.data["deploy"][0] = {}
def query(self):
def query(self, from_release, to_release):
"""
Query deploy based on from and to release version
:return: A deploy dictionary
:param from_release: The current release version.
:param to_release: The target release version.
:return: A list of deploy dictionary
"""
super().query()
return self.data.get("deploy", {})
super().query(from_release, to_release)
for deploy in self.data.get("deploy", []):
if (deploy.get("from_release") == from_release
and deploy.get("to_release") == to_release):
return deploy
return []
def query_all(self):
"""
Query all deployments inside software.json file.
:return: A list of deploy dictionary
"""
return self.data.get("deploy", [])
def update(self, new_state: DEPLOY_STATES):
"""
@ -272,29 +294,29 @@ class DeployHandler(Deploy):
:param new_state: The new state
"""
super().update(new_state)
deploy = self.query()
deploy = self.query_all()
if not deploy:
raise DeployDoNotExist("Error to update deploy state. No deploy in progress.")
try:
self.data["deploy"]["state"] = new_state.value
self.data["deploy"][0]["state"] = new_state.value
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
except Exception:
self.data["deploy"] = deploy
self.data["deploy"][0] = deploy
def delete(self):
"""
Delete a deploy based on given from and to release version
"""
super().delete()
deploy = self.query()
deploy = self.query_all()
if not deploy:
raise DeployDoNotExist("Error to delete deploy state. No deploy in progress.")
try:
self.data["deploy"] = {}
self.data["deploy"].clear()
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
except Exception:
self.data["deploy"] = deploy
self.data["deploy"][0] = deploy
class DeployHostHandler(DeployHosts):
@ -326,6 +348,11 @@ class DeployHostHandler(DeployHosts):
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
def query(self, hostname):
"""
Query deploy based on hostname
:param hostname: The name of the host.
:return: A list of deploy dictionary
"""
super().query(hostname)
for deploy in self.data.get("deploy_host", []):
if deploy.get("hostname") == hostname: