1import os, logging, six.moves.configparser 2from autotest_lib.client.common_lib import autotemp, packages, error 3from autotest_lib.client.common_lib import global_config 4from autotest_lib.client.bin import harness 5 6 7class harness_autoserv(harness.harness): 8 """ 9 The server harness for running from autoserv 10 11 Properties: 12 job 13 The job object for this job 14 """ 15 16 def __init__(self, job, harness_args): 17 """ 18 job 19 The job object for this job 20 """ 21 super(harness_autoserv, self).__init__(job) 22 # 2 for buffer size. Can't use the kwarg 'buffering' on fdopen in py2. 23 self.status = os.fdopen(3, 'w', 2) 24 25 # If a bug on the client run code prevents global_config.ini 26 # from being copied to the client machine, the client will run 27 # without a global config, relying only on the defaults of the 28 # config items. To avoid that happening silently, the check below 29 # was written. 30 try: 31 cfg = global_config.global_config.get_section_values("CLIENT") 32 except six.moves.configparser.NoSectionError: 33 logging.error("Empty CLIENT configuration session. " 34 "global_config.ini missing. This probably means " 35 "a bug on the server code. Please verify.") 36 37 38 def run_start(self): 39 # set up the package fetcher for direct-from-autoserv fetches 40 fetcher = AutoservFetcher(self.job.pkgmgr, self) 41 self.job.pkgmgr.add_repository(fetcher) 42 43 44 def _send_and_wait(self, title, *args): 45 """Send a message to the autoserv and wait for it to signal 46 completion. 47 48 @param title: An alphanumeric string to title the message. 49 @param *args: Additional arbitrary alphanumeric arguments to pass 50 to the server. 51 """ 52 # create a named pipe for us to recieve a signal on 53 fifo_dir = autotemp.tempdir(suffix='-fifo', unique_id='harness', 54 dir=self.job.tmpdir) 55 try: 56 fifo_path = os.path.join(fifo_dir.name, 'autoserv.fifo') 57 os.mkfifo(fifo_path) 58 59 # send signal to the server as title[:args]:path 60 msg = ':'.join([title] + list(args) + [fifo_path]) + '\n' 61 self.status.write(msg) 62 self.status.flush() 63 # wait for the server to signal back to us 64 fifo = open(fifo_path) 65 fifo.read(1) 66 fifo.close() 67 finally: 68 fifo_dir.clean() 69 70 71 def run_test_complete(self): 72 """A test run by this job is complete, signal it to autoserv and 73 wait for it to signal to continue""" 74 self._send_and_wait('AUTOTEST_TEST_COMPLETE') 75 76 77 def test_status(self, status, tag): 78 """A test within this job is completing""" 79 for line in status.split('\n'): 80 # sent status messages with AUTOTEST_STATUS:tag:message 81 msg = ('AUTOTEST_STATUS:%s:%s\n' % (tag, line)) 82 self.status.write(msg) 83 84 85 def fetch_package(self, pkg_name, dest_path): 86 """Request a package from the remote autoserv. 87 88 @param pkg_name: The name of the package, as generally used by the 89 client.common_lib.packages infrastructure. 90 @param dest_path: The path the package should be copied to. 91 """ 92 self._send_and_wait('AUTOTEST_FETCH_PACKAGE', pkg_name, dest_path) 93 94 95class AutoservFetcher(packages.RepositoryFetcher): 96 def __init__(self, package_manager, job_harness): 97 self.url = "autoserv://" 98 self.job_harness = job_harness 99 100 101 def fetch_pkg_file(self, filename, dest_path): 102 if os.path.exists(dest_path): 103 os.remove(dest_path) 104 105 if not global_config.global_config.get_config_value( 106 'CLIENT', 'fetch_from_autoserv', type=bool, default=True): 107 # In order to preserve autotest semantics, we treat this as a 108 # PackageFetchError rather than a success or not including the 109 # fetcher: see crosbug.com/35080. 110 logging.error('Not fetching %s from autoserv.', filename) 111 raise error.PackageFetchError( 112 '%s not fetched from autoserv as fetching from autoserv is ' 113 'disabled.' % filename) 114 115 logging.info('Fetching %s from autoserv to %s.', filename, dest_path) 116 self.job_harness.fetch_package(filename, dest_path) 117 if os.path.exists(dest_path): 118 logging.debug('Successfully fetched %s from autoserv.', filename) 119 else: 120 raise error.PackageFetchError('%s not fetched from autoserv.' 121 % filename) 122