[Bug/Feature] Server class for managing the life cycle of the server.
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests, run security-containers-server
Change-Id: I46fe53bffe9ce7d588bd9cacfefb28af475d048b
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Jan Olszak (j.olszak@samsung.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Synchronization latch
+ */
+
+#include "typeinfo.hpp"
+
+#include <string>
+#include <cxxabi.h>
+#include <stdexcept>
+
+namespace security_containers {
+namespace utils {
+
+std::string getTypeName(const std::type_info& ti)
+{
+ int status;
+ char* demangled = abi::__cxa_demangle(ti.name() , 0, 0, &status);
+ if (status) {
+ std::string message = "abi::__cxa_demangle failed with ret code: " + std::to_string(status);
+ throw std::runtime_error(message);
+ }
+
+ std::string ret(demangled);
+ free(demangled);
+ return ret;
+}
+
+} // namespace utils
+} // namespace security_containers
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Jan Olszak (j.olszak@samsung.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Synchronization latch
+ */
+
+#ifndef COMMON_TYPE_INFO_HPP
+#define COMMON_TYPE_INFO_HPP
+
+#include <string>
+#include <typeinfo>
+
+namespace security_containers {
+namespace utils {
+
+std::string getTypeName(const std::type_info& ti);
+
+template<class T> std::string getTypeName(const T& t)
+{
+ return getTypeName(typeid(t));
+}
+
+} // namespace utils
+} // namespace security_containers
+
+
+#endif // COMMON_TYPE_INFO_HPP
%files
%attr(755,root,root) %{_bindir}/security-containers-server
%config %attr(644,root,root) /etc/security-containers/daemon.conf
-%config %attr(644,root,root) /etc/security-containers/containers/xminimal.conf
+%config %attr(644,root,root) /etc/security-containers/containers/*.conf
%config %attr(400,root,root) /etc/security-containers/libvirt-config/*.xml
%prep
%attr(755,root,root) %{script_dir}/sc_launch_test.py
%{script_dir}/sc_test_parser.py
%config %attr(644,root,root) /etc/security-containers/tests/dbus/ut-connection/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/server/ut-server/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/server/ut-server/containers/*.conf
+%config %attr(644,root,root) /etc/security-containers/tests/server/ut-server/libvirt-config/*.xml
%config %attr(644,root,root) /etc/security-containers/tests/server/ut-containers-manager/*.conf
%config %attr(644,root,root) /etc/security-containers/tests/server/ut-containers-manager/containers/*.conf
%config %attr(644,root,root) /etc/security-containers/tests/server/ut-containers-manager/libvirt-config/*.xml
INSTALL(FILES daemon.conf
DESTINATION ${SC_CONFIG_INSTALL_DIR})
-INSTALL(FILES containers/xminimal.conf
+INSTALL(FILES containers/private.conf
DESTINATION ${SC_CONFIG_INSTALL_DIR}/containers)
-INSTALL(FILES libvirt-config/xminimal.xml
+INSTALL(FILES libvirt-config/private.xml
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/libvirt-config)
+
+INSTALL(FILES containers/business.conf
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/containers)
+
+INSTALL(FILES libvirt-config/business.xml
DESTINATION ${SC_CONFIG_INSTALL_DIR}/libvirt-config)
--- /dev/null
+{
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000,
+ "privilege" : 1,
+ "config" : "../libvirt-config/business.xml"
+}
--- /dev/null
+{
+ "cpuQuotaForeground" : -1,
+ "cpuQuotaBackground" : 1000,
+ "privilege" : 10,
+ "config" : "../libvirt-config/private.xml"
+}
+++ /dev/null
-{
- "cpuQuotaForeground" : 1,
- "cpuQuotaBackground" : 0.01,
- "privilege" : 10,
- "config" : "../libvirt-config/xminimal.xml"
-}
{
- "containerConfigs" : ["containers/xminimal.conf" ]
+ "containerConfigs" : ["containers/private.conf", "containers/business.conf" ],
+ "foregroundId" : "private"
}
<domain type='lxc'>
- <name>xminimal</name>
+ <name>business</name>
<memory>102400</memory>
<os>
<type>exe</type>
<source network='default'/>
</interface>
<filesystem type='mount'>
- <source dir='/domains/xminimal'/>
+ <source dir='/domains/business'/>
<target dir='/'/>
</filesystem>
</devices>
--- /dev/null
+<domain type='lxc'>
+ <name>private</name>
+ <memory>102400</memory>
+ <os>
+ <type>exe</type>
+ <init>/usr/lib/systemd/systemd</init>
+ </os>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <console type='pty'/>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/fb0</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/tty2</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/tty3</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/tty4</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/tty5</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/event0</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/event1</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/event2</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/event3</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/event4</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/mice</char>
+ </source>
+ </hostdev>
+ <hostdev mode='capabilities' type='misc'>
+ <source>
+ <char>/dev/input/mouse0</char>
+ </source>
+ </hostdev>
+ <interface type='network'>
+ <source network='default'/>
+ </interface>
+ <filesystem type='mount'>
+ <source dir='/domains/private'/>
+ <target dir='/'/>
+ </filesystem>
+ </devices>
+</domain>
void ContainersManager::startAll()
{
+ LOGI("Starting all containers");
+
bool isForegroundFound = false;
for (auto& container : mContainers) {
void ContainersManager::stopAll()
{
+ LOGI("Stopping all containers");
+
for (auto& container : mContainers) {
container.second->stop();
}
#include "log/logger.hpp"
#include "log/backend-stderr.hpp"
-#include "utils/glib-loop.hpp"
-#include "utils/latch.hpp"
+#include "utils/typeinfo.hpp"
+#include "exception.hpp"
+#include "server.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <iostream>
-#include <csignal>
+using namespace security_containers::log;
+using namespace security_containers;
namespace po = boost::program_options;
-namespace security_containers {
-namespace {
-
-
-utils::Latch signalLatch;
-
-void signalHandler(int sig)
-{
- LOGI("Got signal " << sig);
- signalLatch.set();
-}
-
-void runDaemon()
-{
- signal(SIGINT, signalHandler);
- signal(SIGTERM, signalHandler);
-
- LOGI("Starting daemon...");
- {
- utils::ScopedGlibLoop loop;
- //TODO bootstrap
- LOGI("Daemon started");
- signalLatch.wait();
- LOGI("Stopping daemon...");
- }
- LOGI("Daemon stopped");
-}
-
-} // namespace
-} // namespace security_containers
-
namespace {
-
const std::string PROGRAM_NAME_AND_VERSION =
"Security Containers Server " PROGRAM_VERSION;
-using namespace security_containers::log;
-
/**
* Resolve if given log severity level is valid
*
int main(int argc, char* argv[])
{
+ std::string configPath ;
+
try {
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "print this help")
("version,v", "show application version")
- ("log-level", po::value<std::string>()->default_value("DEBUG"), "set log level")
+ ("log-level,l", po::value<std::string>()->default_value("DEBUG"), "set log level")
+ ("config,c", po::value<std::string>()->default_value("/etc/security-containers/daemon.conf"), "server configuration file")
;
po::variables_map vm;
return 0;
}
- if (vm.count("log-level")) {
- using namespace security_containers::log;
- LogLevel level = validateLogLevel(vm["log-level"].as<std::string>());
- Logger::setLogLevel(level);
- Logger::setLogBackend(new StderrBackend());
- }
+ LogLevel level = validateLogLevel(vm["log-level"].as<std::string>());
+ Logger::setLogLevel(level);
+ Logger::setLogBackend(new StderrBackend());
+
+ configPath = vm["config"].as<std::string>();
+
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
}
- security_containers::runDaemon();
+ try {
+ Server server(configPath);
+ server.run();
+
+ } catch (std::exception& e) {
+ LOGE("Unexpected: " << utils::getTypeName(e) << ": " << e.what());
+ return 1;
+ }
return 0;
}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Jan Olszak (j.olszak@samsung.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Server class definition
+ */
+
+#include "server.hpp"
+#include "containers-manager.hpp"
+#include "exception.hpp"
+
+#include "log/logger.hpp"
+#include "utils/glib-loop.hpp"
+
+#include <csignal>
+#include <string>
+
+namespace security_containers {
+
+
+Server::Server(const std::string& configPath)
+ : mConfigPath(configPath)
+{
+}
+
+
+Server::~Server()
+{
+}
+
+
+namespace {
+utils::Latch signalLatch;
+void signalHandler(const int sig)
+{
+ LOGI("Got signal " << sig);
+ signalLatch.set();
+}
+}
+
+void Server::run()
+{
+ signal(SIGINT, signalHandler);
+ signal(SIGTERM, signalHandler);
+
+ LOGI("Starting daemon...");
+ {
+ utils::ScopedGlibLoop loop;
+ ContainersManager manager(mConfigPath);
+
+ manager.startAll();
+ LOGI("Daemon started");
+
+ signalLatch.wait();
+
+ LOGI("Stopping daemon...");
+ // manager.stopAll() will be called in destructor
+ }
+ LOGI("Daemon stopped");
+}
+
+void Server::terminate()
+{
+ LOGI("Terminating server");
+ signalLatch.set();
+}
+
+} // namespace security_containers
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Jan Olszak (j.olszak@samsung.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Server class declaration
+ */
+
+
+#ifndef SERVER_SERVER_HPP
+#define SERVER_SERVER_HPP
+
+#include "utils/latch.hpp"
+
+#include <string>
+
+namespace security_containers {
+
+class Server {
+public:
+ Server(const std::string& configPath);
+ virtual ~Server();
+
+ /**
+ * Starts all the containers and blocks until SIGINT or SIGTERM
+ */
+ void run();
+
+ /**
+ * Terminates the server.
+ * Equivalent of sending SIGINT or SIGTERM signal
+ */
+ void terminate();
+private:
+ std::string mConfigPath;
+};
+
+
+} // namespace security_containers
+
+
+#endif // SERVER_SERVER_HPP
#
MESSAGE(STATUS "Installing configs for the Server Unit Tests to " ${SC_CONFIG_INSTALL_DIR})
+
+FILE(GLOB server_manager_CONF ut-server/*.conf)
+FILE(GLOB server_container_CONF ut-server/containers/*.conf)
+FILE(GLOB server_admin_CONF ut-server/libvirt-config/*.xml)
+
FILE(GLOB manager_manager_CONF ut-containers-manager/*.conf)
FILE(GLOB manager_container_CONF ut-containers-manager/containers/*.conf)
FILE(GLOB manager_admin_CONF ut-containers-manager/libvirt-config/*.xml)
## Install #####################################################################
+INSTALL(FILES ${server_manager_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/server/ut-server)
+INSTALL(FILES ${server_container_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/server/ut-server/containers)
+INSTALL(FILES ${server_admin_CONF}
+ DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/server/ut-server/libvirt-config)
+
INSTALL(FILES ${manager_manager_CONF}
DESTINATION ${SC_CONFIG_INSTALL_DIR}/tests/server/ut-containers-manager)
INSTALL(FILES ${manager_container_CONF}
--- /dev/null
+{
+ "containerConfigs" : ["containers/console1.conf", "missing/file/path/missing.conf", "containers/console3.conf"],
+ "foregroundId" : "console1"
+}
--- /dev/null
+{
+ "privilege" : 20,
+ "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
+<domain type="lxc">
+ <name>console1</name>
+ <memory>102400</memory>
+ <os>
+ <type>exe</type>
+ <init>/bin/sh</init>
+ </os>
+ <devices>
+ <console type="pty"/>
+ </devices>
+</domain>
--- /dev/null
+<domain type="lxc">
+ <name>console2</name>
+ <memory>102400</memory>
+ <os>
+ <type>exe</type>
+ <init>/bin/sh</init>
+ </os>
+ <devices>
+ <console type="pty"/>
+ </devices>
+</domain>
--- /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>
--- /dev/null
+{
+ "containerConfigs" : ["containers/console1.conf", "containers/console2.conf", "containers/console3.conf"],
+ "foregroundId" : "console1"
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Unit tests of the Server class
+ */
+
+#include "ut.hpp"
+
+#include "server.hpp"
+#include "exception.hpp"
+#include "config/exception.hpp"
+
+#include <string>
+#include <thread>
+
+BOOST_AUTO_TEST_SUITE(ServerSuite)
+
+using namespace security_containers;
+using namespace security_containers::config;
+
+const std::string TEST_CONFIG_PATH = "/etc/security-containers/tests/server/ut-server/test-daemon.conf";
+const std::string BUGGY_CONFIG_PATH = "/etc/security-containers/tests/server/ut-server/buggy-daemon.conf";
+const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/missing-daemon.conf";
+
+
+BOOST_AUTO_TEST_CASE(ConstructorDestructorTest)
+{
+ std::unique_ptr<Server> s;
+ BOOST_REQUIRE_NO_THROW(s.reset(new Server(TEST_CONFIG_PATH)));
+ BOOST_REQUIRE_NO_THROW(s.reset());
+}
+
+BOOST_AUTO_TEST_CASE(BuggyConfigTest)
+{
+ BOOST_REQUIRE_THROW(Server(BUGGY_CONFIG_PATH).run(), ConfigException);
+}
+
+BOOST_AUTO_TEST_CASE(MissingConfigTest)
+{
+ BOOST_REQUIRE_THROW(Server(MISSING_CONFIG_PATH).run(), ConfigException);
+}
+
+BOOST_AUTO_TEST_CASE(TerminateTest)
+{
+ Server s(TEST_CONFIG_PATH);
+ BOOST_REQUIRE_NO_THROW(s.terminate());
+}
+
+BOOST_AUTO_TEST_CASE(RunTerminateTest)
+{
+ Server s(TEST_CONFIG_PATH);
+ std::thread t([&]() {
+ BOOST_REQUIRE_NO_THROW(s.run());
+ });
+ BOOST_REQUIRE_NO_THROW(s.terminate());
+ t.join();
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()