blob: cbd6e4489ffc0d58bc7e06f523a294de39d06d93 [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// Copyright (c) 2009 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
Andrew de los Reyes1e338b82010-01-22 14:57:27 -08005// TODO(adlr): get rid of commented out lines or comment them back in.
6// Look for "// re-add" next to those comments.
7
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -08008#include <string>
9#include <tr1/memory>
10#include <vector>
11#include <gflags/gflags.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000012#include <glib.h>
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080013#include "chromeos/obsolete_logging.h"
14#include "update_engine/action_processor.h"
15#include "update_engine/download_action.h"
16#include "update_engine/filesystem_copier_action.h"
Andrew de los Reyes1e338b82010-01-22 14:57:27 -080017// #include "update_engine/install_action.h" // re-add
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080018#include "update_engine/libcurl_http_fetcher.h"
19#include "update_engine/omaha_request_prep_action.h"
20#include "update_engine/omaha_response_handler_action.h"
21#include "update_engine/postinstall_runner_action.h"
22#include "update_engine/set_bootable_flag_action.h"
23#include "update_engine/update_check_action.h"
24
25using std::string;
26using std::tr1::shared_ptr;
27using std::vector;
28
29namespace chromeos_update_engine {
30
31class UpdateAttempter : public ActionProcessorDelegate {
32 public:
33 UpdateAttempter(GMainLoop *loop)
34 : full_update_(false),
35 loop_(loop) {}
36 void Update(bool force_full_update);
37
38 // Delegate method:
39 void ProcessingDone(const ActionProcessor* processor, bool success);
40 private:
41 bool full_update_;
42 vector<shared_ptr<AbstractAction> > actions_;
43 ActionProcessor processor_;
44 GMainLoop *loop_;
45
46 // pointer to the OmahaResponseHandlerAction in the actions_ vector;
47 shared_ptr<OmahaResponseHandlerAction> response_handler_action_;
48 DISALLOW_COPY_AND_ASSIGN(UpdateAttempter);
49};
50
51// Returns true on success. If there was no update available, that's still
52// success.
53// If force_full is true, try to force a full update.
54void UpdateAttempter::Update(bool force_full_update) {
55 full_update_ = force_full_update;
56 CHECK(!processor_.IsRunning());
57 processor_.set_delegate(this);
58
59 // Actions:
60 shared_ptr<OmahaRequestPrepAction> request_prep_action(
61 new OmahaRequestPrepAction(force_full_update));
62 shared_ptr<UpdateCheckAction> update_check_action(
63 new UpdateCheckAction(new LibcurlHttpFetcher));
64 shared_ptr<OmahaResponseHandlerAction> response_handler_action(
65 new OmahaResponseHandlerAction);
66 shared_ptr<FilesystemCopierAction> filesystem_copier_action(
67 new FilesystemCopierAction);
68 shared_ptr<DownloadAction> download_action(
69 new DownloadAction(new LibcurlHttpFetcher));
Andrew de los Reyes1e338b82010-01-22 14:57:27 -080070 // shared_ptr<InstallAction> install_action( // re-add
71 // new InstallAction);
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080072 shared_ptr<PostinstallRunnerAction> postinstall_runner_action(
73 new PostinstallRunnerAction);
74 shared_ptr<SetBootableFlagAction> set_bootable_flag_action(
75 new SetBootableFlagAction);
76
77 response_handler_action_ = response_handler_action;
78
79 actions_.push_back(shared_ptr<AbstractAction>(request_prep_action));
80 actions_.push_back(shared_ptr<AbstractAction>(update_check_action));
81 actions_.push_back(shared_ptr<AbstractAction>(response_handler_action));
82 actions_.push_back(shared_ptr<AbstractAction>(filesystem_copier_action));
83 actions_.push_back(shared_ptr<AbstractAction>(download_action));
Andrew de los Reyes1e338b82010-01-22 14:57:27 -080084 // actions_.push_back(shared_ptr<AbstractAction>(install_action)); // re-add
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080085 actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action));
86 actions_.push_back(shared_ptr<AbstractAction>(set_bootable_flag_action));
87
88 // Enqueue the actions
89 for (vector<shared_ptr<AbstractAction> >::iterator it = actions_.begin();
90 it != actions_.end(); ++it) {
91 processor_.EnqueueAction(it->get());
92 }
93
94 // Bond them together. We have to use the leaf-types when calling
95 // BondActions().
96 BondActions(request_prep_action.get(), update_check_action.get());
97 BondActions(update_check_action.get(), response_handler_action.get());
98 BondActions(response_handler_action.get(), filesystem_copier_action.get());
99 BondActions(filesystem_copier_action.get(), download_action.get());
Andrew de los Reyes1e338b82010-01-22 14:57:27 -0800100 // BondActions(download_action.get(), install_action.get()); // re-add
101 // BondActions(install_action.get(), postinstall_runner_action.get());
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -0800102 BondActions(postinstall_runner_action.get(), set_bootable_flag_action.get());
103
104 processor_.StartProcessing();
105}
106
107void UpdateAttempter::ProcessingDone(const ActionProcessor* processor,
108 bool success) {
109 CHECK(response_handler_action_);
110 if (response_handler_action_->GotNoUpdateResponse()) {
111 // All done.
112 g_main_loop_quit(loop_);
113 return;
114 }
115 if (!success) {
116 if (!full_update_) {
117 LOG(ERROR) << "Update failed. Attempting full update";
118 actions_.clear();
119 response_handler_action_.reset();
120 Update(true);
121 return;
122 } else {
123 LOG(ERROR) << "Full update failed. Aborting";
124 }
125 }
126 g_main_loop_quit(loop_);
127}
128
129gboolean UpdateInMainLoop(void* arg) {
130 UpdateAttempter* update_attempter = reinterpret_cast<UpdateAttempter*>(arg);
131 update_attempter->Update(false);
132 return FALSE; // Don't call this callback function again
133}
134
135} // namespace chromeos_update_engine
rspangler@google.com49fdf182009-10-10 00:57:34 +0000136
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000137#include "update_engine/subprocess.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +0000138
139int main(int argc, char** argv) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000140 g_thread_init(NULL);
141 chromeos_update_engine::Subprocess::Init();
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -0800142 google::ParseCommandLineFlags(&argc, &argv, true);
143 // TODO(adlr): figure out log file
144 logging::InitLogging("",
145 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
146 logging::DONT_LOCK_LOG_FILE,
147 logging::APPEND_TO_OLD_LOG_FILE);
148 LOG(INFO) << "Chrome OS Update Engine starting";
149
150 // Create the single GMainLoop
151 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
152
153 chromeos_update_engine::UpdateAttempter update_attempter(loop);
154
155 g_timeout_add(0, &chromeos_update_engine::UpdateInMainLoop,
156 &update_attempter);
157
158 g_main_loop_run(loop);
159 g_main_loop_unref(loop);
160
161 LOG(INFO) << "Chrome OS Update Engine terminating";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000162 return 0;
163}