diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ae7cf2..df2a730 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,11 +23,18 @@ protobuf_generate_cpp( GENERATED_PROTOBUF_BRIDGE_SRCS GENERATED_PROTOBUF_BRIDGE_HDRS anbox/protobuf/anbox_bridge.proto) +protobuf_generate_cpp( + GENERATED_PROTOBUF_CONTAINER_SRCS GENERATED_PROTOBUF_CONTAINER_HDRS + anbox/protobuf/anbox_container.proto) + + add_library(anbox-protobuf ${GENERATED_PROTOBUF_BRIDGE_SRCS} ${GENERATED_PROTOBUF_BRIDGE_HDRS} ${GENERATED_PROTOBUF_RPC_SRCS} ${GENERATED_PROTOBUF_RPC_HDRS} + ${GENERATED_PROTOBUF_CONTAINER_SRCS} + ${GENERATED_PROTOBUF_CONTAINER_HDRS} anbox/protobuf/google_protobuf_guard.cpp) target_link_libraries(anbox-protobuf ${PROTOBUF_LITE_LIBRARIES}) @@ -51,8 +58,12 @@ set(SOURCES anbox/container/service.cpp anbox/container/client.cpp + anbox/container/configuration.h anbox/container/container.cpp anbox/container/lxc_container.cpp + anbox/container/management_api_stub.cpp + anbox/container/management_api_skeleton.cpp + anbox/container/management_api_message_processor.cpp anbox/network/credentials.cpp anbox/network/message_sender.h diff --git a/src/anbox/cmds/run.cpp b/src/anbox/cmds/run.cpp index b11a28f..74926a9 100644 --- a/src/anbox/cmds/run.cpp +++ b/src/anbox/cmds/run.cpp @@ -147,7 +147,23 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory) })); container::Client container(rt); + container::Configuration container_configuration; + container_configuration.bind_mounts = { + { qemud_connector->socket_file(), "/dev/qemud" }, + { qemu_pipe_connector->socket_file(), "/dev/qemu_pipe" }, + { bridge_connector->socket_file(), "/dev/anbox_bridge" }, + { config::host_share_path(), config::container_android_share_path()}, + { config::host_android_data_path(), "/data" }, + { config::host_android_cache_path(), "/cache" }, + { config::host_android_storage_path(), "/storage" }, + { config::host_input_device_path(), "/dev/input" }, + { "/dev/binder", "/dev/binder" }, + { "/dev/ashmem", "/dev/ashmem" }, + }; + dispatcher->dispatch([&]() { + container.start_container(container_configuration); + }); auto bus = bus_factory_(); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); diff --git a/src/anbox/cmds/start_container.cpp b/src/anbox/cmds/start_container.cpp index 3c62cb2..f7ee94c 100644 --- a/src/anbox/cmds/start_container.cpp +++ b/src/anbox/cmds/start_container.cpp @@ -37,11 +37,7 @@ anbox::cmds::StartContainer::StartContainer() rt->start(); - auto container = std::make_shared(); - container->start(); - trap->run(); - container->stop(); rt->stop(); return 0; diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index 6c696ff..679545a 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -41,14 +41,14 @@ std::string in_snap_dir(const std::string &path) { } std::string in_snap_data_dir(const std::string &path) { - return prefix_dir_from_env(path, "SNAP_DATA"); + return prefix_dir_from_env(path, "SNAP_COMMON"); } std::string in_snap_user_data_dir(const std::string &path) { - return prefix_dir_from_env(path, "SNAP_USER_DATA"); + return prefix_dir_from_env(path, "SNAP_USER_COMMON"); } -std::string home_path() { +std::string home_dir() { static std::string path; if (path.empty()) { path = utils::get_env_value("HOME", ""); @@ -69,7 +69,7 @@ std::string runtime_dir() { } std::string state_dir() { - static std::string path = "/var/lib"; + static std::string path = in_snap_data_dir("/var/lib"); return path; } @@ -85,7 +85,7 @@ std::string socket_path() { } std::string data_path() { - static std::string path = utils::string_format("%s/.local/share/anbox/data", home_path()); + static std::string path = utils::string_format("%s/.anbox/data", home_dir()); return path; } @@ -104,13 +104,13 @@ std::string container_socket_path() { return path; } -std::string host_share_path() { - static std::string path = utils::string_format("%s/android-share", data_path()); +std::string host_input_device_path() { + static std::string path = utils::string_format("%s/anbox/input-devices", runtime_dir()); return path; } -std::string host_input_device_path() { - static std::string path = utils::string_format("%s/input-devices", data_path()); +std::string host_share_path() { + static std::string path = utils::string_format("%s/android-share", data_path()); return path; } diff --git a/src/anbox/container/client.cpp b/src/anbox/container/client.cpp index f6d5d51..f7bc599 100644 --- a/src/anbox/container/client.cpp +++ b/src/anbox/container/client.cpp @@ -16,16 +16,53 @@ */ #include "anbox/container/client.h" +#include "anbox/container/management_api_stub.h" +#include "anbox/network/local_socket_messenger.h" +#include "anbox/rpc/pending_call_cache.h" +#include "anbox/rpc/channel.h" +#include "anbox/rpc/message_processor.h" #include "anbox/config.h" #include "anbox/logger.h" +namespace ba = boost::asio; +namespace bs = boost::system; + namespace anbox { namespace container { Client::Client(const std::shared_ptr &rt) : - messenger_(config::container_socket_path(), rt) { + messenger_(std::make_shared(config::container_socket_path(), rt)), + pending_calls_(std::make_shared()), + rpc_channel_(std::make_shared(pending_calls_, messenger_)), + management_api_(std::make_shared(rpc_channel_)), + processor_(std::make_shared(messenger_, pending_calls_)) { + + read_next_message(); } Client::~Client() { } + +void Client::start_container(const Configuration &configuration) { + management_api_->start_container(configuration); +} + +void Client::read_next_message() +{ + auto callback = std::bind(&Client::on_read_size, + this, std::placeholders::_1, std::placeholders::_2); + messenger_->async_receive_msg(callback, ba::buffer(buffer_)); +} + +void Client::on_read_size(const boost::system::error_code& error, std::size_t bytes_read) +{ + if (error) + BOOST_THROW_EXCEPTION(std::runtime_error(error.message())); + + std::vector data(bytes_read); + std::copy(buffer_.data(), buffer_.data() + bytes_read, data.data()); + + if (processor_->process_data(data)) + read_next_message(); +} } // namespace container } // namespace anbox diff --git a/src/anbox/container/client.h b/src/anbox/container/client.h index e30c630..e0236b4 100644 --- a/src/anbox/container/client.h +++ b/src/anbox/container/client.h @@ -18,18 +18,37 @@ #ifndef ANBOX_CONTAINER_CLIENT_H_ #define ANBOX_CONTAINER_CLIENT_H_ -#include "anbox/network/local_socket_messenger.h" #include "anbox/runtime.h" +#include "anbox/container/configuration.h" namespace anbox { +namespace rpc { +class PendingCallCache; +class Channel; +class MessageProcessor; +} // namespace rpc +namespace network { +class LocalSocketMessenger; +} // namespace network namespace container { +class ManagementApiStub; class Client { public: Client(const std::shared_ptr &rt); ~Client(); + void start_container(const Configuration &configuration); + private: - network::LocalSocketMessenger messenger_; + void read_next_message(); + void on_read_size(const boost::system::error_code& ec, std::size_t bytes_read); + + std::shared_ptr messenger_; + std::shared_ptr pending_calls_; + std::shared_ptr rpc_channel_; + std::shared_ptr management_api_; + std::shared_ptr processor_; + std::array buffer_; }; } // namespace container } // namespace anbox diff --git a/src/anbox/container/configuration.h b/src/anbox/container/configuration.h new file mode 100644 index 0000000..2bb8768 --- /dev/null +++ b/src/anbox/container/configuration.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef ANBOX_CONTAINER_CONFIGURATION_H_ +#define ANBOX_CONTAINER_CONFIGURATION_H_ + +#include +#include + +namespace anbox { +namespace container { +struct Configuration { + std::map bind_mounts; +}; +} // namespace container +} // namespace anbox + +#endif diff --git a/src/anbox/container/container.h b/src/anbox/container/container.h index 2712090..2e1776d 100644 --- a/src/anbox/container/container.h +++ b/src/anbox/container/container.h @@ -18,8 +18,10 @@ #ifndef ANBOX_CONTAINER_CONTAINER_H_ #define ANBOX_CONTAINER_CONTAINER_H_ +#include "anbox/container/configuration.h" + #include -#include +#include namespace anbox { namespace container { @@ -33,7 +35,7 @@ public: }; // Start the container in background - virtual void start() = 0; + virtual void start(const Configuration &configuration) = 0; // Stop a running container virtual void stop() = 0; diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index cd04636..625f5ee 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -24,15 +24,14 @@ #include #include +#include #include #include #include #include -namespace { -static constexpr char *kAndroidShellCommand{"/system/bin/ls"}; -} +namespace fs = boost::filesystem; namespace anbox { namespace container { @@ -46,16 +45,19 @@ LxcContainer::LxcContainer() : config::host_android_data_path(), config::host_android_cache_path(), config::host_android_storage_path(), - config::host_input_device_path(), }); } LxcContainer::~LxcContainer() { + DEBUG(""); + + stop(); + if (container_) lxc_container_put(container_); } -void LxcContainer::start() { +void LxcContainer::start(const Configuration &configuration) { if (getuid() != 0) BOOST_THROW_EXCEPTION(std::runtime_error("You have to start the container as root")); @@ -112,30 +114,21 @@ void LxcContainer::start() { set_config_item("lxc.aa_profile", "unconfined"); #endif - std::map bind_mount_dirs = { - { config::host_share_path(), config::container_android_share_path() }, - { config::host_android_data_path(), "data" }, - { config::host_android_cache_path(), "cache" }, - { config::host_android_storage_path(), "storage" }, - { config::host_input_device_path(), "dev/input" }, - }; + for (const auto &bind_mount : configuration.bind_mounts) { + std::string create_type = "file"; + + if (fs::is_directory(bind_mount.first)) + create_type = "dir"; + + auto target_path = bind_mount.second; + // LXC wants target paths relative to the container rootfs so + // prividing an absolute path doesn't work. + if (utils::string_starts_with(target_path, "/")) + target_path.erase(0, 1); - for (const auto &item : bind_mount_dirs) { set_config_item("lxc.mount.entry", - utils::string_format("%s %s none bind,create=dir,optional 0 0", item.first, item.second)); - } - - std::map bind_mount_files = { - { "/dev/binder", "dev/binder" }, - { "/dev/ashmem", "dev/ashmem" }, - { utils::string_format("%s/qemu_pipe", config::socket_path()), "dev/qemu_pipe" }, - { utils::string_format("%s/qemud", config::socket_path()), "dev/qemud" }, - { utils::string_format("%s/anbox_bridge", config::socket_path()), "dev/anbox_bridge" }, - }; - - for (const auto &item : bind_mount_files) { - set_config_item("lxc.mount.entry", - utils::string_format("%s %s none bind,create=file,optional 0 0", item.first, item.second)); + utils::string_format("%s %s none bind,create=%s,optional 0 0", + bind_mount.first, target_path, create_type)); } if (!container_->save_config(container_, nullptr)) @@ -144,6 +137,8 @@ void LxcContainer::start() { if (not container_->start(container_, 0, nullptr)) BOOST_THROW_EXCEPTION(std::runtime_error("Failed to start container")); + state_ = Container::State::running; + DEBUG("Container successfully started"); } @@ -154,6 +149,8 @@ void LxcContainer::stop() { if (not container_->stop(container_)) BOOST_THROW_EXCEPTION(std::runtime_error("Failed to stop container")); + state_ = Container::State::inactive; + DEBUG("Container successfully stopped"); } diff --git a/src/anbox/container/lxc_container.h b/src/anbox/container/lxc_container.h index ad8cabb..c412b55 100644 --- a/src/anbox/container/lxc_container.h +++ b/src/anbox/container/lxc_container.h @@ -31,7 +31,7 @@ public: LxcContainer(); ~LxcContainer(); - void start() override; + void start(const Configuration &configuration) override; void stop() override; State state() override; diff --git a/src/anbox/container/management_api_message_processor.cpp b/src/anbox/container/management_api_message_processor.cpp new file mode 100644 index 0000000..1573fcf --- /dev/null +++ b/src/anbox/container/management_api_message_processor.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#include "anbox/container/management_api_message_processor.h" +#include "anbox/container/management_api_skeleton.h" +#include "anbox/rpc/template_message_processor.h" + +#include "anbox_bridge.pb.h" +#include "anbox_container.pb.h" + +namespace anbox { +namespace container { +ManagementApiMessageProcessor::ManagementApiMessageProcessor(const std::shared_ptr &sender, + const std::shared_ptr &pending_calls, + const std::shared_ptr &server) : + rpc::MessageProcessor(sender, pending_calls), + server_(server) { +} + +ManagementApiMessageProcessor::~ManagementApiMessageProcessor() { +} + +void ManagementApiMessageProcessor::dispatch(rpc::Invocation const& invocation) { + if (invocation.method_name() == "start_container") + invoke(this, server_.get(), &ManagementApiSkeleton::start_container, invocation); +} + +void ManagementApiMessageProcessor::process_event_sequence(const std::string&) { +} +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/management_api_message_processor.h b/src/anbox/container/management_api_message_processor.h new file mode 100644 index 0000000..9b5e851 --- /dev/null +++ b/src/anbox/container/management_api_message_processor.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef ANBOX_CONTAINER_MANAGEMENT_API_MESSAGE_PROCESSOR_H_ +#define ANBOX_CONTAINER_MANAGEMENT_API_MESSAGE_PROCESSOR_H_ + +#include "anbox/rpc/message_processor.h" + +namespace anbox { +namespace container { +class ManagementApiSkeleton; +class ManagementApiMessageProcessor : public rpc::MessageProcessor { +public: + ManagementApiMessageProcessor(const std::shared_ptr &sender, + const std::shared_ptr &pending_calls, + const std::shared_ptr &server); + ~ManagementApiMessageProcessor(); + + void dispatch(rpc::Invocation const& invocation) override; + void process_event_sequence(const std::string &event) override; + +private: + std::shared_ptr server_; +}; +} // namespace anbox +} // namespace network + +#endif diff --git a/src/anbox/container/management_api_skeleton.cpp b/src/anbox/container/management_api_skeleton.cpp new file mode 100644 index 0000000..a11067e --- /dev/null +++ b/src/anbox/container/management_api_skeleton.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#include "anbox/container/management_api_skeleton.h" +#include "anbox/container/container.h" +#include "anbox/container/configuration.h" +#include "anbox/defer_action.h" +#include "anbox/utils.h" +#include "anbox/logger.h" + +#include "anbox_rpc.pb.h" +#include "anbox_container.pb.h" + +namespace anbox { +namespace container { +ManagementApiSkeleton::ManagementApiSkeleton(const std::shared_ptr &pending_calls, + const std::shared_ptr &container) : + pending_calls_(pending_calls), + container_(container) { +} + +ManagementApiSkeleton::~ManagementApiSkeleton() { +} + +void ManagementApiSkeleton::start_container(anbox::protobuf::container::StartContainer const *request, + anbox::protobuf::rpc::Void *response, + google::protobuf::Closure *done) { + + if (container_->state() == Container::State::running) { + response->set_error("Container is already running"); + done->Run(); + return; + } + + Configuration container_configuration; + + const auto configuration = request->configuration(); + for (int n = 0; n < configuration.bind_mounts_size(); n++) { + const auto bind_mount = configuration.bind_mounts(n); + container_configuration.bind_mounts.insert({ bind_mount.source(), bind_mount.target() }); + } + + try { + container_->start(container_configuration); + } + catch (std::exception &err) { + response->set_error(utils::string_format("Failed to start container: %s", err.what())); + } + + DEBUG(""); + + done->Run(); +} +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/management_api_skeleton.h b/src/anbox/container/management_api_skeleton.h new file mode 100644 index 0000000..3007ee7 --- /dev/null +++ b/src/anbox/container/management_api_skeleton.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef ANBOX_CONTAINER_MANAGEMENT_API_SKELETON_H_ +#define ANBOX_CONTAINER_MANAGEMENT_API_SKELETON_H_ + +#include + +namespace google { +namespace protobuf { +class Closure; +} // namespace protobuf +} // namespace google + +namespace anbox { +namespace protobuf { +namespace rpc { +class Void; +} // namespace rpc +namespace container { +class StartContainer; +} // namespace container +} // namespace protobuf +namespace rpc { +class PendingCallCache; +} // namespace rpc +namespace container { +class Container; +class ManagementApiSkeleton { +public: + ManagementApiSkeleton(const std::shared_ptr &pending_calls, + const std::shared_ptr &container); + ~ManagementApiSkeleton(); + + void start_container(anbox::protobuf::container::StartContainer const *request, + anbox::protobuf::rpc::Void *response, + google::protobuf::Closure *done); + +private: + std::shared_ptr pending_calls_; + std::shared_ptr container_; +}; +} // namespace container +} // namespace anbox + +#endif diff --git a/src/anbox/container/management_api_stub.cpp b/src/anbox/container/management_api_stub.cpp new file mode 100644 index 0000000..9a8254b --- /dev/null +++ b/src/anbox/container/management_api_stub.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#include "anbox/container/management_api_stub.h" +#include "anbox/rpc/channel.h" +#include "anbox/logger.h" + +#include "anbox_rpc.pb.h" +#include "anbox_container.pb.h" + +namespace anbox { +namespace container { +ManagementApiStub::ManagementApiStub(const std::shared_ptr &channel) : + channel_(channel) { +} + +ManagementApiStub::~ManagementApiStub() { +} + +void ManagementApiStub::start_container(const Configuration &configuration) { + auto c = std::make_shared>(); + + protobuf::container::StartContainer message; + auto message_configuration = new protobuf::container::Configuration; + + for (const auto item : configuration.bind_mounts) { + auto bind_mount_message = message_configuration->add_bind_mounts(); + bind_mount_message->set_source(item.first); + bind_mount_message->set_target(item.second); + } + + message.set_allocated_configuration(message_configuration); + + { + std::lock_guard lock(mutex_); + start_wait_handle_.expect_result(); + } + + channel_->call_method("start_container", + &message, + c->response.get(), + google::protobuf::NewCallback(this, &ManagementApiStub::container_started, c.get())); + + start_wait_handle_.wait_for_all(); + + if (c->response->has_error()) + throw std::runtime_error(c->response->error()); +} + +void ManagementApiStub::container_started(Request *request) { + (void) request; + DEBUG(""); + start_wait_handle_.result_received(); +} +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/management_api_stub.h b/src/anbox/container/management_api_stub.h new file mode 100644 index 0000000..3577b73 --- /dev/null +++ b/src/anbox/container/management_api_stub.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef ANBOX_CONTAINER_MANAGEMENT_API_STUB_H_ +#define ANBOX_CONTAINER_MANAGEMENT_API_STUB_H_ + +#include "anbox/do_not_copy_or_move.h" +#include "anbox/container/configuration.h" +#include "anbox/common/wait_handle.h" + +#include + +namespace anbox { +namespace protobuf { +namespace rpc { +class Void; +} // namespace rpc +} // namespace protobuf +namespace rpc { +class Channel; +} // namespace rpc +namespace container { +class ManagementApiStub : public DoNotCopyOrMove { +public: + ManagementApiStub(const std::shared_ptr &channel); + ~ManagementApiStub(); + + void start_container(const Configuration &configuration); + +private: + template + struct Request { + Request() : response(std::make_shared()), success(true) { } + std::shared_ptr response; + bool success; + }; + + void container_started(Request *request); + + mutable std::mutex mutex_; + std::shared_ptr channel_; + common::WaitHandle start_wait_handle_; +}; +} // namespace container +} // namespace anbox + +#endif diff --git a/src/anbox/container/service.cpp b/src/anbox/container/service.cpp index 5d5f5ce..7a3bfc4 100644 --- a/src/anbox/container/service.cpp +++ b/src/anbox/container/service.cpp @@ -20,7 +20,11 @@ #include "anbox/network/delegate_message_processor.h" #include "anbox/network/socket_messenger.h" #include "anbox/qemu/null_message_processor.h" +#include "anbox/rpc/pending_call_cache.h" +#include "anbox/rpc/channel.h" #include "anbox/container/lxc_container.h" +#include "anbox/container/management_api_message_processor.h" +#include "anbox/container/management_api_skeleton.h" #include "anbox/config.h" #include "anbox/logger.h" @@ -40,8 +44,6 @@ std::shared_ptr Service::create(const std::shared_ptr &rt) { // 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); - sp->connections_->set_observer(sp); - DEBUG("Everything setup. Waiting for incoming connections."); return sp; @@ -54,29 +56,7 @@ Service::Service(const std::shared_ptr &rt) : } Service::~Service() { -} - -void Service::connection_added(int id) { -} - -void Service::connection_removed(int id) { - stop_container(); -} - -void Service::start_container() { - if (backend_) - BOOST_THROW_EXCEPTION(std::runtime_error("Container is already running")); - - backend_ = std::make_shared(); - backend_->start(); -} - -void Service::stop_container() { - if (not backend_) - return; - - backend_->stop(); - backend_.reset(); + DEBUG(""); } int Service::next_id() { @@ -90,23 +70,21 @@ void Service::new_client(std::shared_ptr(socket); + + DEBUG("Got connection from pid %d", messenger->creds().pid()); + + auto pending_calls = std::make_shared(); + auto rpc_channel = std::make_shared(pending_calls, messenger); + auto server = std::make_shared( + pending_calls, std::make_shared()); + auto processor = std::make_shared( + messenger, pending_calls, server); + auto const& connection = std::make_shared( - messenger, messenger, next_id(), connections_, - std::make_shared()); + messenger, messenger, next_id(), connections_, processor); connections_->add(connection); connection->read_next_message(); - - // To get access to the sockets the application manager - // services creates we need to make sure we're running - // against the right runtime directory here. Its a bit - // hacky but works for now. - auto creds = messenger->creds(); - setenv("XDG_RUNTIME_DIR", utils::string_format("/run/user/%d", creds.uid()).c_str(), 1); - - DEBUG("Got connection from pid %d", creds.pid()); - - start_container(); } } // namespace container } // namespace anbox diff --git a/src/anbox/container/service.h b/src/anbox/container/service.h index b717de4..89f19be 100644 --- a/src/anbox/container/service.h +++ b/src/anbox/container/service.h @@ -28,24 +28,17 @@ namespace anbox { namespace container { -class Service : public network::Connections::Observer, - public std::enable_shared_from_this { +class Service : public std::enable_shared_from_this { public: static std::shared_ptr create(const std::shared_ptr &rt); Service(const std::shared_ptr &rt); ~Service(); - void connection_added(int id) override; - void connection_removed(int id) override; - private: int next_id(); void new_client(std::shared_ptr const &socket); - void start_container(); - void stop_container(); - std::shared_ptr dispatcher_; std::shared_ptr connector_; std::atomic next_connection_id_; diff --git a/src/anbox/input/manager.cpp b/src/anbox/input/manager.cpp index 95eb15b..7d244dc 100644 --- a/src/anbox/input/manager.cpp +++ b/src/anbox/input/manager.cpp @@ -19,6 +19,7 @@ #include "anbox/input/device.h" #include "anbox/runtime.h" #include "anbox/config.h" +#include "anbox/utils.h" #include @@ -26,6 +27,7 @@ namespace anbox { namespace input { Manager::Manager(const std::shared_ptr &runtime) : runtime_(runtime) { + utils::ensure_paths({ config::host_input_device_path() }); } Manager::~Manager() { diff --git a/src/anbox/network/socket_connection.cpp b/src/anbox/network/socket_connection.cpp index b439e8c..2fe950f 100644 --- a/src/anbox/network/socket_connection.cpp +++ b/src/anbox/network/socket_connection.cpp @@ -80,15 +80,6 @@ void SocketConnection::on_read_size(const boost::system::error_code& error, std: else connections_->remove(id()); } - -void SocketConnection::on_response_sent(bs::error_code const& error, std::size_t) -{ - if (error) - { - connections_->remove(id()); - BOOST_THROW_EXCEPTION(std::runtime_error(error.message())); - } -} } // namespace anbox } // namespace network diff --git a/src/anbox/network/socket_connection.h b/src/anbox/network/socket_connection.h index 8a79243..66c5b59 100644 --- a/src/anbox/network/socket_connection.h +++ b/src/anbox/network/socket_connection.h @@ -48,7 +48,6 @@ public: void read_next_message(); private: - void on_response_sent(boost::system::error_code const& error, std::size_t); void on_read_size(const boost::system::error_code& ec, std::size_t bytes_read); std::shared_ptr const message_receiver_; diff --git a/src/anbox/protobuf/anbox_container.proto b/src/anbox/protobuf/anbox_container.proto new file mode 100644 index 0000000..07f8e0c --- /dev/null +++ b/src/anbox/protobuf/anbox_container.proto @@ -0,0 +1,15 @@ +option optimize_for = LITE_RUNTIME; + +package anbox.protobuf.container; + +message Configuration { + message BindMount { + required string source = 1; + required string target = 2; + } + repeated BindMount bind_mounts = 1; +} + +message StartContainer { + required Configuration configuration = 1; +} diff --git a/src/anbox/rpc/message_processor.cpp b/src/anbox/rpc/message_processor.cpp index e19066b..b7a68fe 100644 --- a/src/anbox/rpc/message_processor.cpp +++ b/src/anbox/rpc/message_processor.cpp @@ -20,6 +20,7 @@ #include "anbox/rpc/make_protobuf_object.h" #include "anbox/rpc/constants.h" #include "anbox/common/variable_length_array.h" +#include "anbox/logger.h" #include "anbox_rpc.pb.h" @@ -64,6 +65,8 @@ bool MessageProcessor::process_data(const std::vector &data) { buffer_.erase(buffer_.begin(), buffer_.begin() + header_size); + DEBUG("type %d", message_type); + if (message_type == MessageType::invocation) { anbox::protobuf::rpc::Invocation raw_invocation; raw_invocation.ParseFromArray(buffer_.data(), message_size); diff --git a/src/anbox/rpc/message_processor.h b/src/anbox/rpc/message_processor.h index 8a4de70..dd6a44e 100644 --- a/src/anbox/rpc/message_processor.h +++ b/src/anbox/rpc/message_processor.h @@ -57,8 +57,8 @@ public: void send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response); - virtual void dispatch(Invocation const& invocation) = 0; - virtual void process_event_sequence(const std::string &event) = 0; + virtual void dispatch(Invocation const& invocation) { } + virtual void process_event_sequence(const std::string &event) { } private: std::shared_ptr sender_;