blob: 2e48e110e5790062510a2608c50e63fa1d4c623b [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2010 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
adlr@google.com3defe6a2009-12-04 20:57:17 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
18#define UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
adlr@google.com3defe6a2009-12-04 20:57:17 +000019
20#include <string>
Alex Deymo0d298542016-03-30 18:31:49 -070021#include <vector>
22
23#include <brillo/message_loops/message_loop.h>
24#include <gtest/gtest_prod.h>
Darin Petkov6f03a3b2010-11-10 14:27:14 -080025
Alex Deymo39910dc2015-11-09 17:04:30 -080026#include "update_engine/common/action.h"
Alex Deymofb905d92016-06-03 19:26:58 -070027#include "update_engine/common/boot_control_interface.h"
28#include "update_engine/common/hardware_interface.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080029#include "update_engine/payload_consumer/install_plan.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000030
31// The Postinstall Runner Action is responsible for running the postinstall
32// script of a successfully downloaded update.
33
34namespace chromeos_update_engine {
35
Alex Deymob15a0b82015-11-25 20:30:40 -030036class BootControlInterface;
37
Chris Sosad317e402013-06-12 13:47:09 -070038class PostinstallRunnerAction : public InstallPlanAction {
adlr@google.com3defe6a2009-12-04 20:57:17 +000039 public:
Alex Deymofb905d92016-06-03 19:26:58 -070040 PostinstallRunnerAction(BootControlInterface* boot_control,
41 HardwareInterface* hardware)
42 : boot_control_(boot_control), hardware_(hardware) {}
adlr@google.com3defe6a2009-12-04 20:57:17 +000043
Alex Deymod15c5462016-03-09 18:11:12 -080044 // InstallPlanAction overrides.
Alex Deymocbc22742016-03-04 17:53:02 -080045 void PerformAction() override;
Alex Deymod15c5462016-03-09 18:11:12 -080046 void SuspendAction() override;
47 void ResumeAction() override;
48 void TerminateProcessing() override;
adlr@google.com3defe6a2009-12-04 20:57:17 +000049
Alex Deymo0d298542016-03-30 18:31:49 -070050 class DelegateInterface {
51 public:
52 virtual ~DelegateInterface() = default;
53
54 // Called whenever there is an overall progress update from the postinstall
55 // programs.
56 virtual void ProgressUpdate(double progress) = 0;
57 };
58
59 void set_delegate(DelegateInterface* delegate) { delegate_ = delegate; }
60
adlr@google.com3defe6a2009-12-04 20:57:17 +000061 // Debugging/logging
62 static std::string StaticType() { return "PostinstallRunnerAction"; }
Alex Deymocbc22742016-03-04 17:53:02 -080063 std::string Type() const override { return StaticType(); }
adlr@google.com3defe6a2009-12-04 20:57:17 +000064
65 private:
Alex Deymo31d95ac2015-09-17 11:56:18 -070066 friend class PostinstallRunnerActionTest;
Alex Deymo0d298542016-03-30 18:31:49 -070067 FRIEND_TEST(PostinstallRunnerActionTest, ProcessProgressLineTest);
Alex Deymo31d95ac2015-09-17 11:56:18 -070068
Alex Deymoe5e5fe92015-10-05 09:28:19 -070069 void PerformPartitionPostinstall();
70
Alex Deymo0d298542016-03-30 18:31:49 -070071 // Called whenever the |progress_fd_| has data available to read.
72 void OnProgressFdReady();
73
74 // Updates the action progress according to the |line| passed from the
75 // postinstall program. Valid lines are:
76 // global_progress <frac>
77 // <frac> should be between 0.0 and 1.0; sets the progress to the
78 // <frac> value.
79 bool ProcessProgressLine(const std::string& line);
80
81 // Report the progress to the delegate given that the postinstall operation
82 // for |current_partition_| has a current progress of |frac|, a value between
83 // 0 and 1 for that step.
84 void ReportProgress(double frac);
85
86 // Cleanup the setup made when running postinstall for a given partition.
87 // Unmount and remove the mountpoint directory if needed and cleanup the
88 // status file descriptor and message loop task watching for it.
89 void Cleanup();
Alex Deymod15c5462016-03-09 18:11:12 -080090
Darin Petkov6f03a3b2010-11-10 14:27:14 -080091 // Subprocess::Exec callback.
Alex Deymoe5e5fe92015-10-05 09:28:19 -070092 void CompletePartitionPostinstall(int return_code,
93 const std::string& output);
94
Alex Deymob15a0b82015-11-25 20:30:40 -030095 // Complete the Action with the passed |error_code| and mark the new slot as
96 // ready. Called when the post-install script was run for all the partitions.
Alex Deymoe5e5fe92015-10-05 09:28:19 -070097 void CompletePostinstall(ErrorCode error_code);
Darin Petkov6f03a3b2010-11-10 14:27:14 -080098
Chris Sosad317e402013-06-12 13:47:09 -070099 InstallPlan install_plan_;
Alex Deymo390efed2016-02-18 11:00:40 -0800100
101 // The path where the filesystem will be mounted during post-install.
102 std::string fs_mount_dir_;
Darin Petkov6f03a3b2010-11-10 14:27:14 -0800103
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700104 // The partition being processed on the list of partitions specified in the
105 // InstallPlan.
106 size_t current_partition_{0};
107
Alex Deymo0d298542016-03-30 18:31:49 -0700108 // A non-negative value representing the estimated weight of each partition
109 // passed in the install plan. The weight is used to predict the overall
110 // progress from the individual progress of each partition and should
111 // correspond to the time it takes to run it.
112 std::vector<double> partition_weight_;
113
114 // The sum of all the weights in |partition_weight_|.
115 double total_weight_{0};
116
117 // The sum of all the weights in |partition_weight_| up to but not including
118 // the |current_partition_|.
119 double accumulated_weight_{0};
120
121 // The delegate used to notify of progress updates, if any.
122 DelegateInterface* delegate_{nullptr};
123
Alex Deymob15a0b82015-11-25 20:30:40 -0300124 // The BootControlInerface used to mark the new slot as ready.
125 BootControlInterface* boot_control_;
Alex Deymo31d95ac2015-09-17 11:56:18 -0700126
Alex Deymofb905d92016-06-03 19:26:58 -0700127 // HardwareInterface used to signal powerwash.
128 HardwareInterface* hardware_;
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700129
Alex Deymofb905d92016-06-03 19:26:58 -0700130 // Whether the Powerwash was scheduled before invoking post-install script.
131 // Used for cleaning up if post-install fails.
132 bool powerwash_scheduled_{false};
Gilad Arnold30dedd82013-07-03 06:19:09 -0700133
Alex Deymod15c5462016-03-09 18:11:12 -0800134 // Postinstall command currently running, or 0 if no program running.
135 pid_t current_command_{0};
136
Ben Chan7f4bc3f2017-01-10 15:32:11 -0800137 // True if |current_command_| has been suspended by SuspendAction().
138 bool is_current_command_suspended_{false};
139
Alex Deymo0d298542016-03-30 18:31:49 -0700140 // The parent progress file descriptor used to watch for progress reports from
141 // the postinstall program and the task watching for them.
142 int progress_fd_{-1};
143 brillo::MessageLoop::TaskId progress_task_{brillo::MessageLoop::kTaskIdNull};
144
145 // A buffer of a partial read line from the progress file descriptor.
146 std::string progress_buffer_;
147
adlr@google.com3defe6a2009-12-04 20:57:17 +0000148 DISALLOW_COPY_AND_ASSIGN(PostinstallRunnerAction);
149};
150
151} // namespace chromeos_update_engine
152
Alex Deymo39910dc2015-11-09 17:04:30 -0800153#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_