%{script_dir}/sc_test_parser.py
%{_bindir}/sc_tests_all
%{_bindir}/sc_test_launch
+%config %attr(644,root,root) /etc/security-containers/config/tests/ut-scs-container-manager/test-daemon.conf
+%config %attr(644,root,root) /etc/security-containers/config/tests/ut-scs-container-manager/libvirt-config/*.xml
namespace security_containers {
-struct ContainerConfig : public ConfigurationBase
-{
- // it's just an example
- int memory;
- std::string rootDir;
-
- CONFIG_REGISTER
- {
- CONFIG_VALUE(memory)
- CONFIG_VALUE(rootDir)
+struct ContainerConfig : public ConfigurationBase {
+ /**
+ * Privilege of the container.
+ * The smaller the value the more important the container
+ */
+ int privilege;
+
+ /**
+ * String id of the container
+ */
+ std::string id;
+
+ CONFIG_REGISTER {
+ CONFIG_VALUE(privilege)
+ CONFIG_VALUE(id)
}
};
--- /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 scs-container-manager-config.hpp
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Declaration of the class for storing container manager configuration
+ */
+
+
+#ifndef SECURITY_CONTAINERS_SERVER_CONTAINER_MANAGER_CONFIG_HPP
+#define SECURITY_CONTAINERS_SERVER_CONTAINER_MANAGER_CONFIG_HPP
+
+#include "scs-configuration.hpp"
+#include <string>
+#include <vector>
+
+namespace security_containers {
+
+const std::string CONTAINER_MANAGER_CONFIG_PATH = "/etc/security-containers/config/.daemon.json";
+
+struct ContainerManagerConfig : public ConfigurationBase {
+ /**
+ * Directory with the libvirt's configuration files
+ */
+ std::string libvirtConfigDir;
+
+ /**
+ * List of containers that we manage.
+ * Appropriate files have to be inside config file
+ */
+ std::vector<std::string> containerIds;
+
+ CONFIG_REGISTER {
+ CONFIG_VALUE(libvirtConfigDir)
+ CONFIG_VALUE(containerIds)
+ }
+};
+
+}
+
+#endif // SECURITY_CONTAINERS_SERVER_CONTAINER_MANAGER_CONFIG_HPP
--- /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 scs-container-manager.hpp
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Declaration of the class for managing many containers
+ */
+
+
+#ifndef SECURITY_CONTAINERS_SERVER_CONTAINER_MANAGER_HPP
+#define SECURITY_CONTAINERS_SERVER_CONTAINER_MANAGER_HPP
+
+#include "scs-container.hpp"
+#include "scs-container-manager-config.hpp"
+
+#include <string>
+#include <unordered_map>
+
+#include <libvirt/libvirt.h>
+
+namespace security_containers {
+
+class ContainerManager final {
+
+public:
+ ContainerManager(const std::string& configFilePath);
+ ~ContainerManager();
+
+ /**
+ * Switch to this container.
+ * Method blocks until the focus is switched.
+ *
+ * @param containerId id of the container
+ */
+ void focus(const std::string& containerId);
+
+ /**
+ * Start up all the configured containers
+ */
+ void startAll();
+
+ /**
+ * Stop all managed containers
+ */
+ void stopAll();
+
+ /**
+ * @return id of the currently running container
+ */
+ std::string getRunningContainerId();
+
+ /**
+ * @return vector of suspended container ids
+ */
+ std::vector<std::string> getSuspendedContainerIds();
+
+private:
+ ContainerManagerConfig mConfig;
+ virConnectPtr mVir = NULL; // pointer to the connection with libvirt
+ std::unordered_map<std::string, Container> mContainers; // map of containers, id is the key
+
+ void connect();
+ void disconnect();
+};
+}
+#endif // SECURITY_CONTAINERS_SERVER_CONTAINER_MANAGER_HPP
--- /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 scs-utils.hpp
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Utility function declaration
+ */
+
+
+#include <string>
+#include <vector>
+
+
+namespace security_containers {
+
+template <class ...Paths> std::string createFilePath(const Paths& ... paths)
+{
+ std::vector<std::string> pathVec = {paths...};
+ std::string retPath = "";
+
+ if (pathVec.empty()) {
+ return retPath;
+ }
+
+ for (std::string& p : pathVec) {
+ // Repeat until retPath is not empty
+ if (retPath.empty() || p.empty()) {
+ retPath += p;
+ continue;
+ }
+
+ // We need a slash
+ if (retPath.back() != '/' && p.front() != '/' && p.front() != '.') {
+ retPath += "/" + p;
+ continue;
+ }
+
+ // Too many slashes
+ if (retPath.back() == '/' && p.front() == '/') {
+ retPath += p.substr(1);
+ continue;
+ }
+
+ retPath += p;
+ }
+
+ return retPath;
+}
+
+} // namespace security_containers
\ No newline at end of file
--- /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 scs-container-manager.cpp
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Definition of the class for managing containers
+ */
+
+#include "scs-container-manager.hpp"
+#include "scs-container.hpp"
+#include "scs-exception.hpp"
+#include "scs-log.hpp"
+#include "scs-utils.hpp"
+
+#include <assert.h>
+#include <string>
+#include <fstream>
+#include <streambuf>
+
+namespace security_containers {
+
+ContainerManager::ContainerManager(const std::string& configFilePath)
+{
+ mConfig.parseFile(configFilePath);
+ connect();
+ for (auto& containerId : mConfig.containerIds) {
+ std::string libvirtConfigPath = createFilePath(mConfig.libvirtConfigDir, containerId, ".xml");
+ std::ifstream t(libvirtConfigPath);
+ std::string libvirtConfig((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
+ LOGT("Creating Container " << libvirtConfigPath);
+ mContainers.emplace(containerId, libvirtConfig);
+ }
+}
+
+
+ContainerManager::~ContainerManager()
+{
+ try {
+ stopAll();
+ } catch (ServerException& e) {
+ LOGE("Failed to stop all of the containers");
+ }
+ disconnect();
+}
+
+
+void ContainerManager::focus(const std::string& containerId)
+{
+ for (auto& container : mContainers) {
+ container.second.suspend();
+ }
+ mContainers.at(containerId).resume();
+}
+
+
+void ContainerManager::startAll()
+{
+ for (auto& container : mContainers) {
+ container.second.start();
+ }
+}
+
+
+void ContainerManager::stopAll()
+{
+ for (auto& container : mContainers) {
+ container.second.stop();
+ }
+}
+
+
+std::string ContainerManager::getRunningContainerId()
+{
+ for (auto& container : mContainers) {
+ if (container.second.isRunning()) {
+ return container.first;
+ }
+ }
+ return "";
+}
+
+
+std::vector<std::string> ContainerManager::getSuspendedContainerIds()
+{
+ std::vector<std::string> retContainerIds;
+ for (auto& container : mContainers) {
+ if (container.second.isPaused()) {
+ retContainerIds.push_back(container.first);
+ }
+ }
+ return retContainerIds;
+}
+
+
+void ContainerManager::connect()
+{
+ assert(mVir == NULL);
+
+ mVir = virConnectOpen("lxc://");
+ if (mVir == NULL) {
+ LOGE("Failed to open connection to lxc://");
+ throw ConnectionException();
+ }
+}
+
+
+void ContainerManager::disconnect()
+{
+ if (mVir == NULL) {
+ return;
+ }
+
+ if (virConnectClose(mVir) < 0) {
+ LOGE("Error during unconnecting from libvirt");
+ };
+ mVir = NULL;
+}
+
+
+} // namespace security_containers
\ No newline at end of file
MESSAGE ("Generating makefile for the Server unit tests...")
FILE(GLOB_RECURSE project_SRCS *.cpp)
FILE(GLOB src_SRCS ${SERVER_FOLDER}/src/scs-container.cpp
+ ${SERVER_FOLDER}/src/scs-container-manager.cpp
${SERVER_FOLDER}/src/scs-configuration.cpp)
MESSAGE("Files: " ${project_SRCS} ${src_SRCS})
TARGET_LINK_LIBRARIES(${UT_SERVER_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES})
## Install #####################################################################
-INSTALL(TARGETS ${UT_SERVER_CODENAME} DESTINATION bin)
\ No newline at end of file
+INSTALL(TARGETS ${UT_SERVER_CODENAME} DESTINATION bin)
+
+INSTALL(FILES ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/test-daemon.conf
+ DESTINATION /etc/security-containers/config/tests/ut-scs-container-manager/)
+
+INSTALL(FILES ${SERVER_FOLDER}/unit_tests/config/ut-scs-container-manager/libvirt-config/console.xml
+ DESTINATION /etc/security-containers/config/tests/ut-scs-container-manager/libvirt-config/)
--- /dev/null
+<domain type="lxc">
+ <name>console</name>
+ <memory>102400</memory>
+ <os>
+ <type>exe</type>
+ <init>/bin/sh</init>
+ </os>
+ <devices>
+ <console type="pty"/>
+ </devices>
+</domain>
--- /dev/null
+{
+ "libvirtConfigDir" : "/etc/security-containers/config/tests/ut-scs-container-manager/libvirt-config",
+ "containerIds" : ["console", "console1"]
+}
{
TestConfig testConfig;
BOOST_REQUIRE_NO_THROW(testConfig.parseStr(json_test_string));
-
- std::cout << "Input:" << std::endl << json_test_string << std::endl;
-
- std::string out;
- BOOST_REQUIRE_NO_THROW(out = testConfig.toString());
- std::cout << std::endl << "Output:" << std::endl << out << std::endl;
+ BOOST_REQUIRE_NO_THROW(testConfig.toString());
// parse output again and check if both objects match
- std::cout << "Validating output..." << std::endl;
TestConfig outputConfig;
BOOST_REQUIRE_NO_THROW(outputConfig.parseStr(json_test_string));
BOOST_CHECK(outputConfig == testConfig);
--- /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 ut-scs-container.cpp
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Unit tests of the Container class
+ */
+
+#include "ut.hpp"
+#include "scs-container-manager.hpp"
+#include "scs-exception.hpp"
+
+#include <memory>
+#include <string>
+
+
+BOOST_AUTO_TEST_SUITE(ContainerManagerSuite)
+
+using namespace security_containers;
+
+const std::string daemonConfigPath = "/etc/security-containers/config/tests/ut-scs-container-manager/test-daemon.conf";
+
+
+BOOST_AUTO_TEST_CASE(ConstructorTest)
+{
+ BOOST_REQUIRE_NO_THROW(ContainerManager cm(daemonConfigPath););
+}
+
+BOOST_AUTO_TEST_CASE(DestructorTest)
+{
+ std::unique_ptr<ContainerManager> cm(new ContainerManager(daemonConfigPath));
+ BOOST_REQUIRE_NO_THROW(cm.reset());
+}
+
+BOOST_AUTO_TEST_CASE(StartAllTest)
+{
+ ContainerManager cm(daemonConfigPath);
+ BOOST_REQUIRE_NO_THROW(cm.startAll());
+ BOOST_CHECK(!cm.getRunningContainerId().empty());
+}
+
+BOOST_AUTO_TEST_CASE(StopAllTest)
+{
+ ContainerManager cm(daemonConfigPath);
+ BOOST_REQUIRE_NO_THROW(cm.startAll());
+ BOOST_REQUIRE_NO_THROW(cm.stopAll());
+ BOOST_CHECK(cm.getRunningContainerId().empty());
+
+}
+
+BOOST_AUTO_TEST_CASE(FocusTest)
+{
+ ContainerManager cm(daemonConfigPath);
+ 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_AUTO_TEST_SUITE_END()
--- /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 ut-scs-utils.cpp
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief Unit tests of utils
+ */
+
+#include "ut.hpp"
+#include "scs-utils.hpp"
+#include "scs-exception.hpp"
+
+#include <memory>
+
+BOOST_AUTO_TEST_SUITE(UtilsSuite)
+
+using namespace security_containers;
+
+BOOST_AUTO_TEST_CASE(CreateFilePathTest)
+{
+ BOOST_CHECK_EQUAL("", createFilePath());
+
+ BOOST_CHECK_EQUAL("a", createFilePath("a"));
+ BOOST_CHECK_EQUAL("/", createFilePath("/"));
+
+ BOOST_CHECK_EQUAL("", createFilePath("", ""));
+ BOOST_CHECK_EQUAL("a", createFilePath("a", ""));
+ BOOST_CHECK_EQUAL("b", createFilePath("", "b"));
+ BOOST_CHECK_EQUAL("/", createFilePath("", "/"));
+ BOOST_CHECK_EQUAL("/", createFilePath("/", ""));
+ BOOST_CHECK_EQUAL("/", createFilePath("/", "/"));
+
+ BOOST_CHECK_EQUAL("a/b", createFilePath("a", "b"));
+ BOOST_CHECK_EQUAL("a/b", createFilePath("a/", "b"));
+ BOOST_CHECK_EQUAL("a/b", createFilePath("a", "/b"));
+ BOOST_CHECK_EQUAL("a/b", createFilePath("a/", "/b"));
+
+ BOOST_CHECK_EQUAL("a/b.txt", createFilePath("a", "b", ".txt"));
+ BOOST_CHECK_EQUAL("a/b.txt", createFilePath("a/", "b", ".txt"));
+ BOOST_CHECK_EQUAL("a/b.txt", createFilePath("a", "/b", ".txt"));
+ BOOST_CHECK_EQUAL("a/b/.txt", createFilePath("a", "/b", "/.txt"));
+ BOOST_CHECK_EQUAL("a/b/.txt", createFilePath("a", "/b/", "/.txt"));
+}
+
+BOOST_AUTO_TEST_SUITE_END()