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