Add RPC communication between container manager and client
This commit is contained in:
parent
51e9cfa777
commit
3d05c50c8b
24 changed files with 542 additions and 104 deletions
|
|
@ -23,11 +23,18 @@ protobuf_generate_cpp(
|
||||||
GENERATED_PROTOBUF_BRIDGE_SRCS GENERATED_PROTOBUF_BRIDGE_HDRS
|
GENERATED_PROTOBUF_BRIDGE_SRCS GENERATED_PROTOBUF_BRIDGE_HDRS
|
||||||
anbox/protobuf/anbox_bridge.proto)
|
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
|
add_library(anbox-protobuf
|
||||||
${GENERATED_PROTOBUF_BRIDGE_SRCS}
|
${GENERATED_PROTOBUF_BRIDGE_SRCS}
|
||||||
${GENERATED_PROTOBUF_BRIDGE_HDRS}
|
${GENERATED_PROTOBUF_BRIDGE_HDRS}
|
||||||
${GENERATED_PROTOBUF_RPC_SRCS}
|
${GENERATED_PROTOBUF_RPC_SRCS}
|
||||||
${GENERATED_PROTOBUF_RPC_HDRS}
|
${GENERATED_PROTOBUF_RPC_HDRS}
|
||||||
|
${GENERATED_PROTOBUF_CONTAINER_SRCS}
|
||||||
|
${GENERATED_PROTOBUF_CONTAINER_HDRS}
|
||||||
anbox/protobuf/google_protobuf_guard.cpp)
|
anbox/protobuf/google_protobuf_guard.cpp)
|
||||||
target_link_libraries(anbox-protobuf
|
target_link_libraries(anbox-protobuf
|
||||||
${PROTOBUF_LITE_LIBRARIES})
|
${PROTOBUF_LITE_LIBRARIES})
|
||||||
|
|
@ -51,8 +58,12 @@ set(SOURCES
|
||||||
|
|
||||||
anbox/container/service.cpp
|
anbox/container/service.cpp
|
||||||
anbox/container/client.cpp
|
anbox/container/client.cpp
|
||||||
|
anbox/container/configuration.h
|
||||||
anbox/container/container.cpp
|
anbox/container/container.cpp
|
||||||
anbox/container/lxc_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/credentials.cpp
|
||||||
anbox/network/message_sender.h
|
anbox/network/message_sender.h
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,23 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
container::Client container(rt);
|
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_();
|
auto bus = bus_factory_();
|
||||||
bus->install_executor(core::dbus::asio::make_executor(bus, rt->service()));
|
bus->install_executor(core::dbus::asio::make_executor(bus, rt->service()));
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,7 @@ anbox::cmds::StartContainer::StartContainer()
|
||||||
|
|
||||||
rt->start();
|
rt->start();
|
||||||
|
|
||||||
auto container = std::make_shared<container::LxcContainer>();
|
|
||||||
container->start();
|
|
||||||
|
|
||||||
trap->run();
|
trap->run();
|
||||||
container->stop();
|
|
||||||
rt->stop();
|
rt->stop();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ std::string in_snap_dir(const std::string &path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string in_snap_data_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) {
|
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;
|
static std::string path;
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
path = utils::get_env_value("HOME", "");
|
path = utils::get_env_value("HOME", "");
|
||||||
|
|
@ -69,7 +69,7 @@ std::string runtime_dir() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string state_dir() {
|
std::string state_dir() {
|
||||||
static std::string path = "/var/lib";
|
static std::string path = in_snap_data_dir("/var/lib");
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ std::string socket_path() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string data_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;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,13 +104,13 @@ std::string container_socket_path() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string host_share_path() {
|
std::string host_input_device_path() {
|
||||||
static std::string path = utils::string_format("%s/android-share", data_path());
|
static std::string path = utils::string_format("%s/anbox/input-devices", runtime_dir());
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string host_input_device_path() {
|
std::string host_share_path() {
|
||||||
static std::string path = utils::string_format("%s/input-devices", data_path());
|
static std::string path = utils::string_format("%s/android-share", data_path());
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,53 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "anbox/container/client.h"
|
#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/config.h"
|
||||||
#include "anbox/logger.h"
|
#include "anbox/logger.h"
|
||||||
|
|
||||||
|
namespace ba = boost::asio;
|
||||||
|
namespace bs = boost::system;
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace container {
|
namespace container {
|
||||||
Client::Client(const std::shared_ptr<Runtime> &rt) :
|
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() {
|
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 container
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,37 @@
|
||||||
#ifndef ANBOX_CONTAINER_CLIENT_H_
|
#ifndef ANBOX_CONTAINER_CLIENT_H_
|
||||||
#define ANBOX_CONTAINER_CLIENT_H_
|
#define ANBOX_CONTAINER_CLIENT_H_
|
||||||
|
|
||||||
#include "anbox/network/local_socket_messenger.h"
|
|
||||||
#include "anbox/runtime.h"
|
#include "anbox/runtime.h"
|
||||||
|
#include "anbox/container/configuration.h"
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
|
namespace rpc {
|
||||||
|
class PendingCallCache;
|
||||||
|
class Channel;
|
||||||
|
class MessageProcessor;
|
||||||
|
} // namespace rpc
|
||||||
|
namespace network {
|
||||||
|
class LocalSocketMessenger;
|
||||||
|
} // namespace network
|
||||||
namespace container {
|
namespace container {
|
||||||
|
class ManagementApiStub;
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
Client(const std::shared_ptr<Runtime> &rt);
|
Client(const std::shared_ptr<Runtime> &rt);
|
||||||
~Client();
|
~Client();
|
||||||
|
|
||||||
|
void start_container(const Configuration &configuration);
|
||||||
|
|
||||||
private:
|
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 container
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
32
src/anbox/container/configuration.h
Normal file
32
src/anbox/container/configuration.h
Normal 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
|
||||||
|
|
@ -18,8 +18,10 @@
|
||||||
#ifndef ANBOX_CONTAINER_CONTAINER_H_
|
#ifndef ANBOX_CONTAINER_CONTAINER_H_
|
||||||
#define ANBOX_CONTAINER_CONTAINER_H_
|
#define ANBOX_CONTAINER_CONTAINER_H_
|
||||||
|
|
||||||
|
#include "anbox/container/configuration.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <map>
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace container {
|
namespace container {
|
||||||
|
|
@ -33,7 +35,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start the container in background
|
// Start the container in background
|
||||||
virtual void start() = 0;
|
virtual void start(const Configuration &configuration) = 0;
|
||||||
|
|
||||||
// Stop a running container
|
// Stop a running container
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,14 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/capability.h>
|
#include <sys/capability.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
|
|
||||||
namespace {
|
namespace fs = boost::filesystem;
|
||||||
static constexpr char *kAndroidShellCommand{"/system/bin/ls"};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace container {
|
namespace container {
|
||||||
|
|
@ -46,16 +45,19 @@ LxcContainer::LxcContainer() :
|
||||||
config::host_android_data_path(),
|
config::host_android_data_path(),
|
||||||
config::host_android_cache_path(),
|
config::host_android_cache_path(),
|
||||||
config::host_android_storage_path(),
|
config::host_android_storage_path(),
|
||||||
config::host_input_device_path(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LxcContainer::~LxcContainer() {
|
LxcContainer::~LxcContainer() {
|
||||||
|
DEBUG("");
|
||||||
|
|
||||||
|
stop();
|
||||||
|
|
||||||
if (container_)
|
if (container_)
|
||||||
lxc_container_put(container_);
|
lxc_container_put(container_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LxcContainer::start() {
|
void LxcContainer::start(const Configuration &configuration) {
|
||||||
if (getuid() != 0)
|
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"));
|
||||||
|
|
||||||
|
|
@ -112,30 +114,21 @@ void LxcContainer::start() {
|
||||||
set_config_item("lxc.aa_profile", "unconfined");
|
set_config_item("lxc.aa_profile", "unconfined");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::map<std::string,std::string> bind_mount_dirs = {
|
for (const auto &bind_mount : configuration.bind_mounts) {
|
||||||
{ config::host_share_path(), config::container_android_share_path() },
|
std::string create_type = "file";
|
||||||
{ config::host_android_data_path(), "data" },
|
|
||||||
{ config::host_android_cache_path(), "cache" },
|
if (fs::is_directory(bind_mount.first))
|
||||||
{ config::host_android_storage_path(), "storage" },
|
create_type = "dir";
|
||||||
{ config::host_input_device_path(), "dev/input" },
|
|
||||||
};
|
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",
|
set_config_item("lxc.mount.entry",
|
||||||
utils::string_format("%s %s none bind,create=dir,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));
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!container_->save_config(container_, nullptr))
|
if (!container_->save_config(container_, nullptr))
|
||||||
|
|
@ -144,6 +137,8 @@ void LxcContainer::start() {
|
||||||
if (not container_->start(container_, 0, nullptr))
|
if (not container_->start(container_, 0, nullptr))
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to start container"));
|
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to start container"));
|
||||||
|
|
||||||
|
state_ = Container::State::running;
|
||||||
|
|
||||||
DEBUG("Container successfully started");
|
DEBUG("Container successfully started");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,6 +149,8 @@ void LxcContainer::stop() {
|
||||||
if (not container_->stop(container_))
|
if (not container_->stop(container_))
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to stop container"));
|
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to stop container"));
|
||||||
|
|
||||||
|
state_ = Container::State::inactive;
|
||||||
|
|
||||||
DEBUG("Container successfully stopped");
|
DEBUG("Container successfully stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public:
|
||||||
LxcContainer();
|
LxcContainer();
|
||||||
~LxcContainer();
|
~LxcContainer();
|
||||||
|
|
||||||
void start() override;
|
void start(const Configuration &configuration) override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
State state() override;
|
State state() override;
|
||||||
|
|
||||||
|
|
|
||||||
45
src/anbox/container/management_api_message_processor.cpp
Normal file
45
src/anbox/container/management_api_message_processor.cpp
Normal 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
|
||||||
42
src/anbox/container/management_api_message_processor.h
Normal file
42
src/anbox/container/management_api_message_processor.h
Normal 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
|
||||||
69
src/anbox/container/management_api_skeleton.cpp
Normal file
69
src/anbox/container/management_api_skeleton.cpp
Normal 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
|
||||||
60
src/anbox/container/management_api_skeleton.h
Normal file
60
src/anbox/container/management_api_skeleton.h
Normal 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
|
||||||
70
src/anbox/container/management_api_stub.cpp
Normal file
70
src/anbox/container/management_api_stub.cpp
Normal 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
|
||||||
61
src/anbox/container/management_api_stub.h
Normal file
61
src/anbox/container/management_api_stub.h
Normal 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
|
||||||
|
|
@ -20,7 +20,11 @@
|
||||||
#include "anbox/network/delegate_message_processor.h"
|
#include "anbox/network/delegate_message_processor.h"
|
||||||
#include "anbox/network/socket_messenger.h"
|
#include "anbox/network/socket_messenger.h"
|
||||||
#include "anbox/qemu/null_message_processor.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/lxc_container.h"
|
||||||
|
#include "anbox/container/management_api_message_processor.h"
|
||||||
|
#include "anbox/container/management_api_skeleton.h"
|
||||||
#include "anbox/config.h"
|
#include "anbox/config.h"
|
||||||
#include "anbox/logger.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
|
// 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(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.");
|
DEBUG("Everything setup. Waiting for incoming connections.");
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
|
|
@ -54,29 +56,7 @@ Service::Service(const std::shared_ptr<Runtime> &rt) :
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::~Service() {
|
Service::~Service() {
|
||||||
}
|
DEBUG("");
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Service::next_id() {
|
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);
|
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>(
|
auto const& connection = std::make_shared<network::SocketConnection>(
|
||||||
messenger, messenger, next_id(), connections_,
|
messenger, messenger, next_id(), connections_, processor);
|
||||||
std::make_shared<qemu::NullMessageProcessor>());
|
|
||||||
|
|
||||||
connections_->add(connection);
|
connections_->add(connection);
|
||||||
connection->read_next_message();
|
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 container
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -28,24 +28,17 @@
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace container {
|
namespace container {
|
||||||
class Service : public network::Connections<network::SocketConnection>::Observer,
|
class Service : public std::enable_shared_from_this<Service> {
|
||||||
public std::enable_shared_from_this<Service> {
|
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<Service> create(const std::shared_ptr<Runtime> &rt);
|
static std::shared_ptr<Service> create(const std::shared_ptr<Runtime> &rt);
|
||||||
|
|
||||||
Service(const std::shared_ptr<Runtime> &rt);
|
Service(const std::shared_ptr<Runtime> &rt);
|
||||||
~Service();
|
~Service();
|
||||||
|
|
||||||
void connection_added(int id) override;
|
|
||||||
void connection_removed(int id) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int next_id();
|
int next_id();
|
||||||
void new_client(std::shared_ptr<boost::asio::local::stream_protocol::socket> const &socket);
|
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<common::Dispatcher> dispatcher_;
|
||||||
std::shared_ptr<network::PublishedSocketConnector> connector_;
|
std::shared_ptr<network::PublishedSocketConnector> connector_;
|
||||||
std::atomic<int> next_connection_id_;
|
std::atomic<int> next_connection_id_;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "anbox/input/device.h"
|
#include "anbox/input/device.h"
|
||||||
#include "anbox/runtime.h"
|
#include "anbox/runtime.h"
|
||||||
#include "anbox/config.h"
|
#include "anbox/config.h"
|
||||||
|
#include "anbox/utils.h"
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@ namespace anbox {
|
||||||
namespace input {
|
namespace input {
|
||||||
Manager::Manager(const std::shared_ptr<Runtime> &runtime) :
|
Manager::Manager(const std::shared_ptr<Runtime> &runtime) :
|
||||||
runtime_(runtime) {
|
runtime_(runtime) {
|
||||||
|
utils::ensure_paths({ config::host_input_device_path() });
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::~Manager() {
|
Manager::~Manager() {
|
||||||
|
|
|
||||||
|
|
@ -80,15 +80,6 @@ void SocketConnection::on_read_size(const boost::system::error_code& error, std:
|
||||||
else
|
else
|
||||||
connections_->remove(id());
|
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 anbox
|
||||||
} // namespace network
|
} // namespace network
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ public:
|
||||||
void read_next_message();
|
void read_next_message();
|
||||||
|
|
||||||
private:
|
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);
|
void on_read_size(const boost::system::error_code& ec, std::size_t bytes_read);
|
||||||
|
|
||||||
std::shared_ptr<MessageReceiver> const message_receiver_;
|
std::shared_ptr<MessageReceiver> const message_receiver_;
|
||||||
|
|
|
||||||
15
src/anbox/protobuf/anbox_container.proto
Normal file
15
src/anbox/protobuf/anbox_container.proto
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "anbox/rpc/make_protobuf_object.h"
|
#include "anbox/rpc/make_protobuf_object.h"
|
||||||
#include "anbox/rpc/constants.h"
|
#include "anbox/rpc/constants.h"
|
||||||
#include "anbox/common/variable_length_array.h"
|
#include "anbox/common/variable_length_array.h"
|
||||||
|
#include "anbox/logger.h"
|
||||||
|
|
||||||
#include "anbox_rpc.pb.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);
|
buffer_.erase(buffer_.begin(), buffer_.begin() + header_size);
|
||||||
|
|
||||||
|
DEBUG("type %d", message_type);
|
||||||
|
|
||||||
if (message_type == MessageType::invocation) {
|
if (message_type == MessageType::invocation) {
|
||||||
anbox::protobuf::rpc::Invocation raw_invocation;
|
anbox::protobuf::rpc::Invocation raw_invocation;
|
||||||
raw_invocation.ParseFromArray(buffer_.data(), message_size);
|
raw_invocation.ParseFromArray(buffer_.data(), message_size);
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@ public:
|
||||||
|
|
||||||
void send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response);
|
void send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response);
|
||||||
|
|
||||||
virtual void dispatch(Invocation const& invocation) = 0;
|
virtual void dispatch(Invocation const& invocation) { }
|
||||||
virtual void process_event_sequence(const std::string &event) = 0;
|
virtual void process_event_sequence(const std::string &event) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<network::MessageSender> sender_;
|
std::shared_ptr<network::MessageSender> sender_;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue