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