blob: 4cdc47e3db6b24aae62c11716eb58c58b87fbaed [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"
27#include "update_engine/payload_consumer/install_plan.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000028
29// The Postinstall Runner Action is responsible for running the postinstall
30// script of a successfully downloaded update.
31
32namespace chromeos_update_engine {
33
Alex Deymob15a0b82015-11-25 20:30:40 -030034class BootControlInterface;
35
Chris Sosad317e402013-06-12 13:47:09 -070036class PostinstallRunnerAction : public InstallPlanAction {
adlr@google.com3defe6a2009-12-04 20:57:17 +000037 public:
Alex Deymob15a0b82015-11-25 20:30:40 -030038 explicit PostinstallRunnerAction(BootControlInterface* boot_control)
39 : PostinstallRunnerAction(boot_control, nullptr) {}
adlr@google.com3defe6a2009-12-04 20:57:17 +000040
Alex Deymod15c5462016-03-09 18:11:12 -080041 // InstallPlanAction overrides.
Alex Deymocbc22742016-03-04 17:53:02 -080042 void PerformAction() override;
Alex Deymod15c5462016-03-09 18:11:12 -080043 void SuspendAction() override;
44 void ResumeAction() override;
45 void TerminateProcessing() override;
adlr@google.com3defe6a2009-12-04 20:57:17 +000046
Alex Deymo0d298542016-03-30 18:31:49 -070047 class DelegateInterface {
48 public:
49 virtual ~DelegateInterface() = default;
50
51 // Called whenever there is an overall progress update from the postinstall
52 // programs.
53 virtual void ProgressUpdate(double progress) = 0;
54 };
55
56 void set_delegate(DelegateInterface* delegate) { delegate_ = delegate; }
57
adlr@google.com3defe6a2009-12-04 20:57:17 +000058 // Debugging/logging
59 static std::string StaticType() { return "PostinstallRunnerAction"; }
Alex Deymocbc22742016-03-04 17:53:02 -080060 std::string Type() const override { return StaticType(); }
adlr@google.com3defe6a2009-12-04 20:57:17 +000061
62 private:
Alex Deymo31d95ac2015-09-17 11:56:18 -070063 friend class PostinstallRunnerActionTest;
Alex Deymo0d298542016-03-30 18:31:49 -070064 FRIEND_TEST(PostinstallRunnerActionTest, ProcessProgressLineTest);
Alex Deymo31d95ac2015-09-17 11:56:18 -070065
66 // Special constructor used for testing purposes.
Alex Deymob15a0b82015-11-25 20:30:40 -030067 PostinstallRunnerAction(BootControlInterface* boot_control,
Alex Deymo31d95ac2015-09-17 11:56:18 -070068 const char* powerwash_marker_file)
Alex Deymob15a0b82015-11-25 20:30:40 -030069 : boot_control_(boot_control),
Alex Deymo31d95ac2015-09-17 11:56:18 -070070 powerwash_marker_file_(powerwash_marker_file) {}
71
Alex Deymoe5e5fe92015-10-05 09:28:19 -070072 void PerformPartitionPostinstall();
73
Alex Deymo0d298542016-03-30 18:31:49 -070074 // Called whenever the |progress_fd_| has data available to read.
75 void OnProgressFdReady();
76
77 // Updates the action progress according to the |line| passed from the
78 // postinstall program. Valid lines are:
79 // global_progress <frac>
80 // <frac> should be between 0.0 and 1.0; sets the progress to the
81 // <frac> value.
82 bool ProcessProgressLine(const std::string& line);
83
84 // Report the progress to the delegate given that the postinstall operation
85 // for |current_partition_| has a current progress of |frac|, a value between
86 // 0 and 1 for that step.
87 void ReportProgress(double frac);
88
89 // Cleanup the setup made when running postinstall for a given partition.
90 // Unmount and remove the mountpoint directory if needed and cleanup the
91 // status file descriptor and message loop task watching for it.
92 void Cleanup();
Alex Deymod15c5462016-03-09 18:11:12 -080093
Darin Petkov6f03a3b2010-11-10 14:27:14 -080094 // Subprocess::Exec callback.
Alex Deymoe5e5fe92015-10-05 09:28:19 -070095 void CompletePartitionPostinstall(int return_code,
96 const std::string& output);
97
Alex Deymob15a0b82015-11-25 20:30:40 -030098 // Complete the Action with the passed |error_code| and mark the new slot as
99 // ready. Called when the post-install script was run for all the partitions.
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700100 void CompletePostinstall(ErrorCode error_code);
Darin Petkov6f03a3b2010-11-10 14:27:14 -0800101
Chris Sosad317e402013-06-12 13:47:09 -0700102 InstallPlan install_plan_;
Alex Deymo390efed2016-02-18 11:00:40 -0800103
104 // The path where the filesystem will be mounted during post-install.
105 std::string fs_mount_dir_;
Darin Petkov6f03a3b2010-11-10 14:27:14 -0800106
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700107 // The partition being processed on the list of partitions specified in the
108 // InstallPlan.
109 size_t current_partition_{0};
110
Alex Deymo0d298542016-03-30 18:31:49 -0700111 // A non-negative value representing the estimated weight of each partition
112 // passed in the install plan. The weight is used to predict the overall
113 // progress from the individual progress of each partition and should
114 // correspond to the time it takes to run it.
115 std::vector<double> partition_weight_;
116
117 // The sum of all the weights in |partition_weight_|.
118 double total_weight_{0};
119
120 // The sum of all the weights in |partition_weight_| up to but not including
121 // the |current_partition_|.
122 double accumulated_weight_{0};
123
124 // The delegate used to notify of progress updates, if any.
125 DelegateInterface* delegate_{nullptr};
126
Alex Deymob15a0b82015-11-25 20:30:40 -0300127 // The BootControlInerface used to mark the new slot as ready.
128 BootControlInterface* boot_control_;
Alex Deymo31d95ac2015-09-17 11:56:18 -0700129
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700130 // True if Powerwash Marker was created before invoking post-install script.
131 // False otherwise. Used for cleaning up if post-install fails.
Alex Deymoe5e5fe92015-10-05 09:28:19 -0700132 bool powerwash_marker_created_{false};
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700133
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700134 // Non-null value will cause post-install to override the default marker
135 // file name; used for testing.
Gilad Arnold30dedd82013-07-03 06:19:09 -0700136 const char* powerwash_marker_file_;
137
Alex Deymod15c5462016-03-09 18:11:12 -0800138 // Postinstall command currently running, or 0 if no program running.
139 pid_t current_command_{0};
140
Alex Deymo0d298542016-03-30 18:31:49 -0700141 // The parent progress file descriptor used to watch for progress reports from
142 // the postinstall program and the task watching for them.
143 int progress_fd_{-1};
144 brillo::MessageLoop::TaskId progress_task_{brillo::MessageLoop::kTaskIdNull};
145
146 // A buffer of a partial read line from the progress file descriptor.
147 std::string progress_buffer_;
148
adlr@google.com3defe6a2009-12-04 20:57:17 +0000149 DISALLOW_COPY_AND_ASSIGN(PostinstallRunnerAction);
150};
151
152} // namespace chromeos_update_engine
153
Alex Deymo39910dc2015-11-09 17:04:30 -0800154#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_