1#
2# Copyright 2008 Google Inc. All Rights Reserved.
3#
4"""Command line interface for autotest
5
6This module contains the generic CLI processing
7
8See topic_common.py for a High Level Design and Algorithm.
9
10This file figures out the topic and action from the 2 first arguments
11on the command line and imports the <topic> module.
12
13It then creates a <topic>_<action> object, and calls it parses),
14execute() and output() methods.
15"""
16
17from __future__ import print_function
18
19__author__ = 'jmeurin@google.com (Jean-Marc Eurin)'
20
21import os, sys, re, traceback
22
23import common
24from autotest_lib.cli import topic_common
25from autotest_lib.client.common_lib import lsbrelease_utils
26from autotest_lib.server import utils
27
28
29def main():
30    """
31    The generic syntax is:
32    atest <topic> <action> <options>
33    atest-<topic> <action> <options>
34    atest --help
35    """
36    _disallow_root_user_on_moblab()
37    cli = os.path.basename(sys.argv[0])
38    syntax_obj = topic_common.atest()
39
40    # Normalize the various --help, -h and help to -h
41    sys.argv = [re.sub('--help|help', '-h', arg) for arg in sys.argv]
42
43    match = re.search('^atest-(\w+)$', cli)
44    if match:
45        topic = match.group(1)
46    else:
47        if len(sys.argv) > 1:
48            topic = sys.argv.pop(1)
49        else:
50            syntax_obj.invalid_syntax('No topic argument')
51
52
53    if topic == '-h':
54        sys.argv.insert(1, '-h')
55        syntax_obj.parse()
56
57    # Import the topic specific file
58    cli_dir = os.path.abspath(os.path.dirname(__file__))
59    if not os.path.exists(os.path.join(cli_dir, '%s.py' % topic)):
60        syntax_obj.invalid_syntax('Invalid topic %s' % topic)
61    topic_module = common.setup_modules.import_module(topic,
62                                                      'autotest_lib.cli')
63
64    # If we have a syntax error now, it should
65    # refer to the topic class.
66    topic_class = getattr(topic_module, topic)
67    topic_obj = topic_class()
68
69    if len(sys.argv) > 1:
70        action = sys.argv.pop(1)
71
72        if action == '-h':
73            action = 'help'
74            sys.argv.insert(1, '-h')
75    else:
76        topic_obj.invalid_syntax('No action argument')
77
78    # Any backward compatibility changes?
79    action = topic_obj.backward_compatibility(action, sys.argv)
80
81    # Instantiate a topic object
82    try:
83        action_class = getattr(topic_module, topic + '_' + action)
84    except AttributeError:
85        topic_obj.invalid_syntax('Invalid action %s' % action)
86
87    action_obj = action_class()
88
89    action_obj.parse()
90    try:
91        try:
92            results = action_obj.execute()
93        except topic_common.CliError:
94            pass
95        except Exception as err:
96            traceback.print_exc()
97            action_obj.generic_error("Unexpected exception: %s" % err)
98        else:
99            try:
100                action_obj.output(results)
101            except Exception:
102                traceback.print_exc()
103    finally:
104        return action_obj.show_all_failures()
105
106
107def _disallow_root_user_on_moblab():
108    """Running these tools as root interferes with moblab services"""
109    if lsbrelease_utils.is_moblab():
110        utils.verify_not_root_user()
111