From 4cb2d8abe6d102214cce7356293188c7637025ca Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Wed, 29 Oct 2014 16:48:00 +0100
Subject: [PATCH] Bind LxcDomain to the logic
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] All tests should pass
Change-Id: I212f4cfa2b377ed03c0cd08d03bba0772524da1b
---
client/utils.cpp | 19 ++-
common/lxc/domain.cpp | 4 +-
common/lxc/domain.hpp | 2 +-
server/configs/containers/business.conf | 3 +
server/configs/containers/private.conf | 3 +
server/configs/daemon.conf | 3 +-
server/container-admin.cpp | 177 ++++++++++++---------
server/container-admin.hpp | 15 +-
server/container-config.hpp | 19 +++
server/container.cpp | 8 +-
server/container.hpp | 13 +-
server/containers-manager-config.hpp | 6 +
server/containers-manager.cpp | 4 +-
tests/unit_tests/client/configs/CMakeLists.txt | 18 ++-
.../ut-client/containers/console1-dbus.conf | 11 --
.../ut-client/containers/console1-dbus.conf.in | 14 ++
.../ut-client/containers/console2-dbus.conf | 11 --
.../ut-client/containers/console2-dbus.conf.in | 14 ++
.../ut-client/containers/console3-dbus.conf | 11 --
.../ut-client/containers/console3-dbus.conf.in | 14 ++
...t-dbus-daemon.conf => test-dbus-daemon.conf.in} | 3 +-
tests/unit_tests/client/ut-client-utils.cpp | 2 +
tests/unit_tests/client/ut-client.cpp | 13 +-
tests/unit_tests/lxc/templates/minimal-dbus1.sh | 68 ++++++++
tests/unit_tests/lxc/templates/minimal-dbus2.sh | 68 ++++++++
tests/unit_tests/lxc/templates/minimal-dbus3.sh | 68 ++++++++
tests/unit_tests/lxc/ut-domain.cpp | 6 +-
tests/unit_tests/server/configs/CMakeLists.txt | 38 +++++
.../configs/ut-container/containers/buggy.conf | 3 +
.../configs/ut-container/containers/test-dbus.conf | 11 --
.../ut-container/containers/test-dbus.conf.in | 14 ++
.../configs/ut-container/containers/test.conf | 3 +
.../server/configs/ut-container/ut-dbus.conf | 2 +-
.../{buggy-daemon.conf => buggy-daemon.conf.in} | 5 +-
...lt-daemon.conf => buggy-default-daemon.conf.in} | 5 +-
...daemon.conf => buggy-foreground-daemon.conf.in} | 5 +-
.../containers/console1-dbus.conf | 11 --
.../containers/console1-dbus.conf.in | 14 ++
.../ut-containers-manager/containers/console1.conf | 3 +
.../containers/console2-dbus.conf | 11 --
.../containers/console2-dbus.conf.in | 14 ++
.../ut-containers-manager/containers/console2.conf | 3 +
.../containers/console3-dbus.conf | 11 --
.../containers/console3-dbus.conf.in | 14 ++
.../ut-containers-manager/containers/console3.conf | 3 +
.../{test-daemon.conf => test-daemon.conf.in} | 5 +-
...t-dbus-daemon.conf => test-dbus-daemon.conf.in} | 5 +-
.../configs/ut-containers-manager/ut-dbus.conf | 2 +-
.../{buggy-daemon.conf => buggy-daemon.conf.in} | 5 +-
.../configs/ut-server/containers/container1.conf | 3 +
.../configs/ut-server/containers/container2.conf | 3 +
.../configs/ut-server/containers/container3.conf | 3 +
.../{test-daemon.conf => test-daemon.conf.in} | 3 +-
tests/unit_tests/server/ut-container.cpp | 43 +++--
tests/unit_tests/server/ut-containers-manager.cpp | 132 +++++++--------
tests/unit_tests/server/ut-network-admin.cpp | 114 ++++++-------
tests/unit_tests/server/ut-server.cpp | 24 ++-
tests/unit_tests/utils/scoped-dir.cpp | 70 ++++++++
tests/unit_tests/utils/scoped-dir.hpp | 64 ++++++++
59 files changed, 903 insertions(+), 340 deletions(-)
delete mode 100644 tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf
create mode 100644 tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf.in
delete mode 100644 tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf
create mode 100644 tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf.in
delete mode 100644 tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf
create mode 100644 tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf.in
rename tests/unit_tests/client/configs/ut-client/{test-dbus-daemon.conf => test-dbus-daemon.conf.in} (89%)
create mode 100755 tests/unit_tests/lxc/templates/minimal-dbus1.sh
create mode 100755 tests/unit_tests/lxc/templates/minimal-dbus2.sh
create mode 100755 tests/unit_tests/lxc/templates/minimal-dbus3.sh
delete mode 100644 tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf
create mode 100644 tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf.in
rename tests/unit_tests/server/configs/ut-containers-manager/{buggy-daemon.conf => buggy-daemon.conf.in} (73%)
rename tests/unit_tests/server/configs/ut-containers-manager/{buggy-default-daemon.conf => buggy-default-daemon.conf.in} (73%)
rename tests/unit_tests/server/configs/ut-containers-manager/{buggy-foreground-daemon.conf => buggy-foreground-daemon.conf.in} (73%)
delete mode 100644 tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf
create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf.in
delete mode 100644 tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf
create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf.in
delete mode 100644 tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf
create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf.in
rename tests/unit_tests/server/configs/ut-containers-manager/{test-daemon.conf => test-daemon.conf.in} (73%)
rename tests/unit_tests/server/configs/ut-containers-manager/{test-dbus-daemon.conf => test-dbus-daemon.conf.in} (81%)
rename tests/unit_tests/server/configs/ut-server/{buggy-daemon.conf => buggy-daemon.conf.in} (84%)
rename tests/unit_tests/server/configs/ut-server/{test-daemon.conf => test-daemon.conf.in} (84%)
create mode 100644 tests/unit_tests/utils/scoped-dir.cpp
create mode 100644 tests/unit_tests/utils/scoped-dir.hpp
diff --git a/client/utils.cpp b/client/utils.cpp
index 98b6905..d6157c4 100644
--- a/client/utils.cpp
+++ b/client/utils.cpp
@@ -30,12 +30,23 @@
namespace {
const std::string CPUSET_HOST = "/";
+const std::string CPUSET_LXC_PREFIX = "/lxc/";
const std::string CPUSET_LIBVIRT_PREFIX_OLD = "/machine/";
const std::string CPUSET_LIBVIRT_SUFFIX_OLD = ".libvirt-lxc";
const std::string CPUSET_LIBVIRT_PREFIX = "/machine.slice/machine-lxc\\x2d";
const std::string CPUSET_LIBVIRT_SUFFIX = ".scope";
-bool parseOldFormat(const std::string& cpuset, std::string& id)
+bool parseLxcFormat(const std::string& cpuset, std::string& id)
+{
+ // /lxc/
+ if (!boost::starts_with(cpuset, CPUSET_LXC_PREFIX)) {
+ return false;
+ }
+ id.assign(cpuset, CPUSET_LXC_PREFIX.size(), cpuset.size() - CPUSET_LXC_PREFIX.size());
+ return true;
+}
+
+bool parseOldLibvirtFormat(const std::string& cpuset, std::string& id)
{
// '/machine/.libvirt-lxc'
if (!boost::starts_with(cpuset, CPUSET_LIBVIRT_PREFIX_OLD)) {
@@ -87,7 +98,7 @@ void unescape(std::string& value)
value.resize(outPos);
}
-bool parseNewFormat(const std::string& cpuset, std::string& id)
+bool parseNewLibvirtFormat(const std::string& cpuset, std::string& id)
{
// '/machine.slice/machine-lxc\x2d.scope'
if (!boost::starts_with(cpuset, CPUSET_LIBVIRT_PREFIX)) {
@@ -113,6 +124,8 @@ bool parseContainerIdFromCpuSet(const std::string& cpuset, std::string& id)
return true;
}
- return parseNewFormat(cpuset, id) || parseOldFormat(cpuset, id);
+ return parseLxcFormat(cpuset, id) ||
+ parseNewLibvirtFormat(cpuset, id) ||
+ parseOldLibvirtFormat(cpuset, id);
}
diff --git a/common/lxc/domain.cpp b/common/lxc/domain.cpp
index 2e70eee..07b7c77 100644
--- a/common/lxc/domain.cpp
+++ b/common/lxc/domain.cpp
@@ -96,9 +96,9 @@ void LxcDomain::destroy()
}
}
-void LxcDomain::start(const char* argv[])
+void LxcDomain::start(const char* const* argv)
{
- if (!mContainer->start(mContainer, false, const_cast(argv))) {
+ if (!mContainer->start(mContainer, false, const_cast(argv))) {
LOGE("Could not start domain " + getName());
throw LxcException("Could not start domain");
}
diff --git a/common/lxc/domain.hpp b/common/lxc/domain.hpp
index 53049a0..2f0cbf8 100644
--- a/common/lxc/domain.hpp
+++ b/common/lxc/domain.hpp
@@ -57,7 +57,7 @@ public:
void create(const std::string& templatePath);
void destroy();
- void start(const char* argv[]);
+ void start(const char* const* argv);
void stop();
void reboot();
void shutdown(int timeout);
diff --git a/server/configs/containers/business.conf b/server/configs/containers/business.conf
index c7b1fb4..c141111 100644
--- a/server/configs/containers/business.conf
+++ b/server/configs/containers/business.conf
@@ -1,4 +1,7 @@
{
+ "name" : "business",
+ "lxcTemplate" : "",
+ "initWithArgs" : [],
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 10000,
"enableDbusIntegration" : true,
diff --git a/server/configs/containers/private.conf b/server/configs/containers/private.conf
index a741c64..94261b8 100644
--- a/server/configs/containers/private.conf
+++ b/server/configs/containers/private.conf
@@ -1,4 +1,7 @@
{
+ "name" : "private",
+ "lxcTemplate" : "",
+ "initWithArgs" : [],
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 10000,
"enableDbusIntegration" : true,
diff --git a/server/configs/daemon.conf b/server/configs/daemon.conf
index dbfac95..116b32e 100644
--- a/server/configs/daemon.conf
+++ b/server/configs/daemon.conf
@@ -1,5 +1,5 @@
{
- "containerConfigs" : ["containers/private.conf", "containers/business.conf" ],
+ "containerConfigs" : ["containers/private.conf", "containers/business.conf"],
"containersPath" : "/opt/usr/containers",
"containerImagePath" : "/opt/usr/containers/img/system-data.img",
"containerTemplatePath" : "templates",
@@ -7,6 +7,7 @@
"runMountPointPrefix" : "/var/run/containers",
"foregroundId" : "private",
"defaultId" : "private",
+ "lxcTemplatePrefix" : "TODO",
"inputConfig" : {"enabled" : true,
"device" : "gpio_keys.6",
"code" : 139,
diff --git a/server/container-admin.cpp b/server/container-admin.cpp
index a54d00a..11c88fd 100644
--- a/server/container-admin.cpp
+++ b/server/container-admin.cpp
@@ -27,9 +27,9 @@
#include "container-admin.hpp"
#include "exception.hpp"
-//#include "libvirt/helpers.hpp"
#include "logger/logger.hpp"
#include "utils/fs.hpp"
+#include "utils/paths.hpp"
#include "utils/latch.hpp"
#include "utils/callback-wrapper.hpp"
@@ -47,36 +47,62 @@ namespace {
// TODO: this should be in container's configuration file
const int SHUTDOWN_WAIT = 10 * 1000;
-//std::string getDomainName(virDomainPtr dom)
-//{
-// assert(dom);
-//
-// const char* name = virDomainGetName(dom);
-// if (name == nullptr) {
-// LOGE("Failed to get the domain's id:\n"
-// << libvirt::libvirtFormatError());
-// throw ContainerOperationException();
-// }
-//
-// return name;
-//}
+class Args {
+public:
+ Args(const std::vector& args)
+ {
+ mArgs.reserve(args.size() + 1);
+ for (const std::string& arg : args) {
+ mArgs.push_back(arg.c_str());
+ }
+ mArgs.push_back(NULL);
+ }
+ bool empty() const
+ {
+ return mArgs.size() == 1;
+ }
+ const char* const* getAsCArray() const
+ {
+ return mArgs.data();
+ }
+ friend std::ostream& operator<<(std::ostream& os, const Args& a)
+ {
+ for (const char* arg : a.mArgs) {
+ if (arg != NULL) {
+ os << "'" << arg << "' ";
+ }
+ }
+ return os;
+ }
+private:
+ std::vector mArgs;
+};
} // namespace
const std::uint64_t DEFAULT_CPU_SHARES = 1024;
const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000;
-ContainerAdmin::ContainerAdmin(const ContainerConfig& config)
+ContainerAdmin::ContainerAdmin(const std::string& containersPath,
+ const std::string& lxcTemplatePrefix,
+ const ContainerConfig& config)
: mConfig(config),
- //mDom(utils::readFileContent(mConfig.config)),
- mId("TODO"),//mId(getDomainName(mDom.get())),
+ mDom(containersPath, config.name),
+ mId(mDom.getName()),
mDetachOnExit(false),
mLifecycleCallbackId(-1),
mRebootCallbackId(-1),
mNextIdForListener(1)
{
-// LOGD(mId << ": Instantiating ContainerAdmin object");
-//
+ LOGD(mId << ": Instantiating ContainerAdmin object");
+
+ if (!mDom.isDefined()) {
+
+ std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate, lxcTemplatePrefix);
+ LOGI(mId << ": Creating domain from template: " << lxcTemplate);
+ mDom.create(lxcTemplate);
+ }
+
// // ContainerAdmin owns those callbacks
// mLifecycleCallbackId = virConnectDomainEventRegisterAny(virDomainGetConnect(mDom.get()),
// mDom.get(),
@@ -112,8 +138,8 @@ ContainerAdmin::ContainerAdmin(const ContainerConfig& config)
ContainerAdmin::~ContainerAdmin()
{
-// LOGD(mId << ": Destroying ContainerAdmin object...");
-//
+ LOGD(mId << ": Destroying ContainerAdmin object...");
+
// // Deregister callbacks
// if (mLifecycleCallbackId >= 0) {
// virConnectDomainEventDeregisterAny(virDomainGetConnect(mDom.get()),
@@ -124,16 +150,16 @@ ContainerAdmin::~ContainerAdmin()
// mRebootCallbackId);
// }
//
-// // Try to forcefully stop
-// if (!mDetachOnExit) {
-// try {
-// destroy();
-// } catch (ServerException&) {
-// LOGE(mId << ": Failed to destroy the container");
-// }
-// }
-//
-// LOGD(mId << ": ContainerAdmin object destroyed");
+ // Try to forcefully stop
+ if (!mDetachOnExit) {
+ try {
+ destroy();
+ } catch (ServerException&) {
+ LOGE(mId << ": Failed to destroy the container");
+ }
+ }
+
+ LOGD(mId << ": ContainerAdmin object destroyed");
}
@@ -145,14 +171,20 @@ const std::string& ContainerAdmin::getId() const
void ContainerAdmin::start()
{
-// assert(mDom);
-//
-// LOGD(mId << ": Starting...");
-// if (isRunning()) {
-// LOGD(mId << ": Already running - nothing to do...");
-// return;
-// }
-//
+ LOGD(mId << ": Starting...");
+ if (isRunning()) {
+ LOGD(mId << ": Already running - nothing to do...");
+ return;
+ }
+
+ Args args(mConfig.initWithArgs);
+ if (args.empty()) {
+ mDom.start(NULL);
+ } else {
+ LOGD(mId << ": Init: " << args);
+ mDom.start(args.getAsCArray());
+ }
+
// // In order to update daemon without shutting down the containers
// // autodestroy option must NOT be set. It's best to create domain
// // without any flags.
@@ -164,20 +196,20 @@ void ContainerAdmin::start()
// throw ContainerOperationException();
// }
//
-// LOGD(mId << ": Started");
+ LOGD(mId << ": Started");
}
void ContainerAdmin::stop()
{
-// assert(mDom);
-//
-// LOGD(mId << ": Stopping procedure started...");
-// if (isStopped()) {
-// LOGD(mId << ": Already crashed/down/off - nothing to do");
-// return;
-// }
-//
+ LOGD(mId << ": Stopping procedure started...");
+ if (isStopped()) {
+ LOGD(mId << ": Already crashed/down/off - nothing to do");
+ return;
+ }
+
+ mDom.stop();
+
// utils::Latch stoppedOccured;
//
// LifecycleListener setStopped = [&](const int eventId, const int detailId) {
@@ -200,20 +232,20 @@ void ContainerAdmin::stop()
// destroy();
// }
//
-// LOGD(mId << ": Stopping procedure ended");
+ LOGD(mId << ": Stopping procedure ended");
}
void ContainerAdmin::destroy()
{
-// assert(mDom);
-//
-// LOGD(mId << ": Destroying...");
-// if (isStopped()) {
-// LOGD(mId << ": Already crashed/down/off - nothing to do");
-// return;
-// }
-//
+ LOGD(mId << ": Destroying...");
+ if (isStopped()) {
+ LOGD(mId << ": Already crashed/down/off - nothing to do");
+ return;
+ }
+
+ mDom.stop();//TODO
+
// setSchedulerLevel(SchedulerLevel::FOREGROUND);
//
// // Forceful termination of the guest
@@ -225,20 +257,20 @@ void ContainerAdmin::destroy()
// throw ContainerOperationException();
// }
//
-// LOGD(mId << ": Destroyed");
+ LOGD(mId << ": Destroyed");
}
void ContainerAdmin::shutdown()
{
-// assert(mDom);
-//
-// LOGD(mId << ": Shutting down...");
-// if (isStopped()) {
-// LOGD(mId << ": Already crashed/down/off - nothing to do");
-// return;
-// }
-//
+ LOGD(mId << ": Shutting down...");
+ if (isStopped()) {
+ LOGD(mId << ": Already crashed/down/off - nothing to do");
+ return;
+ }
+
+ mDom.stop(); //TODO
+
// setSchedulerLevel(SchedulerLevel::FOREGROUND);
//
// if (virDomainShutdownFlags(mDom.get(), VIR_DOMAIN_SHUTDOWN_SIGNAL) < 0) {
@@ -247,24 +279,19 @@ void ContainerAdmin::shutdown()
// throw ContainerOperationException();
// }
//
-// LOGD(mId << ": Shut down initiated (async)");
+ LOGD(mId << ": Shut down initiated (async)");
}
bool ContainerAdmin::isRunning()
{
-// return getState() == VIR_DOMAIN_RUNNING;
- return false;
+ return mDom.isRunning();
}
bool ContainerAdmin::isStopped()
{
-// int state = getState();
-// return state == VIR_DOMAIN_SHUTDOWN ||
-// state == VIR_DOMAIN_SHUTOFF ||
-// state == VIR_DOMAIN_CRASHED;
- return false;
+ return !mDom.isRunning();//TODO
}
@@ -311,7 +338,7 @@ void ContainerAdmin::resume()
bool ContainerAdmin::isPaused()
{
// return getState() == VIR_DOMAIN_PAUSED;
- return false;
+ return false;//TODO
}
diff --git a/server/container-admin.hpp b/server/container-admin.hpp
index 1ee6027..f2ca5f9 100644
--- a/server/container-admin.hpp
+++ b/server/container-admin.hpp
@@ -30,8 +30,7 @@
#include "utils/callback-guard.hpp"
#include "utils/callback-wrapper.hpp"
-//#include "libvirt/connection.hpp"
-//#include "libvirt/domain.hpp"
+#include "lxc/domain.hpp"
#include