blob: c8dda0717c4784f96441ea7f17faddf4a93afed7 [file] [log] [blame]
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07001// Copyright (c) 2010 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
Darin Petkov5a7f5652010-07-22 21:40:09 -07005#include <string>
6
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07007#include <gflags/gflags.h>
8#include <glib.h>
9
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070010#include "update_engine/marshal.glibmarshal.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070011#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;
Andrew de los Reyesc7020782010-04-28 10:46:04 -070022using chromeos_update_engine::utils::GetGErrorMessage;
Darin Petkov5a7f5652010-07-22 21:40:09 -070023using std::string;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070024
Darin Petkov296889c2010-07-23 16:20:54 -070025DEFINE_string(app_version, "", "Force the current app version.");
26DEFINE_bool(check_for_update, false, "Initiate check for updates.");
Darin Petkov5a7f5652010-07-22 21:40:09 -070027DEFINE_bool(force_update, false,
28 "Force an update, even over an expensive network.");
Darin Petkov296889c2010-07-23 16:20:54 -070029DEFINE_string(omaha_url, "", "The URL of the Omaha update server.");
30DEFINE_bool(reboot, false, "Initiate a reboot if needed.");
Darin Petkov5a7f5652010-07-22 21:40:09 -070031DEFINE_bool(status, false, "Print the status to stdout.");
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070032DEFINE_bool(watch_for_updates, false,
33 "Listen for status updates and print them to the screen.");
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070034
35namespace {
36
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070037bool GetProxy(DBusGProxy** out_proxy) {
38 DBusGConnection* bus;
39 DBusGProxy* proxy;
40 GError* error = NULL;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070041
42 bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
43 if (!bus) {
44 LOG(FATAL) << "Failed to get bus";
45 }
46 proxy = dbus_g_proxy_new_for_name_owner(bus,
47 kUpdateEngineServiceName,
48 kUpdateEngineServicePath,
49 kUpdateEngineServiceInterface,
50 &error);
51 if (!proxy) {
Andrew de los Reyesc7020782010-04-28 10:46:04 -070052 LOG(FATAL) << "Error getting proxy: " << GetGErrorMessage(error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070053 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070054 *out_proxy = proxy;
55 return true;
56}
57
58static void StatusUpdateSignalHandler(DBusGProxy* proxy,
59 int64_t last_checked_time,
60 double progress,
61 gchar* current_operation,
62 gchar* new_version,
63 int64_t new_size,
64 void* user_data) {
65 LOG(INFO) << "Got status update:";
66 LOG(INFO) << " last_checked_time: " << last_checked_time;
67 LOG(INFO) << " progress: " << progress;
68 LOG(INFO) << " current_operation: " << current_operation;
69 LOG(INFO) << " new_version: " << new_version;
70 LOG(INFO) << " new_size: " << new_size;
71}
72
73bool GetStatus() {
74 DBusGProxy* proxy;
75 GError* error = NULL;
Andrew de los Reyesada42202010-07-15 22:23:20 -070076
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070077 CHECK(GetProxy(&proxy));
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070078
79 gint64 last_checked_time = 0;
80 gdouble progress = 0.0;
81 char* current_op = NULL;
82 char* new_version = NULL;
83 gint64 new_size = 0;
84
85 gboolean rc = org_chromium_UpdateEngineInterface_get_status(
86 proxy,
87 &last_checked_time,
88 &progress,
89 &current_op,
90 &new_version,
91 &new_size,
92 &error);
93 if (rc == FALSE) {
Andrew de los Reyesc7020782010-04-28 10:46:04 -070094 LOG(INFO) << "Error getting status: " << GetGErrorMessage(error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070095 }
96 printf("LAST_CHECKED_TIME=%" PRIi64 "\nPROGRESS=%f\nCURRENT_OP=%s\n"
97 "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
98 last_checked_time,
99 progress,
100 current_op,
101 new_version,
102 new_size);
103 return true;
104}
105
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700106// Should never return.
107void WatchForUpdates() {
108 DBusGProxy* proxy;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700109
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700110 CHECK(GetProxy(&proxy));
Andrew de los Reyesada42202010-07-15 22:23:20 -0700111
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700112 // Register marshaller
113 dbus_g_object_register_marshaller(
114 update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
115 G_TYPE_NONE,
116 G_TYPE_INT64,
117 G_TYPE_DOUBLE,
118 G_TYPE_STRING,
119 G_TYPE_STRING,
120 G_TYPE_INT64,
121 G_TYPE_INVALID);
Andrew de los Reyesada42202010-07-15 22:23:20 -0700122
123 static const char kStatusUpdate[] = "StatusUpdate";
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700124 dbus_g_proxy_add_signal(proxy,
Andrew de los Reyesada42202010-07-15 22:23:20 -0700125 kStatusUpdate,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700126 G_TYPE_INT64,
127 G_TYPE_DOUBLE,
128 G_TYPE_STRING,
129 G_TYPE_STRING,
130 G_TYPE_INT64,
131 G_TYPE_INVALID);
132 GMainLoop* loop = g_main_loop_new (NULL, TRUE);
133 dbus_g_proxy_connect_signal(proxy,
Andrew de los Reyesada42202010-07-15 22:23:20 -0700134 kStatusUpdate,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700135 G_CALLBACK(StatusUpdateSignalHandler),
136 NULL,
137 NULL);
138 g_main_loop_run(loop);
139 g_main_loop_unref(loop);
140}
141
Darin Petkov5a7f5652010-07-22 21:40:09 -0700142bool CheckForUpdates(bool force, const string& app_version,
143 const string& omaha_url) {
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700144 DBusGProxy* proxy;
145 GError* error = NULL;
Andrew de los Reyesada42202010-07-15 22:23:20 -0700146
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700147 CHECK(GetProxy(&proxy));
148
149 gboolean rc =
Darin Petkov5a7f5652010-07-22 21:40:09 -0700150 org_chromium_UpdateEngineInterface_attempt_update(proxy,
151 app_version.c_str(),
152 omaha_url.c_str(),
153 &error);
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700154 CHECK_EQ(rc, TRUE) << "Error checking for update: "
155 << GetGErrorMessage(error);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700156 return true;
157}
158
Darin Petkov296889c2010-07-23 16:20:54 -0700159bool RebootIfNeeded() {
160 DBusGProxy* proxy;
161 GError* error = NULL;
162
163 CHECK(GetProxy(&proxy));
164
165 gboolean rc =
166 org_chromium_UpdateEngineInterface_reboot_if_needed(proxy, &error);
167 // Reboot error code doesn't necessarily mean that a reboot
168 // failed. For example, D-Bus may be shutdown before we receive the
169 // result.
170 LOG_IF(INFO, !rc) << "Reboot error message: " << GetGErrorMessage(error);
171 return true;
172}
173
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700174} // namespace {}
175
176int main(int argc, char** argv) {
177 // Boilerplate init commands.
178 g_type_init();
179 g_thread_init(NULL);
180 dbus_g_thread_init();
181 chromeos_update_engine::Subprocess::Init();
182 google::ParseCommandLineFlags(&argc, &argv, true);
Andrew de los Reyesada42202010-07-15 22:23:20 -0700183
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700184 if (FLAGS_status) {
185 LOG(INFO) << "Querying Update Engine status...";
186 if (!GetStatus()) {
187 LOG(FATAL) << "GetStatus() failed.";
188 }
189 return 0;
190 }
Darin Petkov5a7f5652010-07-22 21:40:09 -0700191 if (FLAGS_force_update || FLAGS_check_for_update ||
192 !FLAGS_app_version.empty() || !FLAGS_omaha_url.empty()) {
Darin Petkov296889c2010-07-23 16:20:54 -0700193 LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700194 LOG(INFO) << "Initiating update check and install.";
195 if (FLAGS_force_update) {
196 LOG(INFO) << "Will not abort due to being on expensive network.";
197 }
Darin Petkov5a7f5652010-07-22 21:40:09 -0700198 CHECK(CheckForUpdates(FLAGS_force_update, FLAGS_app_version,
199 FLAGS_omaha_url))
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700200 << "Update check/initiate update failed.";
201 return 0;
202 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700203 if (FLAGS_watch_for_updates) {
Darin Petkov296889c2010-07-23 16:20:54 -0700204 LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700205 LOG(INFO) << "Watching for status updates.";
206 WatchForUpdates(); // Should never return.
207 return 1;
208 }
Darin Petkov296889c2010-07-23 16:20:54 -0700209 if (FLAGS_reboot) {
210 LOG(INFO) << "Requesting a reboot...";
211 CHECK(RebootIfNeeded());
212 return 0;
213 }
Andrew de los Reyesada42202010-07-15 22:23:20 -0700214
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700215 LOG(INFO) << "No flags specified. Exiting.";
216 return 0;
217}