update_engine: Migrate UE DBus service to chrome DBus bindings.
chromeos-dbus-bindings now generates the adaptor interface that
update_engine exposes over DBus. This interface is implemented in
dbus_service.{h,cc}, which now has a UpdateEngineService class
encapsulating all the service methods implementation.
This allows to write unit test for those methods, which are included
in this CL for all the non-trivial methods.
This CL now uses chrome's DBus bindings for the update_engine serive,
but the proxy interaction is still done using dbus-glib. The main loop
in the main.cc file is now replaced with the chromeos::Dameon, which
uses a chromeos::BaseMessageLoop instead of a GlibMessageLoop. This
causes the asynchronous interactions in the proxy side to not work,
which will be fixed in the next CL.
CQ-DEPEND=CL:290990,CL:291092,CL:293334
BUG=chromium:419827
TEST=Added unittest for all dbus_service methods. deployed and tested manually that update_engine dbus interface works.
Change-Id: I6a6d142b2ac1a61a4c3abcb927665b26114abe5c
Reviewed-on: https://chromium-review.googlesource.com/225324
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
diff --git a/main.cc b/main.cc
index cf06f2a..4fe0c84 100644
--- a/main.cc
+++ b/main.cc
@@ -5,101 +5,30 @@
#include <unistd.h>
#include <string>
-#include <vector>
#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/files/file_util.h>
-#include <base/location.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
-#include <base/time/time.h>
#include <chromeos/flag_helper.h>
-#include <chromeos/message_loops/glib_message_loop.h>
+#include <chromeos/message_loops/base_message_loop.h>
#include <glib.h>
#include <metrics/metrics_library.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include "update_engine/certificate_checker.h"
-#include "update_engine/dbus_constants.h"
-#include "update_engine/dbus_service.h"
-#include "update_engine/dbus_wrapper_interface.h"
+#include "update_engine/daemon.h"
#include "update_engine/glib_utils.h"
-#include "update_engine/real_system_state.h"
-#include "update_engine/subprocess.h"
#include "update_engine/terminator.h"
-#include "update_engine/update_attempter.h"
-extern "C" {
-#include "update_engine/org.chromium.UpdateEngineInterface.dbusserver.h"
-}
#include "update_engine/utils.h"
using std::string;
-using std::vector;
-
-namespace {
-const int kDBusSystemMaxWaitSeconds = 2 * 60;
-} // namespace
namespace chromeos_update_engine {
-
namespace {
-// Wait for DBus to be ready by attempting to get the system bus up to
-// |timeout| time. Returns whether it succeeded to get the bus.
-bool WaitForDBusSystem(base::TimeDelta timeout) {
- GError *error = nullptr;
- DBusGConnection *bus = nullptr;
- Clock clock;
- base::Time deadline = clock.GetMonotonicTime() + timeout;
-
- while (clock.GetMonotonicTime() < deadline) {
- bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
- if (bus)
- return true;
- LOG(WARNING) << "Failed to get system bus, waiting: "
- << utils::GetAndFreeGError(&error);
- // Wait 1 second.
- sleep(1);
- }
- LOG(ERROR) << "Failed to get system bus after " << timeout.InSeconds()
- << " seconds.";
- return false;
-}
-
-void SetupDBusService(UpdateEngineService* service) {
- DBusGConnection *bus;
- DBusGProxy *proxy;
- GError *error = nullptr;
-
- bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
- LOG_IF(FATAL, !bus) << "Failed to get bus: "
- << utils::GetAndFreeGError(&error);
- proxy = dbus_g_proxy_new_for_name(bus,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
- guint32 request_name_ret;
- if (!org_freedesktop_DBus_request_name(proxy,
- kUpdateEngineServiceName,
- 0,
- &request_name_ret,
- &error)) {
- LOG(FATAL) << "Failed to get name: " << utils::GetAndFreeGError(&error);
- }
- if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_warning("Got result code %u from requesting name", request_name_ret);
- LOG(FATAL) << "Got result code " << request_name_ret
- << " from requesting name, but expected "
- << DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
- }
- dbus_g_connection_register_g_object(bus,
- "/org/chromium/UpdateEngine",
- G_OBJECT(service));
-}
-
void SetupLogSymlink(const string& symlink_path, const string& log_path) {
// TODO(petkov): To ensure a smooth transition between non-timestamped and
// timestamped logs, move an existing log to start the first timestamped
@@ -168,7 +97,6 @@
::g_type_init();
dbus_threads_init_default();
- base::AtExitManager exit_manager; // Required for base/rand_util.h.
chromeos_update_engine::Terminator::Init();
chromeos::FlagHelper::Init(argc, argv, "Chromium OS Update Engine");
chromeos_update_engine::SetupLogging(FLAGS_logtostderr);
@@ -183,74 +111,10 @@
// Done _after_ log file creation.
umask(S_IXUSR | S_IRWXG | S_IRWXO);
- // Create the single Glib main loop. Code accessing directly the glib main
- // loop (such as calling g_timeout_add() or similar functions) will still work
- // since the backend for the message loop is still the Glib main loop.
- // TODO(deymo): Replace this |loop| with one based on libevent once no other
- // code here uses glib directly.
- chromeos::GlibMessageLoop loop;
- loop.SetAsCurrent();
+ chromeos_update_engine::UpdateEngineDaemon update_engine_daemon;
+ int exit_code = update_engine_daemon.Run();
- // The Subprocess class requires a chromeos::MessageLoop setup.
- chromeos_update_engine::Subprocess subprocess;
- subprocess.Init();
-
- // Wait up to 2 minutes for DBus to be ready.
- LOG_IF(FATAL, !chromeos_update_engine::WaitForDBusSystem(
- base::TimeDelta::FromSeconds(kDBusSystemMaxWaitSeconds)))
- << "Failed to initialize DBus, aborting.";
-
- chromeos_update_engine::RealSystemState real_system_state;
- LOG_IF(ERROR, !real_system_state.Initialize())
- << "Failed to initialize system state.";
- chromeos_update_engine::UpdateAttempter *update_attempter =
- real_system_state.update_attempter();
- CHECK(update_attempter);
-
- // Sets static members for the certificate checker.
- chromeos_update_engine::CertificateChecker::set_system_state(
- &real_system_state);
- chromeos_update_engine::OpenSSLWrapper openssl_wrapper;
- chromeos_update_engine::CertificateChecker::set_openssl_wrapper(
- &openssl_wrapper);
-
- // Create the dbus service object:
- dbus_g_object_type_install_info(UPDATE_ENGINE_TYPE_SERVICE,
- &dbus_glib_update_engine_service_object_info);
- UpdateEngineService* service = update_engine_service_new();
- service->system_state_ = &real_system_state;
- update_attempter->set_dbus_service(service);
- chromeos_update_engine::SetupDBusService(service);
-
- // Initiate update checks.
- update_attempter->ScheduleUpdates();
-
- // Update boot flags after 45 seconds.
- loop.PostDelayedTask(
- FROM_HERE,
- base::Bind(&chromeos_update_engine::UpdateAttempter::UpdateBootFlags,
- base::Unretained(update_attempter)),
- base::TimeDelta::FromSeconds(45));
-
- // Broadcast the update engine status on startup to ensure consistent system
- // state on crashes.
- loop.PostTask(FROM_HERE, base::Bind(
- &chromeos_update_engine::UpdateAttempter::BroadcastStatus,
- base::Unretained(update_attempter)));
-
- // Run the UpdateEngineStarted() method on |update_attempter|.
- loop.PostTask(FROM_HERE, base::Bind(
- &chromeos_update_engine::UpdateAttempter::UpdateEngineStarted,
- base::Unretained(update_attempter)));
-
- // Run the main loop until exit time:
- loop.Run();
-
- // Cleanup:
- update_attempter->set_dbus_service(nullptr);
- g_object_unref(G_OBJECT(service));
-
- loop.ReleaseFromCurrent();
- LOG(INFO) << "Chrome OS Update Engine terminating";
- return 0;
+ LOG(INFO) << "Chrome OS Update Engine terminating with exit code "
+ << exit_code;
+ return exit_code;
}