コード例 #1
0
ファイル: test_cliutils.py プロジェクト: shsingh/rally
 def _unregister_opts(self):
     CONF.reset()
     category_opt = cfg.SubCommandOpt("category",
                                      title="Command categories",
                                      help="Available categories")
     CONF.unregister_opt(category_opt)
コード例 #2
0
ファイル: cliutils.py プロジェクト: sapcc/rally
def run(argv, categories):
    if len(argv) > 1 and argv[1] in ["version", "--version"]:
        _print_version()
        return 0

    parser = lambda subparsers: _add_command_parsers(categories, subparsers)
    category_opt = cfg.SubCommandOpt("category",
                                     title="Command categories",
                                     help="Available categories",
                                     handler=parser)

    CONF.register_cli_opt(category_opt)
    help_msg = ("Additional custom plugin locations. Multiple files or "
                "directories may be specified. All plugins in the specified"
                " directories and subdirectories will be imported. Plugins in"
                " /opt/rally/plugins and ~/.rally/plugins will always be "
                "imported.")

    CONF.register_cli_opt(cfg.ListOpt("plugin-paths",
                                      default=os.environ.get(
                                          "RALLY_PLUGIN_PATHS"),
                                      help=help_msg))

    # NOTE(andreykurilin): this dirty hack is done to unblock the gates.
    #   Currently, we are using oslo.config for CLI purpose (don't do this!)
    #   and it makes the things too complicated.
    #   To discover which CLI method can be affected by warnings and which not
    #   (based on suppress_warnings decorator) we need to obtain a desired
    #   CLI method. It can be done only after initialization of oslo_config
    #   which is located in rally.api.API init method.
    #   Initialization of rally.api.API can produce a warning (for example,
    #   from pymysql), so suppressing of warnings later will not work in such
    #   case (it is what actually had happened now in our CI with the latest
    #   release of PyMySQL).
    #
    # https://bitbucket.org/zzzeek/sqlalchemy/issues/4120/mysql-5720-warns-on-tx_isolation
    try:
        import pymysql
        warnings.filterwarnings("ignore", category=pymysql.Warning)
    except ImportError:
        pass

    try:
        rapi = api.API(config_args=argv[1:], skip_db_check=True)
    except exceptions.RallyException as e:
        print(e)
        return(2)

    if CONF.category.name == "bash-completion":
        print(_generate_bash_completion_script())
        return(0)

    fn = CONF.category.action_fn
    fn_args = [encodeutils.safe_decode(arg)
               for arg in CONF.category.action_args]
    # api instance always is the first argument
    fn_args.insert(0, rapi)
    fn_kwargs = {}
    for k in CONF.category.action_kwargs:
        v = getattr(CONF.category, "action_kwarg_" + k)
        if v is None:
            continue
        if isinstance(v, str):
            v = encodeutils.safe_decode(v)
        fn_kwargs[k] = v

    # call the action with the remaining arguments
    # check arguments
    try:
        validate_args(fn, *fn_args, **fn_kwargs)
    except MissingArgs as e:
        # NOTE(mikal): this isn't the most helpful error message ever. It is
        # long, and tells you a lot of things you probably don't want to know
        # if you just got a single arg wrong.
        print(fn.__doc__)
        CONF.print_help()
        print("Missing arguments:")
        for missing in e.missing:
            for arg in fn.args:
                if arg[1].get("dest", "").endswith(missing):
                    print(" " + arg[0][0])
                    break
        return(1)

    try:
        validate_deprecated_args(argv, fn)

        # skip db check for db and plugin commands
        if CONF.category.name not in ("db", "plugin"):
            rapi.check_db_revision()

        if getattr(fn, "_suppress_warnings", False):
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                ret = fn(*fn_args, **fn_kwargs)
        else:
            ret = fn(*fn_args, **fn_kwargs)
        return ret

    except (IOError, TypeError, ValueError,
            exceptions.RallyException, jsonschema.ValidationError) as e:
        known_errors = (exceptions.InvalidTaskConfig, )
        if logging.is_debug() and not isinstance(e, known_errors):
            LOG.exception("Unexpected exception in CLI")
        else:
            print(e)
        return getattr(e, "error_code", 1)
    except sqlalchemy.exc.OperationalError as e:
        if logging.is_debug():
            LOG.exception("Something went wrong with database")
        print(e)
        print("Looks like Rally can't connect to its DB.")
        print("Make sure that connection string in rally.conf is proper:")
        print(CONF.database.connection)
        return 1
    except Exception:
        print("Command failed, please check log for more info")
        raise