From 14ad168b8ffff24f1775e497e4762d1682c544f9 Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Thu, 27 Nov 2014 16:39:33 +0100
Subject: [PATCH] Support for destroying container
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests
Change-Id: I4303284b06fdebf452a040c9dfa2c1cddc0b8abf
---
cli/command-line-interface.cpp | 11 +++
cli/command-line-interface.hpp | 7 ++
cli/main.cpp | 8 ++
client/security-containers-client-impl.cpp | 9 ++-
client/security-containers-client.cpp | 2 +-
client/security-containers-client.h | 2 +-
server/common-dbus-definitions.hpp | 2 +-
server/container-admin.cpp | 14 ++++
server/container-admin.hpp | 6 ++
server/container.cpp | 6 ++
server/container.hpp | 5 ++
server/containers-manager.cpp | 94 +++++++++++++++-------
server/containers-manager.hpp | 17 +++-
server/host-connection.cpp | 24 ++++--
server/host-connection.hpp | 15 +++-
server/host-dbus-definitions.hpp | 9 ++-
tests/unit_tests/client/ut-client.cpp | 2 +-
tests/unit_tests/server/configs/CMakeLists.txt | 9 ++-
.../empty-dbus-daemon.conf.in | 22 +++++
.../ut-containers-manager/templates/template.conf | 11 ---
.../templates/template.conf.in | 16 ++++
tests/unit_tests/server/ut-containers-manager.cpp | 83 ++++++++++++-------
22 files changed, 279 insertions(+), 95 deletions(-)
create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in
delete mode 100644 tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf
create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in
diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp
index 0549afd..b46871d 100644
--- a/cli/command-line-interface.cpp
+++ b/cli/command-line-interface.cpp
@@ -154,6 +154,17 @@ void create_domain(int pos, int argc, const char** argv)
one_shot(bind(vsm_create_domain, _1, argv[pos + 1], nullptr));
}
+void destroy_domain(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 1) {
+ throw runtime_error("Not enough parameters");
+ }
+
+ one_shot(bind(vsm_destroy_domain, _1, argv[pos + 1], 1));
+}
+
void lock_domain(int pos, int argc, const char** argv)
{
using namespace std::placeholders;
diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp
index 41f5048..360f46c 100644
--- a/cli/command-line-interface.hpp
+++ b/cli/command-line-interface.hpp
@@ -111,6 +111,13 @@ void set_active_container(int pos, int argc, const char** argv);
void create_domain(int pos, int argc, const char** argv);
/**
+ * Parses command line arguments and call vsm_destroy_domain
+ *
+ * @see vsm_destroy_domain
+ */
+void destroy_domain(int pos, int argc, const char** argv);
+
+/**
* Parses command line arguments and call vsm_lock_domain
*
* @see vsm_lock_domain
diff --git a/cli/main.cpp b/cli/main.cpp
index 774881b..0ceb1e5 100644
--- a/cli/main.cpp
+++ b/cli/main.cpp
@@ -50,6 +50,14 @@ std::map commands = {
}
},
{
+ "destroy_domain", {
+ destroy_domain,
+ "destroy_domain container_id",
+ "Destroy container",
+ {{"container_id", "id container name"}}
+ }
+ },
+ {
"lock_domain", {
lock_domain,
"lock_domain container_id",
diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp
index 0f08a02..1a6e999 100644
--- a/client/security-containers-client-impl.cpp
+++ b/client/security-containers-client-impl.cpp
@@ -450,13 +450,14 @@ VsmStatus Client::vsm_create_domain(const char* id, const char* tname) noexcept
}
GVariant* args_in = g_variant_new("(s)", id);
- return callMethod(HOST_INTERFACE, api::host::METHOD_ADD_CONTAINER, args_in);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_CONTAINER, args_in);
}
-VsmStatus Client::vsm_destroy_domain(const char*) noexcept
+VsmStatus Client::vsm_destroy_domain(const char* id) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
- return vsm_get_status();
+ assert(id);
+ GVariant* args_in = g_variant_new("(s)", id);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_DESTROY_CONTAINER, args_in);
}
VsmStatus Client::vsm_shutdown_domain(const char*) noexcept
diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp
index b96718f..ef571c8 100644
--- a/client/security-containers-client.cpp
+++ b/client/security-containers-client.cpp
@@ -158,7 +158,7 @@ API VsmStatus vsm_create_domain(VsmClient client, const char* id, const char* tn
return getClient(client).vsm_create_domain(id, tname);
}
-API VsmStatus vsm_destroy_domain(VsmClient client, const char* id)
+API VsmStatus vsm_destroy_domain(VsmClient client, const char* id, int /*force*/)
{
return getClient(client).vsm_destroy_domain(id);
}
diff --git a/client/security-containers-client.h b/client/security-containers-client.h
index b796c16..e7e738c 100644
--- a/client/security-containers-client.h
+++ b/client/security-containers-client.h
@@ -380,7 +380,7 @@ VsmStatus vsm_create_domain(VsmClient client, const char* id, const char* tname)
* @param[in] force if 0 data will be kept, otherwise data will be lost
* @return status of this function call
*/
-VsmStatus vsm_destroy_domain(VsmStatus clent, const char* id, int force);
+VsmStatus vsm_destroy_domain(VsmClient clent, const char* id, int force);
/**
* Shutdown domain
diff --git a/server/common-dbus-definitions.hpp b/server/common-dbus-definitions.hpp
index 14bb037..77d0949 100644
--- a/server/common-dbus-definitions.hpp
+++ b/server/common-dbus-definitions.hpp
@@ -32,7 +32,7 @@ namespace security_containers {
namespace api {
const std::string ERROR_FORBIDDEN = "org.tizen.containers.Error.Forbidden";
const std::string ERROR_FORWARDED = "org.tizen.containers.Error.Forwarded";
-const std::string ERROR_UNKNOWN_ID = "org.tizen.containers.Error.UnknownId";
+const std::string ERROR_INVALID_ID = "org.tizen.containers.Error.InvalidId";
const std::string ERROR_INTERNAL = "org.tizen.containers.Error.Internal";
const std::string METHOD_PROXY_CALL = "ProxyCall";
diff --git a/server/container-admin.cpp b/server/container-admin.cpp
index ef8ae0f..65179c3 100644
--- a/server/container-admin.cpp
+++ b/server/container-admin.cpp
@@ -111,6 +111,15 @@ ContainerAdmin::~ContainerAdmin()
{
LOGD(mId << ": Destroying ContainerAdmin object...");
+ if (mDestroyOnExit) {
+ if (!mDom.stop()) {
+ LOGE(mId << ": Failed to stop the container");
+ }
+ if (!mDom.destroy()) {
+ LOGE(mId << ": Failed to destroy the container");
+ }
+ }
+
if (!mDetachOnExit) {
// Try to forcefully stop
if (!mDom.stop()) {
@@ -271,6 +280,11 @@ void ContainerAdmin::setDetachOnExit()
mDetachOnExit = true;
}
+void ContainerAdmin::setDestroyOnExit()
+{
+ mDestroyOnExit = true;
+}
+
std::int64_t ContainerAdmin::getSchedulerQuota()
{
// assert(mDom);
diff --git a/server/container-admin.hpp b/server/container-admin.hpp
index 79b0193..f3c9a4f 100644
--- a/server/container-admin.hpp
+++ b/server/container-admin.hpp
@@ -116,6 +116,11 @@ public:
void setDetachOnExit();
/**
+ * Set if container should be destroyed on exit.
+ */
+ void setDestroyOnExit();
+
+ /**
* @return Scheduler CFS quota,
* TODO: this function is only for UNIT TESTS
*/
@@ -126,6 +131,7 @@ private:
lxc::LxcDomain mDom;
const std::string mId;
bool mDetachOnExit;
+ bool mDestroyOnExit;
void setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota);
};
diff --git a/server/container.cpp b/server/container.cpp
index 80decd5..c371d8a 100644
--- a/server/container.cpp
+++ b/server/container.cpp
@@ -240,6 +240,12 @@ void Container::setDetachOnExit()
}
}
+void Container::setDestroyOnExit()
+{
+ Lock lock(mReconnectMutex);
+ mAdmin->setDestroyOnExit();
+}
+
bool Container::isRunning()
{
Lock lock(mReconnectMutex);
diff --git a/server/container.hpp b/server/container.hpp
index 76e098a..bc1303c 100644
--- a/server/container.hpp
+++ b/server/container.hpp
@@ -135,6 +135,11 @@ public:
void setDetachOnExit();
/**
+ * Set if container should be destroyed on exit.
+ */
+ void setDestroyOnExit();
+
+ /**
* @return Is the container running?
*/
bool isRunning();
diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp
index def04c2..5a6a32b 100644
--- a/server/containers-manager.cpp
+++ b/server/containers-manager.cpp
@@ -101,11 +101,14 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet
mHostConnection.setSetActiveContainerCallback(bind(&ContainersManager::handleSetActiveContainerCall,
this, _1, _2));
- mHostConnection.setAddContainerCallback(bind(&ContainersManager::handleAddContainerCall,
- this, _1, _2));
+ mHostConnection.setCreateContainerCallback(bind(&ContainersManager::handleCreateContainerCall,
+ this, _1, _2));
+
+ mHostConnection.setDestroyContainerCallback(bind(&ContainersManager::handleDestroyContainerCall,
+ this, _1, _2));
for (auto& containerConfig : mConfig.containerConfigs) {
- addContainer(containerConfig);
+ createContainer(containerConfig);
}
// check if default container exists, throw ContainerOperationException if not found
@@ -143,7 +146,7 @@ ContainersManager::~ContainersManager()
LOGD("ContainersManager object destroyed");
}
-void ContainersManager::addContainer(const std::string& containerConfig)
+void ContainersManager::createContainer(const std::string& containerConfig)
{
std::string baseConfigPath = utils::dirName(mConfigPath);
std::string containerConfigPath = utils::getAbsolutePath(containerConfig, baseConfigPath);
@@ -177,6 +180,20 @@ void ContainersManager::addContainer(const std::string& containerConfig)
mContainers.insert(ContainerMap::value_type(id, std::move(c)));
}
+void ContainersManager::destroyContainer(const std::string& containerId)
+{
+ // TODO mutex for mContainers access
+ auto it = mContainers.find(containerId);
+ if (it == mContainers.end()) {
+ LOGE("Failed to destroy container " << containerId << ": no such container");
+ throw ContainerOperationException("No such container");
+ }
+
+ // TODO give back the focus
+ it->second->setDestroyOnExit();
+ mContainers.erase(it);
+}
+
void ContainersManager::focus(const std::string& containerId)
{
/* try to access the object first to throw immediately if it doesn't exist */
@@ -440,7 +457,7 @@ void ContainersManager::handleProxyCall(const std::string& caller,
ContainerMap::const_iterator targetIter = mContainers.find(target);
if (targetIter == mContainers.end()) {
LOGE("Target container '" << target << "' not found");
- result->setError(api::ERROR_UNKNOWN_ID, "Unknown proxy call target");
+ result->setError(api::ERROR_INVALID_ID, "Unknown proxy call target");
return;
}
@@ -501,7 +518,7 @@ void ContainersManager::handleGetContainerInfoCall(const std::string& id,
LOGI("GetContainerInfo call");
if (mContainers.count(id) == 0) {
LOGE("No container with id=" << id);
- result->setError(api::ERROR_UNKNOWN_ID, "No such container id");
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
return;
}
const auto& container = mContainers[id];
@@ -536,7 +553,7 @@ void ContainersManager::handleSetActiveContainerCall(const std::string& id,
auto container = mContainers.find(id);
if (container == mContainers.end()){
LOGE("No container with id=" << id );
- result->setError(api::ERROR_UNKNOWN_ID, "No such container id");
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
return;
}
@@ -597,33 +614,30 @@ void ContainersManager::generateNewConfig(const std::string& id,
fs::perms::others_read);
}
-void ContainersManager::handleAddContainerCall(const std::string& id,
- dbus::MethodResultBuilder::Pointer result)
+void ContainersManager::handleCreateContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result)
{
if (id.empty()) {
LOGE("Failed to add container - invalid name.");
- result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED,
- "Failed to add container - invalid name.");
+ result->setError(api::ERROR_INVALID_ID, "Invalid name");
return;
}
- LOGI("Adding container " << id);
+ LOGI("Creating container " << id);
// TODO: This solution is temporary. It utilizes direct access to config files when creating new
// containers. Update this handler when config database will appear.
namespace fs = boost::filesystem;
- boost::system::error_code ec;
- const std::string containerPathStr = utils::createFilePath(mConfig.containersPath, "/", id, "/");
-
// check if container does not exist
if (mContainers.find(id) != mContainers.end()) {
LOGE("Cannot create " << id << " container - already exists!");
- result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED,
- "Cannot create " + id + " container - already exists!");
+ result->setError(api::ERROR_INVALID_ID, "Already exists");
return;
}
+ const std::string containerPathStr = utils::createFilePath(mConfig.containersPath, "/", id, "/");
+
// copy container image if config contains path to image
LOGT("Image path: " << mConfig.containerImagePath);
if (!mConfig.containerImagePath.empty()) {
@@ -633,8 +647,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id,
if (!utils::launchAsRoot(copyImageContentsWrapper)) {
LOGE("Failed to copy container image.");
- result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED,
- "Failed to copy container image.");
+ result->setError(api::ERROR_INTERNAL, "Failed to copy container image.");
return;
}
}
@@ -647,7 +660,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id,
std::string configPath = utils::createFilePath(templateDir, "/", CONTAINER_TEMPLATE_CONFIG_PATH);
std::string newConfigPath = utils::createFilePath(configDir, "/containers/", id + ".conf");
- auto removeAllWrapper = [](const std::string& path) {
+ auto removeAllWrapper = [](const std::string& path) -> bool {
try {
LOGD("Removing copied data");
fs::remove_all(fs::path(path));
@@ -662,19 +675,19 @@ void ContainersManager::handleAddContainerCall(const std::string& id,
generateNewConfig(id, configPath, newConfigPath);
} catch (SecurityContainersException& e) {
- LOGE(e.what());
+ LOGE("Generate config failed: " << e.what());
utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr));
- result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, e.what());
+ result->setError(api::ERROR_INTERNAL, "Failed to generate config");
return;
}
- LOGT("Adding new container");
+ LOGT("Creating new container");
try {
- addContainer(newConfigPath);
+ createContainer(newConfigPath);
} catch (SecurityContainersException& e) {
- LOGE(e.what());
+ LOGE("Creating new container failed: " << e.what());
utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr));
- result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, e.what());
+ result->setError(api::ERROR_INTERNAL, "Failed to create container");
return;
}
@@ -685,11 +698,36 @@ void ContainersManager::handleAddContainerCall(const std::string& id,
} else {
LOGE("Failed to start container.");
// TODO removeContainer
- result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED,
- "Failed to start container.");
+ result->setError(api::ERROR_INTERNAL, "Failed to start container");
}
};
mContainers[id]->startAsync(resultCallback);
}
+void ContainersManager::handleDestroyContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result)
+{
+ if (mContainers.find(id) == mContainers.end()) {
+ LOGE("Failed to destroy container - no such container id: " << id);
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
+ return;
+ }
+
+ LOGI("Destroying container " << id);
+
+ auto destroyer = [id, result, this] {
+ try {
+ destroyContainer(id);
+ } catch (const SecurityContainersException& e) {
+ LOGE("Error during container destruction: " << e.what());
+ result->setError(api::ERROR_INTERNAL, "Failed to destroy container");
+ return;
+ }
+ result->setVoid();
+ };
+
+ std::thread thread(destroyer);
+ thread.detach(); //TODO fix it
+}
+
} // namespace security_containers
diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp
index 16a8cf5..70637bc 100644
--- a/server/containers-manager.hpp
+++ b/server/containers-manager.hpp
@@ -47,11 +47,18 @@ public:
~ContainersManager();
/**
- * Add new container.
+ * Create new container.
*
* @param containerConfig config of new container
*/
- void addContainer(const std::string& containerConfig);
+ void createContainer(const std::string& containerConfig);
+
+ /**
+ * Destroy container.
+ *
+ * @param containerId id of the container
+ */
+ void destroyContainer(const std::string& containerId);
/**
* Focus this container, put it to the foreground.
@@ -126,8 +133,10 @@ private:
void handleGetContainerInfoCall(const std::string& id, dbus::MethodResultBuilder::Pointer result);
void handleSetActiveContainerCall(const std::string& id,
dbus::MethodResultBuilder::Pointer result);
- void handleAddContainerCall(const std::string& id,
- dbus::MethodResultBuilder::Pointer result);
+ void handleCreateContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result);
+ void handleDestroyContainerCall(const std::string& id,
+ dbus::MethodResultBuilder::Pointer result);
};
diff --git a/server/host-connection.cpp b/server/host-connection.cpp
index 1b38a9c..b7d72b7 100644
--- a/server/host-connection.cpp
+++ b/server/host-connection.cpp
@@ -135,9 +135,14 @@ void HostConnection::setSetActiveContainerCallback(const SetActiveContainerCallb
mSetActiveContainerCallback = callback;
}
-void HostConnection::setAddContainerCallback(const AddContainerCallback& callback)
+void HostConnection::setCreateContainerCallback(const CreateContainerCallback& callback)
{
- mAddContainerCallback = callback;
+ mCreateContainerCallback = callback;
+}
+
+void HostConnection::setDestroyContainerCallback(const DestroyContainerCallback& callback)
+{
+ mDestroyContainerCallback = callback;
}
void HostConnection::onMessageCall(const std::string& objectPath,
@@ -220,12 +225,21 @@ void HostConnection::onMessageCall(const std::string& objectPath,
return;
}
- if (methodName == api::host::METHOD_ADD_CONTAINER) {
+ if (methodName == api::host::METHOD_CREATE_CONTAINER) {
+ const gchar* id = NULL;
+ g_variant_get(parameters, "(&s)", &id);
+
+ if (mCreateContainerCallback){
+ mCreateContainerCallback(id, result);
+ }
+ }
+
+ if (methodName == api::host::METHOD_DESTROY_CONTAINER) {
const gchar* id = NULL;
g_variant_get(parameters, "(&s)", &id);
- if (mAddContainerCallback){
- mAddContainerCallback(id, result);
+ if (mDestroyContainerCallback){
+ mDestroyContainerCallback(id, result);
}
}
}
diff --git a/server/host-connection.hpp b/server/host-connection.hpp
index 1dacd11..8392578 100644
--- a/server/host-connection.hpp
+++ b/server/host-connection.hpp
@@ -65,7 +65,10 @@ public:
)> SetActiveContainerCallback;
typedef std::function AddContainerCallback;
+ )> CreateContainerCallback;
+ typedef std::function DestroyContainerCallback;
/**
* Register proxy call callback
@@ -105,7 +108,12 @@ public:
/**
* Register a callback called to create new container
*/
- void setAddContainerCallback(const AddContainerCallback& callback);
+ void setCreateContainerCallback(const CreateContainerCallback& callback);
+
+ /**
+ * Register a callback called to destroy container
+ */
+ void setDestroyContainerCallback(const DestroyContainerCallback& callback);
/**
* Make a proxy call
@@ -129,7 +137,8 @@ private:
GetActiveContainerIdCallback mGetActiveContainerIdCallback;
GetContainerInfoCallback mGetContainerInfoCallback;
SetActiveContainerCallback mSetActiveContainerCallback;
- AddContainerCallback mAddContainerCallback;
+ CreateContainerCallback mCreateContainerCallback;
+ DestroyContainerCallback mDestroyContainerCallback;
void onNameAcquired();
void onNameLost();
diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp
index a722aee..b7b49c4 100644
--- a/server/host-dbus-definitions.hpp
+++ b/server/host-dbus-definitions.hpp
@@ -37,14 +37,14 @@ const std::string OBJECT_PATH = "/org/tizen/containers/host";
const std::string INTERFACE = "org.tizen.containers.host.manager";
const std::string ERROR_CONTAINER_STOPPED = "org.tizen.containers.host.Error.ContainersStopped";
-const std::string ERROR_CONTAINER_CREATE_FAILED = "org.tizen.containers.host.Error.ContainerCreateFailed";
const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses";
const std::string METHOD_GET_CONTAINER_ID_LIST = "GetContainerIds";
const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId";
const std::string METHOD_GET_CONTAINER_INFO = "GetContainerInfo";
const std::string METHOD_SET_ACTIVE_CONTAINER = "SetActiveContainer";
-const std::string METHOD_ADD_CONTAINER = "AddContainer";
+const std::string METHOD_CREATE_CONTAINER = "CreateContainer";
+const std::string METHOD_DESTROY_CONTAINER = "DestroyContainer";
const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState";
@@ -77,7 +77,10 @@ const std::string DEFINITION =
" "
" "
" "
- " "
+ " "
+ " "
+ " "
+ " "
" "
" "
" "
diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp
index d6b3fbb..934a062 100644
--- a/tests/unit_tests/client/ut-client.cpp
+++ b/tests/unit_tests/client/ut-client.cpp
@@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest)
vsm_client_free(client);
}
-BOOST_AUTO_TEST_CASE(AddContainerTest)
+BOOST_AUTO_TEST_CASE(CreateContainerTest)
{
const std::string newActiveContainerId = "";
diff --git a/tests/unit_tests/server/configs/CMakeLists.txt b/tests/unit_tests/server/configs/CMakeLists.txt
index 17e10a2..fc73fd4 100644
--- a/tests/unit_tests/server/configs/CMakeLists.txt
+++ b/tests/unit_tests/server/configs/CMakeLists.txt
@@ -24,7 +24,6 @@ FILE(GLOB server_container_CONF ut-server/containers/*.conf)
FILE(GLOB manager_manager_CONF ut-containers-manager/*.conf)
FILE(GLOB manager_container_CONF ut-containers-manager/containers/*.conf)
-FILE(GLOB manager_admin_TEMPLATE ut-containers-manager/templates/*.conf)
FILE(GLOB container_CONF ut-container/*.conf)
FILE(GLOB container_container_CONF ut-container/containers/*.conf)
@@ -55,6 +54,8 @@ CONFIGURE_FILE(ut-containers-manager/buggy-foreground-daemon.conf.in
${CMAKE_BINARY_DIR}/ut-containers-manager/buggy-foreground-daemon.conf @ONLY)
CONFIGURE_FILE(ut-containers-manager/test-dbus-daemon.conf.in
${CMAKE_BINARY_DIR}/ut-containers-manager/test-dbus-daemon.conf @ONLY)
+CONFIGURE_FILE(ut-containers-manager/empty-dbus-daemon.conf.in
+ ${CMAKE_BINARY_DIR}/ut-containers-manager/empty-dbus-daemon.conf @ONLY)
FILE(GLOB manager_manager_CONF_GEN ${CMAKE_BINARY_DIR}/ut-containers-manager/*.conf)
CONFIGURE_FILE(ut-containers-manager/containers/console1-dbus.conf.in
@@ -65,6 +66,10 @@ CONFIGURE_FILE(ut-containers-manager/containers/console3-dbus.conf.in
${CMAKE_BINARY_DIR}/ut-containers-manager/containers/console3-dbus.conf @ONLY)
FILE(GLOB manager_container_CONF_GEN ${CMAKE_BINARY_DIR}/ut-containers-manager/containers/*.conf)
+CONFIGURE_FILE(ut-containers-manager/templates/template.conf.in
+ ${CMAKE_BINARY_DIR}/ut-containers-manager/templates/template.conf @ONLY)
+FILE(GLOB manager_container_TEMPLATE_GEN ${CMAKE_BINARY_DIR}/ut-containers-manager/templates/*.conf)
+
## Install #####################################################################
INSTALL(FILES ${server_manager_CONF}
@@ -82,7 +87,7 @@ INSTALL(FILES ${manager_container_CONF}
DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/server/ut-containers-manager/containers)
INSTALL(FILES ${manager_container_CONF_GEN}
DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/server/ut-containers-manager/containers)
-INSTALL(FILES ${manager_admin_TEMPLATE}
+INSTALL(FILES ${manager_container_TEMPLATE_GEN}
DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/server/ut-containers-manager/templates)
INSTALL(FILES ${container_CONF}
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in
new file mode 100644
index 0000000..82f6c0e
--- /dev/null
+++ b/tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in
@@ -0,0 +1,22 @@
+{
+ "containerConfigs" : [],
+ "foregroundId" : "",
+ "defaultId" : "",
+ "containersPath" : "/tmp/ut-containers",
+ "containerImagePath" : "",
+ "containerTemplatePath" : "templates",
+ "containerNewConfigPrefix" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/",
+ "runMountPointPrefix" : "",
+ "lxcTemplatePrefix" : "@SC_TEST_LXC_TEMPLATES_INSTALL_DIR@",
+ "inputConfig" : {"enabled" : false,
+ "device" : "/dev/doesnotexist",
+ "code" : 139,
+ "numberOfEvents" : 2,
+ "timeWindowMs" : 500},
+ "proxyCallRules" : [{"caller" : "*",
+ "target" : "*",
+ "targetBusName" : "org.tizen.containers.tests",
+ "targetObjectPath" : "*",
+ "targetInterface" : "*",
+ "targetMethod" : "*"}]
+}
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf
deleted file mode 100644
index 1229c12..0000000
--- a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "privilege" : 20,
- "vt" : -1,
- "switchToDefaultAfterTimeout" : true,
- "cpuQuotaForeground" : -1,
- "cpuQuotaBackground" : 1000,
- "runMountPoint" : "/tmp/ut-containers-manager/~NAME~-dbus",
- "enableDbusIntegration" : true,
- "permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
-}
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in
new file mode 100644
index 0000000..f01cfff
--- /dev/null
+++ b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in
@@ -0,0 +1,16 @@
+{
+ "name" : "~NAME~",
+ "lxcTemplate" : "minimal-dbus1.sh",
+ "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"],
+ "ipv4Gateway" : "",
+ "ipv4" : "",
+ "privilege" : 20,
+ "vt" : -1,
+ "switchToDefaultAfterTimeout" : true,
+ "enableDbusIntegration" : true,
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000,
+ "runMountPoint" : "/tmp/ut-run1",
+ "permittedToSend" : [ "/tmp/.*" ],
+ "permittedToRecv" : [ "/tmp/.*" ]
+}
diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp
index 399cd12..46f659f 100644
--- a/tests/unit_tests/server/ut-containers-manager.cpp
+++ b/tests/unit_tests/server/ut-containers-manager.cpp
@@ -62,6 +62,7 @@ namespace {
const std::string TEST_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/test-daemon.conf";
const std::string TEST_DBUS_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/test-dbus-daemon.conf";
+const std::string EMPTY_DBUS_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/empty-dbus-daemon.conf";
const std::string BUGGY_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/buggy-daemon.conf";
const std::string BUGGY_FOREGROUND_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/buggy-foreground-daemon.conf";
const std::string BUGGY_DEFAULTID_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/buggy-default-daemon.conf";
@@ -85,7 +86,7 @@ public:
typedef std::function TestApiMethodCallback;
- typedef std::function AddContainerResultCallback;
+ typedef std::function VoidResultCallback;
typedef std::map Dbuses;
@@ -308,8 +309,8 @@ public:
}
- void callAsyncMethodAddContainer(const std::string& id,
- const AddContainerResultCallback& result)
+ void callAsyncMethodCreateContainer(const std::string& id,
+ const VoidResultCallback& result)
{
auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
@@ -321,7 +322,26 @@ public:
mClient->callMethodAsync(api::host::BUS_NAME,
api::host::OBJECT_PATH,
api::host::INTERFACE,
- api::host::METHOD_ADD_CONTAINER,
+ api::host::METHOD_CREATE_CONTAINER,
+ parameters,
+ "()",
+ asyncResult);
+ }
+
+ void callAsyncMethodDestroyContainer(const std::string& id,
+ const VoidResultCallback& result)
+ {
+ auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
+ BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
+ result();
+ };
+
+ assert(isHost());
+ GVariant* parameters = g_variant_new("(s)", id.c_str());
+ mClient->callMethodAsync(api::host::BUS_NAME,
+ api::host::OBJECT_PATH,
+ api::host::INTERFACE,
+ api::host::METHOD_DESTROY_CONTAINER,
parameters,
"()",
asyncResult);
@@ -938,32 +958,33 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest)
DbusException);
}
-//TODO fix it
-//BOOST_AUTO_TEST_CASE(AddContainerTest)
-//{
-// const std::string newContainerId = "test1234";
-// const std::vector newContainerConfigs = {
-// TEST_CONTAINER_CONF_PATH + newContainerId + ".conf",
-// };
-// FileCleanerRAII cleaner(newContainerConfigs);
-//
-// ContainersManager cm(TEST_DBUS_CONFIG_PATH);
-// cm.startAll();
-//
-// Latch callDone;
-// auto resultCallback = [&]() {
-// callDone.set();
-// };
-//
-// DbusAccessory dbus(DbusAccessory::HOST_ID);
-//
-// // create new container
-// dbus.callAsyncMethodAddContainer(newContainerId, resultCallback);
-// callDone.wait(EVENT_TIMEOUT);
-//
-// // focus new container
-// cm.focus(newContainerId);
-// BOOST_CHECK(cm.getRunningForegroundContainerId() == newContainerId);
-//}
+BOOST_AUTO_TEST_CASE(CreateDestroyContainerTest)
+{
+ const std::string newContainerId = "test1234";
+
+ ContainersManager cm(EMPTY_DBUS_CONFIG_PATH);
+ cm.startAll();
+
+ Latch callDone;
+ auto resultCallback = [&]() {
+ callDone.set();
+ };
+
+ DbusAccessory dbus(DbusAccessory::HOST_ID);
+
+ // create new container
+ dbus.callAsyncMethodCreateContainer(newContainerId, resultCallback);
+ BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+
+ // focus new container
+ cm.focus(newContainerId);
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == newContainerId);
+
+ // destroy container
+ dbus.callAsyncMethodDestroyContainer(newContainerId, resultCallback);
+ BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == "");
+}
BOOST_AUTO_TEST_SUITE_END()
--
2.7.4