SET(SCRIPT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/sbin")
ENDIF(NOT DEFINED SCRIPT_INSTALL_DIR)
-SET(SC_CONFIG_INSTALL_DIR ${SYSCONF_INSTALL_DIR}/security-containers/config)
+SET(SC_CONFIG_INSTALL_DIR ${SYSCONF_INSTALL_DIR}/security-containers)
ADD_SUBDIRECTORY(src)
indent=spaces=4
indent-col1-comments
min-conditional-indent=2
-max-instatement-indent=40
+max-instatement-indent=100
pad-oper
pad-header
unpad-paren
%files
%attr(755,root,root) %{_bindir}/security-containers-server
-%config %attr(644,root,root) /etc/security-containers/config/daemon.conf
-%config %attr(644,root,root) /etc/security-containers/config/containers/xminimal.conf
-%config %attr(400,root,root) /etc/security-containers/config/libvirt-config/*.xml
+%config %attr(644,root,root) /etc/security-containers/daemon.conf
+%config %attr(644,root,root) /etc/security-containers/containers/xminimal.conf
+%config %attr(400,root,root) /etc/security-containers/libvirt-config/*.xml
%prep
%setup -q
%attr(755,root,root) %{script_dir}/sc_all_tests.py
%attr(755,root,root) %{script_dir}/sc_launch_test.py
%{script_dir}/sc_test_parser.py
-%config %attr(644,root,root) /etc/security-containers/config/tests/ut-scs-container-manager/*.conf
-%config %attr(644,root,root) /etc/security-containers/config/tests/ut-scs-container-manager/containers/*.conf
-%config %attr(644,root,root) /etc/security-containers/config/tests/ut-scs-container-manager/libvirt-config/*.xml
-%config %attr(644,root,root) /etc/security-containers/config/tests/ut-dbus-connection/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container-manager/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container-manager/containers/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container-manager/libvirt-config/*.xml
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container/containers/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container/libvirt-config/*.xml
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container-admin/containers/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/ut-scs-container-admin/libvirt-config/*.xml
+%config %attr(644,root,root) /etc/security-containers/tests/ut-dbus-connection/*.conf
{
+ "cpuQuotaForeground" : 1,
+ "cpuQuotaBackground" : 0.01,
"privilege" : 10,
"config" : "../libvirt-config/xminimal.xml"
}
#ifndef SECURITY_CONTAINERS_SERVER_CONTAINER_ADMIN_HPP
#define SECURITY_CONTAINERS_SERVER_CONTAINER_ADMIN_HPP
+#include "scs-container-config.hpp"
+
#include <string>
+#include <cstdint>
#include <libvirt/libvirt.h>
namespace security_containers {
+enum class SchedulerLevel {
+ FOREGROUND,
+ BACKGROUND
+};
+
class ContainerAdmin {
public:
- ContainerAdmin(const std::string& libvirtConfigPath);
+ ContainerAdmin(ContainerConfig& config);
virtual ~ContainerAdmin();
/**
std::string getId();
/**
- * Boot the container
+ * Boot the container to the background.
*/
void start();
void shutdown();
/**
- * @return Is the process started?
+ * @return Is the container running?
*/
bool isRunning();
* because it checks different internal libvirt's states. There are other states,
* (e.g. paused) when the container isn't runnig nor stopped.
*
- * @return Is the process stopped?
+ * @return Is the container stopped?
*/
bool isStopped();
*/
bool isPaused();
+ /**
+ * Sets the containers scheduler CFS quota.
+ */
+ void setSchedulerLevel(SchedulerLevel sched);
+
+ /**
+ * @return Scheduler CFS quota,
+ * TODO: this function is only for UNIT TESTS
+ */
+ std::int64_t getSchedulerQuota();
+
private:
// TODO: secure those pointers from exceptions (e.g. in constructor)
virConnectPtr mVir = NULL; // pointer to the connection with libvirt
virDomainPtr mDom = NULL; // pointer to the domain
+ ContainerConfig& mConfig;
+
// TODO: This is a temporary sollution.
const std::string mDefaultConfigXML = "<domain type=\"lxc\">\
<name>cnsl</name>\
void disconnect(); // release mVir
void define(const std::string& configXML); // containers can't share the same libvirt configuration
void undefine();
-
int getState(); // get the libvirt's domain state
- bool isPMSuspended(); // the cotainer suspended by the power manager
+ void setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota);
};
}
#endif // SECURITY_CONTAINERS_SERVER_CONTAINER_ADMIN_HPP
*/
std::string config;
+ /**
+ * Container's CFS quota in us when it's in the foreground
+ */
+ double cpuQuotaForeground;
+
+ /**
+ * Container's CFS quota in us when it's in the background
+ */
+ double cpuQuotaBackground;
+
CONFIG_REGISTER {
CONFIG_VALUE(privilege)
CONFIG_VALUE(config)
+ CONFIG_VALUE(cpuQuotaForeground)
+ CONFIG_VALUE(cpuQuotaBackground)
}
};
*/
std::vector<std::string> containerConfigs;
+ /**
+ * An ID of a currently focused/foreground container.
+ */
+ std::string foregroundId;
+
CONFIG_REGISTER {
CONFIG_VALUE(containerConfigs)
+ CONFIG_VALUE(foregroundId)
}
};
~ContainerManager();
/**
- * Switch to this container.
+ * Focus this container, put it to the foreground.
* Method blocks until the focus is switched.
*
* @param containerId id of the container
void stopAll();
/**
- * @return id of the currently running container
+ * @return id of the currently focused/foreground container
*/
- std::string getRunningContainerId();
-
- /**
- * @return vector of suspended container ids
- */
- std::vector<std::string> getSuspendedContainerIds();
+ std::string getRunningForegroundContainerId();
private:
ContainerManagerConfig mConfig;
// TODO: secure this pointer from exceptions (e.g. in constructor)
virConnectPtr mVir = NULL; // pointer to the connection with libvirt
- std::unordered_map<std::string, std::unique_ptr<Container>> mContainers; // map of containers, id is the key
+ typedef std::unordered_map<std::string, std::unique_ptr<Container>> ContainerMap;
+ ContainerMap mContainers; // map of containers, id is the key
void connect();
void disconnect();
Container(Container&&) = default;
virtual ~Container();
- ContainerAdmin& getAdmin();
+ /**
+ * Get the container id
+ */
+ std::string getId();
+
+ /**
+ * Get the container privilege
+ */
+ int getPrivilege();
+
+ /**
+ * Boot the container to the background.
+ */
+ void start();
+
+ /**
+ * Forcefully stop the container.
+ */
+ void stop();
+
+ /**
+ * Setup this container to be put in the foreground.
+ * I.e. set appropriate scheduler level.
+ */
+ void goForeground();
+
+ /**
+ * Setup this container to be put in the background.
+ * I.e. set appropriate scheduler level.
+ */
+ void goBackground();
+
+ /**
+ * @return Is the container running?
+ */
+ bool isRunning();
+
+ /**
+ * Check if the container is stopped. It's NOT equivalent to !isRunning,
+ * because it checks different internal libvirt's states. There are other states,
+ * (e.g. paused) when the container isn't runnig nor stopped.
+ *
+ * @return Is the container stopped?
+ */
+ bool isStopped();
+
+ /**
+ * @return Is the container in a paused state?
+ */
+ bool isPaused();
private:
ContainerConfig mConfig;
#include <string>
#include <fstream>
#include <streambuf>
+#include <memory>
+#include <cstdint>
namespace security_containers {
-ContainerAdmin::ContainerAdmin(const std::string& libvirtConfigPath)
+const std::uint64_t DEFAULT_CPU_SHARES = 1024;
+const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000;
+
+ContainerAdmin::ContainerAdmin(ContainerConfig& config)
+ : mConfig(config)
{
connect();
- std::ifstream t(libvirtConfigPath);
+ std::ifstream t(mConfig.config);
if (!t.is_open()) {
LOGE("libvirt config file is missing");
throw ConfigException();
{
// Try to shutdown
try {
- resume();
shutdown();
} catch (ServerException& e) {}
LOGE("Failed to start the container");
throw DomainOperationException();
}
+
+ // TODO: the container should be started in the background,
+ // unfortunately libvirt doesn't allow us to set cgroups
+ // before the start, hence we do it immediately afterwards
+ setSchedulerLevel(SchedulerLevel::BACKGROUND);
}
assert(mVir != NULL);
assert(mDom != NULL);
- if (!isRunning()) {
+ if (isStopped()) {
return;
}
assert(mVir != NULL);
assert(mDom != NULL);
- if (!isRunning()) {
+ if (isStopped()) {
return;
}
+ resume();
+
if (virDomainShutdown(mDom) < 0) {
LOGE("Error during domain shutdown");
throw DomainOperationException();
return;
}
- if (isPMSuspended() || virDomainSuspend(mDom) < 0) {
+ if (virDomainSuspend(mDom) < 0) {
LOGE("Error during domain suspension");
throw DomainOperationException();
}
return;
}
- if (isPMSuspended() || virDomainResume(mDom) < 0) {
+ if (virDomainResume(mDom) < 0) {
LOGE("Error during domain resumming");
throw DomainOperationException();
}
}
-bool ContainerAdmin::isPMSuspended()
-{
- return getState() == VIR_DOMAIN_PMSUSPENDED;
-}
-
-
int ContainerAdmin::getState()
{
assert(mVir != NULL);
return state;
}
+
+void ContainerAdmin::setSchedulerLevel(SchedulerLevel sched)
+{
+ switch (sched) {
+ case SchedulerLevel::FOREGROUND:
+ setSchedulerParams(DEFAULT_CPU_SHARES,
+ DEFAULT_VCPU_PERIOD_MS,
+ mConfig.cpuQuotaForeground);
+ break;
+ case SchedulerLevel::BACKGROUND:
+ setSchedulerParams(DEFAULT_CPU_SHARES,
+ DEFAULT_VCPU_PERIOD_MS,
+ mConfig.cpuQuotaBackground);
+ break;
+ default:
+ assert(!"Unknown sched parameter value");
+ }
+}
+
+
+void ContainerAdmin::setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota)
+{
+ assert(mVir != NULL);
+ assert(mDom != NULL);
+
+ int maxParams = 3;
+ int numParamsBuff = 0;
+
+ std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[maxParams]);
+
+ virTypedParameterPtr paramsTmp = params.get();
+
+ virTypedParamsAddULLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_CPU_SHARES, cpuShares);
+ virTypedParamsAddULLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, vcpuPeriod);
+ virTypedParamsAddLLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
+
+ if (virDomainSetSchedulerParameters(mDom, params.get(), numParamsBuff) < 0) {
+ LOGE("Error whilte setting scheduler params");
+ throw DomainOperationException();
+ }
+}
+
+
+std::int64_t ContainerAdmin::getSchedulerQuota()
+{
+ assert(mVir != NULL);
+ assert(mDom != NULL);
+
+ int numParamsBuff;
+ std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mDom, &numParamsBuff), free);
+
+ if (type == NULL || numParamsBuff <= 0 || strcmp(type.get(), "posix") != 0) {
+ LOGE("Error while getting scheduler type");
+ throw DomainOperationException();
+ }
+
+ std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
+
+ if (virDomainGetSchedulerParameters(mDom, params.get(), &numParamsBuff) < 0) {
+ LOGE("Error whilte getting scheduler parameters");
+ throw DomainOperationException();
+ }
+
+ long long quota;
+ if (virTypedParamsGetLLong(params.get(),
+ numParamsBuff,
+ VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
+ "a) <= 0) {
+ LOGE("Error whilte getting scheduler quota parameter");
+ throw DomainOperationException();
+ }
+
+ return quota;
+}
+
} // namespace security_containers
#include <assert.h>
#include <string>
+#include <climits>
namespace security_containers {
+
ContainerManager::ContainerManager(const std::string& managerConfigPath)
{
mConfig.parseFile(managerConfigPath);
LOGT("Creating Container " << containerConfigPath);
std::unique_ptr<Container> c(new Container(containerConfigPath));
- std::string id = c->getAdmin().getId();
+ std::string id = c->getId();
mContainers.emplace(id, std::move(c));
}
}
void ContainerManager::focus(const std::string& containerId)
{
+ /* try to access the object first to throw immediately if it doesn't exist */
+ ContainerMap::mapped_type& foregroundContainer = mContainers.at(containerId);
+
for (auto& container : mContainers) {
- container.second->getAdmin().suspend();
+ container.second->goBackground();
}
- mContainers.at(containerId)->getAdmin().resume();
+ mConfig.foregroundId = foregroundContainer->getId();
+ foregroundContainer->goForeground();
}
void ContainerManager::startAll()
{
+ bool isForegroundFound = false;
+
for (auto& container : mContainers) {
- container.second->getAdmin().start();
+ container.second->start();
+
+ if (container.first == mConfig.foregroundId) {
+ isForegroundFound = true;
+ container.second->goForeground();
+ }
}
-}
+ if (!isForegroundFound) {
+ auto foregroundIterator = std::min_element(mContainers.begin(), mContainers.end(),
+ [](ContainerMap::value_type &c1, ContainerMap::value_type &c2) {
+ return c1.second->getPrivilege() < c2.second->getPrivilege();
+ });
-void ContainerManager::stopAll()
-{
- for (auto& container : mContainers) {
- container.second->getAdmin().stop();
+ mConfig.foregroundId = foregroundIterator->second->getId();
+ foregroundIterator->second->goForeground();
}
}
-std::string ContainerManager::getRunningContainerId()
+void ContainerManager::stopAll()
{
for (auto& container : mContainers) {
- if (container.second->getAdmin().isRunning()) {
- return container.first;
- }
+ container.second->stop();
}
- return "";
}
-std::vector<std::string> ContainerManager::getSuspendedContainerIds()
+std::string ContainerManager::getRunningForegroundContainerId()
{
- std::vector<std::string> retContainerIds;
for (auto& container : mContainers) {
- if (container.second->getAdmin().isPaused()) {
- retContainerIds.push_back(container.first);
+ if (container.first == mConfig.foregroundId &&
+ container.second->isRunning()) {
+ return container.first;
}
}
- return retContainerIds;
+ return "";
}
libvirtConfigPath = utils::createFilePath(baseConfigPath, "/", mConfig.config);
}
- LOGT("Creating Container Admin " << libvirtConfigPath);
- mAdmin.reset(new ContainerAdmin(libvirtConfigPath));
+ mConfig.config = libvirtConfigPath;
+ LOGT("Creating Container Admin " << mConfig.config);
+ mAdmin.reset(new ContainerAdmin(mConfig));
}
{
}
-ContainerAdmin& Container::getAdmin()
+
+std::string Container::getId()
{
- assert(mAdmin.get() != NULL);
+ return mAdmin->getId();
+}
+
- return *mAdmin;
+int Container::getPrivilege()
+{
+ return mConfig.privilege;
}
+
+void Container::start()
+{
+ return mAdmin->start();
+}
+
+
+void Container::stop()
+{
+ return mAdmin->stop();
+}
+
+
+void Container::goForeground()
+{
+ mAdmin->setSchedulerLevel(SchedulerLevel::FOREGROUND);
+}
+
+
+void Container::goBackground()
+{
+ mAdmin->setSchedulerLevel(SchedulerLevel::BACKGROUND);
+}
+
+
+bool Container::isRunning()
+{
+ return mAdmin->isRunning();
+}
+
+
+bool Container::isStopped()
+{
+ return mAdmin->isStopped();
+}
+
+
+bool Container::isPaused()
+{
+ return mAdmin->isPaused();
+}
+
+
} // namespace security_containers
## Install #####################################################################
INSTALL(TARGETS ${UT_SERVER_CODENAME} DESTINATION bin)
-FILE(GLOB manager_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/*.conf)
-FILE(GLOB container_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/containers/*.conf)
-FILE(GLOB containeradmin_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/libvirt-config/*.xml)
-FILE(GLOB dbus_CONF ${SERVER_FOLDER}/unit_tests/config/ut-dbus-connection/*.conf)
+FILE(GLOB manager_manager_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/*.conf)
+FILE(GLOB manager_container_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/containers/*.conf)
+FILE(GLOB manager_admin_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/libvirt-config/*.xml)
-INSTALL(FILES ${manager_CONF}
+FILE(GLOB container_container_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container/containers/*.conf)
+FILE(GLOB container_admin_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container/libvirt-config/*.xml)
+
+FILE(GLOB admin_container_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-admin/containers/*.conf)
+FILE(GLOB admin_admin_CONF ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-admin/libvirt-config/*.xml)
+
+FILE(GLOB dbus_CONF ${SERVER_FOLDER}/unit_tests/config/ut-dbus-connection/*.conf)
+
+INSTALL(FILES ${manager_manager_CONF}
DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container-manager)
-INSTALL(FILES ${container_CONF}
+INSTALL(FILES ${manager_container_CONF}
DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container-manager/containers)
-INSTALL(FILES ${containeradmin_CONF}
+INSTALL(FILES ${manager_admin_CONF}
DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container-manager/libvirt-config)
+
+INSTALL(FILES ${container_container_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container/containers)
+INSTALL(FILES ${container_admin_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container/libvirt-config)
+
+INSTALL(FILES ${admin_container_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container-admin/containers)
+INSTALL(FILES ${admin_admin_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-scs-container-admin/libvirt-config)
+
INSTALL(FILES ${dbus_CONF}
DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/ut-dbus-connection)
--- /dev/null
+{
+ "privilege" : 10,
+ "config" : "/etc/security-containers/tests/ut-scs-container-admin/libvirt-config/buggy.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
--- /dev/null
+{
+ "privilege" : 10,
+ "config" : "/this/is/a/missing/file/path/missing.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
--- /dev/null
+{
+ "privilege" : 10,
+ "config" : "/etc/security-containers/tests/ut-scs-container-admin/libvirt-config/test.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
{
- "containerConfigs" : ["containers/console.conf", "missing/file/path/missing.conf"]
+ "containerConfigs" : ["containers/console1.conf", "missing/file/path/missing.conf", "containers/console3.conf"],
+ "foregroundId" : "console1"
}
--- /dev/null
+{
+ "containerConfigs" : ["containers/console1.conf", "containers/console2.conf", "containers/console3.conf"],
+ "foregroundId" : "this_id_does_not_exist"
+}
+++ /dev/null
-{
- "privilege" : 10,
- "config" : "/missing/file/path/libvirt.xml"
-}
+++ /dev/null
-{
- "privilege" : 10,
- "config" : "../libvirt-config/console.xml"
-}
{
"privilege" : 20,
- "config" : "../libvirt-config/console1.xml"
+ "config" : "../libvirt-config/console1.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
}
--- /dev/null
+{
+ "privilege" : 10,
+ "config" : "../libvirt-config/console2.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
--- /dev/null
+{
+ "privilege" : 15,
+ "config" : "../libvirt-config/console3.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
+++ /dev/null
-{
- "privilege" : 10,
- "config" : "../libvirt-config/test.xml"
-}
<domain type="lxc">
- <name>console</name>
+ <name>console2</name>
<memory>102400</memory>
<os>
<type>exe</type>
--- /dev/null
+<domain type="lxc">
+ <name>console3</name>
+ <memory>102400</memory>
+ <os>
+ <type>exe</type>
+ <init>/bin/sh</init>
+ </os>
+ <devices>
+ <console type="pty"/>
+ </devices>
+</domain>
{
- "containerConfigs" : ["containers/console.conf", "containers/console1.conf"]
+ "containerConfigs" : ["containers/console1.conf", "containers/console2.conf", "containers/console3.conf"],
+ "foregroundId" : "console1"
}
--- /dev/null
+{
+ "privilege" : 10,
+ "config" : "/missing/file/path/libvirt.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
--- /dev/null
+{
+ "privilege" : 10,
+ "config" : "../libvirt-config/test.xml",
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000
+}
--- /dev/null
+<domain type="lxc">
+ <name>test</name>
+ <memory>102400</memory>
+ <on_poweroff>destroy</on_poweroff>
+ <os>
+ <type>exe</type>
+ <init>/bin/sh</init>
+ </os>
+ <devices>
+ <console type="pty"/>
+ </devices>
+</domain>
const char* DBUS_DAEMON_PROC = "/bin/dbus-daemon";
const char* const DBUS_DAEMON_ARGS[] = {
DBUS_DAEMON_PROC,
- "--config-file=/etc/security-containers/config/tests/ut-dbus-connection/ut-dbus.conf",
+ "--config-file=/etc/security-containers/tests/ut-dbus-connection/ut-dbus.conf",
"--nofork",
NULL
};
#include <memory>
#include <string>
+#include <thread>
+#include <chrono>
BOOST_AUTO_TEST_SUITE(ContainerAdminSuite)
using namespace security_containers;
-const std::string TEST_CONFIG_PATH = "/etc/security-containers/config/tests/ut-scs-container-manager/libvirt-config/test.xml";
-const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/config/tests/ut-scs-container-manager/libvirt-config/buggy.xml";
-const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/missing.xml";
+const std::string TEST_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container-admin/containers/test.conf";
+const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container-admin/containers/buggy.conf";
+const std::string MISSING_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container-admin/containers/missing.conf";
BOOST_AUTO_TEST_CASE(ConstructorTest)
{
- BOOST_REQUIRE_NO_THROW(ContainerAdmin ca(TEST_CONFIG_PATH));
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ BOOST_REQUIRE_NO_THROW(ContainerAdmin ca(config));
}
BOOST_AUTO_TEST_CASE(DestructorTest)
{
- std::unique_ptr<ContainerAdmin> ca(new ContainerAdmin(TEST_CONFIG_PATH));
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ std::unique_ptr<ContainerAdmin> ca(new ContainerAdmin(config));
BOOST_REQUIRE_NO_THROW(ca.reset());
}
BOOST_AUTO_TEST_CASE(BuggyConfigTest)
{
- BOOST_REQUIRE_THROW(ContainerAdmin ca(BUGGY_CONFIG_PATH), ServerException);
+ ContainerConfig config; config.parseFile(BUGGY_CONFIG_PATH);
+ BOOST_REQUIRE_THROW(ContainerAdmin ca(config), ServerException);
}
BOOST_AUTO_TEST_CASE(MissingConfigTest)
{
- BOOST_REQUIRE_THROW(ContainerAdmin ca(MISSING_CONFIG_PATH), ConfigException);
+ ContainerConfig config; config.parseFile(MISSING_CONFIG_PATH);
+ BOOST_REQUIRE_THROW(ContainerAdmin ca(config), ConfigException);
}
BOOST_AUTO_TEST_CASE(StartTest)
{
- ContainerAdmin ca(TEST_CONFIG_PATH);
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ ContainerAdmin ca(config);
BOOST_REQUIRE_NO_THROW(ca.start());
BOOST_CHECK(ca.isRunning());
}
BOOST_AUTO_TEST_CASE(StopTest)
{
- ContainerAdmin ca(TEST_CONFIG_PATH);
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ ContainerAdmin ca(config);
BOOST_REQUIRE_NO_THROW(ca.start());
BOOST_CHECK(ca.isRunning());
BOOST_REQUIRE_NO_THROW(ca.stop())
BOOST_AUTO_TEST_CASE(ShutdownTest)
{
- ContainerAdmin ca(TEST_CONFIG_PATH);
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ ContainerAdmin ca(config);
BOOST_REQUIRE_NO_THROW(ca.start())
BOOST_CHECK(ca.isRunning());
BOOST_REQUIRE_NO_THROW(ca.shutdown())
BOOST_AUTO_TEST_CASE(SuspendTest)
{
- ContainerAdmin ca(TEST_CONFIG_PATH);
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ ContainerAdmin ca(config);
BOOST_REQUIRE_NO_THROW(ca.start())
BOOST_CHECK(ca.isRunning());
- BOOST_REQUIRE_NO_THROW(ca.suspend())
+ // TODO: fix the libvirt usage so this is not required
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ BOOST_REQUIRE_NO_THROW(ca.suspend());
BOOST_CHECK(!ca.isRunning());
BOOST_CHECK(ca.isPaused());
}
BOOST_AUTO_TEST_CASE(ResumeTest)
{
- ContainerAdmin ca(TEST_CONFIG_PATH);
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ ContainerAdmin ca(config);
BOOST_REQUIRE_NO_THROW(ca.start());
+ // TODO: fix the libvirt usage so this is not required
+ std::this_thread::sleep_for(std::chrono::seconds(1));
BOOST_REQUIRE_NO_THROW(ca.suspend())
BOOST_CHECK(ca.isPaused());
BOOST_REQUIRE_NO_THROW(ca.resume());
BOOST_CHECK(ca.isRunning());
}
+BOOST_AUTO_TEST_CASE(SchedulerLevelTest)
+{
+ ContainerConfig config; config.parseFile(TEST_CONFIG_PATH);
+ ContainerAdmin ca(config);
+ BOOST_REQUIRE_NO_THROW(ca.start());
+ BOOST_REQUIRE(ca.getSchedulerQuota() == config.cpuQuotaBackground);
+ BOOST_REQUIRE_NO_THROW(ca.setSchedulerLevel(SchedulerLevel::FOREGROUND));
+ BOOST_REQUIRE(ca.getSchedulerQuota() == config.cpuQuotaForeground);
+ BOOST_REQUIRE_NO_THROW(ca.setSchedulerLevel(SchedulerLevel::BACKGROUND));
+ BOOST_REQUIRE(ca.getSchedulerQuota() == config.cpuQuotaBackground);
+}
+
BOOST_AUTO_TEST_SUITE_END()
using namespace security_containers;
-const std::string TEST_CONFIG_PATH = "/etc/security-containers/config/tests/ut-scs-container-manager/test-daemon.conf";
-const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/config/tests/ut-scs-container-manager/buggy-daemon.conf";
+const std::string TEST_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container-manager/test-daemon.conf";
+const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container-manager/buggy-daemon.conf";
+const std::string BUGGY_FOREGROUND_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container-manager/buggy-foreground-daemon.conf";
const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/missing-daemon.conf";
{
ContainerManager cm(TEST_CONFIG_PATH);
BOOST_REQUIRE_NO_THROW(cm.startAll());
- BOOST_CHECK(!cm.getRunningContainerId().empty());
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == "console1");
+}
+
+BOOST_AUTO_TEST_CASE(BuggyForegroundTest)
+{
+ ContainerManager cm(BUGGY_FOREGROUND_CONFIG_PATH);
+ BOOST_REQUIRE_NO_THROW(cm.startAll());
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == "console2");
}
BOOST_AUTO_TEST_CASE(StopAllTest)
ContainerManager cm(TEST_CONFIG_PATH);
BOOST_REQUIRE_NO_THROW(cm.startAll());
BOOST_REQUIRE_NO_THROW(cm.stopAll());
- BOOST_CHECK(cm.getRunningContainerId().empty());
-
+ BOOST_CHECK(cm.getRunningForegroundContainerId().empty());
}
BOOST_AUTO_TEST_CASE(FocusTest)
{
ContainerManager cm(TEST_CONFIG_PATH);
BOOST_REQUIRE_NO_THROW(cm.startAll());
- BOOST_REQUIRE_NO_THROW(cm.focus("console"));
- BOOST_CHECK(!cm.getSuspendedContainerIds().empty());
- BOOST_TEST_MESSAGE("Suspended");
- for (auto& id : cm.getSuspendedContainerIds()) {
- BOOST_TEST_MESSAGE(id);
- }
+ BOOST_REQUIRE_NO_THROW(cm.focus("console2"));
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == "console2");
+ BOOST_REQUIRE_NO_THROW(cm.focus("console1"));
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == "console1");
+ BOOST_REQUIRE_NO_THROW(cm.focus("console3"));
+ BOOST_CHECK(cm.getRunningForegroundContainerId() == "console3");
}
BOOST_AUTO_TEST_SUITE_END()
using namespace security_containers;
-const std::string TEST_CONFIG_PATH = "/etc/security-containers/config/tests/ut-scs-container-manager/containers/test.conf";
-const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/config/tests/ut-scs-container-manager/containers/buggy.conf";
+const std::string TEST_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container/containers/test.conf";
+const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/tests/ut-scs-container/containers/buggy.conf";
const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/config.conf";
BOOST_REQUIRE_THROW(Container c(MISSING_CONFIG_PATH), ConfigException);
}
-BOOST_AUTO_TEST_CASE(AdminTest)
-{
- std::unique_ptr<Container> c(new Container(TEST_CONFIG_PATH));
- //BOOST_REQUIRE(c->getAdmin());
-}
BOOST_AUTO_TEST_SUITE_END()