Add RPC communication between container manager and client

This commit is contained in:
Simon Fels 2016-08-17 11:31:13 +02:00
commit 3d05c50c8b
24 changed files with 542 additions and 104 deletions

View file

@ -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

View file

@ -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()));

View file

@ -37,11 +37,7 @@ anbox::cmds::StartContainer::StartContainer()
rt->start();
auto container = std::make_shared<container::LxcContainer>();
container->start();
trap->run();
container->stop();
rt->stop();
return 0;

View file

@ -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;
}

View file

@ -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<Runtime> &rt) :
messenger_(config::container_socket_path(), rt) {
messenger_(std::make_shared<network::LocalSocketMessenger>(config::container_socket_path(), rt)),
pending_calls_(std::make_shared<rpc::PendingCallCache>()),
rpc_channel_(std::make_shared<rpc::Channel>(pending_calls_, messenger_)),
management_api_(std::make_shared<ManagementApiStub>(rpc_channel_)),
processor_(std::make_shared<rpc::MessageProcessor>(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<std::uint8_t> 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

View file

@ -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<Runtime> &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<network::LocalSocketMessenger> messenger_;
std::shared_ptr<rpc::PendingCallCache> pending_calls_;
std::shared_ptr<rpc::Channel> rpc_channel_;
std::shared_ptr<ManagementApiStub> management_api_;
std::shared_ptr<rpc::MessageProcessor> processor_;
std::array<std::uint8_t, 8192> buffer_;
};
} // namespace container
} // namespace anbox

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef ANBOX_CONTAINER_CONFIGURATION_H_
#define ANBOX_CONTAINER_CONFIGURATION_H_
#include <string>
#include <map>
namespace anbox {
namespace container {
struct Configuration {
std::map<std::string,std::string> bind_mounts;
};
} // namespace container
} // namespace anbox
#endif

View file

@ -18,8 +18,10 @@
#ifndef ANBOX_CONTAINER_CONTAINER_H_
#define ANBOX_CONTAINER_CONTAINER_H_
#include "anbox/container/configuration.h"
#include <string>
#include <vector>
#include <map>
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;

View file

@ -24,15 +24,14 @@
#include <map>
#include <boost/throw_exception.hpp>
#include <boost/filesystem.hpp>
#include <sys/wait.h>
#include <sys/capability.h>
#include <sys/types.h>
#include <sys/prctl.h>
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<std::string,std::string> 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<std::string,std::string> 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");
}

View file

@ -31,7 +31,7 @@ public:
LxcContainer();
~LxcContainer();
void start() override;
void start(const Configuration &configuration) override;
void stop() override;
State state() override;

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#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<network::MessageSender> &sender,
const std::shared_ptr<rpc::PendingCallCache> &pending_calls,
const std::shared_ptr<ManagementApiSkeleton> &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

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#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<network::MessageSender> &sender,
const std::shared_ptr<rpc::PendingCallCache> &pending_calls,
const std::shared_ptr<ManagementApiSkeleton> &server);
~ManagementApiMessageProcessor();
void dispatch(rpc::Invocation const& invocation) override;
void process_event_sequence(const std::string &event) override;
private:
std::shared_ptr<ManagementApiSkeleton> server_;
};
} // namespace anbox
} // namespace network
#endif

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#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<rpc::PendingCallCache> &pending_calls,
const std::shared_ptr<Container> &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

View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef ANBOX_CONTAINER_MANAGEMENT_API_SKELETON_H_
#define ANBOX_CONTAINER_MANAGEMENT_API_SKELETON_H_
#include <memory>
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<rpc::PendingCallCache> &pending_calls,
const std::shared_ptr<Container> &container);
~ManagementApiSkeleton();
void start_container(anbox::protobuf::container::StartContainer const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done);
private:
std::shared_ptr<rpc::PendingCallCache> pending_calls_;
std::shared_ptr<Container> container_;
};
} // namespace container
} // namespace anbox
#endif

View file

@ -0,0 +1,70 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#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<rpc::Channel> &channel) :
channel_(channel) {
}
ManagementApiStub::~ManagementApiStub() {
}
void ManagementApiStub::start_container(const Configuration &configuration) {
auto c = std::make_shared<Request<protobuf::rpc::Void>>();
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<decltype(mutex_)> 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<protobuf::rpc::Void> *request) {
(void) request;
DEBUG("");
start_wait_handle_.result_received();
}
} // namespace container
} // namespace anbox

View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#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 <memory>
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<rpc::Channel> &channel);
~ManagementApiStub();
void start_container(const Configuration &configuration);
private:
template<typename Response>
struct Request {
Request() : response(std::make_shared<Response>()), success(true) { }
std::shared_ptr<Response> response;
bool success;
};
void container_started(Request<protobuf::rpc::Void> *request);
mutable std::mutex mutex_;
std::shared_ptr<rpc::Channel> channel_;
common::WaitHandle start_wait_handle_;
};
} // namespace container
} // namespace anbox
#endif

View file

@ -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> Service::create(const std::shared_ptr<Runtime> &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<Runtime> &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<LxcContainer>();
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<boost::asio::local::stream_protocol::so
}
auto const messenger = std::make_shared<network::SocketMessenger>(socket);
DEBUG("Got connection from pid %d", messenger->creds().pid());
auto pending_calls = std::make_shared<rpc::PendingCallCache>();
auto rpc_channel = std::make_shared<rpc::Channel>(pending_calls, messenger);
auto server = std::make_shared<container::ManagementApiSkeleton>(
pending_calls, std::make_shared<LxcContainer>());
auto processor = std::make_shared<container::ManagementApiMessageProcessor>(
messenger, pending_calls, server);
auto const& connection = std::make_shared<network::SocketConnection>(
messenger, messenger, next_id(), connections_,
std::make_shared<qemu::NullMessageProcessor>());
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

View file

@ -28,24 +28,17 @@
namespace anbox {
namespace container {
class Service : public network::Connections<network::SocketConnection>::Observer,
public std::enable_shared_from_this<Service> {
class Service : public std::enable_shared_from_this<Service> {
public:
static std::shared_ptr<Service> create(const std::shared_ptr<Runtime> &rt);
Service(const std::shared_ptr<Runtime> &rt);
~Service();
void connection_added(int id) override;
void connection_removed(int id) override;
private:
int next_id();
void new_client(std::shared_ptr<boost::asio::local::stream_protocol::socket> const &socket);
void start_container();
void stop_container();
std::shared_ptr<common::Dispatcher> dispatcher_;
std::shared_ptr<network::PublishedSocketConnector> connector_;
std::atomic<int> next_connection_id_;

View file

@ -19,6 +19,7 @@
#include "anbox/input/device.h"
#include "anbox/runtime.h"
#include "anbox/config.h"
#include "anbox/utils.h"
#include <boost/format.hpp>
@ -26,6 +27,7 @@ namespace anbox {
namespace input {
Manager::Manager(const std::shared_ptr<Runtime> &runtime) :
runtime_(runtime) {
utils::ensure_paths({ config::host_input_device_path() });
}
Manager::~Manager() {

View file

@ -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

View file

@ -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<MessageReceiver> const message_receiver_;

View file

@ -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;
}

View file

@ -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<std::uint8_t> &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);

View file

@ -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<network::MessageSender> sender_;