blob: d27f027eac4822e211d5709fa2387055d611b1eb [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
11#include "update_engine/dbus_constants.h"
12#include "update_engine/subprocess.h"
13#include "update_engine/utils.h"
14
15extern "C" {
16#include "update_engine/update_engine.dbusclient.h"
17}
18
19using chromeos_update_engine::kUpdateEngineServiceName;
20using chromeos_update_engine::kUpdateEngineServicePath;
21using chromeos_update_engine::kUpdateEngineServiceInterface;
David Zeuthen75a4c3e2013-09-06 11:36:59 -070022using chromeos_update_engine::AttemptUpdateFlags;
23using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
Darin Petkova0b9e772011-10-06 05:05:56 -070024using chromeos_update_engine::utils::GetAndFreeGError;
Darin Petkov5a7f5652010-07-22 21:40:09 -070025using std::string;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070026
Darin Petkov296889c2010-07-23 16:20:54 -070027DEFINE_string(app_version, "", "Force the current app version.");
Jay Srinivasanae4697c2013-03-18 17:08:08 -070028DEFINE_string(channel, "",
Chris Sosa192449e2013-10-28 14:16:19 -070029 "Set the target channel. The device will be powerwashed if the "
30 "target channel is more stable than the current channel unless "
31 "--nopowerwash is specified.");
Chris Sosad317e402013-06-12 13:47:09 -070032DEFINE_bool(check_for_update, false, "Initiate check for updates.");
Chris Sosa192449e2013-10-28 14:16:19 -070033DEFINE_bool(follow, false, "Wait for any update operations to complete."
34 "Exit status is 0 if the update succeeded, and 1 otherwise.");
35DEFINE_bool(interactive, true, "Mark the update request as interactive.");
Chris Sosad317e402013-06-12 13:47:09 -070036DEFINE_string(omaha_url, "", "The URL of the Omaha update server.");
Chris Sosa192449e2013-10-28 14:16:19 -070037DEFINE_string(p2p_update, "",
38 "Enables (\"yes\") or disables (\"no\") the peer-to-peer update "
39 "sharing.");
40DEFINE_bool(powerwash, true, "When performing rollback or channel change, "
41 "do a powerwash or allow it respectively.");
Chris Sosad317e402013-06-12 13:47:09 -070042DEFINE_bool(reboot, false, "Initiate a reboot if needed.");
43DEFINE_bool(reset_status, false, "Sets the status in update_engine to idle.");
44DEFINE_bool(rollback, false, "Perform a rollback to the previous partition.");
Alex Vakulenko59e253e2014-02-24 10:40:21 -080045DEFINE_bool(can_rollback, false, "Shows whether rollback partition "
46 "is available.");
Chris Sosad317e402013-06-12 13:47:09 -070047DEFINE_bool(show_channel, false, "Show the current and target channels.");
Chris Sosa192449e2013-10-28 14:16:19 -070048DEFINE_bool(show_p2p_update, false,
49 "Show the current setting for peer-to-peer update sharing.");
Alex Deymof4867c42013-06-28 14:41:39 -070050DEFINE_bool(show_update_over_cellular, false,
51 "Show the current setting for updates over cellular networks.");
Chris Sosa192449e2013-10-28 14:16:19 -070052DEFINE_bool(status, false, "Print the status to stdout.");
53DEFINE_bool(update, false, "Forces an update and waits for it to complete. "
54 "Implies --follow.");
Alex Deymof4867c42013-06-28 14:41:39 -070055DEFINE_string(update_over_cellular, "",
56 "Enables (\"yes\") or disables (\"no\") the updates over "
57 "cellular networks.");
Chris Sosa192449e2013-10-28 14:16:19 -070058DEFINE_bool(watch_for_updates, false,
59 "Listen for status updates and print them to the screen.");
Alex Vakulenkodea2eac2014-03-14 15:56:59 -070060DEFINE_bool(prev_version, false,
61 "Show the previous OS version used before the update reboot.");
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070062
63namespace {
64
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070065bool GetProxy(DBusGProxy** out_proxy) {
66 DBusGConnection* bus;
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070067 DBusGProxy* proxy = NULL;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070068 GError* error = NULL;
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070069 const int kTries = 4;
Darin Petkova0b9e772011-10-06 05:05:56 -070070 const int kRetrySeconds = 10;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070071
72 bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
Richard Barnetted7936062013-01-18 13:38:51 -080073 if (bus == NULL) {
74 LOG(ERROR) << "Failed to get bus: " << GetAndFreeGError(&error);
75 exit(1);
76 }
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070077 for (int i = 0; !proxy && i < kTries; ++i) {
Darin Petkova0b9e772011-10-06 05:05:56 -070078 if (i > 0) {
79 LOG(INFO) << "Retrying to get dbus proxy. Try "
80 << (i + 1) << "/" << kTries;
Gilad Arnold8e3f1262013-01-08 14:59:54 -080081 g_usleep(kRetrySeconds * G_USEC_PER_SEC);
Darin Petkova0b9e772011-10-06 05:05:56 -070082 }
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070083 proxy = dbus_g_proxy_new_for_name_owner(bus,
84 kUpdateEngineServiceName,
85 kUpdateEngineServicePath,
86 kUpdateEngineServiceInterface,
87 &error);
Darin Petkova0b9e772011-10-06 05:05:56 -070088 LOG_IF(WARNING, !proxy) << "Error getting dbus proxy for "
89 << kUpdateEngineServiceName << ": "
90 << GetAndFreeGError(&error);
Andrew de los Reyes68ab6ed2011-08-09 14:46:39 -070091 }
Richard Barnetted7936062013-01-18 13:38:51 -080092 if (proxy == NULL) {
93 LOG(ERROR) << "Giving up -- unable to get dbus proxy for "
94 << kUpdateEngineServiceName;
95 exit(1);
96 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070097 *out_proxy = proxy;
98 return true;
99}
100
101static void StatusUpdateSignalHandler(DBusGProxy* proxy,
102 int64_t last_checked_time,
103 double progress,
104 gchar* current_operation,
105 gchar* new_version,
106 int64_t new_size,
107 void* user_data) {
108 LOG(INFO) << "Got status update:";
109 LOG(INFO) << " last_checked_time: " << last_checked_time;
110 LOG(INFO) << " progress: " << progress;
111 LOG(INFO) << " current_operation: " << current_operation;
112 LOG(INFO) << " new_version: " << new_version;
113 LOG(INFO) << " new_size: " << new_size;
114}
115
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700116bool ResetStatus() {
117 DBusGProxy* proxy;
118 GError* error = NULL;
119
120 CHECK(GetProxy(&proxy));
121
Alex Deymo36dc2f32013-08-29 15:45:06 -0700122 gboolean rc = update_engine_client_reset_status(proxy, &error);
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700123 return rc;
124}
125
126
Darin Petkov58529db2010-08-13 09:19:47 -0700127// If |op| is non-NULL, sets it to the current operation string or an
128// empty string if unable to obtain the current status.
129bool GetStatus(string* op) {
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700130 DBusGProxy* proxy;
131 GError* error = NULL;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700132
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700133 CHECK(GetProxy(&proxy));
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700134
135 gint64 last_checked_time = 0;
136 gdouble progress = 0.0;
137 char* current_op = NULL;
138 char* new_version = NULL;
139 gint64 new_size = 0;
140
Alex Deymo36dc2f32013-08-29 15:45:06 -0700141 gboolean rc = update_engine_client_get_status(proxy,
142 &last_checked_time,
143 &progress,
144 &current_op,
145 &new_version,
146 &new_size,
147 &error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700148 if (rc == FALSE) {
Darin Petkova0b9e772011-10-06 05:05:56 -0700149 LOG(INFO) << "Error getting status: " << GetAndFreeGError(&error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700150 }
151 printf("LAST_CHECKED_TIME=%" PRIi64 "\nPROGRESS=%f\nCURRENT_OP=%s\n"
152 "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
153 last_checked_time,
154 progress,
155 current_op,
156 new_version,
157 new_size);
Darin Petkov58529db2010-08-13 09:19:47 -0700158 if (op) {
159 *op = current_op ? current_op : "";
160 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700161 return true;
162}
163
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700164// Should never return.
165void WatchForUpdates() {
166 DBusGProxy* proxy;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700167
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700168 CHECK(GetProxy(&proxy));
Andrew de los Reyesada42202010-07-15 22:23:20 -0700169
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700170 // Register marshaller
171 dbus_g_object_register_marshaller(
Alex Deymo3d41c4d2014-02-13 23:26:33 -0800172 NULL,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700173 G_TYPE_NONE,
174 G_TYPE_INT64,
175 G_TYPE_DOUBLE,
176 G_TYPE_STRING,
177 G_TYPE_STRING,
178 G_TYPE_INT64,
179 G_TYPE_INVALID);
Andrew de los Reyesada42202010-07-15 22:23:20 -0700180
181 static const char kStatusUpdate[] = "StatusUpdate";
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700182 dbus_g_proxy_add_signal(proxy,
Andrew de los Reyesada42202010-07-15 22:23:20 -0700183 kStatusUpdate,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700184 G_TYPE_INT64,
185 G_TYPE_DOUBLE,
186 G_TYPE_STRING,
187 G_TYPE_STRING,
188 G_TYPE_INT64,
189 G_TYPE_INVALID);
190 GMainLoop* loop = g_main_loop_new (NULL, TRUE);
191 dbus_g_proxy_connect_signal(proxy,
Andrew de los Reyesada42202010-07-15 22:23:20 -0700192 kStatusUpdate,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700193 G_CALLBACK(StatusUpdateSignalHandler),
194 NULL,
195 NULL);
196 g_main_loop_run(loop);
197 g_main_loop_unref(loop);
198}
199
Chris Sosad317e402013-06-12 13:47:09 -0700200bool Rollback(bool rollback) {
201 DBusGProxy* proxy;
202 GError* error = NULL;
203
204 CHECK(GetProxy(&proxy));
205
Alex Deymo36dc2f32013-08-29 15:45:06 -0700206 gboolean rc = update_engine_client_attempt_rollback(proxy,
207 rollback,
208 &error);
Chris Sosad317e402013-06-12 13:47:09 -0700209 CHECK_EQ(rc, TRUE) << "Error with rollback request: "
210 << GetAndFreeGError(&error);
211 return true;
212}
213
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800214bool CanRollback() {
215 DBusGProxy* proxy;
216 GError* error = NULL;
217
218 CHECK(GetProxy(&proxy));
219
220 gboolean can_rollback = FALSE;
221 gboolean rc = update_engine_client_can_rollback(proxy,
222 &can_rollback,
223 &error);
224 CHECK_EQ(rc, TRUE) << "Error while querying rollback partition availabilty: "
225 << GetAndFreeGError(&error);
226 return can_rollback;
227}
Darin Petkov58529db2010-08-13 09:19:47 -0700228bool CheckForUpdates(const string& app_version, const string& omaha_url) {
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700229 DBusGProxy* proxy;
230 GError* error = NULL;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700231
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700232 CHECK(GetProxy(&proxy));
233
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700234 AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(
235 FLAGS_interactive ? 0 : kAttemptUpdateFlagNonInteractive);
236 gboolean rc =
237 update_engine_client_attempt_update_with_flags(proxy,
238 app_version.c_str(),
239 omaha_url.c_str(),
240 static_cast<gint>(flags),
241 &error);
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700242 CHECK_EQ(rc, TRUE) << "Error checking for update: "
Darin Petkova0b9e772011-10-06 05:05:56 -0700243 << GetAndFreeGError(&error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700244 return true;
245}
246
Darin Petkov296889c2010-07-23 16:20:54 -0700247bool RebootIfNeeded() {
248 DBusGProxy* proxy;
249 GError* error = NULL;
250
251 CHECK(GetProxy(&proxy));
252
253 gboolean rc =
Alex Deymo36dc2f32013-08-29 15:45:06 -0700254 update_engine_client_reboot_if_needed(proxy, &error);
Darin Petkov296889c2010-07-23 16:20:54 -0700255 // Reboot error code doesn't necessarily mean that a reboot
256 // failed. For example, D-Bus may be shutdown before we receive the
257 // result.
Darin Petkova0b9e772011-10-06 05:05:56 -0700258 LOG_IF(INFO, !rc) << "Reboot error message: " << GetAndFreeGError(&error);
Darin Petkov296889c2010-07-23 16:20:54 -0700259 return true;
260}
261
Chris Sosacb7fa882013-07-25 17:02:59 -0700262void SetTargetChannel(const string& target_channel, bool allow_powerwash) {
Darin Petkov8daa3242010-10-25 13:28:47 -0700263 DBusGProxy* proxy;
264 GError* error = NULL;
265
266 CHECK(GetProxy(&proxy));
267
Alex Deymo36dc2f32013-08-29 15:45:06 -0700268 gboolean rc = update_engine_client_set_channel(proxy,
269 target_channel.c_str(),
270 allow_powerwash,
271 &error);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700272 CHECK_EQ(rc, true) << "Error setting the channel: "
Darin Petkova0b9e772011-10-06 05:05:56 -0700273 << GetAndFreeGError(&error);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700274 LOG(INFO) << "Channel permanently set to: " << target_channel;
Darin Petkov8daa3242010-10-25 13:28:47 -0700275}
276
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700277string GetChannel(bool get_current_channel) {
Satoru Takabayashi583667b2010-10-27 13:09:57 +0900278 DBusGProxy* proxy;
279 GError* error = NULL;
280
281 CHECK(GetProxy(&proxy));
282
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700283 char* channel = NULL;
Alex Deymo36dc2f32013-08-29 15:45:06 -0700284 gboolean rc = update_engine_client_get_channel(proxy,
285 get_current_channel,
286 &channel,
287 &error);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700288 CHECK_EQ(rc, true) << "Error getting the channel: "
289 << GetAndFreeGError(&error);
290 string output = channel;
291 g_free(channel);
Satoru Takabayashi583667b2010-10-27 13:09:57 +0900292 return output;
293}
294
Alex Deymo5fdf7762013-07-17 20:01:40 -0700295void SetUpdateOverCellularPermission(gboolean allowed) {
Alex Deymof4867c42013-06-28 14:41:39 -0700296 DBusGProxy* proxy;
297 GError* error = NULL;
298
299 CHECK(GetProxy(&proxy));
300
Alex Deymo36dc2f32013-08-29 15:45:06 -0700301 gboolean rc = update_engine_client_set_update_over_cellular_permission(
302 proxy,
303 allowed,
304 &error);
Alex Deymof4867c42013-06-28 14:41:39 -0700305 CHECK_EQ(rc, true) << "Error setting the update over cellular setting: "
306 << GetAndFreeGError(&error);
Alex Deymof4867c42013-06-28 14:41:39 -0700307}
308
309bool GetUpdateOverCellularPermission() {
310 DBusGProxy* proxy;
311 GError* error = NULL;
312
313 CHECK(GetProxy(&proxy));
314
315 gboolean allowed;
Alex Deymo36dc2f32013-08-29 15:45:06 -0700316 gboolean rc = update_engine_client_get_update_over_cellular_permission(
317 proxy,
318 &allowed,
319 &error);
Alex Deymof4867c42013-06-28 14:41:39 -0700320 CHECK_EQ(rc, true) << "Error getting the update over cellular setting: "
321 << GetAndFreeGError(&error);
322 return allowed;
323}
324
Alex Deymo5fdf7762013-07-17 20:01:40 -0700325void SetP2PUpdatePermission(gboolean enabled) {
326 DBusGProxy* proxy;
327 GError* error = NULL;
328
329 CHECK(GetProxy(&proxy));
330
Alex Deymo36dc2f32013-08-29 15:45:06 -0700331 gboolean rc = update_engine_client_set_p2p_update_permission(
332 proxy,
333 enabled,
334 &error);
Alex Deymo5fdf7762013-07-17 20:01:40 -0700335 CHECK_EQ(rc, true) << "Error setting the peer-to-peer update setting: "
336 << GetAndFreeGError(&error);
337}
338
339bool GetP2PUpdatePermission() {
340 DBusGProxy* proxy;
341 GError* error = NULL;
342
343 CHECK(GetProxy(&proxy));
344
345 gboolean enabled;
Alex Deymo36dc2f32013-08-29 15:45:06 -0700346 gboolean rc = update_engine_client_get_p2p_update_permission(
347 proxy,
348 &enabled,
349 &error);
Alex Deymo5fdf7762013-07-17 20:01:40 -0700350 CHECK_EQ(rc, true) << "Error getting the peer-to-peer update setting: "
351 << GetAndFreeGError(&error);
352 return enabled;
353}
354
Darin Petkov58529db2010-08-13 09:19:47 -0700355static gboolean CompleteUpdateSource(gpointer data) {
356 string current_op;
357 if (!GetStatus(&current_op) || current_op == "UPDATE_STATUS_IDLE") {
358 LOG(ERROR) << "Update failed.";
359 exit(1);
360 }
361 if (current_op == "UPDATE_STATUS_UPDATED_NEED_REBOOT") {
362 LOG(INFO) << "Update succeeded -- reboot needed.";
363 exit(0);
364 }
365 return TRUE;
366}
367
368// This is similar to watching for updates but rather than registering
369// a signal watch, activelly poll the daemon just in case it stops
370// sending notifications.
371void CompleteUpdate() {
372 GMainLoop* loop = g_main_loop_new (NULL, TRUE);
373 g_timeout_add_seconds(5, CompleteUpdateSource, NULL);
374 g_main_loop_run(loop);
375 g_main_loop_unref(loop);
376}
377
Alex Vakulenkodea2eac2014-03-14 15:56:59 -0700378void ShowPrevVersion() {
379 DBusGProxy* proxy;
380 GError* error = nullptr;
381
382 CHECK(GetProxy(&proxy));
383
384 char* prev_version = nullptr;
385
386 gboolean rc = update_engine_client_get_prev_version(proxy,
387 &prev_version,
388 &error);
389 if (!rc) {
390 LOG(ERROR) << "Error getting previous version: "
391 << GetAndFreeGError(&error);
392 } else {
393 LOG(INFO) << "Previous version = " << prev_version;
394 g_free(prev_version);
395 }
396}
397
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700398} // namespace {}
399
400int main(int argc, char** argv) {
401 // Boilerplate init commands.
402 g_type_init();
Ben Chan46bf5c82013-06-24 11:17:41 -0700403 dbus_threads_init_default();
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700404 chromeos_update_engine::Subprocess::Init();
405 google::ParseCommandLineFlags(&argc, &argv, true);
Andrew de los Reyesada42202010-07-15 22:23:20 -0700406
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700407 // Update the status if requested.
408 if (FLAGS_reset_status) {
409 LOG(INFO) << "Setting Update Engine status to idle ...";
410 if (!ResetStatus()) {
411 LOG(ERROR) << "ResetStatus failed.";
412 return 1;
413 }
Gilad Arnold50c60632013-01-25 10:27:19 -0800414 LOG(INFO) << "ResetStatus succeeded; to undo partition table changes run:\n"
415 "(D=$(rootdev -d) P=$(rootdev -s); cgpt p -i$(($(echo ${P#$D} "
416 "| sed 's/^[^0-9]*//')-1)) $D;)";
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700417 }
Darin Petkov58529db2010-08-13 09:19:47 -0700418
Alex Deymof4867c42013-06-28 14:41:39 -0700419 // Changes the current update over cellular network setting.
420 if (!FLAGS_update_over_cellular.empty()) {
421 gboolean allowed = FLAGS_update_over_cellular == "yes";
422 if (!allowed && FLAGS_update_over_cellular != "no") {
423 LOG(ERROR) << "Unknown option: \"" << FLAGS_update_over_cellular
424 << "\". Please specify \"yes\" or \"no\".";
425 } else {
426 SetUpdateOverCellularPermission(allowed);
427 }
428 }
429
430 // Show the current update over cellular network setting.
431 if (FLAGS_show_update_over_cellular) {
432 bool allowed = GetUpdateOverCellularPermission();
433 LOG(INFO) << "Current update over cellular network setting: "
434 << (allowed ? "ENABLED" : "DISABLED");
435 }
436
Chris Sosacb7fa882013-07-25 17:02:59 -0700437 if (!FLAGS_powerwash && !FLAGS_rollback && FLAGS_channel.empty()) {
Chris Sosa192449e2013-10-28 14:16:19 -0700438 LOG(ERROR) << "powerwash flag only makes sense rollback or channel change";
Chris Sosacb7fa882013-07-25 17:02:59 -0700439 return 1;
440 }
441
Alex Deymo5fdf7762013-07-17 20:01:40 -0700442 // Change the P2P enabled setting.
443 if (!FLAGS_p2p_update.empty()) {
444 gboolean enabled = FLAGS_p2p_update == "yes";
445 if (!enabled && FLAGS_p2p_update != "no") {
446 LOG(ERROR) << "Unknown option: \"" << FLAGS_p2p_update
447 << "\". Please specify \"yes\" or \"no\".";
448 } else {
449 SetP2PUpdatePermission(enabled);
450 }
451 }
452
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800453 // Show the rollback availability.
454 if (FLAGS_can_rollback) {
455 bool can_rollback = CanRollback();
456 LOG(INFO) << "Rollback partition: "
457 << (can_rollback ? "AVAILABLE" : "UNAVAILABLE");
458 }
459
Alex Deymo5fdf7762013-07-17 20:01:40 -0700460 // Show the current P2P enabled setting.
461 if (FLAGS_show_p2p_update) {
462 bool enabled = GetP2PUpdatePermission();
463 LOG(INFO) << "Current update using P2P setting: "
464 << (enabled ? "ENABLED" : "DISABLED");
465 }
466
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700467 // First, update the target channel if requested.
468 if (!FLAGS_channel.empty())
Chris Sosacb7fa882013-07-25 17:02:59 -0700469 SetTargetChannel(FLAGS_channel, FLAGS_powerwash);
Darin Petkov8daa3242010-10-25 13:28:47 -0700470
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700471 // Show the current and target channels if requested.
472 if (FLAGS_show_channel) {
473 string current_channel = GetChannel(true);
474 LOG(INFO) << "Current Channel: " << current_channel;
475
476 string target_channel = GetChannel(false);
477 if (!target_channel.empty())
478 LOG(INFO) << "Target Channel (pending update): " << target_channel;
Satoru Takabayashi583667b2010-10-27 13:09:57 +0900479 }
480
Chris Sosad317e402013-06-12 13:47:09 -0700481 bool do_update_request = FLAGS_check_for_update | FLAGS_update |
482 !FLAGS_app_version.empty() | !FLAGS_omaha_url.empty();
Chris Sosa192449e2013-10-28 14:16:19 -0700483 if (FLAGS_update)
484 FLAGS_follow = true;
Chris Sosad317e402013-06-12 13:47:09 -0700485
Chris Sosad317e402013-06-12 13:47:09 -0700486 if (do_update_request && FLAGS_rollback) {
Chris Sosa192449e2013-10-28 14:16:19 -0700487 LOG(ERROR) << "Incompatible flags specified with rollback."
488 << "Rollback should not include update-related flags.";
Chris Sosad317e402013-06-12 13:47:09 -0700489 return 1;
490 }
491
492 if(FLAGS_rollback) {
493 LOG(INFO) << "Requesting rollback.";
494 CHECK(Rollback(FLAGS_powerwash)) << "Request for rollback failed.";
Chris Sosad317e402013-06-12 13:47:09 -0700495 }
496
Darin Petkov58529db2010-08-13 09:19:47 -0700497 // Initiate an update check, if necessary.
Chris Sosad317e402013-06-12 13:47:09 -0700498 if (do_update_request) {
Darin Petkov296889c2010-07-23 16:20:54 -0700499 LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
Darin Petkov58529db2010-08-13 09:19:47 -0700500 string app_version = FLAGS_app_version;
501 if (FLAGS_update && app_version.empty()) {
502 app_version = "ForcedUpdate";
503 LOG(INFO) << "Forcing an update by setting app_version to ForcedUpdate.";
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700504 }
Darin Petkov58529db2010-08-13 09:19:47 -0700505 LOG(INFO) << "Initiating update check and install.";
506 CHECK(CheckForUpdates(app_version, FLAGS_omaha_url))
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700507 << "Update check/initiate update failed.";
Chris Sosa192449e2013-10-28 14:16:19 -0700508 }
Darin Petkov58529db2010-08-13 09:19:47 -0700509
Chris Sosa192449e2013-10-28 14:16:19 -0700510 // These final options are all mutually exclusive with one another.
511 if (FLAGS_follow + FLAGS_watch_for_updates + FLAGS_reboot + FLAGS_status > 1)
512 {
513 LOG(ERROR) << "Multiple exclusive options selected. "
514 << "Select only one of --follow, --watch_for_updates, --reboot, "
515 << "or --status.";
516 return 1;
517 }
518
519 if (FLAGS_status) {
520 LOG(INFO) << "Querying Update Engine status...";
521 if (!GetStatus(NULL)) {
522 LOG(ERROR) << "GetStatus failed.";
Darin Petkov58529db2010-08-13 09:19:47 -0700523 return 1;
524 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700525 return 0;
526 }
Darin Petkov58529db2010-08-13 09:19:47 -0700527
Chris Sosa192449e2013-10-28 14:16:19 -0700528 if (FLAGS_follow) {
529 LOG(INFO) << "Waiting for update to complete.";
530 CompleteUpdate(); // Should never return.
531 return 1;
532 }
533
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700534 if (FLAGS_watch_for_updates) {
535 LOG(INFO) << "Watching for status updates.";
536 WatchForUpdates(); // Should never return.
537 return 1;
538 }
Darin Petkov58529db2010-08-13 09:19:47 -0700539
Darin Petkov296889c2010-07-23 16:20:54 -0700540 if (FLAGS_reboot) {
541 LOG(INFO) << "Requesting a reboot...";
542 CHECK(RebootIfNeeded());
543 return 0;
544 }
Andrew de los Reyesada42202010-07-15 22:23:20 -0700545
Alex Vakulenkodea2eac2014-03-14 15:56:59 -0700546 if (FLAGS_prev_version) {
547 ShowPrevVersion();
548 }
549
Darin Petkov8daa3242010-10-25 13:28:47 -0700550 LOG(INFO) << "Done.";
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700551 return 0;
552}