blob: 9c6935271ef794cca4922b79f37d63cc1bb2cfad [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
23import logging
24import os
25
xixuancf58dd32016-08-24 13:57:06 -070026# only import setup_chromite before chromite import.
27import setup_chromite # pylint: disable=unused-import
xixuan52c2fba2016-05-20 17:02:48 -070028try:
29 from chromite.lib import osutils
30except ImportError as e:
31 logging.debug('chromite cannot be imported: %r', e)
32 osutils = None
33
34# Path for status tracking log.
35TRACK_LOG_FILE_PATH = '/tmp/auto-update/tracking_log/%s_%s.log'
36
37# Path for executing log.
38EXECUTE_LOG_FILE_PATH = '/tmp/auto-update/executing_log/%s_%s.log'
39
40# The string for update process finished
41FINISHED = 'Completed'
42ERROR_TAG = 'Error'
43
44
45def ReadOneLine(filename):
46 """Read one line from file.
47
48 Args:
49 filename: The file to be read.
50 """
51 return open(filename, 'r').readline().rstrip('\n')
52
53
54def IsProcessAlive(pid):
55 """Detect whether a process is alive or not.
56
57 Args:
58 pid: The process id.
59 """
60 path = '/proc/%s/stat' % pid
61 try:
62 stat = ReadOneLine(path)
63 except IOError:
64 if not os.path.exists(path):
65 return False
66
67 raise
68
69 return stat.split()[2] != 'Z'
70
71
72def GetExecuteLogFile(host_name, pid):
73 """Return the whole path of execute log file."""
74 if not os.path.exists(os.path.dirname(EXECUTE_LOG_FILE_PATH)):
75 osutils.SafeMakedirs(os.path.dirname(EXECUTE_LOG_FILE_PATH))
76
77 return EXECUTE_LOG_FILE_PATH % (host_name, pid)
78
79
80def GetTrackStatusFile(host_name, pid):
81 """Return the whole path of track status file."""
82 if not os.path.exists(os.path.dirname(TRACK_LOG_FILE_PATH)):
83 osutils.SafeMakedirs(os.path.dirname(TRACK_LOG_FILE_PATH))
84
85 return TRACK_LOG_FILE_PATH % (host_name, pid)
86
87
xixuan1bbfaba2016-10-13 17:53:22 -070088def ReadExecuteLogFile(host_name, pid):
89 """Return the content of execute log file."""
90 return osutils.ReadFile(GetExecuteLogFile(host_name, pid))
91
92
xixuan52c2fba2016-05-20 17:02:48 -070093def DelTrackStatusFile(host_name, pid):
94 """Delete the track status log."""
95 osutils.SafeUnlink(GetTrackStatusFile(host_name, pid))
96
97
xixuan1bbfaba2016-10-13 17:53:22 -070098def DelExecuteLogFile(host_name, pid):
99 """Delete the track status log."""
100 osutils.SafeUnlink(GetExecuteLogFile(host_name, pid))
101
102
xixuan52c2fba2016-05-20 17:02:48 -0700103class AUProgress(object):
104 """Used for tracking the CrOS auto-update progress."""
105
106 def __init__(self, host_name, pid):
107 """Initialize a CrOS update progress instance.
108
109 Args:
110 host_name: The name of host, should be in the file_name of the status
111 tracking file of auto-update process.
112 pid: The process id, should be in the file_name too.
113 """
114 self.host_name = host_name
115 self.pid = pid
116
117 @property
118 def track_status_file(self):
119 """The track status file to record the CrOS auto-update progress."""
120 return GetTrackStatusFile(self.host_name, self.pid)
121
122 def WriteStatus(self, content):
123 """Write auto-update progress into status tracking file.
124
125 Args:
126 content: The content to be recorded.
127 """
128 if not self.track_status_file:
129 return
130
131 try:
132 with open(self.track_status_file, 'w') as out_log:
133 out_log.write(content)
134 except Exception as e:
135 logging.error('Cannot write au status: %r', e)
136
137 def ReadStatus(self):
138 """Read auto-update progress from status tracking file."""
xixuan28d99072016-10-06 12:24:16 -0700139 with open(self.track_status_file, 'r') as out_log:
140 return out_log.read().rstrip('\n')