cros_update: Migrate to chromite
This is mostly uses the cros_update files in the chromite.
BUG=chromium:1003986
TEST=./devserver_integration_test.py
Cq-Depend: chromium:1866027
Change-Id: Id9c3f6e4c6b8e08889ec96942f37f3e084380e9a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/1894676
Tested-by: Amin Hassani <ahassani@chromium.org>
Tested-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/Makefile b/Makefile
index b8100a5..99c3309 100644
--- a/Makefile
+++ b/Makefile
@@ -17,9 +17,6 @@
autoupdate.py \
builder.py \
cherrypy_ext.py \
- cros_update.py \
- cros_update_logging.py \
- cros_update_progress.py \
health_checker.py \
nebraska/nebraska.py \
setup_chromite.py \
diff --git a/cros_update.py b/cros_update.py
deleted file mode 100644
index 10cd6fd..0000000
--- a/cros_update.py
+++ /dev/null
@@ -1,392 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2016 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""An executable function cros-update for auto-update of a CrOS host.
-
-The reason to create this file is to let devserver to trigger a background
-process for CrOS auto-update. Therefore, when devserver service is restarted
-sometimes, the CrOS auto-update process is still running and the corresponding
-provision task won't claim failure.
-
-It includes two classes:
- a. CrOSUpdateTrigger:
- 1. Includes all logics which identify which types of update need to be
- performed in the current DUT.
- 2. Responsible for write current status of CrOS auto-update process into
- progress_tracker.
-
- b. CrOSAUParser:
- 1. Pre-setup the required args for CrOS auto-update.
- 2. Parse the input parameters for cmd that runs 'cros_update.py'.
-"""
-
-from __future__ import print_function
-
-import os
-import re
-import sys
-import time
-import traceback
-import logging # pylint: disable=cros-logging-import
-
-import cros_update_logging
-import cros_update_progress
-
-import setup_chromite # pylint: disable=unused-import
-from chromite.lib import auto_updater
-from chromite.lib import commandline
-from chromite.lib import cros_build_lib
-from chromite.lib import remote_access
-from chromite.lib import timeout_util
-
-
-# The build channel for recovering host's stateful partition
-STABLE_BUILD_CHANNEL = 'stable-channel'
-
-# Timeout for CrOS auto-update process.
-CROS_UPDATE_TIMEOUT_MIN = 30
-
-# The preserved path in remote device, won't be deleted after rebooting.
-CROS_PRESERVED_PATH = ('/mnt/stateful_partition/unencrypted/'
- 'preserve/cros-update')
-
-# Standard error tmeplate to be written into status tracking log.
-CROS_ERROR_TEMPLATE = cros_update_progress.ERROR_TAG + ' %s'
-
-# How long after a quick provision fails to wait before falling back to the
-# standard provisioning flow.
-QUICK_PROVISION_FAILURE_DELAY_SEC = 45
-
-# Setting logging level
-logConfig = cros_update_logging.loggingConfig()
-logConfig.ConfigureLogging()
-
-
-class CrOSUpdateTrigger(object):
- """The class for CrOS auto-updater trigger.
-
- This class is used for running all CrOS auto-update trigger logic.
- """
- def __init__(self, host_name, build_name, static_dir, progress_tracker=None,
- log_file=None, au_tempdir=None, force_update=False,
- full_update=False, original_build=None, payload_filename=None,
- clobber_stateful=True, quick_provision=False,
- devserver_url=None, static_url=None):
- self.host_name = host_name
- self.build_name = build_name
- self.static_dir = static_dir
- self.progress_tracker = progress_tracker
- self.log_file = log_file
- self.au_tempdir = au_tempdir
- self.force_update = force_update
- self.full_update = full_update
- self.original_build = original_build
- self.payload_filename = payload_filename
- self.clobber_stateful = clobber_stateful
- self.quick_provision = quick_provision
- self.devserver_url = devserver_url
- self.static_url = static_url
-
- def _WriteAUStatus(self, content):
- if self.progress_tracker:
- self.progress_tracker.WriteStatus(content)
-
- def _StatefulUpdate(self, cros_updater):
- """The detailed process in stateful update.
-
- Args:
- cros_updater: The CrOS auto updater for auto-update.
- """
- self._WriteAUStatus('pre-setup stateful update')
- cros_updater.PreSetupStatefulUpdate()
- self._WriteAUStatus('perform stateful update')
- cros_updater.UpdateStateful()
- self._WriteAUStatus('post-check stateful update')
- cros_updater.PostCheckStatefulUpdate()
-
- def _RootfsUpdate(self, cros_updater):
- """The detailed process in rootfs update.
-
- Args:
- cros_updater: The CrOS auto updater for auto-update.
- """
- self._WriteAUStatus('Check whether devserver can run before rootfs update')
- cros_updater.CheckDevserverRun()
- self._WriteAUStatus('transfer rootfs update package')
- cros_updater.TransferRootfsUpdate()
- self._WriteAUStatus('pre-setup rootfs update')
- cros_updater.PreSetupRootfsUpdate()
- self._WriteAUStatus('rootfs update')
- cros_updater.UpdateRootfs()
- self._WriteAUStatus('post-check rootfs update')
- cros_updater.PostCheckRootfsUpdate()
-
- def _GetOriginalPayloadDir(self):
- """Get the directory of original payload.
-
- Returns:
- The directory of original payload, whose format is like:
- 'static/stable-channel/link/3428.210.0'
- """
- if self.original_build:
- return os.path.join(self.static_dir, '%s/%s' % (STABLE_BUILD_CHANNEL,
- self.original_build))
- else:
- return None
-
- def _MakeStatusUrl(self, devserver_url, host_name, pid):
- """Generates a URL to post auto update status to.
-
- Args:
- devserver_url: URL base for devserver RPCs.
- host_name: Host to post status for.
- pid: pid of the update process.
-
- Returns:
- An unescaped URL.
- """
- return '%s/post_au_status?host_name=%s&pid=%d' % (devserver_url, host_name,
- pid)
-
- def _QuickProvision(self, device):
- """Performs a quick provision of device.
-
- Returns:
- A dictionary of extracted key-value pairs returned from the script
- execution.
-
- Raises:
- cros_build_lib.RunCommandError: error executing command or script
- remote_access.SSHConnectionError: SSH connection error
- """
- pid = os.getpid()
- pgid = os.getpgid(pid)
- if self.progress_tracker is None:
- self.progress_tracker = cros_update_progress.AUProgress(self.host_name,
- pgid)
-
- dut_script = '/tmp/quick-provision'
- status_url = self._MakeStatusUrl(self.devserver_url, self.host_name, pgid)
- cmd = ('curl -o %s %s && bash '
- '%s --status_url %s %s %s') % (
- dut_script, os.path.join(self.static_url, 'quick-provision'),
- dut_script, cros_build_lib.ShellQuote(status_url),
- self.build_name, self.static_url
- )
- # Quick provision script issues a reboot and might result in the SSH
- # connection being terminated so set ssh_error_ok so that output can
- # still be captured.
- results = device.RunCommand(cmd, log_output=True, capture_output=True,
- ssh_error_ok=True)
- key_re = re.compile(r'^KEYVAL: ([^\d\W]\w*)=(.*)$')
- matches = [key_re.match(l) for l in results.output.splitlines()]
- keyvals = {m.group(1): m.group(2) for m in matches if m}
- logging.info('DUT returned keyvals: %s', keyvals)
-
- # If there was an SSH error, check the keyvals to see if it actually
- # completed and suppress the error if so.
- if results.returncode == remote_access.SSH_ERROR_CODE:
- if 'COMPLETED' in keyvals:
- logging.warning('Quick provision completed with ssh error, ignoring...')
- else:
- logging.error('Incomplete quick provision failed with ssh error')
- raise remote_access.SSHConnectionError(results.error)
-
- return keyvals
-
- def TriggerAU(self):
- """Execute auto update for cros_host.
-
- The auto update includes 4 steps:
- 1. if devserver cannot run, restore the stateful partition.
- 2. if possible, do stateful update first, but never raise errors, except
- for timeout_util.TimeoutError caused by system.signal.
- 3. If required or stateful_update fails, first do rootfs update, then do
- stateful_update.
- 4. Post-check for the whole update.
- """
- try:
- with remote_access.ChromiumOSDeviceHandler(
- self.host_name, port=None,
- base_dir=CROS_PRESERVED_PATH,
- ping=False) as device:
-
- logging.debug('Remote device %s is connected', self.host_name)
- payload_dir = os.path.join(self.static_dir, self.build_name)
- original_payload_dir = self._GetOriginalPayloadDir()
-
- chromeos_AU = auto_updater.ChromiumOSUpdater(
- device, self.build_name, payload_dir,
- dev_dir=os.path.abspath(os.path.dirname(__file__)),
- tempdir=self.au_tempdir,
- log_file=self.log_file,
- original_payload_dir=original_payload_dir,
- yes=True,
- payload_filename=self.payload_filename,
- clobber_stateful=self.clobber_stateful)
-
- # Allow fall back if the quick provision does not succeed.
- invoke_autoupdate = True
-
- if (self.quick_provision and self.clobber_stateful and
- not self.full_update):
- try:
- logging.debug('Start CrOS quick provision process...')
- self._WriteAUStatus('Start Quick Provision')
- keyvals = self._QuickProvision(device)
- logging.debug('Start CrOS check process...')
- self._WriteAUStatus('Finish Quick Provision, reboot')
- chromeos_AU.AwaitReboot(keyvals.get('BOOT_ID'))
- self._WriteAUStatus('Finish Quick Provision, post-check')
- chromeos_AU.PostCheckCrOSUpdate()
- self._WriteAUStatus(cros_update_progress.FINISHED)
- invoke_autoupdate = False
- except (cros_build_lib.RunCommandError,
- remote_access.SSHConnectionError,
- auto_updater.RebootVerificationError) as e:
- logging.warning(
- 'Error during quick provision, falling back to legacy: %s: %s',
- type(e).__name__, e)
- time.sleep(QUICK_PROVISION_FAILURE_DELAY_SEC)
-
- if invoke_autoupdate:
- chromeos_AU.CheckPayloads()
-
- version_match = chromeos_AU.PreSetupCrOSUpdate()
- self._WriteAUStatus('Transfer Devserver/Stateful Update Package')
- chromeos_AU.TransferDevServerPackage()
- chromeos_AU.TransferStatefulUpdate()
-
- restore_stateful = chromeos_AU.CheckRestoreStateful()
- do_stateful_update = (not self.full_update) and (
- version_match and self.force_update)
- stateful_update_complete = False
- logging.debug('Start CrOS update process...')
- try:
- if restore_stateful:
- self._WriteAUStatus('Restore Stateful Partition')
- chromeos_AU.RestoreStateful()
- stateful_update_complete = True
- else:
- # Whether to execute stateful update depends on:
- # a. full_update=False: No full reimage is required.
- # b. The update version is matched to the current version, And
- # force_update=True: Update is forced even if the version
- # installed is the same.
- if do_stateful_update:
- self._StatefulUpdate(chromeos_AU)
- stateful_update_complete = True
-
- except timeout_util.TimeoutError:
- raise
- except Exception as e:
- logging.debug('Error happens in stateful update: %r', e)
-
- # Whether to execute rootfs update depends on:
- # a. stateful update is not completed, or completed by
- # update action 'restore_stateful'.
- # b. force_update=True: Update is forced no matter what the current
- # version is. Or, the update version is not matched to the current
- # version.
- require_rootfs_update = self.force_update or (
- not chromeos_AU.CheckVersion())
- if (not (do_stateful_update and stateful_update_complete)
- and require_rootfs_update):
- self._RootfsUpdate(chromeos_AU)
- self._StatefulUpdate(chromeos_AU)
-
- self._WriteAUStatus('post-check for CrOS auto-update')
- chromeos_AU.PostCheckCrOSUpdate()
- self._WriteAUStatus(cros_update_progress.FINISHED)
-
- logging.debug('Provision successfully completed (%s)',
- 'legacy' if invoke_autoupdate else 'quick provision')
- except Exception as e:
- logging.debug('Error happens in CrOS auto-update: %r', e)
- self._WriteAUStatus(CROS_ERROR_TEMPLATE % str(traceback.format_exc()))
- raise
-
-
-def ParseArguments(argv):
- """Returns a namespace for the CLI arguments."""
- parser = commandline.ArgumentParser(description=__doc__)
- parser.add_argument('-d', action='store', type=str, dest='host_name',
- help='host_name of a DUT')
- parser.add_argument('-b', action='store', type=str, dest='build_name',
- help='build name to be auto-updated')
- parser.add_argument('--static_dir', action='store', type='path',
- help='static directory of the devserver')
- parser.add_argument('--force_update', action='store_true', default=False,
- help=('force an update even if the version installed is '
- 'the same'))
- parser.add_argument('--full_update', action='store_true', default=False,
- help='force a rootfs update, skip stateful update')
- parser.add_argument('--original_build', action='store', type=str, default='',
- help=('force stateful update with the same version of '
- 'previous rootfs partition'))
- parser.add_argument('--payload_filename', action='store', type=str,
- default=None, help='A custom payload filename')
- parser.add_argument('--clobber_stateful', action='store_true', default=False,
- help='Whether to clobber stateful')
- parser.add_argument('--quick_provision', action='store_true', default=False,
- help='Whether to attempt quick provisioning path')
- parser.add_argument('--devserver_url', action='store', type=str, default=None,
- help='Devserver URL base for RPCs')
- parser.add_argument('--static_url', action='store', type=str, default=None,
- help='Devserver URL base for static files')
-
- opts = parser.parse_args(argv)
- opts.Freeze()
-
- return opts
-
-
-def main(argv):
- options = ParseArguments(argv)
-
- # Use process group id as the unique id in track and log files, since
- # os.setsid is executed before the current process is run.
- pid = os.getpid()
- pgid = os.getpgid(pid)
-
- # Setting log files for CrOS auto-update process.
- # Log file: file to record every details of CrOS auto-update process.
- log_file = cros_update_progress.GetExecuteLogFile(options.host_name, pgid)
- logging.info('Writing executing logs into file: %s', log_file)
- logConfig.SetFileHandler(log_file)
-
- # Create a progress_tracker for tracking CrOS auto-update progress.
- progress_tracker = cros_update_progress.AUProgress(options.host_name, pgid)
-
- # Create a dir for temporarily storing devserver codes and logs.
- au_tempdir = cros_update_progress.GetAUTempDirectory(options.host_name, pgid)
-
- # Create cros_update instance to run CrOS auto-update.
- cros_updater_trigger = CrOSUpdateTrigger(
- options.host_name, options.build_name, options.static_dir,
- progress_tracker=progress_tracker,
- log_file=log_file,
- au_tempdir=au_tempdir,
- force_update=options.force_update,
- full_update=options.full_update,
- original_build=options.original_build,
- payload_filename=options.payload_filename,
- clobber_stateful=options.clobber_stateful,
- quick_provision=options.quick_provision,
- devserver_url=options.devserver_url,
- static_url=options.static_url)
-
- # Set timeout the cros-update process.
- try:
- with timeout_util.Timeout(CROS_UPDATE_TIMEOUT_MIN*60):
- cros_updater_trigger.TriggerAU()
- except timeout_util.TimeoutError as e:
- error_msg = ('%s. The CrOS auto-update process is timed out, thus will be '
- 'terminated' % str(e))
- progress_tracker.WriteStatus(CROS_ERROR_TEMPLATE % error_msg)
-
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/cros_update_logging.py b/cros_update_logging.py
deleted file mode 100644
index 9cc6dd8..0000000
--- a/cros_update_logging.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2016 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A logging strategy for cros-update.
-
-1. Logging format is set as the same as autoserv.
-2. Globally, set log level of output as 'DEBUG'.
-3. For control output, set LEVEL as 'INFO', to avoid unnecessary logs in
- cherrypy logs.
-4. Add file handler to record all logs above level 'DEBUG' into file.
-"""
-
-from __future__ import print_function
-
-import logging # pylint: disable=cros-logging-import
-import sys
-
-
-class loggingConfig(object):
- """Configuration for auto-update logging."""
-
- LOGGING_FORMAT = ('%(asctime)s.%(msecs)03d %(levelname)-5.5s|%(module)18.18s:'
- '%(lineno)4.4d| %(message)s')
-
- def __init__(self):
- self.logger = logging.getLogger()
- self.GLOBAL_LEVEL = logging.DEBUG
- self.CONSOLE_LEVEL = logging.INFO
- self.FILE_LEVEL = logging.DEBUG
- self.ENABLE_CONSOLE_LOGGING = False
-
- def SetControlHandler(self, stream):
- """Set console handler for logging.
-
- Args:
- stream: The input stream, could be stdout/stderr.
- """
- handler = logging.StreamHandler(stream)
- handler.setLevel(self.CONSOLE_LEVEL)
- file_formatter = logging.Formatter(fmt=self.LOGGING_FORMAT,
- datefmt='%Y/%m/%d %H:%M:%S')
- handler.setFormatter(file_formatter)
- self.logger.addHandler(handler)
- return handler
-
-
- def SetFileHandler(self, file_name):
- """Set file handler for logging.
-
- Args:
- file_name: The file to save logs into.
- """
- handler = logging.FileHandler(file_name)
- handler.setLevel(self.FILE_LEVEL)
- # file format is set as same as concole format
- file_formatter = logging.Formatter(fmt=self.LOGGING_FORMAT,
- datefmt='%Y/%m/%d %H:%M:%S')
- handler.setFormatter(file_formatter)
- self.logger.addHandler(handler)
-
-
- def ConfigureLogging(self):
- self.logger.setLevel(self.GLOBAL_LEVEL)
- if self.ENABLE_CONSOLE_LOGGING:
- self.SetControlHandler(sys.stdout)
diff --git a/cros_update_progress.py b/cros_update_progress.py
deleted file mode 100644
index 9a288c2..0000000
--- a/cros_update_progress.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2016 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A progress class for tracking CrOS auto-update process.
-
-This class is mainly designed for:
- 1. Set the pattern for generating the filenames of
- track_status_file/execute_log_file.
- track_status_file: Used for record the current step of CrOS auto-update
- process. Only has one line.
- execute_log_file: Used for record the whole logging info of the CrOS
- auto-update process, including any debug information.
- 2. Write current auto-update process into the track_status_file.
- 3. Read current auto-update process from the track_status_file.
-
-This file also offers external functions that are related to add/check/delete
-the progress of the CrOS auto-update process.
-"""
-
-from __future__ import print_function
-
-import datetime
-import glob
-import logging # pylint: disable=cros-logging-import
-import os
-import re
-
-import setup_chromite # pylint: disable=unused-import
-from chromite.lib import osutils
-from chromite.lib.xbuddy import cherrypy_log_util
-
-
-# Module-local log function.
-def _Log(message, *args):
- return cherrypy_log_util.LogWithTag('CROS_UPDATE_PROGRESS', message, *args)
-
-# Path for status tracking log.
-_TRACK_LOG_FILE_PATH = '/tmp/auto-update/tracking_log/%s_%s.log'
-
-# Pattern for status tracking log filename.
-_TRACK_LOG_FILE_NAME_PATTERN = r'([^_]+)_([^_]+).log'
-
-# The gap hour used in checking AU processes' count.
-AU_PROCESS_HOUR_GAP = 3
-
-# Path for executing log.
-_EXECUTE_LOG_FILE_PATH = '/tmp/auto-update/executing_log/%s_%s.log'
-
-# Path and files for temporarily saving devserver codes, devserver and
-# update engine log.
-_CROS_UPDATE_TEMP_PATH = '/tmp/cros-update_%s_%s'
-
-_CROS_HOSTLOG_PATTERN = 'devserver_hostlog*'
-
-# The string for update process finished
-FINISHED = 'Completed'
-ERROR_TAG = 'Error'
-
-
-def ReadOneLine(filename):
- """Read one line from file.
-
- Args:
- filename: The file to be read.
- """
- return open(filename, 'r').readline().rstrip('\n')
-
-
-def IsProcessAlive(pid):
- """Detect whether a process is alive or not.
-
- Args:
- pid: The process id.
- """
- path = '/proc/%s/stat' % pid
- try:
- stat = ReadOneLine(path)
- except IOError:
- if not os.path.exists(path):
- return False
-
- raise
-
- return stat.split()[2] != 'Z'
-
-
-def GetExecuteLogFile(host_name, pid):
- """Return the whole path of execute log file."""
- if not os.path.exists(os.path.dirname(_EXECUTE_LOG_FILE_PATH)):
- osutils.SafeMakedirs(os.path.dirname(_EXECUTE_LOG_FILE_PATH))
-
- return _EXECUTE_LOG_FILE_PATH % (host_name, pid)
-
-
-def GetTrackStatusFile(host_name, pid):
- """Return the whole path of track status file."""
- if not os.path.exists(os.path.dirname(_TRACK_LOG_FILE_PATH)):
- osutils.SafeMakedirs(os.path.dirname(_TRACK_LOG_FILE_PATH))
-
- return _TRACK_LOG_FILE_PATH % (host_name, pid)
-
-
-def GetAllTrackStatusFileByTime():
- """Return all track status files existing in TRACK_LOG_FILE_PATH.
-
- Returns:
- A track status file list ordered by created time reversely.
- """
- return sorted(glob.glob(_TRACK_LOG_FILE_PATH % ('*', '*')),
- key=os.path.getctime, reverse=True)
-
-
-def ParsePidFromTrackLogFileName(track_log_filename):
- """Parse pid from a given track log file's name.
-
- The track log file's name for auto-update is fixed:
- hostname_pid.log
-
- This func is used to parse pid from a given track log file.
-
- Args:
- track_log_filename: the filename of the track log to be parsed.
-
- Returns:
- the parsed pid (int).
- """
- match = re.match(_TRACK_LOG_FILE_NAME_PATTERN, track_log_filename)
- try:
- return int(match.groups()[1])
- except (AttributeError, IndexError, ValueError) as e:
- _Log('Cannot parse pid from track log file %s: %s', track_log_filename, e)
- return None
-
-
-def GetAllTrackStatusFileByHostName(host_name):
- """Return a list of existing track status files generated for a host."""
- return glob.glob(_TRACK_LOG_FILE_PATH % (host_name, '*'))
-
-
-def GetAllRunningAUProcess():
- """Get all the ongoing AU processes' pids from tracking logs.
-
- This func only checks the tracking logs generated in latest several hours,
- which is for avoiding the case that 'there's a running process whose id is
- as the same as a previous AU process'.
-
- Returns:
- A list of background AU processes' pids.
- """
- pids = []
- now = datetime.datetime.now()
- track_log_list = GetAllTrackStatusFileByTime()
- # Only check log file created in 3 hours.
- for track_log in track_log_list:
- try:
- created_time = datetime.datetime.fromtimestamp(
- os.path.getctime(track_log))
- if now - created_time >= datetime.timedelta(hours=AU_PROCESS_HOUR_GAP):
- break
-
- pid = ParsePidFromTrackLogFileName(os.path.basename(track_log))
- if pid and IsProcessAlive(pid):
- pids.append(pid)
- except (ValueError, os.error) as e:
- _Log('Error happened in getting pid from %s: %s', track_log, e)
-
- return pids
-
-
-def GetAUTempDirectory(host_name, pid):
- """Return the temp dir for storing codes and logs during auto-update."""
- au_tempdir = _CROS_UPDATE_TEMP_PATH % (host_name, pid)
- if not os.path.exists(au_tempdir):
- osutils.SafeMakedirs(au_tempdir)
-
- return au_tempdir
-
-
-def ReadExecuteLogFile(host_name, pid):
- """Return the content of execute log file."""
- return osutils.ReadFile(GetExecuteLogFile(host_name, pid))
-
-
-def ReadAUHostLogFiles(host_name, pid):
- """Returns a dictionary containing the devserver host log files."""
- au_dir = GetAUTempDirectory(host_name, pid)
- hostlog_filenames = glob.glob(os.path.join(au_dir, _CROS_HOSTLOG_PATTERN))
- hostlog_files = {}
- for f in hostlog_filenames:
- hostlog_files[os.path.basename(f)] = osutils.ReadFile(f)
- return hostlog_files
-
-
-def DelTrackStatusFile(host_name, pid):
- """Delete the track status log."""
- osutils.SafeUnlink(GetTrackStatusFile(host_name, pid))
-
-
-def DelExecuteLogFile(host_name, pid):
- """Delete the track status log."""
- osutils.SafeUnlink(GetExecuteLogFile(host_name, pid))
-
-
-def DelAUTempDirectory(host_name, pid):
- """Delete the directory including auto-update-related logs."""
- osutils.RmDir(GetAUTempDirectory(host_name, pid))
-
-
-class AUProgress(object):
- """Used for tracking the CrOS auto-update progress."""
-
- def __init__(self, host_name, pid):
- """Initialize a CrOS update progress instance.
-
- Args:
- host_name: The name of host, should be in the file_name of the status
- tracking file of auto-update process.
- pid: The process id, should be in the file_name too.
- """
- self.host_name = host_name
- self.pid = pid
-
- @property
- def track_status_file(self):
- """The track status file to record the CrOS auto-update progress."""
- return GetTrackStatusFile(self.host_name, self.pid)
-
- def WriteStatus(self, content):
- """Write auto-update progress into status tracking file.
-
- Args:
- content: The content to be recorded.
- """
- if not self.track_status_file:
- return
-
- try:
- with open(self.track_status_file, 'w') as out_log:
- out_log.write(content)
- except Exception as e:
- logging.error('Cannot write au status: %r', e)
-
- def ReadStatus(self):
- """Read auto-update progress from status tracking file."""
- with open(self.track_status_file, 'r') as out_log:
- return out_log.read().rstrip('\n')
diff --git a/devserver.py b/devserver.py
index 3b89260..8478a44 100755
--- a/devserver.py
+++ b/devserver.py
@@ -49,14 +49,13 @@
import autoupdate
import cherrypy_ext
-import cros_update
-import cros_update_progress
import health_checker
# This must happen before any local modules get a chance to import
# anything from chromite. Otherwise, really bad things will happen, and
# you will _not_ understand why.
import setup_chromite # pylint: disable=unused-import
+from chromite.lib import cros_update_progress
from chromite.lib.xbuddy import android_build
from chromite.lib.xbuddy import artifact_info
from chromite.lib.xbuddy import build_artifact
@@ -65,7 +64,7 @@
from chromite.lib.xbuddy import devserver_constants
from chromite.lib.xbuddy import downloader
from chromite.lib.xbuddy import xbuddy
-
+from chromite.scripts import cros_update
# Module-local log function.
def _Log(message, *args):
@@ -779,10 +778,8 @@
if is_async:
# Command of running auto-update.
- path = os.path.dirname(os.path.abspath(__file__))
- execute_file = os.path.join(path, 'cros_update.py')
- cmd = ['/usr/bin/python', '-u', execute_file, '-d', host_name,
- '-b', build_name, '--static_dir', updater.static_dir]
+ cmd = ['cros_update', '--hostname', host_name, '-b', build_name,
+ '--static_dir', updater.static_dir]
# The original_build's format is like: link/3428.210.0
# The corresponding release_archive_url's format is like:
diff --git a/devserver_integration_test.py b/devserver_integration_test.py
index 502da78..c1cca8c 100755
--- a/devserver_integration_test.py
+++ b/devserver_integration_test.py
@@ -33,10 +33,9 @@
import psutil # pylint: disable=import-error
-import cros_update_progress
-
import setup_chromite # pylint: disable=unused-import
from chromite.lib import cros_logging as logging
+from chromite.lib import cros_update_progress
from chromite.lib.xbuddy import devserver_constants
diff --git a/health_checker.py b/health_checker.py
index d978fdb..5d9ce20 100644
--- a/health_checker.py
+++ b/health_checker.py
@@ -15,26 +15,12 @@
import time
import cherrypy # pylint: disable=import-error
-
-import cros_update_progress
+import psutil # pylint: disable=import-error
import setup_chromite # pylint: disable=unused-import
+from chromite.lib import cros_update_progress
from chromite.lib.xbuddy import cherrypy_log_util
-try:
- import psutil
-except ImportError:
- # Ignore psutil import failure. This is for backwards compatibility, so
- # "cros flash" can still update duts with build without psutil installed.
- # The reason is that, during cros flash, local devserver code is copied over
- # to DUT, and devserver will be running inside DUT to stage the build.
- psutil = None
-except OSError:
- # Ignore error like following. psutil may not work properly in builder. Ignore
- # the error as load information of devserver is not used in builder.
- # OSError: [Errno 2] No such file or directory: '/dev/pts/0'
- psutil = None
-
def _Log(message, *args):
"""Module-local log function."""