def setIsMoblab(self, is_moblab): """Set lsbrelease_utils.is_moblab result. @param is_moblab: Value to have lsbrelease_utils.is_moblab to return. """ self.mox.StubOutWithMock(lsbrelease_utils, 'is_moblab') lsbrelease_utils.is_moblab().AndReturn(is_moblab)
def parse_config_file(self): """Parse config files.""" self.config = ConfigParser.ConfigParser() if self.config_file and os.path.exists(self.config_file): self.config.read(self.config_file) else: raise ConfigError('%s not found' % (self.config_file)) # If it's running in Moblab, read moblab config file if exists, # overwrite the value in global config. if (lsbrelease_utils.is_moblab() and self.moblab_file and os.path.exists(self.moblab_file)): moblab_config = ConfigParser.ConfigParser() moblab_config.read(self.moblab_file) # now we merge moblab into global self.merge_configs(moblab_config) # now also read the shadow file if there is one # this will overwrite anything that is found in the # other config if self.shadow_file and os.path.exists(self.shadow_file): shadow_config = ConfigParser.ConfigParser() shadow_config.read(self.shadow_file) # now we merge shadow into global self.merge_configs(shadow_config)
def get_offload_gsuri(): """Return the GSURI to offload test results to. For the normal use case this is the results_storage_server in the global_config. However partners using Moblab will be offloading their results to a subdirectory of their image storage buckets. The subdirectory is determined by the MAC Address of the Moblab device. @returns gsuri to offload test results to. """ if not lsbrelease_utils.is_moblab(): return DEFAULT_OFFLOAD_GSURI moblab_id_filepath = '/home/moblab/.moblab_id' if os.path.exists(moblab_id_filepath): with open(moblab_id_filepath, 'r') as moblab_id_file: random_id = moblab_id_file.read() else: random_id = uuid.uuid1() with open(moblab_id_filepath, 'w') as moblab_id_file: moblab_id_file.write('%s' % random_id) return '%sresults/%s/%s/' % (CONFIG.get_config_value( 'CROS', 'image_storage_server'), get_interface_mac_address(MOBLAB_ETH), random_id)
def get_offload_gsuri(): """Return the GSURI to offload test results to. For the normal use case this is the results_storage_server in the global_config. However partners using Moblab will be offloading their results to a subdirectory of their image storage buckets. The subdirectory is determined by the MAC Address of the Moblab device. @returns gsuri to offload test results to. """ # For non-moblab, use results_storage_server or default. if not lsbrelease_utils.is_moblab(): return DEFAULT_OFFLOAD_GSURI # For moblab, use results_storage_server or image_storage_server as bucket # name and mac-address/moblab_id as path. gsuri = DEFAULT_OFFLOAD_GSURI if not gsuri: gsuri = "%sresults/" % CONFIG.get_config_value('CROS', 'image_storage_server') return '%s%s/%s/' % ( gsuri, get_interface_mac_address( get_built_in_ethernet_nic_name()), get_moblab_id())
def testUpdateConfig(self): """Ensure that updating the config works as expected.""" self.setIsMoblab(True) moblab_rpc_interface.os = self.mox.CreateMockAnything() self.mox.StubOutWithMock(__builtin__, 'open') self._mockReadFile(global_config.DEFAULT_CONFIG_FILE) self.mox.StubOutWithMock(lsbrelease_utils, 'is_moblab') lsbrelease_utils.is_moblab().AndReturn(True) self._mockReadFile(global_config.DEFAULT_MOBLAB_FILE, ['[section1]', 'item1: value1']) moblab_rpc_interface.os = self.mox.CreateMockAnything() moblab_rpc_interface.os.path = self.mox.CreateMockAnything() moblab_rpc_interface.os.path.exists( moblab_rpc_interface._CONFIG.shadow_file).AndReturn( True) mockShadowFile = self.mox.CreateMockAnything() mockShadowFileContents = StringIO.StringIO() mockShadowFile.__enter__().AndReturn(mockShadowFileContents) mockShadowFile.__exit__(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) open(moblab_rpc_interface._CONFIG.shadow_file, 'w').AndReturn(mockShadowFile) moblab_rpc_interface.os.system('sudo reboot') self.mox.ReplayAll() moblab_rpc_interface.update_config_handler( {'section1' : [('item1', 'value1'), ('item2', 'value2')], 'section2' : [('item3', 'value3'), ('item4', 'value4')]}) # item1 should not be in the new shadow config as its updated value # matches the original config's value. self.assertEquals( mockShadowFileContents.getvalue(), '[section2]\nitem3 = value3\nitem4 = value4\n\n' '[section1]\nitem2 = value2\n\n')
def update_image(self, wait_for_update=False): """Update the image on the servo host, if needed. This method recognizes the following cases: * If the Host is not running Chrome OS, do nothing. * If a previously triggered update is now complete, reboot to the new version. * If the host is processing a previously triggered update, do nothing. * If the host is running a version of Chrome OS different from the default for servo Hosts, trigger an update, but don't wait for it to complete. @param wait_for_update If an update needs to be applied and this is true, then don't return until the update is downloaded and finalized, and the host rebooted. @raises dev_server.DevServerException: If all the devservers are down. @raises site_utils.ParseBuildNameException: If the devserver returns an invalid build name. @raises autoupdater.ChromiumOSError: If something goes wrong in the checking update engine client status or applying an update. @raises AutoservRunError: If the update_engine_client isn't present on the host, and the host is a cros_host. """ # servod could be running in a Ubuntu workstation. if not self.is_cros_host(): logging.info( 'Not attempting an update, either %s is not running ' 'chromeos or we cannot find enough information about ' 'the host.', self.hostname) return if lsbrelease_utils.is_moblab(): logging.info('Not attempting an update, %s is running moblab.', self.hostname) return target_build = afe_utils.get_stable_cros_image_name(self.get_board()) target_build_number = server_site_utils.ParseBuildName(target_build)[3] # For servo image staging, we want it as more widely distributed as # possible, so that devservers' load can be evenly distributed. So use # hostname instead of target_build as hash. ds = dev_server.ImageServer.resolve(self.hostname, hostname=self.hostname) url = ds.get_update_url(target_build) updater = autoupdater.ChromiumOSUpdater(update_url=url, host=self) status, current_build_number = self._check_for_reboot(updater) update_pending = True if status in autoupdater.UPDATER_PROCESSING_UPDATE: logging.info( 'servo host %s already processing an update, update ' 'engine client status=%s', self.hostname, status) elif current_build_number != target_build_number: logging.info( 'Using devserver url: %s to trigger update on ' 'servo host %s, from %s to %s', url, self.hostname, current_build_number, target_build_number) try: ds.stage_artifacts(target_build, artifacts=['full_payload']) except Exception as e: logging.error('Staging artifacts failed: %s', str(e)) logging.error('Abandoning update for this cycle.') else: try: # TODO(jrbarnette): This 'touch' is a gross hack # to get us past crbug.com/613603. Once that # bug is resolved, we should remove this code. self.run('touch /home/chronos/.oobe_completed') updater.trigger_update() except autoupdater.RootFSUpdateError as e: trigger_download_status = 'failed with %s' % str(e) metrics.Counter('chromeos/autotest/servo/' 'rootfs_update_failed').increment() else: trigger_download_status = 'passed' logging.info( 'Triggered download and update %s for %s, ' 'update engine currently in status %s', trigger_download_status, self.hostname, updater.check_update_status()) else: logging.info('servo host %s does not require an update.', self.hostname) update_pending = False if update_pending and wait_for_update: logging.info('Waiting for servo update to complete.') self.run('update_engine_client --follow', ignore_status=True)
def test_is_moblab_with_moblab_lsbrelease(self): """is_moblab correctly validates the contents from a moblab device.""" self.assertTrue( lsbrelease_utils.is_moblab(_GUADO_MOBLAB_LSB_RELEASE_REDACTED))
def test_is_moblab_with_link_lsbrelease(self): """is_moblab correctly validates the contents from some other board.""" self.assertFalse( lsbrelease_utils.is_moblab(_LINK_LSB_RELEASE_REDACTED))
def test_is_moblab_with_empty_lsbrelease(self): """is_moblab correctly validates trivial lsb-release information.""" self.assertFalse(lsbrelease_utils.is_moblab(''))
def _disallow_root_user_on_moblab(): """Running these tools as root interferes with moblab services""" if lsbrelease_utils.is_moblab(): utils.verify_not_root_user()
def host_in_lab(hostname): return (not utils.in_moblab_ssp() and not lsbrelease_utils.is_moblab() and utils.host_is_in_lab_zone(hostname))