blob: e09c0d405b4fedbccf669c33a649a272a24705d0 [file] [log] [blame]
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Darin Petkov5a7f5652010-07-22 21:40:09 -07005#include <string>
6
Ben Chan46bf5c82013-06-24 11:17:41 -07007#include <dbus/dbus.h>
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07008#include <gflags/gflags.h>
9#include <glib.h>
10
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070011#include "update_engine/marshal.glibmarshal.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070012#include "update_engine/dbus_constants.h"
13#include "update_engine/subprocess.h"
14#include "update_engine/utils.h"
15
16extern "C" {
17#include "update_engine/update_engine.dbusclient.h"
18}
19
20using chromeos_update_engine::kUpdateEngineServiceName;
21using chromeos_update_engine::kUpdateEngineServicePath;
22using chromeos_update_engine::kUpdateEngineServiceInterface;
David Zeuthen75a4c3e2013-09-06 11:36:59 -070023using chromeos_update_engine::AttemptUpdateFlags;
24using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
Darin Petkova0b9e772011-10-06 05:05:56 -070025using chromeos_update_engine::utils::GetAndFreeGError;
Darin Petkov5a7f5652010-07-22 21:40:09 -070026using std::string;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070027
Darin Petkov296889c2010-07-23 16:20:54 -070028DEFINE_string(app_version, "", "Force the current app version.");
Jay Srinivasanae4697c2013-03-18 17:08:08 -070029DEFINE_string(channel, "",
30 "Set the target channel. The device will be powerwashed if the target "
31 "channel is more stable than the current channel.");
Chris Sosad317e402013-06-12 13:47:09 -070032DEFINE_bool(check_for_update, false, "Initiate check for updates.");
33DEFINE_string(omaha_url, "", "The URL of the Omaha update server.");
34DEFINE_bool(reboot, false, "Initiate a reboot if needed.");
35DEFINE_bool(reset_status, false, "Sets the status in update_engine to idle.");
36DEFINE_bool(rollback, false, "Perform a rollback to the previous partition.");
37DEFINE_bool(show_channel, false, "Show the current and target channels.");
Chris Sosacb7fa882013-07-25 17:02:59 -070038DEFINE_bool(powerwash, true, "When performing rollback or channel change, "
39 "do a powerwash or allow it respectively.");
Chris Sosad317e402013-06-12 13:47:09 -070040DEFINE_bool(status, false, "Print the status to stdout.");
Darin Petkov58529db2010-08-13 09:19:47 -070041DEFINE_bool(update, false, "Forces an update and waits for its completion. "
42 "Exit status is 0 if the update succeeded, and 1 otherwise.");
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070043DEFINE_bool(watch_for_updates, false,
44 "Listen for status updates and print them to the screen.");
Alex Deymof4867c42013-06-28 14:41:39 -070045DEFINE_bool(show_update_over_cellular, false,
46 "Show the current setting for updates over cellular networks.");
47DEFINE_string(update_over_cellular, "",
48 "Enables (\"yes\") or disables (\"no\") the updates over "
49 "cellular networks.");
Alex Deymo5fdf7762013-07-17 20:01:40 -070050DEFINE_bool(show_p2p_update, false,
51 "Show the current setting for peer-to-peer update sharing.");
52DEFINE_string(p2p_update, "",
53 "Enables (\"yes\") or disables (\"no\") the peer-to-peer update "
54 "sharing.");
David Zeuthen75a4c3e2013-09-06 11:36:59 -070055DEFINE_bool(interactive, true, "Mark the update request as interactive.");
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070056
57namespace {
58
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070059bool GetProxy(DBusGProxy** out_proxy) {
60 DBusGConnection* bus;
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070061 DBusGProxy* proxy = NULL;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070062 GError* error = NULL;
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070063 const int kTries = 4;
Darin Petkova0b9e772011-10-06 05:05:56 -070064 const int kRetrySeconds = 10;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070065
66 bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
Richard Barnetted7936062013-01-18 13:38:51 -080067 if (bus == NULL) {
68 LOG(ERROR) << "Failed to get bus: " << GetAndFreeGError(&error);
69 exit(1);
70 }
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070071 for (int i = 0; !proxy && i < kTries; ++i) {
Darin Petkova0b9e772011-10-06 05:05:56 -070072 if (i > 0) {
73 LOG(INFO) << "Retrying to get dbus proxy. Try "
74 << (i + 1) << "/" << kTries;
Gilad Arnold8e3f1262013-01-08 14:59:54 -080075 g_usleep(kRetrySeconds * G_USEC_PER_SEC);
Darin Petkova0b9e772011-10-06 05:05:56 -070076 }
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070077 proxy = dbus_g_proxy_new_for_name_owner(bus,
78 kUpdateEngineServiceName,
79 kUpdateEngineServicePath,
80 kUpdateEngineServiceInterface,
81 &error);
Darin Petkova0b9e772011-10-06 05:05:56 -070082 LOG_IF(WARNING, !proxy) << "Error getting dbus proxy for "
83 << kUpdateEngineServiceName << ": "
84 << GetAndFreeGError(&error);
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070085 }
Richard Barnetted7936062013-01-18 13:38:51 -080086 if (proxy == NULL) {
87 LOG(ERROR) << "Giving up -- unable to get dbus proxy for "
88 << kUpdateEngineServiceName;
89 exit(1);
90 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070091 *out_proxy = proxy;
92 return true;
93}
94
95static void StatusUpdateSignalHandler(DBusGProxy* proxy,
96 int64_t last_checked_time,
97 double progress,
98 gchar* current_operation,
99 gchar* new_version,
100 int64_t new_size,
101 void* user_data) {
102 LOG(INFO) << "Got status update:";
103 LOG(INFO) << " last_checked_time: " << last_checked_time;
104 LOG(INFO) << " progress: " << progress;
105 LOG(INFO) << " current_operation: " << current_operation;
106 LOG(INFO) << " new_version: " << new_version;
107 LOG(INFO) << " new_size: " << new_size;
108}
109
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700110bool ResetStatus() {
111 DBusGProxy* proxy;
112 GError* error = NULL;
113
114 CHECK(GetProxy(&proxy));
115
Alex Deymo36dc2f32013-08-29 15:45:06 -0700116 gboolean rc = update_engine_client_reset_status(proxy, &error);
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700117 return rc;
118}
119
120
Darin Petkov58529db2010-08-13 09:19:47 -0700121// If |op| is non-NULL, sets it to the current operation string or an
122// empty string if unable to obtain the current status.
123bool GetStatus(string* op) {
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700124 DBusGProxy* proxy;
125 GError* error = NULL;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700126
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700127 CHECK(GetProxy(&proxy));
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700128
129 gint64 last_checked_time = 0;
130 gdouble progress = 0.0;
131 char* current_op = NULL;
132 char* new_version = NULL;
133 gint64 new_size = 0;
134
Alex Deymo36dc2f32013-08-29 15:45:06 -0700135 gboolean rc = update_engine_client_get_status(proxy,
136 &last_checked_time,
137 &progress,
138 &current_op,
139 &new_version,
140 &new_size,
141 &error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700142 if (rc == FALSE) {
Darin Petkova0b9e772011-10-06 05:05:56 -0700143 LOG(INFO) << "Error getting status: " << GetAndFreeGError(&error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700144 }
145 printf("LAST_CHECKED_TIME=%" PRIi64 "\nPROGRESS=%f\nCURRENT_OP=%s\n"
146 "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
147 last_checked_time,
148 progress,
149 current_op,
150 new_version,
151 new_size);
Darin Petkov58529db2010-08-13 09:19:47 -0700152 if (op) {
153 *op = current_op ? current_op : "";
154 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700155 return true;
156}
157
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700158// Should never return.
159void WatchForUpdates() {
160 DBusGProxy* proxy;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700161
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700162 CHECK(GetProxy(&proxy));
Andrew de los Reyesada42202010-07-15 22:23:20 -0700163
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700164 // Register marshaller
165 dbus_g_object_register_marshaller(
166 update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
167 G_TYPE_NONE,
168 G_TYPE_INT64,
169 G_TYPE_DOUBLE,
170 G_TYPE_STRING,
171 G_TYPE_STRING,
172 G_TYPE_INT64,
173 G_TYPE_INVALID);
Andrew de los Reyesada42202010-07-15 22:23:20 -0700174
175 static const char kStatusUpdate[] = "StatusUpdate";
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700176 dbus_g_proxy_add_signal(proxy,
Andrew de los Reyesada42202010-07-15 22:23:20 -0700177 kStatusUpdate,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700178 G_TYPE_INT64,
179 G_TYPE_DOUBLE,
180 G_TYPE_STRING,
181 G_TYPE_STRING,
182 G_TYPE_INT64,
183 G_TYPE_INVALID);
184 GMainLoop* loop = g_main_loop_new (NULL, TRUE);
185 dbus_g_proxy_connect_signal(proxy,
Andrew de los Reyesada42202010-07-15 22:23:20 -0700186 kStatusUpdate,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700187 G_CALLBACK(StatusUpdateSignalHandler),
188 NULL,
189 NULL);
190 g_main_loop_run(loop);
191 g_main_loop_unref(loop);
192}
193
Chris Sosad317e402013-06-12 13:47:09 -0700194bool Rollback(bool rollback) {
195 DBusGProxy* proxy;
196 GError* error = NULL;
197
198 CHECK(GetProxy(&proxy));
199
Alex Deymo36dc2f32013-08-29 15:45:06 -0700200 gboolean rc = update_engine_client_attempt_rollback(proxy,
201 rollback,
202 &error);
Chris Sosad317e402013-06-12 13:47:09 -0700203 CHECK_EQ(rc, TRUE) << "Error with rollback request: "
204 << GetAndFreeGError(&error);
205 return true;
206}
207
Darin Petkov58529db2010-08-13 09:19:47 -0700208bool CheckForUpdates(const string& app_version, const string& omaha_url) {
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700209 DBusGProxy* proxy;
210 GError* error = NULL;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700211
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700212 CHECK(GetProxy(&proxy));
213
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700214 AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(
215 FLAGS_interactive ? 0 : kAttemptUpdateFlagNonInteractive);
216 gboolean rc =
217 update_engine_client_attempt_update_with_flags(proxy,
218 app_version.c_str(),
219 omaha_url.c_str(),
220 static_cast<gint>(flags),
221 &error);
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700222 CHECK_EQ(rc, TRUE) << "Error checking for update: "
Darin Petkova0b9e772011-10-06 05:05:56 -0700223 << GetAndFreeGError(&error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700224 return true;
225}
226
Darin Petkov296889c2010-07-23 16:20:54 -0700227bool RebootIfNeeded() {
228 DBusGProxy* proxy;
229 GError* error = NULL;
230
231 CHECK(GetProxy(&proxy));
232
233 gboolean rc =
Alex Deymo36dc2f32013-08-29 15:45:06 -0700234 update_engine_client_reboot_if_needed(proxy, &error);
Darin Petkov296889c2010-07-23 16:20:54 -0700235 // Reboot error code doesn't necessarily mean that a reboot
236 // failed. For example, D-Bus may be shutdown before we receive the
237 // result.
Darin Petkova0b9e772011-10-06 05:05:56 -0700238 LOG_IF(INFO, !rc) << "Reboot error message: " << GetAndFreeGError(&error);
Darin Petkov296889c2010-07-23 16:20:54 -0700239 return true;
240}
241
Chris Sosacb7fa882013-07-25 17:02:59 -0700242void SetTargetChannel(const string& target_channel, bool allow_powerwash) {
Darin Petkov8daa3242010-10-25 13:28:47 -0700243 DBusGProxy* proxy;
244 GError* error = NULL;
245
246 CHECK(GetProxy(&proxy));
247
Alex Deymo36dc2f32013-08-29 15:45:06 -0700248 gboolean rc = update_engine_client_set_channel(proxy,
249 target_channel.c_str(),
250 allow_powerwash,
251 &error);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700252 CHECK_EQ(rc, true) << "Error setting the channel: "
Darin Petkova0b9e772011-10-06 05:05:56 -0700253 << GetAndFreeGError(&error);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700254 LOG(INFO) << "Channel permanently set to: " << target_channel;
Darin Petkov8daa3242010-10-25 13:28:47 -0700255}
256
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700257string GetChannel(bool get_current_channel) {
Satoru Takabayashi583667b2010-10-27 13:09:57 +0900258 DBusGProxy* proxy;
259 GError* error = NULL;
260
261 CHECK(GetProxy(&proxy));
262
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700263 char* channel = NULL;
Alex Deymo36dc2f32013-08-29 15:45:06 -0700264 gboolean rc = update_engine_client_get_channel(proxy,
265 get_current_channel,
266 &channel,
267 &error);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700268 CHECK_EQ(rc, true) << "Error getting the channel: "
269 << GetAndFreeGError(&error);
270 string output = channel;
271 g_free(channel);
Satoru Takabayashi583667b2010-10-27 13:09:57 +0900272 return output;
273}
274
Alex Deymo5fdf7762013-07-17 20:01:40 -0700275void SetUpdateOverCellularPermission(gboolean allowed) {
Alex Deymof4867c42013-06-28 14:41:39 -0700276 DBusGProxy* proxy;
277 GError* error = NULL;
278
279 CHECK(GetProxy(&proxy));
280
Alex Deymo36dc2f32013-08-29 15:45:06 -0700281 gboolean rc = update_engine_client_set_update_over_cellular_permission(
282 proxy,
283 allowed,
284 &error);
Alex Deymof4867c42013-06-28 14:41:39 -0700285 CHECK_EQ(rc, true) << "Error setting the update over cellular setting: "
286 << GetAndFreeGError(&error);
Alex Deymof4867c42013-06-28 14:41:39 -0700287}
288
289bool GetUpdateOverCellularPermission() {
290 DBusGProxy* proxy;
291 GError* error = NULL;
292
293 CHECK(GetProxy(&proxy));
294
295 gboolean allowed;
Alex Deymo36dc2f32013-08-29 15:45:06 -0700296 gboolean rc = update_engine_client_get_update_over_cellular_permission(
297 proxy,
298 &allowed,
299 &error);
Alex Deymof4867c42013-06-28 14:41:39 -0700300 CHECK_EQ(rc, true) << "Error getting the update over cellular setting: "
301 << GetAndFreeGError(&error);
302 return allowed;
303}
304
Alex Deymo5fdf7762013-07-17 20:01:40 -0700305void SetP2PUpdatePermission(gboolean enabled) {
306 DBusGProxy* proxy;
307 GError* error = NULL;
308
309 CHECK(GetProxy(&proxy));
310
Alex Deymo36dc2f32013-08-29 15:45:06 -0700311 gboolean rc = update_engine_client_set_p2p_update_permission(
312 proxy,
313 enabled,
314 &error);
Alex Deymo5fdf7762013-07-17 20:01:40 -0700315 CHECK_EQ(rc, true) << "Error setting the peer-to-peer update setting: "
316 << GetAndFreeGError(&error);
317}
318
319bool GetP2PUpdatePermission() {
320 DBusGProxy* proxy;
321 GError* error = NULL;
322
323 CHECK(GetProxy(&proxy));
324
325 gboolean enabled;
Alex Deymo36dc2f32013-08-29 15:45:06 -0700326 gboolean rc = update_engine_client_get_p2p_update_permission(
327 proxy,
328 &enabled,
329 &error);
Alex Deymo5fdf7762013-07-17 20:01:40 -0700330 CHECK_EQ(rc, true) << "Error getting the peer-to-peer update setting: "
331 << GetAndFreeGError(&error);
332 return enabled;
333}
334
Darin Petkov58529db2010-08-13 09:19:47 -0700335static gboolean CompleteUpdateSource(gpointer data) {
336 string current_op;
337 if (!GetStatus(&current_op) || current_op == "UPDATE_STATUS_IDLE") {
338 LOG(ERROR) << "Update failed.";
339 exit(1);
340 }
341 if (current_op == "UPDATE_STATUS_UPDATED_NEED_REBOOT") {
342 LOG(INFO) << "Update succeeded -- reboot needed.";
343 exit(0);
344 }
345 return TRUE;
346}
347
348// This is similar to watching for updates but rather than registering
349// a signal watch, activelly poll the daemon just in case it stops
350// sending notifications.
351void CompleteUpdate() {
352 GMainLoop* loop = g_main_loop_new (NULL, TRUE);
353 g_timeout_add_seconds(5, CompleteUpdateSource, NULL);
354 g_main_loop_run(loop);
355 g_main_loop_unref(loop);
356}
357
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700358} // namespace {}
359
360int main(int argc, char** argv) {
361 // Boilerplate init commands.
362 g_type_init();
Ben Chan46bf5c82013-06-24 11:17:41 -0700363 dbus_threads_init_default();
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700364 chromeos_update_engine::Subprocess::Init();
365 google::ParseCommandLineFlags(&argc, &argv, true);
Andrew de los Reyesada42202010-07-15 22:23:20 -0700366
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700367 // Update the status if requested.
368 if (FLAGS_reset_status) {
369 LOG(INFO) << "Setting Update Engine status to idle ...";
370 if (!ResetStatus()) {
371 LOG(ERROR) << "ResetStatus failed.";
372 return 1;
373 }
374
Gilad Arnold50c60632013-01-25 10:27:19 -0800375 LOG(INFO) << "ResetStatus succeeded; to undo partition table changes run:\n"
376 "(D=$(rootdev -d) P=$(rootdev -s); cgpt p -i$(($(echo ${P#$D} "
377 "| sed 's/^[^0-9]*//')-1)) $D;)";
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700378 return 0;
379 }
380
381
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700382 if (FLAGS_status) {
383 LOG(INFO) << "Querying Update Engine status...";
Darin Petkov58529db2010-08-13 09:19:47 -0700384 if (!GetStatus(NULL)) {
385 LOG(FATAL) << "GetStatus failed.";
386 return 1;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700387 }
388 return 0;
389 }
Darin Petkov58529db2010-08-13 09:19:47 -0700390
Alex Deymof4867c42013-06-28 14:41:39 -0700391 // Changes the current update over cellular network setting.
392 if (!FLAGS_update_over_cellular.empty()) {
393 gboolean allowed = FLAGS_update_over_cellular == "yes";
394 if (!allowed && FLAGS_update_over_cellular != "no") {
395 LOG(ERROR) << "Unknown option: \"" << FLAGS_update_over_cellular
396 << "\". Please specify \"yes\" or \"no\".";
397 } else {
398 SetUpdateOverCellularPermission(allowed);
399 }
400 }
401
402 // Show the current update over cellular network setting.
403 if (FLAGS_show_update_over_cellular) {
404 bool allowed = GetUpdateOverCellularPermission();
405 LOG(INFO) << "Current update over cellular network setting: "
406 << (allowed ? "ENABLED" : "DISABLED");
407 }
408
Chris Sosacb7fa882013-07-25 17:02:59 -0700409 if (!FLAGS_powerwash && !FLAGS_rollback && FLAGS_channel.empty()) {
410 LOG(FATAL) << "powerwash flag only makes sense rollback or channel change";
411 return 1;
412 }
413
Alex Deymo5fdf7762013-07-17 20:01:40 -0700414 // Change the P2P enabled setting.
415 if (!FLAGS_p2p_update.empty()) {
416 gboolean enabled = FLAGS_p2p_update == "yes";
417 if (!enabled && FLAGS_p2p_update != "no") {
418 LOG(ERROR) << "Unknown option: \"" << FLAGS_p2p_update
419 << "\". Please specify \"yes\" or \"no\".";
420 } else {
421 SetP2PUpdatePermission(enabled);
422 }
423 }
424
425 // Show the current P2P enabled setting.
426 if (FLAGS_show_p2p_update) {
427 bool enabled = GetP2PUpdatePermission();
428 LOG(INFO) << "Current update using P2P setting: "
429 << (enabled ? "ENABLED" : "DISABLED");
430 }
431
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700432 // First, update the target channel if requested.
433 if (!FLAGS_channel.empty())
Chris Sosacb7fa882013-07-25 17:02:59 -0700434 SetTargetChannel(FLAGS_channel, FLAGS_powerwash);
Darin Petkov8daa3242010-10-25 13:28:47 -0700435
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700436 // Show the current and target channels if requested.
437 if (FLAGS_show_channel) {
438 string current_channel = GetChannel(true);
439 LOG(INFO) << "Current Channel: " << current_channel;
440
441 string target_channel = GetChannel(false);
442 if (!target_channel.empty())
443 LOG(INFO) << "Target Channel (pending update): " << target_channel;
Satoru Takabayashi583667b2010-10-27 13:09:57 +0900444 }
445
Chris Sosad317e402013-06-12 13:47:09 -0700446 bool do_update_request = FLAGS_check_for_update | FLAGS_update |
447 !FLAGS_app_version.empty() | !FLAGS_omaha_url.empty();
448
Chris Sosad317e402013-06-12 13:47:09 -0700449 if (do_update_request && FLAGS_rollback) {
450 LOG(FATAL) << "Update should not be requested with rollback!";
451 return 1;
452 }
453
454 if(FLAGS_rollback) {
455 LOG(INFO) << "Requesting rollback.";
456 CHECK(Rollback(FLAGS_powerwash)) << "Request for rollback failed.";
457 return 0;
458 }
459
Darin Petkov58529db2010-08-13 09:19:47 -0700460 // Initiate an update check, if necessary.
Chris Sosad317e402013-06-12 13:47:09 -0700461 if (do_update_request) {
Darin Petkov296889c2010-07-23 16:20:54 -0700462 LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
Darin Petkov58529db2010-08-13 09:19:47 -0700463 string app_version = FLAGS_app_version;
464 if (FLAGS_update && app_version.empty()) {
465 app_version = "ForcedUpdate";
466 LOG(INFO) << "Forcing an update by setting app_version to ForcedUpdate.";
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700467 }
Darin Petkov58529db2010-08-13 09:19:47 -0700468 LOG(INFO) << "Initiating update check and install.";
469 CHECK(CheckForUpdates(app_version, FLAGS_omaha_url))
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700470 << "Update check/initiate update failed.";
Darin Petkov58529db2010-08-13 09:19:47 -0700471
472 // Wait for an update to complete.
473 if (FLAGS_update) {
Darin Petkov9d911fa2010-08-19 09:36:08 -0700474 LOG(INFO) << "Waiting for update to complete.";
Darin Petkov58529db2010-08-13 09:19:47 -0700475 CompleteUpdate(); // Should never return.
476 return 1;
477 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700478 return 0;
479 }
Darin Petkov58529db2010-08-13 09:19:47 -0700480
481 // Start watching for updates.
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700482 if (FLAGS_watch_for_updates) {
Darin Petkov296889c2010-07-23 16:20:54 -0700483 LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700484 LOG(INFO) << "Watching for status updates.";
485 WatchForUpdates(); // Should never return.
486 return 1;
487 }
Darin Petkov58529db2010-08-13 09:19:47 -0700488
Darin Petkov296889c2010-07-23 16:20:54 -0700489 if (FLAGS_reboot) {
490 LOG(INFO) << "Requesting a reboot...";
491 CHECK(RebootIfNeeded());
492 return 0;
493 }
Andrew de los Reyesada42202010-07-15 22:23:20 -0700494
Darin Petkov8daa3242010-10-25 13:28:47 -0700495 LOG(INFO) << "Done.";
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700496 return 0;
497}