buffet: Read config/state paths from commandline

This allows us to use custom paths and configurations in test without
altering normal system operation.

BUG=brillo:172
TEST=unittests

Change-Id: I1a969093683205d5f600ff88ebba8b22c05368b4
Reviewed-on: https://chromium-review.googlesource.com/247504
Tested-by: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index e947157..187ec39 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -25,7 +25,6 @@
 #include "buffet/commands/command_manager.h"
 #include "buffet/device_registration_storage_keys.h"
 #include "buffet/states/state_manager.h"
-#include "buffet/storage_impls.h"
 #include "buffet/utils.h"
 
 const char buffet::kErrorDomainOAuth2[] = "oauth2";
@@ -57,9 +56,6 @@
 
 namespace {
 
-const base::FilePath::CharType kDeviceInfoFilePath[] =
-    FILE_PATH_LITERAL("/var/lib/buffet/device_reg_info");
-
 std::pair<std::string, std::string> BuildAuthHeader(
     const std::string& access_token_type,
     const std::string& access_token) {
@@ -146,25 +142,11 @@
 DeviceRegistrationInfo::DeviceRegistrationInfo(
     const std::shared_ptr<CommandManager>& command_manager,
     const std::shared_ptr<StateManager>& state_manager,
-    std::unique_ptr<chromeos::KeyValueStore> config_store)
-    : DeviceRegistrationInfo(
-        command_manager,
-        state_manager,
-        std::move(config_store),
-        chromeos::http::Transport::CreateDefault(),
-        // TODO(avakulenko): Figure out security implications of storing
-        // this data unencrypted.
-        std::make_shared<FileStorage>(base::FilePath{kDeviceInfoFilePath})) {
-}
-
-DeviceRegistrationInfo::DeviceRegistrationInfo(
-    const std::shared_ptr<CommandManager>& command_manager,
-    const std::shared_ptr<StateManager>& state_manager,
     std::unique_ptr<chromeos::KeyValueStore> config_store,
     const std::shared_ptr<chromeos::http::Transport>& transport,
-    const std::shared_ptr<StorageInterface>& storage)
+    const std::shared_ptr<StorageInterface>& state_store)
     : transport_{transport},
-      storage_{storage},
+      storage_{state_store},
       command_manager_{command_manager},
       state_manager_{state_manager},
       config_store_{std::move(config_store)} {
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h
index 0e274c6..dc3524a 100644
--- a/buffet/device_registration_info.h
+++ b/buffet/device_registration_info.h
@@ -41,19 +41,13 @@
  public:
   // This is a helper class for unit testing.
   class TestHelper;
-  // This constructor uses CURL HTTP transport.
-  DeviceRegistrationInfo(
-      const std::shared_ptr<CommandManager>& command_manager,
-      const std::shared_ptr<StateManager>& state_manager,
-      std::unique_ptr<chromeos::KeyValueStore> config_store);
-  // This constructor allows to pass in a custom HTTP transport
-  // (mainly for testing).
+
   DeviceRegistrationInfo(
       const std::shared_ptr<CommandManager>& command_manager,
       const std::shared_ptr<StateManager>& state_manager,
       std::unique_ptr<chromeos::KeyValueStore> config_store,
       const std::shared_ptr<chromeos::http::Transport>& transport,
-      const std::shared_ptr<StorageInterface>& storage);
+      const std::shared_ptr<StorageInterface>& state_store);
 
   ~DeviceRegistrationInfo();
 
diff --git a/buffet/etc/init/buffet.conf b/buffet/etc/init/buffet.conf
index 0d7697e..0747ef5 100644
--- a/buffet/etc/init/buffet.conf
+++ b/buffet/etc/init/buffet.conf
@@ -9,6 +9,10 @@
 stop on stopping system-services
 respawn
 
+env BUFFET_LOG_LEVEL=0
+env BUFFET_STATE_PATH=
+env BUFFET_CONFIG_PATH=
+
 pre-start script
   mkdir -m 0755 -p /var/lib/buffet
   chown -R buffet:buffet /var/lib/buffet
@@ -17,5 +21,7 @@
 # Minijail actually forks off our desired process.
 expect fork
 
-exec minijail0 -i -g buffet -u buffet \
-	/usr/bin/buffet --v="${V:-1}"
+exec minijail0 -i -g buffet -u buffet /usr/bin/buffet \
+    --v="${BUFFET_LOG_LEVEL}" \
+    --config_path="${BUFFET_CONFIG_PATH}" \
+    --state_path="${BUFFET_STATE_PATH}"
diff --git a/buffet/main.cc b/buffet/main.cc
index 7cb37fb..1dc3388 100644
--- a/buffet/main.cc
+++ b/buffet/main.cc
@@ -4,10 +4,11 @@
 
 #include <string>
 
-#include <base/command_line.h>
+#include <base/files/file_path.h>
 #include <chromeos/dbus/async_event_sequencer.h>
 #include <chromeos/dbus/exported_object_manager.h>
 #include <chromeos/daemons/dbus_daemon.h>
+#include <chromeos/flag_helper.h>
 #include <chromeos/syslog_logging.h>
 
 #include "buffet/dbus_constants.h"
@@ -22,26 +23,50 @@
 
 class Daemon : public DBusServiceDaemon {
  public:
-  Daemon() : DBusServiceDaemon(kServiceName, kRootServicePath) {}
+  Daemon(const base::FilePath& config_path,
+         const base::FilePath& state_path)
+      : DBusServiceDaemon(kServiceName, kRootServicePath),
+        config_path_{config_path},
+        state_path_{state_path} {}
 
  protected:
   void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
     manager_.reset(new buffet::Manager(object_manager_->AsWeakPtr()));
     manager_->RegisterAsync(
+        config_path_,
+        state_path_,
         sequencer->GetHandler("Manager.RegisterAsync() failed.", true));
   }
 
  private:
   std::unique_ptr<buffet::Manager> manager_;
+  const base::FilePath config_path_;
+  const base::FilePath state_path_;
 
   DISALLOW_COPY_AND_ASSIGN(Daemon);
 };
 
 }  // namespace buffet
 
