1*9c5db199SXin Li#!/usr/bin/python3 2*9c5db199SXin Li# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Liimport os 7*9c5db199SXin Liimport sys 8*9c5db199SXin Li 9*9c5db199SXin Liimport common 10*9c5db199SXin Li 11*9c5db199SXin Lifrom autotest_lib.client.common_lib import control_data 12*9c5db199SXin Lifrom autotest_lib.client.common_lib import global_config 13*9c5db199SXin Li 14*9c5db199SXin LiAUTOTEST_INSTALL_DIR = global_config.global_config.get_config_value('SCHEDULER', 15*9c5db199SXin Li 'drone_installation_directory') 16*9c5db199SXin Liautoserv_directory = os.path.join(AUTOTEST_INSTALL_DIR, 'server') 17*9c5db199SXin Liautoserv_path = os.path.join(autoserv_directory, 'autoserv') 18*9c5db199SXin Li 19*9c5db199SXin Li 20*9c5db199SXin Lidef autoserv_run_job_command(autoserv_directory, 21*9c5db199SXin Li machines, 22*9c5db199SXin Li results_directory=None, 23*9c5db199SXin Li extra_args=[], 24*9c5db199SXin Li job=None, 25*9c5db199SXin Li queue_entry=None, 26*9c5db199SXin Li verbose=True, 27*9c5db199SXin Li write_pidfile=True, 28*9c5db199SXin Li fast_mode=False, 29*9c5db199SXin Li ssh_verbosity=0, 30*9c5db199SXin Li no_console_prefix=False, 31*9c5db199SXin Li ssh_options=None, 32*9c5db199SXin Li use_packaging=True, 33*9c5db199SXin Li in_lab=False, 34*9c5db199SXin Li host_attributes=None, 35*9c5db199SXin Li use_virtualenv=False, 36*9c5db199SXin Li host_info_subdir='', 37*9c5db199SXin Li companion_hosts=None, 38*9c5db199SXin Li dut_servers=None, 39*9c5db199SXin Li is_cft=False): 40*9c5db199SXin Li """ 41*9c5db199SXin Li Construct an autoserv command from a job or host queue entry. 42*9c5db199SXin Li 43*9c5db199SXin Li @param autoserv_directory: Absolute path to directory containing the 44*9c5db199SXin Li autoserv executable. 45*9c5db199SXin Li @param machines: A machine or comma separated list of machines to run 46*9c5db199SXin Li job on. Leave as None or empty string for hostless job 47*9c5db199SXin Li (String). 48*9c5db199SXin Li @param results_directory: Absolute path to directory in which to deposit 49*9c5db199SXin Li results. 50*9c5db199SXin Li @param extra_args: Additional arguments to pass to autoserv 51*9c5db199SXin Li (List of Strings). 52*9c5db199SXin Li @param job: Job object. If supplied, -u owner, -l name, and --test-retry, 53*9c5db199SXin Li and -c or -s (client or server) parameters will be added. 54*9c5db199SXin Li @param queue_entry: HostQueueEntry object. If supplied and no job 55*9c5db199SXin Li was supplied, this will be used to lookup the job. 56*9c5db199SXin Li @param verbose: Boolean (default: True) for autoserv verbosity. 57*9c5db199SXin Li @param write_pidfile: Boolean (default: True) for whether autoserv should 58*9c5db199SXin Li write a pidfile. 59*9c5db199SXin Li @param fast_mode: bool to use fast mode (disables slow autotest features). 60*9c5db199SXin Li @param ssh_verbosity: integer between 0 and 3 (inclusive) which sents the 61*9c5db199SXin Li verbosity level of ssh. Default: 0. 62*9c5db199SXin Li @param no_console_prefix: If true, supress timestamps and other prefix info 63*9c5db199SXin Li in autoserv console logs. 64*9c5db199SXin Li @param ssh_options: A string giving extra arguments to be tacked on to 65*9c5db199SXin Li ssh commands. 66*9c5db199SXin Li @param use_packaging Enable install modes that use the packaging system. 67*9c5db199SXin Li @param in_lab: If true, informs autoserv it is running within a lab 68*9c5db199SXin Li environment. This information is useful as autoserv knows 69*9c5db199SXin Li the database is available and can make database calls such 70*9c5db199SXin Li as looking up host attributes at runtime. 71*9c5db199SXin Li @param host_attributes: Dict of host attributes to pass into autoserv. 72*9c5db199SXin Li @param use_virtualenv: Whether to run autoserv inside of virtualenv. In 73*9c5db199SXin Li general this should be set to True in our production 74*9c5db199SXin Li lab, and probably False in most other use cases 75*9c5db199SXin Li (moblab, local testing) until we rollout virtualenv 76*9c5db199SXin Li support everywhere. Default: False. 77*9c5db199SXin Li @param host_info_subdir: When set, a sub-directory of the results directory 78*9c5db199SXin Li where host info file(s) are stored. 79*9c5db199SXin Li @param companion_hosts: a str or list of hosts to be used as companions 80*9c5db199SXin Li for the and provided to test. NOTE: these are 81*9c5db199SXin Li different than machines, where each host is a host 82*9c5db199SXin Li that the test would be run on. 83*9c5db199SXin Li @param dut_servers: a str or list of hosts to be used as DUT server 84*9c5db199SXin Li provided to test. 85*9c5db199SXin Li 86*9c5db199SXin Li @returns The autoserv command line as a list of executable + parameters. 87*9c5db199SXin Li 88*9c5db199SXin Li """ 89*9c5db199SXin Li script_name = 'virtualenv_autoserv' if use_virtualenv else 'autoserv' 90*9c5db199SXin Li 91*9c5db199SXin Li full_script_path = os.path.join(autoserv_directory, script_name) 92*9c5db199SXin Li 93*9c5db199SXin Li # virtualenv_autoserv is a `POSIX shell script, ASCII text executable`. 94*9c5db199SXin Li # Calling with `sys.executable` would fail because python doesn't 95*9c5db199SXin Li # interpret shebangs itself. 96*9c5db199SXin Li if use_virtualenv: 97*9c5db199SXin Li command = [full_script_path] 98*9c5db199SXin Li else: 99*9c5db199SXin Li command = [sys.executable, full_script_path] 100*9c5db199SXin Li 101*9c5db199SXin Li if write_pidfile: 102*9c5db199SXin Li command.append('-p') 103*9c5db199SXin Li 104*9c5db199SXin Li if results_directory: 105*9c5db199SXin Li command += ['-r', results_directory] 106*9c5db199SXin Li if host_info_subdir: 107*9c5db199SXin Li command += ['--local-only-host-info', 'True'] 108*9c5db199SXin Li command += ['--host-info-subdir', host_info_subdir] 109*9c5db199SXin Li 110*9c5db199SXin Li if machines: 111*9c5db199SXin Li command += ['-m', machines] 112*9c5db199SXin Li 113*9c5db199SXin Li if companion_hosts: 114*9c5db199SXin Li if not isinstance(companion_hosts, list): 115*9c5db199SXin Li companion_hosts = [companion_hosts] 116*9c5db199SXin Li command += ['-ch', ",".join(companion_hosts)] 117*9c5db199SXin Li 118*9c5db199SXin Li if dut_servers: 119*9c5db199SXin Li if not isinstance(dut_servers, list): 120*9c5db199SXin Li dut_servers = [dut_servers] 121*9c5db199SXin Li command += ['--dut_servers', ",".join(dut_servers)] 122*9c5db199SXin Li 123*9c5db199SXin Li if ssh_verbosity: 124*9c5db199SXin Li command += ['--ssh_verbosity', str(ssh_verbosity)] 125*9c5db199SXin Li 126*9c5db199SXin Li if ssh_options: 127*9c5db199SXin Li command += ['--ssh_options', ssh_options] 128*9c5db199SXin Li 129*9c5db199SXin Li if no_console_prefix: 130*9c5db199SXin Li command += ['--no_console_prefix'] 131*9c5db199SXin Li 132*9c5db199SXin Li if job or queue_entry: 133*9c5db199SXin Li if not job: 134*9c5db199SXin Li job = queue_entry.job 135*9c5db199SXin Li 136*9c5db199SXin Li owner = getattr(job, 'owner', None) 137*9c5db199SXin Li name = getattr(job, 'name', None) 138*9c5db199SXin Li control_type = getattr(job, 'control_type', None) 139*9c5db199SXin Li 140*9c5db199SXin Li 141*9c5db199SXin Li if owner: 142*9c5db199SXin Li command += ['-u', owner] 143*9c5db199SXin Li if name: 144*9c5db199SXin Li command += ['-l', name] 145*9c5db199SXin Li if control_type is not None: # still want to enter if control_type==0 146*9c5db199SXin Li control_type_value = control_data.CONTROL_TYPE.get_value( 147*9c5db199SXin Li control_type) 148*9c5db199SXin Li if control_type_value == control_data.CONTROL_TYPE.CLIENT: 149*9c5db199SXin Li command.append('-c') 150*9c5db199SXin Li elif control_type_value == control_data.CONTROL_TYPE.SERVER: 151*9c5db199SXin Li command.append('-s') 152*9c5db199SXin Li 153*9c5db199SXin Li if host_attributes: 154*9c5db199SXin Li command += ['--host_attributes', repr(host_attributes)] 155*9c5db199SXin Li 156*9c5db199SXin Li if verbose: 157*9c5db199SXin Li command.append('--verbose') 158*9c5db199SXin Li 159*9c5db199SXin Li if fast_mode: 160*9c5db199SXin Li command.append('--disable_sysinfo') 161*9c5db199SXin Li command.append('--no_collect_crashinfo') 162*9c5db199SXin Li 163*9c5db199SXin Li if not use_packaging: 164*9c5db199SXin Li command.append('--no_use_packaging') 165*9c5db199SXin Li 166*9c5db199SXin Li if in_lab: 167*9c5db199SXin Li command.extend(['--lab', 'True']) 168*9c5db199SXin Li 169*9c5db199SXin Li if is_cft: 170*9c5db199SXin Li command.append('--CFT') 171*9c5db199SXin Li 172*9c5db199SXin Li py_version = os.getenv('PY_VERSION') 173*9c5db199SXin Li if py_version: 174*9c5db199SXin Li command.extend(['--py_version', py_version]) 175*9c5db199SXin Li 176*9c5db199SXin Li return command + extra_args 177