diff --git a/src/anbox/audio/server.cpp b/src/anbox/audio/server.cpp index 79cd2e35abaab937e5c9d0f33a56b21ad2c1ea3f..ee8e731dd6337df0b075975b72a1515e78784943 100644 --- a/src/anbox/audio/server.cpp +++ b/src/anbox/audio/server.cpp @@ -49,7 +49,7 @@ namespace anbox { namespace audio { Server::Server(const std::shared_ptr& rt, const std::shared_ptr &platform_policy) : platform_policy_(platform_policy), - socket_file_(utils::string_format("%s/anbox_audio", config::socket_path())), + socket_file_(utils::string_format("%s/anbox_audio", SystemConfiguration::instance().socket_dir())), connector_(std::make_shared( socket_file_, rt, std::make_shared>(std::bind(&Server::create_connection_for, this, _1)))), diff --git a/src/anbox/cmds/run.cpp b/src/anbox/cmds/run.cpp index aa03481f5fdba2dbc80f8a12bd8131ac0e2c1a77..870cd50223bd606be8f7ef8b3b87edd662cdc406 100644 --- a/src/anbox/cmds/run.cpp +++ b/src/anbox/cmds/run.cpp @@ -94,7 +94,8 @@ anbox::cmds::Run::Run(const BusFactory &bus_factory) }); utils::ensure_paths({ - config::socket_path(), config::host_input_device_path(), + SystemConfiguration::instance().socket_dir(), + SystemConfiguration::instance().input_device_dir(), }); auto rt = Runtime::create(); @@ -128,15 +129,17 @@ anbox::cmds::Run::Run(const BusFactory &bus_factory) auto audio_server = std::make_shared(rt, policy); + const auto socket_path = SystemConfiguration::instance().socket_dir(); + // The qemu pipe is used as a very fast communication channel between guest // and host for things like the GLES emulation/translation, the RIL or ADB. auto qemu_pipe_connector = std::make_shared( - utils::string_format("%s/qemu_pipe", config::socket_path()), rt, + utils::string_format("%s/qemu_pipe", socket_path), rt, std::make_shared(gl_server->renderer(), rt)); auto bridge_connector = std::make_shared( - utils::string_format("%s/anbox_bridge", config::socket_path()), rt, + utils::string_format("%s/anbox_bridge", socket_path), rt, std::make_shared( rt, [&](const std::shared_ptr &sender) { auto pending_calls = std::make_shared(); @@ -161,20 +164,18 @@ anbox::cmds::Run::Run(const BusFactory &bus_factory) {qemu_pipe_connector->socket_file(), "/dev/qemu_pipe"}, {bridge_connector->socket_file(), "/dev/anbox_bridge"}, {audio_server->socket_file(), "/dev/anbox_audio"}, - {config::host_input_device_path(), "/dev/input"}, + {SystemConfiguration::instance().input_device_dir(), "/dev/input"}, {"/dev/binder", "/dev/binder"}, {"/dev/ashmem", "/dev/ashmem"}, {"/dev/fuse", "/dev/fuse"}, }; - dispatcher->dispatch( - [&]() { container.start_container(container_configuration); }); + dispatcher->dispatch([&]() { container.start_container(container_configuration); }); auto bus = bus_factory_(); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); - auto skeleton = - anbox::dbus::skeleton::Service::create_for_bus(bus, android_api_stub); + auto skeleton = anbox::dbus::skeleton::Service::create_for_bus(bus, android_api_stub); rt->start(); trap->run(); diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index c9db3c2bfaae93ac12069b4d37287a7aed6ddc68..25d0b9bbc7a75136b16b37cce1d52d6cc44b865b 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -15,93 +15,58 @@ * */ -#include #include "anbox/config.h" #include "anbox/utils.h" -#include - -namespace fs = boost::filesystem; - -namespace anbox { -namespace config { -std::string in_snap_dir(const std::string &path) { - return utils::prefix_dir_from_env(path, "SNAP"); -} -std::string in_snap_data_dir(const std::string &path) { - return utils::prefix_dir_from_env(path, "SNAP_COMMON"); -} +#include -std::string in_snap_user_data_dir(const std::string &path) { - return utils::prefix_dir_from_env(path, "SNAP_USER_COMMON"); -} +namespace fs = boost::filesystem; -std::string home_dir() { +namespace { +static std::string runtime_dir() { static std::string path; if (path.empty()) { - path = utils::get_env_value("HOME", ""); + path = anbox::utils::get_env_value("XDG_RUNTIME_DIR", ""); if (path.empty()) - BOOST_THROW_EXCEPTION(std::runtime_error("No home directory specified")); + BOOST_THROW_EXCEPTION(std::runtime_error("No runtime directory specified")); } return path; } - -std::string runtime_dir() { - static std::string path; - if (path.empty()) { - path = utils::get_env_value("XDG_RUNTIME_DIR", ""); - if (path.empty()) - BOOST_THROW_EXCEPTION( - std::runtime_error("No runtime directory specified")); - } - return path; } -std::string state_dir() { - static std::string path = "/var/lib"; - return path; +void anbox::SystemConfiguration::set_data_path(const std::string &path) { + data_path = path; } -std::string log_path() { - static std::string path = - in_snap_data_dir(utils::string_format("%s/anbox/", state_dir())); - return path; +std::string anbox::SystemConfiguration::rootfs_dir() const { + return (data_path / "rootfs").string(); } -std::string socket_path() { - static std::string path = - utils::string_format("%s/anbox/sockets", runtime_dir()); - return path; +std::string anbox::SystemConfiguration::log_dir() const { + return (data_path / "logs").string(); } -std::string data_path() { - static std::string path = utils::string_format("%s/.anbox/data", home_dir()); - return path; +std::string anbox::SystemConfiguration::container_config_dir() const { + return (data_path / "containers").string(); } -std::string rootfs_path() { - static std::string path = - in_snap_data_dir(utils::string_format("%s/anbox/rootfs", state_dir())); - return path; +std::string anbox::SystemConfiguration::container_socket_path() const { + return "/run/anbox-container.socket"; } -std::string container_config_path() { - static std::string path = in_snap_data_dir( - utils::string_format("%s/anbox/containers", state_dir())); - return path; +std::string anbox::SystemConfiguration::socket_dir() const { + static std::string dir = anbox::utils::string_format("%s/anbox/sockets", runtime_dir()); + return dir; } -std::string container_socket_path() { - std::string path = "/run/anbox-container.socket"; - return path; +std::string anbox::SystemConfiguration::input_device_dir() const { + static std::string dir = anbox::utils::string_format("%s/anbox/input", runtime_dir()); + return dir; } -std::string host_input_device_path() { - static std::string path = - utils::string_format("%s/anbox/input-devices", runtime_dir()); - return path; +anbox::SystemConfiguration& anbox::SystemConfiguration::instance() { + static SystemConfiguration config; + return config; } -} // namespace config -} // namespace anbox diff --git a/src/anbox/config.h b/src/anbox/config.h index 21514d1a385d81030dea5d234b20dd738cb025c7..51eadd50c6c8271b76c9e5d3c5518b2025822b13 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -19,20 +19,32 @@ #define ANBOX_CONFIG_H_ #include +#include + +#include namespace anbox { -namespace config { -std::string in_snap_dir(const std::string &path); -std::string in_snap_data_dir(const std::string &path); -std::string in_snap_user_data_dir(const std::string &path); -std::string data_path(); -std::string rootfs_path(); -std::string log_path(); -std::string socket_path(); -std::string container_config_path(); -std::string container_socket_path(); -std::string host_input_device_path(); -} // namespace config +class SystemConfiguration { + public: + static SystemConfiguration& instance(); + + virtual ~SystemConfiguration() = default; + + void set_data_path(const std::string &path); + + std::string rootfs_dir() const; + std::string log_dir() const; + std::string socket_dir() const; + std::string container_config_dir() const; + std::string container_socket_path() const; + std::string input_device_dir() const; + + protected: + SystemConfiguration() = default; + + boost::filesystem::path data_path = "/var/lib/anbox"; + +}; } // namespace anbox #endif diff --git a/src/anbox/container/client.cpp b/src/anbox/container/client.cpp index bde7aad37fea0960a3e260bfd5b1c92ef71608b4..f2c3a40e36302e7d76ac34a0c23216034bfa8c5b 100644 --- a/src/anbox/container/client.cpp +++ b/src/anbox/container/client.cpp @@ -31,7 +31,7 @@ namespace anbox { namespace container { Client::Client(const std::shared_ptr &rt) : messenger_(std::make_shared( - config::container_socket_path(), rt)), + SystemConfiguration::instance().container_socket_path(), rt)), pending_calls_(std::make_shared()), rpc_channel_(std::make_shared(pending_calls_, messenger_)), management_api_(std::make_shared(rpc_channel_)), diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index 1032d43c690dd20a13fe0d14ce43d9d6bb0c7633..e8e532ef4f0932e03c8488d018ad47777d1e23ef 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -38,7 +38,8 @@ namespace container { LxcContainer::LxcContainer(const network::Credentials &creds) : state_(State::inactive), container_(nullptr), creds_(creds) { utils::ensure_paths({ - config::container_config_path(), config::log_path(), + SystemConfiguration::instance().container_config_dir(), + SystemConfiguration::instance().log_dir(), }); } @@ -78,28 +79,23 @@ void LxcContainer::setup_id_maps() { void LxcContainer::start(const Configuration &configuration) { if (getuid() != 0) - BOOST_THROW_EXCEPTION( - std::runtime_error("You have to start the container as root")); + BOOST_THROW_EXCEPTION(std::runtime_error("You have to start the container as root")); if (container_ && container_->is_running(container_)) { - BOOST_THROW_EXCEPTION( - std::runtime_error("Container already started, stopping it now")); + WARNING("Container already started, stopping it now"); container_->stop(container_); } if (!container_) { - DEBUG("Containers are stored in %s", config::container_config_path()); + const auto container_config_dir = SystemConfiguration::instance().container_config_dir(); + DEBUG("Containers are stored in %s", container_config_dir); // Remove container config to be be able to rewrite it - ::unlink(utils::string_format("%s/default/config", - config::container_config_path()) - .c_str()); + ::unlink(utils::string_format("%s/default/config", container_config_dir).c_str()); - container_ = - lxc_container_new("default", config::container_config_path().c_str()); + container_ = lxc_container_new("default", container_config_dir.c_str()); if (!container_) - BOOST_THROW_EXCEPTION( - std::runtime_error("Failed to create LXC container instance")); + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create LXC container instance")); // If container is still running (for example after a crash) we stop it here // to ensure @@ -128,13 +124,13 @@ void LxcContainer::start(const Configuration &configuration) { set_config_item("lxc.init_cmd", "/anbox-init.sh"); set_config_item("lxc.rootfs.backend", "dir"); - DEBUG("Using rootfs path %s", config::rootfs_path()); - set_config_item("lxc.rootfs", config::rootfs_path()); + const auto rootfs_path = SystemConfiguration::instance().rootfs_dir(); + DEBUG("Using rootfs path %s", rootfs_path); + set_config_item("lxc.rootfs", rootfs_path); set_config_item("lxc.loglevel", "0"); - set_config_item( - "lxc.logfile", - utils::string_format("%s/container.log", config::log_path()).c_str()); + const auto log_path = SystemConfiguration::instance().log_dir(); + set_config_item("lxc.logfile", utils::string_format("%s/container.log", log_path).c_str()); if (fs::exists("/sys/class/net/anboxbr0")) { set_config_item("lxc.network.type", "veth"); @@ -178,7 +174,7 @@ void LxcContainer::start(const Configuration &configuration) { // when running in confined environments like snap's. if (!utils::string_starts_with(target_path, "/")) target_path = std::string("/") + target_path; - target_path = config::rootfs_path() + target_path; + target_path = rootfs_path + target_path; set_config_item( "lxc.mount.entry", @@ -213,8 +209,7 @@ void LxcContainer::stop() { void LxcContainer::set_config_item(const std::string &key, const std::string &value) { if (!container_->set_config_item(container_, key.c_str(), value.c_str())) - BOOST_THROW_EXCEPTION( - std::runtime_error("Failed to configure LXC container")); + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to configure LXC container")); } Container::State LxcContainer::state() { return state_; } diff --git a/src/anbox/container/service.cpp b/src/anbox/container/service.cpp index 86ca5abe6d021b648815bf887f4ed4edda3a8347..22e8e151956286c8d45ceb379b33c5d026b38cb0 100644 --- a/src/anbox/container/service.cpp +++ b/src/anbox/container/service.cpp @@ -38,12 +38,11 @@ std::shared_ptr Service::create(const std::shared_ptr &rt) { [sp](std::shared_ptr const &socket) { sp->new_client(socket); }); - sp->connector_ = std::make_shared( - config::container_socket_path(), rt, delegate_connector); + const auto container_socket_path = SystemConfiguration::instance().container_socket_path(); + sp->connector_ = std::make_shared(container_socket_path, rt, delegate_connector); // Make sure others can connect to our socket - ::chmod(config::container_socket_path().c_str(), - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + ::chmod(container_socket_path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); DEBUG("Everything setup. Waiting for incoming connections."); diff --git a/src/anbox/input/manager.cpp b/src/anbox/input/manager.cpp index 8ce84f2dfaa26cbc6792890941773d179c267ea5..0e5a56d83eabc8ade9996aa3293fc5cd02a52275 100644 --- a/src/anbox/input/manager.cpp +++ b/src/anbox/input/manager.cpp @@ -26,7 +26,7 @@ namespace anbox { namespace input { Manager::Manager(const std::shared_ptr &runtime) : runtime_(runtime) { - utils::ensure_paths({config::host_input_device_path()}); + utils::ensure_paths({SystemConfiguration::instance().input_device_dir()}); } Manager::~Manager() {} @@ -45,8 +45,7 @@ std::uint32_t Manager::next_id() { } std::string Manager::build_device_path(const std::uint32_t &id) { - return (boost::format("%1%/event%2%") % config::host_input_device_path() % id) - .str(); + return (boost::format("%1%/event%2%") % SystemConfiguration::instance().input_device_dir() % id).str(); } } // namespace input