blob: f7c6b8eda9b50c88dd77a7596ccfb70e36d94b5f [file] [log] [blame]
xixuan52c2fba2016-05-20 17:02:48 -07001# Copyright (c) 2016 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""A progress class for tracking CrOS auto-update process.
6
7This class is mainly designed for:
8 1. Set the pattern for generating the filenames of
9 track_status_file/execute_log_file.
10 track_status_file: Used for record the current step of CrOS auto-update
11 process. Only has one line.
12 execute_log_file: Used for record the whole logging info of the CrOS
13 auto-update process, including any debug information.
14 2. Write current auto-update process into the track_status_file.
15 3. Read current auto-update process from the track_status_file.
16
17This file also offers external functions that are related to add/check/delete
18the progress of the CrOS auto-update process.
19"""
20
21from __future__ import print_function
22
xixuan3bc974e2016-10-18 17:21:43 -070023import glob
xixuan52c2fba2016-05-20 17:02:48 -070024import logging
25import os
26
xixuancf58dd32016-08-24 13:57:06 -070027# only import setup_chromite before chromite import.
28import setup_chromite # pylint: disable=unused-import
xixuan52c2fba2016-05-20 17:02:48 -070029try:
30 from chromite.lib import osutils
31except ImportError as e:
32 logging.debug('chromite cannot be imported: %r', e)
33 osutils = None
34
35# Path for status tracking log.
xixuan3bc974e2016-10-18 17:21:43 -070036_TRACK_LOG_FILE_PATH = '/tmp/auto-update/tracking_log/%s_%s.log'
xixuan52c2fba2016-05-20 17:02:48 -070037
38# Path for executing log.
xixuan3bc974e2016-10-18 17:21:43 -070039_EXECUTE_LOG_FILE_PATH = '/tmp/auto-update/executing_log/%s_%s.log'
40
41# Path and files for temporarily saving devserver codes, devserver and
42# update engine log.
43_CROS_UPDATE_TEMP_PATH = '/tmp/cros-update_%s_%s'
xixuan52c2fba2016-05-20 17:02:48 -070044
45# The string for update process finished
46FINISHED = 'Completed'
47ERROR_TAG = 'Error'
48
49
50def ReadOneLine(filename):
51 """Read one line from file.
52
53 Args:
54 filename: The file to be read.
55 """
56 return open(filename, 'r').readline().rstrip('\n')
57
58
59def IsProcessAlive(pid):
60 """Detect whether a process is alive or not.
61
62 Args:
63 pid: The process id.
64 """
65 path = '/proc/%s/stat' % pid
66 try:
67 stat = ReadOneLine(path)
68 except IOError:
69 if not os.path.exists(path):
70 return False
71
72 raise
73
74 return stat.split()[2] != 'Z'
75
76
77def GetExecuteLogFile(host_name, pid):
78 """Return the whole path of execute log file."""
xixuan3bc974e2016-10-18 17:21:43 -070079 if not os.path.exists(os.path.dirname(_EXECUTE_LOG_FILE_PATH)):
80 osutils.SafeMakedirs(os.path.dirname(_EXECUTE_LOG_FILE_PATH))
xixuan52c2fba2016-05-20 17:02:48 -070081
xixuan3bc974e2016-10-18 17:21:43 -070082 return _EXECUTE_LOG_FILE_PATH % (host_name, pid)
xixuan52c2fba2016-05-20 17:02:48 -070083
84
85def GetTrackStatusFile(host_name, pid):
86 """Return the whole path of track status file."""
xixuan3bc974e2016-10-18 17:21:43 -070087 if not os.path.exists(os.path.dirname(_TRACK_LOG_FILE_PATH)):
88 osutils.SafeMakedirs(os.path.dirname(_TRACK_LOG_FILE_PATH))
xixuan52c2fba2016-05-20 17:02:48 -070089
xixuan3bc974e2016-10-18 17:21:43 -070090 return _TRACK_LOG_FILE_PATH % (host_name, pid)
91
92
93def GetAllTrackStatusFileByHostName(host_name):
94 """Return a list of existing track status files generated for a host."""
95 return glob.glob(_TRACK_LOG_FILE_PATH % (host_name, '*'))
96
97
98def GetAUTempDirectory(host_name, pid):
99 """Return the temp dir for storing codes and logs during auto-update."""
100 au_tempdir = _CROS_UPDATE_TEMP_PATH % (host_name, pid)
101 if not os.path.exists(au_tempdir):
102 osutils.SafeMakedirs(au_tempdir)
103
104 return au_tempdir
xixuan52c2fba2016-05-20 17:02:48 -0700105
106
xixuan1bbfaba2016-10-13 17:53:22 -0700107def ReadExecuteLogFile(host_name, pid):
108 """Return the content of execute log file."""
109 return osutils.ReadFile(GetExecuteLogFile(host_name, pid))
110
111
xixuan52c2fba2016-05-20 17:02:48 -0700112def DelTrackStatusFile(host_name, pid):
113 """Delete the track status log."""
114 osutils.SafeUnlink(GetTrackStatusFile(host_name, pid))
115
116
xixuan1bbfaba2016-10-13 17:53:22 -0700117def DelExecuteLogFile(host_name, pid):
118 """Delete the track status log."""
119 osutils.SafeUnlink(GetExecuteLogFile(host_name, pid))
120
121
xixuan3bc974e2016-10-18 17:21:43 -0700122def DelAUTempDirectory(host_name, pid):
123 """Delete the directory including auto-update-related logs."""
124 osutils.RmDir(GetAUTempDirectory(host_name, pid))
125
126
xixuan52c2fba2016-05-20 17:02:48 -0700127class AUProgress(object):
128 """Used for tracking the CrOS auto-update progress."""
129
130 def __init__(self, host_name, pid):
131 """Initialize a CrOS update progress instance.
132
133 Args:
134 host_name: The name of host, should be in the file_name of the status
135 tracking file of auto-update process.
136 pid: The process id, should be in the file_name too.
137 """
138 self.host_name = host_name
139 self.pid = pid
140
141 @property
142 def track_status_file(self):
143 """The track status file to record the CrOS auto-update progress."""
144 return GetTrackStatusFile(self.host_name, self.pid)
145
146 def WriteStatus(self, content):
147 """Write auto-update progress into status tracking file.
148
149 Args:
150 content: The content to be recorded.
151 """
152 if not self.track_status_file:
153 return
154
155 try:
156 with open(self.track_status_file, 'w') as out_log:
157 out_log.write(content)
158 except Exception as e:
159 logging.error('Cannot write au status: %r', e)
160
161 def ReadStatus(self):
162 """Read auto-update progress from status tracking file."""
xixuan28d99072016-10-06 12:24:16 -0700163 with open(self.track_status_file, 'r') as out_log:
164 return out_log.read().rstrip('\n')