
Currently the 'software list' output may show strange order of the releases, such as: $ software list +------------------+-------+-----------+ | Release | RR | State | +------------------+-------+-----------+ | STX-8.0 | True | deployed | | STX-10.1 | True | available | | STX_8_PATCH_0001 | True | deployed | | STX_8_PATCH_0002 | True | deployed | | STX_8_PATCH_0003 | True | deployed | | STX_8_PATCH_0004 | True | deployed | | STX_8_PATCH_0005 | True | deployed | | STX_8_PATCH_0006 | False | deployed | +------------------+-------+-----------+ This commit fixes the release order, showing from the oldest (top) to the newest (bottom): $ software list +------------------+-------+-----------+ | Release | RR | State | +------------------+-------+-----------+ | STX-8.0 | True | deployed | | STX_8_PATCH_0001 | True | deployed | | STX_8_PATCH_0002 | True | deployed | | STX_8_PATCH_0003 | True | deployed | | STX_8_PATCH_0004 | True | deployed | | STX_8_PATCH_0005 | True | deployed | | STX_8_PATCH_0006 | False | deployed | | STX-10.1 | True | deploying | +------------------+-------+-----------+ Test Plan PASS: run software list and verify the output shows the new order Story: 2010676 Task: 51540 Change-Id: I517de30cdc3383654e332303fbc0036836a6114a Signed-off-by: Heitor Matsui <heitorvieira.matsui@windriver.com>
261 lines
8.1 KiB
Python
261 lines
8.1 KiB
Python
#
|
|
# Copyright (c) 2015-2024 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
import sys
|
|
import threading
|
|
import time
|
|
|
|
from software_client.common import utils
|
|
|
|
|
|
# --release is an optional argument
|
|
@utils.arg('--release',
|
|
required=False,
|
|
help='filter against a release ID')
|
|
# --state is an optional argument. default: "all"
|
|
@utils.arg('--state',
|
|
default=None,
|
|
required=False,
|
|
help='filter against a release state')
|
|
def do_list(cc, args):
|
|
"""List the software releases"""
|
|
resp, data = cc.release.list(args)
|
|
if args.debug:
|
|
utils.print_result_debug(resp, data)
|
|
|
|
rc = utils.check_rc(resp, data)
|
|
if rc == 0:
|
|
header_data_list = {"Release": "release_id", "RR": "reboot_required", "State": "state"}
|
|
sorted_data = sorted(data, key=lambda x: x['release_id'].translate(
|
|
dict.fromkeys(map(ord, "-_."), "-")))
|
|
utils.display_result_list(header_data_list, sorted_data)
|
|
else:
|
|
utils.display_info(resp)
|
|
|
|
return rc
|
|
|
|
|
|
@utils.arg('release',
|
|
nargs="+", # accepts a list
|
|
help='Release ID to print detailed information')
|
|
@utils.arg('--packages',
|
|
required=False,
|
|
default=False,
|
|
action='store_true',
|
|
help='list packages contained in the release')
|
|
def do_show(cc, args):
|
|
"""Show the software release"""
|
|
resp, data = cc.release.show(args)
|
|
if args.debug:
|
|
utils.print_result_debug(resp, data)
|
|
|
|
rc = utils.check_rc(resp, data)
|
|
if rc == 0:
|
|
if not args.packages and 'packages' in data:
|
|
del data['packages']
|
|
utils.display_detail_result(data)
|
|
else:
|
|
utils.display_info(resp)
|
|
|
|
return rc
|
|
|
|
|
|
@utils.arg('--delete',
|
|
required=False,
|
|
action='store_true',
|
|
help='Delete patch install/remove on the localhost mode')
|
|
def do_install_local(cc, args):
|
|
"""Set patch install/remove on the local host.
|
|
This command can only be used for patch installation.
|
|
"""
|
|
resp, data = cc.release.install_local(args.delete)
|
|
if args.debug:
|
|
utils.print_result_debug(resp, data)
|
|
|
|
utils.display_info(resp)
|
|
|
|
return utils.check_rc(resp, data)
|
|
|
|
|
|
# NOTE (bqian) verify this CLI is needed
|
|
@utils.arg('release',
|
|
nargs="+", # accepts a list
|
|
help='List of releases')
|
|
def do_is_available(cc, args):
|
|
"""Query Available state for list of releases.
|
|
Returns True if all are Available, False otherwise.
|
|
"""
|
|
req, result = cc.release.is_available(args.release)
|
|
rc = 1
|
|
if req.status_code == 200:
|
|
print(result)
|
|
if result is True:
|
|
rc = 0
|
|
elif req.status_code == 500:
|
|
print("An internal error has occurred. Please check /var/log/software.log for details")
|
|
else:
|
|
print("Error: %s has occurred. %s" % (req.status_code, req.reason))
|
|
return rc
|
|
|
|
|
|
# NOTE (bqian) verify this CLI is needed
|
|
@utils.arg('release',
|
|
nargs="+", # accepts a list
|
|
help='List of releases')
|
|
def do_is_deployed(cc, args):
|
|
"""Query Deployed state for list of releases.
|
|
Returns True if all are Deployed, False otherwise.
|
|
"""
|
|
req, result = cc.release.is_deployed(args.release)
|
|
rc = 1
|
|
if req.status_code == 200:
|
|
print(result)
|
|
if result is True:
|
|
rc = 0
|
|
elif req.status_code == 500:
|
|
print("An internal error has occurred. Please check /var/log/software.log for details")
|
|
else:
|
|
print("Error: %s has occurred. %s" % (req.status_code, req.reason))
|
|
return rc
|
|
|
|
|
|
# NOTE (bqian) verify this CLI is needed
|
|
@utils.arg('release',
|
|
nargs="+", # accepts a list
|
|
help='List of releases')
|
|
def do_is_committed(cc, args):
|
|
"""Query Committed state for list of releases.
|
|
Returns True if all are Committed, False otherwise.
|
|
"""
|
|
req, result = cc.release.is_committed(args.release)
|
|
rc = 1
|
|
if req.status_code == 200:
|
|
print(result)
|
|
if result is True:
|
|
rc = 0
|
|
elif req.status_code == 500:
|
|
print("An internal error has occurred. Please check /var/log/software.log for details")
|
|
else:
|
|
print("Error: %s has occurred. %s" % (req.status_code, req.reason))
|
|
return rc
|
|
|
|
|
|
def _print_upload_result(resp, data, debug):
|
|
if debug:
|
|
utils.print_result_debug(resp, data)
|
|
|
|
rc = utils.check_rc(resp, data)
|
|
|
|
utils.display_info(resp)
|
|
if rc == 0:
|
|
if data["upload_info"]:
|
|
upload_info = data["upload_info"]
|
|
data_list = [{"file": k, "release": v["id"]}
|
|
for d in upload_info for k, v in d.items()
|
|
if not k.endswith(".sig")]
|
|
|
|
header_data_list = {"Uploaded File": "file", "Release": "release"}
|
|
utils.display_result_list(header_data_list, data_list)
|
|
return rc
|
|
|
|
|
|
@utils.arg('release',
|
|
metavar='(iso + sig) | patch',
|
|
nargs="+", # accepts a list
|
|
help=('pair of install iso and sig files for major release '
|
|
'(GA or patched) and/or one or more files containing a '
|
|
'patch release. NOTE: specify at most ONE pair of (iso + sig)'))
|
|
@utils.arg('--local',
|
|
required=False,
|
|
default=False,
|
|
action='store_true',
|
|
help=("Upload the release locally from active controller. "
|
|
"To use this option, first upload the .iso,.sig and/or .patch "
|
|
"files to active controller and then specify the absolute path of "
|
|
"each file."))
|
|
def do_upload(cc, args):
|
|
"""Upload a software release."""
|
|
try:
|
|
print("This operation will take a while. Please wait.")
|
|
wait_task = WaitThread()
|
|
wait_task.start()
|
|
result = cc.release.upload(args)
|
|
wait_task.join()
|
|
except Exception as e:
|
|
wait_task.join()
|
|
raise Exception("Upload failed. Reason: %s" % e)
|
|
|
|
if isinstance(result, int):
|
|
return result
|
|
else:
|
|
resp, data = result[0], result[1]
|
|
_print_upload_result(resp, data, args.debug)
|
|
|
|
return utils.check_rc(resp, data)
|
|
|
|
|
|
@utils.arg('release',
|
|
metavar='directory',
|
|
nargs="+", # accepts a list
|
|
help=('directory containing software releases files to upload. '
|
|
'The release files may be either a pair of install iso and '
|
|
'sig files for major release (GA or patched) and/or one or '
|
|
'more files containing a patch release. NOTE: specify at most '
|
|
'ONE pair of (iso + sig)'))
|
|
def do_upload_dir(cc, args):
|
|
"""Upload a software release directory."""
|
|
try:
|
|
print("This operation will take a while. Please wait.")
|
|
wait_task = WaitThread()
|
|
wait_task.start()
|
|
resp, data = cc.release.upload_dir(args)
|
|
wait_task.join()
|
|
except Exception as e:
|
|
wait_task.join()
|
|
raise Exception("Upload directory failed. Reason: %s" % e)
|
|
_print_upload_result(resp, data, args.debug)
|
|
|
|
return utils.check_rc(resp, data)
|
|
|
|
|
|
# --all is an optional argument
|
|
@utils.arg('--all',
|
|
action='store_true',
|
|
required=False,
|
|
help='Delete all patches and major releases related '
|
|
'to the given major release ID')
|
|
@utils.arg('release',
|
|
nargs="+", # accepts a list
|
|
help='Release ID to delete')
|
|
def do_delete(cc, args):
|
|
"""Delete the software release"""
|
|
resp, data = cc.release.release_delete(args.release, args.all)
|
|
if args.debug:
|
|
utils.print_result_debug(resp, data)
|
|
|
|
utils.display_info(resp)
|
|
return utils.check_rc(resp, data)
|
|
|
|
|
|
class WaitThread(threading.Thread):
|
|
"""Thread to show progress indication."""
|
|
def __init__(self):
|
|
super(WaitThread, self).__init__()
|
|
self.stop = threading.Event()
|
|
|
|
def run(self):
|
|
"""Run the progress indication."""
|
|
while not self.stop.is_set():
|
|
sys.stdout.write(".")
|
|
sys.stdout.flush()
|
|
time.sleep(10)
|
|
|
|
def join(self, timeout=None):
|
|
"""Stop the progress indication and join the thread."""
|
|
self.stop.set()
|
|
super(WaitThread, self).join(timeout)
|
|
sys.stdout.write("\n")
|
|
sys.stdout.flush()
|