Merge "Add detailed description for rally commands"
This commit is contained in:
commit
65efb6b2df
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -24,12 +25,52 @@ from rally.openstack.common.apiclient import exceptions
|
|||||||
from rally.openstack.common import cliutils
|
from rally.openstack.common import cliutils
|
||||||
from rally.openstack.common.gettextutils import _
|
from rally.openstack.common.gettextutils import _
|
||||||
from rally.openstack.common import log as logging
|
from rally.openstack.common import log as logging
|
||||||
|
from rally import utils
|
||||||
from rally import version
|
from rally import version
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryParser(argparse.ArgumentParser):
|
||||||
|
|
||||||
|
"""Customized arguments parser
|
||||||
|
|
||||||
|
We need this one to override hardcoded behavior.
|
||||||
|
So, we want to print item's help instead of 'error: too fiew arguments'.
|
||||||
|
Also, we want not to print positional arguments in help messge.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def format_help(self):
|
||||||
|
formatter = self._get_formatter()
|
||||||
|
|
||||||
|
# usage
|
||||||
|
formatter.add_usage(self.usage, self._actions,
|
||||||
|
self._mutually_exclusive_groups)
|
||||||
|
|
||||||
|
# description
|
||||||
|
formatter.add_text(self.description)
|
||||||
|
|
||||||
|
# positionals, optionals and user-defined groups
|
||||||
|
# INFO(oanufriev) _action_groups[0] contains positional arguments.
|
||||||
|
for action_group in self._action_groups[1:]:
|
||||||
|
formatter.start_section(action_group.title)
|
||||||
|
formatter.add_text(action_group.description)
|
||||||
|
formatter.add_arguments(action_group._group_actions)
|
||||||
|
formatter.end_section()
|
||||||
|
|
||||||
|
# epilog
|
||||||
|
formatter.add_text(self.epilog)
|
||||||
|
|
||||||
|
# determine help from format above
|
||||||
|
return formatter.format_help()
|
||||||
|
|
||||||
|
def error(self, message):
|
||||||
|
self.print_help(sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
def pretty_float_formatter(field, ndigits=None):
|
def pretty_float_formatter(field, ndigits=None):
|
||||||
"""Create a formatter function for the given float field.
|
"""Create a formatter function for the given float field.
|
||||||
|
|
||||||
@ -70,7 +111,49 @@ def _methods_of(obj):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _compose_category_description(category):
|
||||||
|
|
||||||
|
descr_pairs = _methods_of(category)
|
||||||
|
|
||||||
|
description = ""
|
||||||
|
if category.__doc__:
|
||||||
|
description = category.__doc__.strip()
|
||||||
|
if descr_pairs:
|
||||||
|
description += "\n\nCommands:\n"
|
||||||
|
sublen = lambda item: len(item[0])
|
||||||
|
first_column_len = max(map(sublen, descr_pairs)) + 3
|
||||||
|
for item in descr_pairs:
|
||||||
|
name = item[0]
|
||||||
|
if item[1].__doc__:
|
||||||
|
doc = utils.parse_docstring(
|
||||||
|
item[1].__doc__)["short_description"]
|
||||||
|
else:
|
||||||
|
doc = ""
|
||||||
|
name += " " * (first_column_len - len(name))
|
||||||
|
description += " %s%s\n" % (name, doc)
|
||||||
|
|
||||||
|
return description
|
||||||
|
|
||||||
|
|
||||||
|
def _compose_action_description(action_fn):
|
||||||
|
description = ""
|
||||||
|
if action_fn.__doc__:
|
||||||
|
parsed_doc = utils.parse_docstring(action_fn.__doc__)
|
||||||
|
short = parsed_doc.get("short_description")
|
||||||
|
long = parsed_doc.get("long_description")
|
||||||
|
|
||||||
|
description = "%s\n\n%s" % (short, long) if long else short
|
||||||
|
|
||||||
|
return description
|
||||||
|
|
||||||
|
|
||||||
def _add_command_parsers(categories, subparsers):
|
def _add_command_parsers(categories, subparsers):
|
||||||
|
|
||||||
|
# INFO(oanufriev) This monkey patching makes our custom parser class to be
|
||||||
|
# used instead of native. This affects all subparsers down from
|
||||||
|
# 'subparsers' parameter of this function (categories and actions).
|
||||||
|
subparsers._parser_class = CategoryParser
|
||||||
|
|
||||||
parser = subparsers.add_parser('version')
|
parser = subparsers.add_parser('version')
|
||||||
|
|
||||||
parser = subparsers.add_parser('bash-completion')
|
parser = subparsers.add_parser('bash-completion')
|
||||||
@ -78,16 +161,20 @@ def _add_command_parsers(categories, subparsers):
|
|||||||
|
|
||||||
for category in categories:
|
for category in categories:
|
||||||
command_object = categories[category]()
|
command_object = categories[category]()
|
||||||
|
descr = _compose_category_description(categories[category])
|
||||||
parser = subparsers.add_parser(category)
|
parser = subparsers.add_parser(
|
||||||
|
category, description=descr,
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
parser.set_defaults(command_object=command_object)
|
parser.set_defaults(command_object=command_object)
|
||||||
|
|
||||||
category_subparsers = parser.add_subparsers(dest='action')
|
category_subparsers = parser.add_subparsers(dest='action')
|
||||||
|
|
||||||
for action, action_fn in _methods_of(command_object):
|
for action, action_fn in _methods_of(command_object):
|
||||||
kwargs = {"help": action_fn.__doc__,
|
descr = _compose_action_description(action_fn)
|
||||||
"description": action_fn.__doc__}
|
parser = category_subparsers.add_parser(
|
||||||
parser = category_subparsers.add_parser(action, **kwargs)
|
action,
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=descr, help=descr)
|
||||||
|
|
||||||
action_kwargs = []
|
action_kwargs = []
|
||||||
for args, kwargs in getattr(action_fn, 'args', []):
|
for args, kwargs in getattr(action_fn, 'args', []):
|
||||||
@ -104,7 +191,6 @@ def _add_command_parsers(categories, subparsers):
|
|||||||
|
|
||||||
parser.set_defaults(action_fn=action_fn)
|
parser.set_defaults(action_fn=action_fn)
|
||||||
parser.set_defaults(action_kwargs=action_kwargs)
|
parser.set_defaults(action_kwargs=action_kwargs)
|
||||||
|
|
||||||
parser.add_argument('action_args', nargs='*')
|
parser.add_argument('action_args', nargs='*')
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ from rally import utils
|
|||||||
|
|
||||||
|
|
||||||
class DeploymentCommands(object):
|
class DeploymentCommands(object):
|
||||||
|
"""Set of commands that allow you to manage deployments."""
|
||||||
|
|
||||||
@cliutils.args('--name', type=str, required=True,
|
@cliutils.args('--name', type=str, required=True,
|
||||||
help='A name of the deployment.')
|
help='A name of the deployment.')
|
||||||
@ -51,7 +52,30 @@ class DeploymentCommands(object):
|
|||||||
help='Don\'t set new deployment as default for'
|
help='Don\'t set new deployment as default for'
|
||||||
' future operations')
|
' future operations')
|
||||||
def create(self, name, fromenv=False, filename=None, do_use=False):
|
def create(self, name, fromenv=False, filename=None, do_use=False):
|
||||||
"""Create a new deployment on the basis of configuration file.
|
"""Create new deployment.
|
||||||
|
|
||||||
|
This command will create new deployment record in rally database.
|
||||||
|
In case of ExistingCloud deployment engine it will use cloud,
|
||||||
|
represented in config.
|
||||||
|
In cases when cloud doesn't exists Rally will deploy new one
|
||||||
|
for you with Devstack or Fuel. For this purposes different deployment
|
||||||
|
engines are developed.
|
||||||
|
|
||||||
|
If you use ExistionCloud deployment engine you can pass deployment
|
||||||
|
config by environment variables:
|
||||||
|
OS_USERNAME
|
||||||
|
OS_PASSWORD
|
||||||
|
OS_AUTH_URL
|
||||||
|
OS_TENANT_NAME
|
||||||
|
|
||||||
|
All other deployment engines need more complex configuration data, so
|
||||||
|
it should be stored in configuration file.
|
||||||
|
|
||||||
|
You can use physical servers, lxc containers, KVM virtual machines
|
||||||
|
or virtual machines in OpenStack for deploying the cloud in.
|
||||||
|
Except physical servers, Rally can create cluster nodes for you.
|
||||||
|
Interaction with virtualisation software, OpenStack
|
||||||
|
cloud or physical servers is provided by server providers.
|
||||||
|
|
||||||
:param fromenv: boolean, read environment instead of config file
|
:param fromenv: boolean, read environment instead of config file
|
||||||
:param filename: a path to the configuration file
|
:param filename: a path to the configuration file
|
||||||
@ -105,6 +129,9 @@ class DeploymentCommands(object):
|
|||||||
def recreate(self, deploy_id=None):
|
def recreate(self, deploy_id=None):
|
||||||
"""Destroy and create an existing deployment.
|
"""Destroy and create an existing deployment.
|
||||||
|
|
||||||
|
Unlike 'deployment destroy' command deployment database record will
|
||||||
|
not be deleted, so deployment's UUID stay same.
|
||||||
|
|
||||||
:param deploy_id: a UUID of the deployment
|
:param deploy_id: a UUID of the deployment
|
||||||
"""
|
"""
|
||||||
api.recreate_deploy(deploy_id)
|
api.recreate_deploy(deploy_id)
|
||||||
@ -113,17 +140,19 @@ class DeploymentCommands(object):
|
|||||||
help='UUID of a deployment.')
|
help='UUID of a deployment.')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def destroy(self, deploy_id=None):
|
def destroy(self, deploy_id=None):
|
||||||
"""Destroy the deployment.
|
"""Destroy existing deployment.
|
||||||
|
|
||||||
Release resources that are allocated for the deployment. The
|
This will delete all containers, virtual machines, OpenStack instances
|
||||||
Deployment, related tasks and their results are also deleted.
|
or Fuel clusters created during Rally deployment creation. Also it will
|
||||||
|
remove deployment record from Rally database.
|
||||||
|
|
||||||
:param deploy_id: a UUID of the deployment
|
:param deploy_id: a UUID of the deployment
|
||||||
"""
|
"""
|
||||||
api.destroy_deploy(deploy_id)
|
api.destroy_deploy(deploy_id)
|
||||||
|
|
||||||
def list(self, deployment_list=None):
|
def list(self, deployment_list=None):
|
||||||
"""Print list of deployments."""
|
"""List existing deployments."""
|
||||||
|
|
||||||
headers = ['uuid', 'created_at', 'name', 'status', 'active']
|
headers = ['uuid', 'created_at', 'name', 'status', 'active']
|
||||||
current_deploy_id = envutils.get_global('RALLY_DEPLOYMENT')
|
current_deploy_id = envutils.get_global('RALLY_DEPLOYMENT')
|
||||||
deployment_list = deployment_list or db.deployment_list()
|
deployment_list = deployment_list or db.deployment_list()
|
||||||
@ -150,9 +179,9 @@ class DeploymentCommands(object):
|
|||||||
help='Output in pretty print format')
|
help='Output in pretty print format')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def config(self, deploy_id=None, output_json=None, output_pprint=None):
|
def config(self, deploy_id=None, output_json=None, output_pprint=None):
|
||||||
"""Print on stdout a config of the deployment.
|
"""Display configuration of the deployment.
|
||||||
|
|
||||||
Output can JSON or Pretty print format.
|
Output can JSON or Pretty print format.
|
||||||
|
|
||||||
:param deploy_id: a UUID of the deployment
|
:param deploy_id: a UUID of the deployment
|
||||||
:param output_json: Output in json format (Default)
|
:param output_json: Output in json format (Default)
|
||||||
@ -174,10 +203,11 @@ class DeploymentCommands(object):
|
|||||||
help='UUID of a deployment.')
|
help='UUID of a deployment.')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def endpoint(self, deploy_id=None):
|
def endpoint(self, deploy_id=None):
|
||||||
"""Print all endpoints of the deployment.
|
"""Display all endpoints of the deployment.
|
||||||
|
|
||||||
:param deploy_id: a UUID of the deployment
|
:param deploy_id: a UUID of the deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
headers = ['auth_url', 'username', 'password', 'tenant_name',
|
headers = ['auth_url', 'username', 'password', 'tenant_name',
|
||||||
'region_name', 'endpoint_type', 'admin_port']
|
'region_name', 'endpoint_type', 'admin_port']
|
||||||
table_rows = []
|
table_rows = []
|
||||||
@ -196,12 +226,11 @@ class DeploymentCommands(object):
|
|||||||
help='UUID of a deployment.')
|
help='UUID of a deployment.')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def check(self, deploy_id=None):
|
def check(self, deploy_id=None):
|
||||||
"""Check the deployment.
|
"""Check keystone authentication and list all available services.
|
||||||
|
|
||||||
Check keystone authentication and list all available services.
|
|
||||||
|
|
||||||
:param deploy_id: a UUID of the deployment
|
:param deploy_id: a UUID of the deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
headers = ['services', 'type', 'status']
|
headers = ['services', 'type', 'status']
|
||||||
table_rows = []
|
table_rows = []
|
||||||
try:
|
try:
|
||||||
|
@ -51,6 +51,11 @@ from rally import utils
|
|||||||
|
|
||||||
|
|
||||||
class InfoCommands(object):
|
class InfoCommands(object):
|
||||||
|
"""This command allows you to get quick doc of some rally entities.
|
||||||
|
|
||||||
|
Available for scenario groups, scenarios, deployment engines and
|
||||||
|
server providers.
|
||||||
|
"""
|
||||||
|
|
||||||
@cliutils.args("--query", dest="query", type=str, help="Search query.")
|
@cliutils.args("--query", dest="query", type=str, help="Search query.")
|
||||||
def find(self, query):
|
def find(self, query):
|
||||||
@ -58,6 +63,7 @@ class InfoCommands(object):
|
|||||||
|
|
||||||
:param query: search query.
|
:param query: search query.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
info = self._find_info(query)
|
info = self._find_info(query)
|
||||||
|
|
||||||
if info:
|
if info:
|
||||||
|
@ -29,6 +29,11 @@ from rally import utils
|
|||||||
|
|
||||||
|
|
||||||
class ShowCommands(object):
|
class ShowCommands(object):
|
||||||
|
"""Show resources.
|
||||||
|
|
||||||
|
Set of commands that allow you to view resourses, provided by OpenStack
|
||||||
|
cloud represented by deployment.
|
||||||
|
"""
|
||||||
|
|
||||||
def _get_endpoints(self, deploy_id):
|
def _get_endpoints(self, deploy_id):
|
||||||
deployment = db.deployment_get(deploy_id)
|
deployment = db.deployment_get(deploy_id)
|
||||||
@ -41,10 +46,11 @@ class ShowCommands(object):
|
|||||||
help='the UUID of a deployment')
|
help='the UUID of a deployment')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def images(self, deploy_id=None):
|
def images(self, deploy_id=None):
|
||||||
"""Show the images that are available in a deployment.
|
"""Display available images.
|
||||||
|
|
||||||
:param deploy_id: the UUID of a deployment
|
:param deploy_id: the UUID of a deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
headers = ['UUID', 'Name', 'Size (B)']
|
headers = ['UUID', 'Name', 'Size (B)']
|
||||||
mixed_case_fields = ['UUID', 'Name']
|
mixed_case_fields = ['UUID', 'Name']
|
||||||
float_cols = ["Size (B)"]
|
float_cols = ["Size (B)"]
|
||||||
@ -74,10 +80,11 @@ class ShowCommands(object):
|
|||||||
help='the UUID of a deployment')
|
help='the UUID of a deployment')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def flavors(self, deploy_id=None):
|
def flavors(self, deploy_id=None):
|
||||||
"""Show the flavors that are available in a deployment.
|
"""Display available flavors.
|
||||||
|
|
||||||
:param deploy_id: the UUID of a deployment
|
:param deploy_id: the UUID of a deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
headers = ['ID', 'Name', 'vCPUs', 'RAM (MB)', 'Swap (MB)', 'Disk (GB)']
|
headers = ['ID', 'Name', 'vCPUs', 'RAM (MB)', 'Swap (MB)', 'Disk (GB)']
|
||||||
mixed_case_fields = ['ID', 'Name', 'vCPUs']
|
mixed_case_fields = ['ID', 'Name', 'vCPUs']
|
||||||
float_cols = ['RAM (MB)', 'Swap (MB)', 'Disk (GB)']
|
float_cols = ['RAM (MB)', 'Swap (MB)', 'Disk (GB)']
|
||||||
@ -107,6 +114,8 @@ class ShowCommands(object):
|
|||||||
help='the UUID of a deployment')
|
help='the UUID of a deployment')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def networks(self, deploy_id=None):
|
def networks(self, deploy_id=None):
|
||||||
|
"""Display configured networks."""
|
||||||
|
|
||||||
headers = ['ID', 'Label', 'CIDR']
|
headers = ['ID', 'Label', 'CIDR']
|
||||||
mixed_case_fields = ['ID', 'Label', 'CIDR']
|
mixed_case_fields = ['ID', 'Label', 'CIDR']
|
||||||
table_rows = []
|
table_rows = []
|
||||||
@ -129,6 +138,8 @@ class ShowCommands(object):
|
|||||||
help='the UUID of a deployment')
|
help='the UUID of a deployment')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def secgroups(self, deploy_id=None):
|
def secgroups(self, deploy_id=None):
|
||||||
|
"""Display security groups."""
|
||||||
|
|
||||||
headers = ['ID', 'Name', 'Description']
|
headers = ['ID', 'Name', 'Description']
|
||||||
mixed_case_fields = ['ID', 'Name', 'Description']
|
mixed_case_fields = ['ID', 'Name', 'Description']
|
||||||
table_rows = []
|
table_rows = []
|
||||||
@ -154,6 +165,8 @@ class ShowCommands(object):
|
|||||||
help='the UUID of a deployment')
|
help='the UUID of a deployment')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def keypairs(self, deploy_id=None):
|
def keypairs(self, deploy_id=None):
|
||||||
|
"""Display available ssh keypairs."""
|
||||||
|
|
||||||
headers = ['Name', 'Fingerprint']
|
headers = ['Name', 'Fingerprint']
|
||||||
mixed_case_fields = ['Name', 'Fingerprint']
|
mixed_case_fields = ['Name', 'Fingerprint']
|
||||||
table_rows = []
|
table_rows = []
|
||||||
|
@ -38,6 +38,10 @@ from rally import utils as rutils
|
|||||||
|
|
||||||
|
|
||||||
class TaskCommands(object):
|
class TaskCommands(object):
|
||||||
|
"""Task management.
|
||||||
|
|
||||||
|
Set of commands that allow you to manage benchmarking tasks and results.
|
||||||
|
"""
|
||||||
|
|
||||||
@cliutils.args('--deploy-id', type=str, dest='deploy_id', required=False,
|
@cliutils.args('--deploy-id', type=str, dest='deploy_id', required=False,
|
||||||
help='UUID of the deployment')
|
help='UUID of the deployment')
|
||||||
@ -45,7 +49,10 @@ class TaskCommands(object):
|
|||||||
help='Path to the file with full configuration of task')
|
help='Path to the file with full configuration of task')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def validate(self, task, deploy_id=None):
|
def validate(self, task, deploy_id=None):
|
||||||
"""Validate a task file.
|
"""Validate a task configuration file.
|
||||||
|
|
||||||
|
This will check that task configuration file has valid syntax and
|
||||||
|
all required options of scenarios, contexts, SLA and runners are set.
|
||||||
|
|
||||||
:param task: a file with yaml/json configration
|
:param task: a file with yaml/json configration
|
||||||
:param deploy_id: a UUID of a deployment
|
:param deploy_id: a UUID of a deployment
|
||||||
@ -71,7 +78,7 @@ class TaskCommands(object):
|
|||||||
help='Don\'t set new task as default for future operations')
|
help='Don\'t set new task as default for future operations')
|
||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def start(self, task, deploy_id=None, tag=None, do_use=False):
|
def start(self, task, deploy_id=None, tag=None, do_use=False):
|
||||||
"""Run a benchmark task.
|
"""Start benchmark task.
|
||||||
|
|
||||||
:param task: a file with yaml/json configration
|
:param task: a file with yaml/json configration
|
||||||
:param deploy_id: a UUID of a deployment
|
:param deploy_id: a UUID of a deployment
|
||||||
@ -99,20 +106,22 @@ class TaskCommands(object):
|
|||||||
@cliutils.args('--uuid', type=str, dest='task_id', help='UUID of task')
|
@cliutils.args('--uuid', type=str, dest='task_id', help='UUID of task')
|
||||||
@envutils.with_default_task_id
|
@envutils.with_default_task_id
|
||||||
def abort(self, task_id=None):
|
def abort(self, task_id=None):
|
||||||
"""Force abort task
|
"""Abort started benchmarking task.
|
||||||
|
|
||||||
:param task_id: Task uuid
|
:param task_id: Task uuid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
api.abort_task(task_id)
|
api.abort_task(task_id)
|
||||||
|
|
||||||
@cliutils.args('--uuid', type=str, dest='task_id', help='UUID of task')
|
@cliutils.args('--uuid', type=str, dest='task_id', help='UUID of task')
|
||||||
@envutils.with_default_task_id
|
@envutils.with_default_task_id
|
||||||
def status(self, task_id=None):
|
def status(self, task_id=None):
|
||||||
"""Get status of task
|
"""Display current status of task.
|
||||||
|
|
||||||
:param task_id: Task uuid
|
:param task_id: Task uuid
|
||||||
Returns current status of task
|
Returns current status of task
|
||||||
"""
|
"""
|
||||||
|
|
||||||
task = db.task_get(task_id)
|
task = db.task_get(task_id)
|
||||||
print(_("Task %(task_id)s is %(status)s.")
|
print(_("Task %(task_id)s is %(status)s.")
|
||||||
% {'task_id': task_id, 'status': task['status']})
|
% {'task_id': task_id, 'status': task['status']})
|
||||||
@ -126,12 +135,13 @@ class TaskCommands(object):
|
|||||||
help='print detailed results for each iteration')
|
help='print detailed results for each iteration')
|
||||||
@envutils.with_default_task_id
|
@envutils.with_default_task_id
|
||||||
def detailed(self, task_id=None, iterations_data=False):
|
def detailed(self, task_id=None, iterations_data=False):
|
||||||
"""Get detailed information about task
|
"""Display results table.
|
||||||
|
|
||||||
:param task_id: Task uuid
|
:param task_id: Task uuid
|
||||||
:param iterations_data: print detailed results for each iteration
|
:param iterations_data: print detailed results for each iteration
|
||||||
Prints detailed information of task.
|
Prints detailed information of task.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _print_iterations_data(raw_data):
|
def _print_iterations_data(raw_data):
|
||||||
headers = ["iteration", "full duration"]
|
headers = ["iteration", "full duration"]
|
||||||
float_cols = ["full duration"]
|
float_cols = ["full duration"]
|
||||||
@ -300,12 +310,15 @@ class TaskCommands(object):
|
|||||||
help=('Output in json format(default)'))
|
help=('Output in json format(default)'))
|
||||||
@envutils.with_default_task_id
|
@envutils.with_default_task_id
|
||||||
def results(self, task_id=None, output_pprint=None, output_json=None):
|
def results(self, task_id=None, output_pprint=None, output_json=None):
|
||||||
"""Print raw results of task.
|
"""Diplay raw task results.
|
||||||
|
|
||||||
|
This will produce a lot of output data about every iteration.
|
||||||
|
|
||||||
:param task_id: Task uuid
|
:param task_id: Task uuid
|
||||||
:param output_pprint: Output in pretty print format
|
:param output_pprint: Output in pretty print format
|
||||||
:param output_json: Output in json format (Default)
|
:param output_json: Output in json format (Default)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
results = map(lambda x: {"key": x["key"], 'result': x['data']['raw'],
|
results = map(lambda x: {"key": x["key"], 'result': x['data']['raw'],
|
||||||
"sla": x["data"]["sla"]},
|
"sla": x["data"]["sla"]},
|
||||||
db.task_result_get_all_by_uuid(task_id))
|
db.task_result_get_all_by_uuid(task_id))
|
||||||
@ -325,7 +338,8 @@ class TaskCommands(object):
|
|||||||
return(1)
|
return(1)
|
||||||
|
|
||||||
def list(self, task_list=None):
|
def list(self, task_list=None):
|
||||||
"""Print a list of all tasks."""
|
"""List all tasks, started and finished."""
|
||||||
|
|
||||||
headers = ['uuid', 'created_at', 'status', 'failed', 'tag']
|
headers = ['uuid', 'created_at', 'status', 'failed', 'tag']
|
||||||
task_list = task_list or db.task_list()
|
task_list = task_list or db.task_list()
|
||||||
if task_list:
|
if task_list:
|
||||||
@ -380,11 +394,12 @@ class TaskCommands(object):
|
|||||||
help='uuid of task or a list of task uuids')
|
help='uuid of task or a list of task uuids')
|
||||||
@envutils.with_default_task_id
|
@envutils.with_default_task_id
|
||||||
def delete(self, task_id=None, force=False):
|
def delete(self, task_id=None, force=False):
|
||||||
"""Delete a specific task and related results.
|
"""Delete task and its results.
|
||||||
|
|
||||||
:param task_id: Task uuid or a list of task uuids
|
:param task_id: Task uuid or a list of task uuids
|
||||||
:param force: Force delete or not
|
:param force: Force delete or not
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(task_id, list):
|
if isinstance(task_id, list):
|
||||||
for tid in task_id:
|
for tid in task_id:
|
||||||
api.delete_task(tid, force=force)
|
api.delete_task(tid, force=force)
|
||||||
@ -397,7 +412,7 @@ class TaskCommands(object):
|
|||||||
help="output in json format")
|
help="output in json format")
|
||||||
@envutils.with_default_task_id
|
@envutils.with_default_task_id
|
||||||
def sla_check(self, task_id=None, tojson=False):
|
def sla_check(self, task_id=None, tojson=False):
|
||||||
"""Check if task was succeded according to SLA.
|
"""Display SLA check results table.
|
||||||
|
|
||||||
:param task_id: Task uuid.
|
:param task_id: Task uuid.
|
||||||
:returns: Number of failed criteria.
|
:returns: Number of failed criteria.
|
||||||
|
@ -24,6 +24,11 @@ from rally import fileutils
|
|||||||
|
|
||||||
|
|
||||||
class UseCommands(object):
|
class UseCommands(object):
|
||||||
|
"""Set of commands that allow you to set an active deployment and task.
|
||||||
|
|
||||||
|
Active deployment and task allow you not to specify deployment UUID and
|
||||||
|
task UUID in the commands requiring this parameter.
|
||||||
|
"""
|
||||||
|
|
||||||
def _update_openrc_deployment_file(self, deploy_id, endpoint):
|
def _update_openrc_deployment_file(self, deploy_id, endpoint):
|
||||||
openrc_path = os.path.expanduser('~/.rally/openrc-%s' % deploy_id)
|
openrc_path = os.path.expanduser('~/.rally/openrc-%s' % deploy_id)
|
||||||
@ -55,10 +60,11 @@ class UseCommands(object):
|
|||||||
@cliutils.args('--name', type=str, dest='name', required=False,
|
@cliutils.args('--name', type=str, dest='name', required=False,
|
||||||
help='Name of the deployment')
|
help='Name of the deployment')
|
||||||
def deployment(self, deploy_id=None, name=None):
|
def deployment(self, deploy_id=None, name=None):
|
||||||
"""Set the RALLY_DEPLOYMENT env var to be used by all CLI commands
|
"""Set active deployment.
|
||||||
|
|
||||||
:param deploy_id: a UUID of a deployment
|
:param deploy_id: a UUID of a deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not (name or deploy_id):
|
if not (name or deploy_id):
|
||||||
print('You should specify --name or --uuid of deployment')
|
print('You should specify --name or --uuid of deployment')
|
||||||
return 1
|
return 1
|
||||||
@ -99,14 +105,9 @@ class UseCommands(object):
|
|||||||
@cliutils.args('--uuid', type=str, dest='task_id', required=False,
|
@cliutils.args('--uuid', type=str, dest='task_id', required=False,
|
||||||
help='UUID of the task')
|
help='UUID of the task')
|
||||||
def task(self, task_id):
|
def task(self, task_id):
|
||||||
"""Set the RALLY_TASK env var.
|
"""Set active task.
|
||||||
|
|
||||||
Is used to allow the user not to specify a task UUID in the command
|
:param task_id: a UUID of task
|
||||||
requiring this parameter.
|
|
||||||
If the task uuid specified in parameter by the user does not exist,
|
|
||||||
a TaskNotFound will be raised by task_get().
|
|
||||||
|
|
||||||
:param task_id: a UUID of a task
|
|
||||||
"""
|
"""
|
||||||
print('Using task: %s' % task_id)
|
print('Using task: %s' % task_id)
|
||||||
self._ensure_rally_configuration_dir_exists()
|
self._ensure_rally_configuration_dir_exists()
|
||||||
|
@ -34,6 +34,11 @@ from rally.verification.verifiers.tempest import json2html
|
|||||||
|
|
||||||
|
|
||||||
class VerifyCommands(object):
|
class VerifyCommands(object):
|
||||||
|
"""Test cloud with Tempest
|
||||||
|
|
||||||
|
Set of commands that allow you to perform Tempest tests of
|
||||||
|
OpenStack live cloud.
|
||||||
|
"""
|
||||||
|
|
||||||
@cliutils.args("--deploy-id", dest="deploy_id", type=str, required=False,
|
@cliutils.args("--deploy-id", dest="deploy_id", type=str, required=False,
|
||||||
help="UUID of a deployment.")
|
help="UUID of a deployment.")
|
||||||
@ -48,13 +53,14 @@ class VerifyCommands(object):
|
|||||||
@envutils.with_default_deploy_id
|
@envutils.with_default_deploy_id
|
||||||
def start(self, deploy_id=None, set_name="smoke", regex=None,
|
def start(self, deploy_id=None, set_name="smoke", regex=None,
|
||||||
tempest_config=None):
|
tempest_config=None):
|
||||||
"""Start running tempest tests against a live cloud cluster.
|
"""Start set of tests.
|
||||||
|
|
||||||
:param deploy_id: a UUID of a deployment
|
:param deploy_id: a UUID of a deployment
|
||||||
:param set_name: Name of tempest test set
|
:param set_name: Name of tempest test set
|
||||||
:param regex: Regular expression of test
|
:param regex: Regular expression of test
|
||||||
:param tempest_config: User specified Tempest config file location
|
:param tempest_config: User specified Tempest config file location
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if regex:
|
if regex:
|
||||||
set_name = "full"
|
set_name = "full"
|
||||||
if set_name not in consts.TEMPEST_TEST_SETS:
|
if set_name not in consts.TEMPEST_TEST_SETS:
|
||||||
@ -65,7 +71,8 @@ class VerifyCommands(object):
|
|||||||
api.verify(deploy_id, set_name, regex, tempest_config)
|
api.verify(deploy_id, set_name, regex, tempest_config)
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
"""Print a result list of verifications."""
|
"""Display all verifications table, started and finished."""
|
||||||
|
|
||||||
fields = ['UUID', 'Deployment UUID', 'Set name', 'Tests', 'Failures',
|
fields = ['UUID', 'Deployment UUID', 'Set name', 'Tests', 'Failures',
|
||||||
'Created at', 'Status']
|
'Created at', 'Status']
|
||||||
verifications = db.verification_list()
|
verifications = db.verification_list()
|
||||||
@ -89,7 +96,7 @@ class VerifyCommands(object):
|
|||||||
help='If specified, output will be saved to given file')
|
help='If specified, output will be saved to given file')
|
||||||
def results(self, verification_uuid, output_file=None, output_html=None,
|
def results(self, verification_uuid, output_file=None, output_html=None,
|
||||||
output_json=None, output_pprint=None):
|
output_json=None, output_pprint=None):
|
||||||
"""Print raw results of verification.
|
"""Get raw results of the verification.
|
||||||
|
|
||||||
:param verification_uuid: Verification UUID
|
:param verification_uuid: Verification UUID
|
||||||
:param output_file: If specified, output will be saved to given file
|
:param output_file: If specified, output will be saved to given file
|
||||||
@ -99,6 +106,7 @@ class VerifyCommands(object):
|
|||||||
:param output_pprint: Save results in pprint format to the
|
:param output_pprint: Save results in pprint format to the
|
||||||
specified file
|
specified file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
results = db.verification_result_get(verification_uuid)['data']
|
results = db.verification_result_get(verification_uuid)['data']
|
||||||
except exceptions.NotFoundException as e:
|
except exceptions.NotFoundException as e:
|
||||||
@ -132,6 +140,8 @@ class VerifyCommands(object):
|
|||||||
@cliutils.args('--detailed', dest='detailed', action='store_true',
|
@cliutils.args('--detailed', dest='detailed', action='store_true',
|
||||||
required=False, help='Prints traceback of failed tests')
|
required=False, help='Prints traceback of failed tests')
|
||||||
def show(self, verification_uuid, sort_by='name', detailed=False):
|
def show(self, verification_uuid, sort_by='name', detailed=False):
|
||||||
|
"""Display results table of the verification."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sortby_index = ('name', 'duration').index(sort_by)
|
sortby_index = ('name', 'duration').index(sort_by)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -182,4 +192,6 @@ class VerifyCommands(object):
|
|||||||
@cliutils.args('--sort-by', dest='sort_by', type=str, required=False,
|
@cliutils.args('--sort-by', dest='sort_by', type=str, required=False,
|
||||||
help='Tests can be sorted by "name" or "duration"')
|
help='Tests can be sorted by "name" or "duration"')
|
||||||
def detailed(self, verification_uuid, sort_by='name'):
|
def detailed(self, verification_uuid, sort_by='name'):
|
||||||
|
"""Display results table of verification with detailed errors."""
|
||||||
|
|
||||||
self.show(verification_uuid, sort_by, True)
|
self.show(verification_uuid, sort_by, True)
|
||||||
|
Loading…
Reference in New Issue
Block a user