update/software/software/api/controllers/v1/software.py

204 lines
6.2 KiB
Python

"""
Copyright (c) 2023-2024 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import cgi
import json
import logging
import os
from pecan import expose
from pecan import request
from pecan import Response
import shutil
from software.exceptions import SoftwareError
from software.exceptions import SoftwareServiceError
from software.software_controller import sc
import software.utils as utils
import software.constants as constants
LOG = logging.getLogger('main_logger')
class SoftwareAPIController(object):
@expose('json')
def commit_patch(self, *args):
result = sc.patch_commit(list(args))
sc.software_sync()
return result
@expose('json')
def commit_dry_run(self, *args):
result = sc.patch_commit(list(args), dry_run=True)
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def delete(self, *args):
result = sc.software_release_delete_api(list(args))
sc.software_sync()
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def deploy_activate(self, *args):
if sc.any_patch_host_installing():
raise SoftwareServiceError(error="Rejected: One or more nodes are installing a release.")
result = sc.software_deploy_activate_api(list(args)[0])
sc.software_sync()
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def deploy_complete(self, *args):
if sc.any_patch_host_installing():
raise SoftwareServiceError(error="Rejected: One or more nodes are installing a release.")
result = sc.software_deploy_complete_api(list(args)[0])
sc.software_sync()
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def deploy_host(self, *args):
if len(list(args)) == 0:
return dict(error="Host must be specified for install")
force = False
if len(list(args)) > 1 and 'force' in list(args)[1:]:
force = True
result = sc.software_deploy_host_api(list(args)[0], force, async_req=True)
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def deploy_precheck(self, *args, **kwargs):
force = False
if 'force' in list(args):
force = True
result = sc.software_deploy_precheck_api(list(args)[0], force, **kwargs)
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def deploy_start(self, *args, **kwargs):
# if --force is provided
force = 'force' in list(args)
if sc.any_patch_host_installing():
raise SoftwareServiceError(error="Rejected: One or more nodes are installing a release.")
result = sc.software_deploy_start_api(list(args)[0], force, **kwargs)
sc.send_latest_feed_commit_to_agent()
sc.software_sync()
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')
def install_local(self):
result = sc.software_install_local_api()
return result
@expose('json')
def is_available(self, *args):
return sc.is_available(list(args))
@expose('json')
def is_committed(self, *args):
return sc.is_committed(list(args))
@expose('json')
def is_deployed(self, *args):
return sc.is_deployed(list(args))
@expose('json')
@expose('show.xml', content_type='application/xml')
def show(self, *args):
result = sc.software_release_query_specific_cached(list(args))
return result
@expose('json')
@expose('query.xml', content_type='application/xml')
def upload(self):
is_local = False
temp_dir = None
uploaded_files = []
request_data = []
local_files = []
# --local option only sends a list of file names
if (request.content_type == "text/plain"):
local_files = list(json.loads(request.body))
is_local = True
else:
request_data = list(request.POST.items())
temp_dir = os.path.join(constants.SCRATCH_DIR, 'upload_files')
try:
if len(request_data) == 0 and len(local_files) == 0:
raise SoftwareError("No files uploaded")
if is_local:
uploaded_files = local_files
LOG.info("Uploaded local files: %s", uploaded_files)
else:
# Protect against duplications
uploaded_files = sorted(set(request_data))
# Save all uploaded files to /scratch/upload_files dir
for file_item in uploaded_files:
assert isinstance(file_item[1], cgi.FieldStorage)
utils.save_temp_file(file_item[1], temp_dir)
# Get all uploaded files from /scratch dir
uploaded_files = utils.get_all_files(temp_dir)
LOG.info("Uploaded files: %s", uploaded_files)
# Process uploaded files
return sc.software_release_upload(uploaded_files)
finally:
# Remove all uploaded files from /scratch dir
sc.software_sync()
if temp_dir:
shutil.rmtree(temp_dir, ignore_errors=True)
@expose('json')
@expose('query.xml', content_type='application/xml')
def query(self, **kwargs):
sd = sc.software_release_query_cached(**kwargs)
return dict(sd=sd)
@expose('json', method="GET")
def host_list(self):
query_hosts = dict(data=sc.deploy_host_list())
response_data = json.dumps(query_hosts)
return Response(body=response_data, status_code=200)
@expose(method='GET', template='json')
def in_sync_controller(self):
return sc.in_sync_controller_api()