+namespace {
+
+const char kDefaultConfigFilePath[] = "/etc/buffet/buffet.conf";
+const char kDefaultStateFilePath[] = "/var/lib/buffet/device_reg_info";
+
+}  // namespace
+
 int main(int argc, char* argv[]) {
-  CommandLine::Init(argc, argv);
+  DEFINE_string(config_path, kDefaultConfigFilePath,
+                "Path to file containing config information.");
+  DEFINE_string(state_path, kDefaultStateFilePath,
+                "Path to file containing state information.");
+  if (FLAGS_config_path.empty())
+    FLAGS_config_path = kDefaultConfigFilePath;
+  if (FLAGS_state_path.empty())
+    FLAGS_state_path = kDefaultStateFilePath;
+  chromeos::FlagHelper::Init(argc, argv, "Privet protocol handler daemon");
   chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogHeader);
-  buffet::Daemon daemon;
+  buffet::Daemon daemon{base::FilePath{FLAGS_config_path},
+                        base::FilePath{FLAGS_state_path}};
   return daemon.Run();
 }
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 04fcc36..6605770 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -23,6 +23,7 @@
 #include "buffet/commands/command_manager.h"
 #include "buffet/states/state_change_queue.h"
 #include "buffet/states/state_manager.h"
+#include "buffet/storage_impls.h"
 
 using chromeos::dbus_utils::AsyncEventSequencer;
 using chromeos::dbus_utils::ExportedObjectManager;
@@ -41,7 +42,10 @@
 
 Manager::~Manager() {}
 
-void Manager::RegisterAsync(const AsyncEventSequencer::CompletionAction& cb) {
+void Manager::RegisterAsync(
+    const base::FilePath& config_path,
+    const base::FilePath& state_path,
+    const AsyncEventSequencer::CompletionAction& cb) {
   command_manager_ =
       std::make_shared<CommandManager>(dbus_object_.GetObjectManager());
   command_manager_->Startup();
@@ -50,13 +54,17 @@
   state_manager_ = std::make_shared<StateManager>(state_change_queue_.get());
   state_manager_->Startup();
   std::unique_ptr<chromeos::KeyValueStore> config_store{
-    new chromeos::KeyValueStore};
-  config_store->Load(base::FilePath(
-      FILE_PATH_LITERAL("/etc/buffet/buffet.conf")));
+      new chromeos::KeyValueStore};
+  std::unique_ptr<FileStorage> state_store{new FileStorage{state_path}};
+  config_store->Load(config_path);
+  // TODO(avakulenko): Figure out security implications of storing
+  // device info state data unencrypted.
   device_info_ = std::unique_ptr<DeviceRegistrationInfo>(
       new DeviceRegistrationInfo(command_manager_,
                                  state_manager_,
-                                 std::move(config_store)));
+                                 std::move(config_store),
+                                 chromeos::http::Transport::CreateDefault(),
+                                 std::move(state_store)));
   device_info_->Load();
   dbus_adaptor_.RegisterWithDBusObject(&dbus_object_);
   dbus_object_.RegisterAsync(cb);
diff --git a/buffet/manager.h b/buffet/manager.h
index ab5171f..c0086ed 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <string>
 
+#include <base/files/file_path.h>
 #include <base/macros.h>
 #include <base/memory/weak_ptr.h>
 #include <base/values.h>
@@ -47,6 +48,8 @@
   ~Manager();
 
   void RegisterAsync(
+      const base::FilePath& config_path,
+      const base::FilePath& state_path,
       const chromeos::dbus_utils::AsyncEventSequencer::CompletionAction& cb);
 
  private: