#include "container.hpp"
#include "base-exception.hpp"
+#include "provisioning-config.hpp"
#include "logger/logger.hpp"
#include "utils/paths.hpp"
// TODO: move constants to the config file when default values are implemented there
const int RECONNECT_RETRIES = 15;
const int RECONNECT_DELAY = 1 * 1000;
+const std::string CONTAINER_PROVISION_FILE = "provision.conf";
+
+void declareUnit(const std::string& file, ContainerProvisioning::Unit&& unit)
+{
+ // TODO: Add to the dynamic configuration
+ ContainerProvisioning config;
+ if (fs::exists(file)) {
+ config::loadFromFile(file, config);
+ }
+ config.units.push_back(std::move(unit));
+ config::saveToFile(file, config);
+}
} // namespace
}
mAdmin.reset(new ContainerAdmin(containersPath, lxcTemplatePrefix, mConfig));
+ const fs::path baseProvision = fs::path(containersPath) / mAdmin->getId();
+ mProvisionConfig = fs::absolute(CONTAINER_PROVISION_FILE, baseProvision).string();
}
Container::~Container()
}
}
+void Container::declareFile(const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode)
+{
+ ContainerProvisioning::Unit unit;
+ unit.set(std::move(ContainerProvisioning::File({type, path, flags, mode})));
+
+ declareUnit(mProvisionConfig, std::move(unit));
+}
+
+void Container::declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t& flags,
+ const std::string& data)
+{
+ ContainerProvisioning::Unit unit;
+ unit.set(std::move(ContainerProvisioning::Mount({source, target, type, flags, data})));
+
+ declareUnit(mProvisionConfig, std::move(unit));
+}
+
+void Container::declareLink(const std::string& source,
+ const std::string& target)
+{
+ ContainerProvisioning::Unit unit;
+ unit.set(std::move(ContainerProvisioning::Link({source, target})));
+
+ declareUnit(mProvisionConfig, std::move(unit));
+}
} // namespace security_containers
*/
int getVT() const;
+ /**
+ * Declare file, directory or pipe that will be created while container startup
+ */
+ void declareFile(const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode);
+ /**
+ * Declare mount that will be created while container startup
+ */
+ void declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t& flags,
+ const std::string& data);
+ /**
+ * Declare link that will be created while container startup
+ */
+ void declareLink(const std::string& source,
+ const std::string& target);
+
private:
ContainerConfig mConfig;
std::vector<boost::regex> mPermittedToSend;
DbusStateChangedCallback mDbusStateChangedCallback;
std::string mDbusAddress;
std::string mRunMountPoint;
+ std::string mProvisionConfig;
void onNameLostCallback();
void reconnectHandler();
rootfsPath.string().c_str()));
}
-void ContainersManager::handleDeclareFileCall(const std::string& /* container */,
- const int32_t& /* type */,
- const std::string& /* path */,
- const int32_t& /* flags */,
- const int32_t& /* mode */,
+void ContainersManager::handleDeclareFileCall(const std::string& container,
+ const int32_t& type,
+ const std::string& path,
+ const int32_t& flags,
+ const int32_t& mode,
dbus::MethodResultBuilder::Pointer result)
{
LOGI("DeclareFile call");
- LOGE("Not implemeted method");
- result->setError(api::ERROR_INTERNAL, "Not implemented");
+ try {
+ mContainers.at(container)->declareFile(type, path, flags, mode);
+ result->setVoid();
+ } catch (const std::out_of_range& ex) {
+ LOGE("No container with id=" << container);
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
+ } catch (const config::ConfigException& ex) {
+ LOGE("Can't declare file: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, "Internal error");
+ }
}
-void ContainersManager::handleDeclareMountCall(const std::string& /* source */,
- const std::string& /* container */,
- const std::string& /* target */,
- const std::string& /* type */,
- const uint64_t& /* flags */,
- const std::string& /* data */,
+void ContainersManager::handleDeclareMountCall(const std::string& source,
+ const std::string& container,
+ const std::string& target,
+ const std::string& type,
+ const uint64_t& flags,
+ const std::string& data,
dbus::MethodResultBuilder::Pointer result)
{
LOGI("DeclareMount call");
- LOGE("Not implemeted method");
- result->setError(api::ERROR_INTERNAL, "Not implemented");
+ try {
+ mContainers.at(container)->declareMount(source, target, type, flags, data);
+ result->setVoid();
+ } catch (const std::out_of_range& ex) {
+ LOGE("No container with id=" << container);
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
+ } catch (const config::ConfigException& ex) {
+ LOGE("Can't declare mount: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, "Internal error");
+ }
}
-void ContainersManager::handleDeclareLinkCall(const std::string& /* source */,
- const std::string& /* container */,
- const std::string& /* target */,
+void ContainersManager::handleDeclareLinkCall(const std::string& source,
+ const std::string& container,
+ const std::string& target,
dbus::MethodResultBuilder::Pointer result)
{
LOGI("DeclareLink call");
- LOGE("Not implemeted method");
- result->setError(api::ERROR_INTERNAL, "Not implemented");
+ try {
+ mContainers.at(container)->declareLink(source, target);
+ result->setVoid();
+ } catch (const std::out_of_range& ex) {
+ LOGE("No container with id=" << container);
+ result->setError(api::ERROR_INVALID_ID, "No such container id");
+ } catch (const config::ConfigException& ex) {
+ LOGE("Can't declare link: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, "Internal error");
+ }
}
void ContainersManager::handleSetActiveContainerCall(const std::string& id,
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Mateusz Malicki <m.malicki2@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 Mateusz Malicki (m.malicki2@samsung.com)
+ * @brief Declaration of the class for storing container provisioning configuration
+ */
+
+
+#ifndef SERVER_PROVISIONING_CONFIG_HPP
+#define SERVER_PROVISIONING_CONFIG_HPP
+
+#include "config/fields.hpp"
+#include "config/fields-union.hpp"
+#include <string>
+#include <vector>
+
+
+namespace security_containers {
+
+struct ContainerProvisioning
+{
+
+ struct File
+ {
+ std::int32_t type;
+ std::string path;
+ std::int32_t flags;
+ std::int32_t mode;
+
+ CONFIG_REGISTER
+ (
+ type,
+ path,
+ flags,
+ mode
+ )
+ };
+
+ struct Mount
+ {
+ std::string source;
+ std::string target;
+ std::string type;
+ std::int64_t flags;
+ std::string data;
+
+ CONFIG_REGISTER
+ (
+ source,
+ target,
+ type,
+ flags,
+ data
+ )
+ };
+
+ struct Link
+ {
+ std::string source;
+ std::string target;
+
+ CONFIG_REGISTER
+ (
+ source,
+ target
+ )
+ };
+
+ struct Unit
+ {
+ CONFIG_DECLARE_UNION
+ (
+ File,
+ Mount,
+ Link
+ )
+ };
+
+ std::vector<Unit> units;
+
+ CONFIG_REGISTER
+ (
+ units
+ )
+};
+
+}
+
+#endif // SERVER_PROVISIONING_CONFIG_HPP
#include "ut.hpp"
#include "containers-manager.hpp"
+#include "containers-manager-config.hpp"
+#include "container-config.hpp"
+#include "provisioning-config.hpp"
#include "container-dbus-definitions.hpp"
#include "host-dbus-definitions.hpp"
#include "test-dbus-definitions.hpp"
#include "dbus/connection.hpp"
#include "dbus/exception.hpp"
#include "utils/glib-loop.hpp"
+#include "config/manager.hpp"
#include "config/exception.hpp"
#include "utils/latch.hpp"
#include "utils/fs.hpp"
"Line 2\n";
const std::string NON_EXISTANT_CONTAINER_ID = "NON_EXISTANT_CONTAINER_ID";
const std::string CONTAINERS_PATH = "/tmp/ut-containers"; // the same as in daemon.conf
+const std::string PROVISON_CONFIG_FILE = "provision.conf";
class DbusAccessory {
public:
{}
};
+std::string getProvisionConfigPath(const std::string& container)
+{
+ namespace fs = boost::filesystem;
+ ContainersManagerConfig managerConfig;
+ loadFromFile(TEST_CONFIG_PATH, managerConfig);
+ for (const auto& containersPath : managerConfig.containerConfigs) {
+ ContainerConfig containerConfig;
+ const fs::path configConfigPath = fs::absolute(containersPath,
+ fs::path(TEST_CONFIG_PATH).parent_path());
+
+ loadFromFile(configConfigPath.string(), containerConfig);
+ if (containerConfig.name == container) {
+ const fs::path base = fs::path(managerConfig.containersPath) / fs::path(container);
+ return fs::absolute(PROVISON_CONFIG_FILE, base).string();
+ }
+ }
+ BOOST_FAIL("There is no provision config file for " + container);
+ return std::string();
+}
+
} // namespace
BOOST_AUTO_TEST_CASE(DeclareFile)
{
- //TODO Fill after implementing
const std::string container = EXPECTED_DBUSES_NO_DBUS.begin()->first;
+ const std::string provisionConfigPath = getProvisionConfigPath(container);
ContainersManager cm(TEST_CONFIG_PATH);
DbusAccessory dbus(DbusAccessory::HOST_ID);
- BOOST_CHECK_EXCEPTION(dbus.callMethodDeclareFile(container, 1, "path", 747, 777),
- DbusException,
- expectedMessage("Not implemented"));
+ dbus.callMethodDeclareFile(container, 1, "path", 0747, 0777);
+ dbus.callMethodDeclareFile(container, 2, "path", 0747, 0777);
+
+ ContainerProvisioning config;
+ BOOST_REQUIRE_NO_THROW(loadFromFile(provisionConfigPath, config));
+ BOOST_REQUIRE_EQUAL(config.units.size(), 2);
+ BOOST_REQUIRE(config.units[0].is<ContainerProvisioning::File>());
+ BOOST_REQUIRE(config.units[1].is<ContainerProvisioning::File>());
+ const ContainerProvisioning::File& unit = config.units[0].as<ContainerProvisioning::File>();
+ BOOST_CHECK_EQUAL(unit.type, 1);
+ BOOST_CHECK_EQUAL(unit.path, "path");
+ BOOST_CHECK_EQUAL(unit.flags, 0747);
+ BOOST_CHECK_EQUAL(unit.mode, 0777);
}
BOOST_AUTO_TEST_CASE(DeclareMount)
{
- //TODO Fill after implementing
const std::string container = EXPECTED_DBUSES_NO_DBUS.begin()->first;
+ const std::string provisionConfigPath = getProvisionConfigPath(container);
ContainersManager cm(TEST_CONFIG_PATH);
DbusAccessory dbus(DbusAccessory::HOST_ID);
- BOOST_CHECK_EXCEPTION(dbus.callMethodDeclareMount("/fake/path1",
- container,
- "/fake/path2",
- "tmpfs",
- 77,
- "fake"),
- DbusException,
- expectedMessage("Not implemented"));
-
+ dbus.callMethodDeclareMount("/fake/path1", container, "/fake/path2", "tmpfs", 077, "fake");
+ dbus.callMethodDeclareMount("/fake/path2", container, "/fake/path2", "tmpfs", 077, "fake");
+
+ ContainerProvisioning config;
+ BOOST_REQUIRE_NO_THROW(loadFromFile(provisionConfigPath, config));
+ BOOST_REQUIRE_EQUAL(config.units.size(), 2);
+ BOOST_REQUIRE(config.units[0].is<ContainerProvisioning::Mount>());
+ BOOST_REQUIRE(config.units[1].is<ContainerProvisioning::Mount>());
+ const ContainerProvisioning::Mount& unit = config.units[0].as<ContainerProvisioning::Mount>();
+ BOOST_CHECK_EQUAL(unit.source, "/fake/path1");
+ BOOST_CHECK_EQUAL(unit.target, "/fake/path2");
+ BOOST_CHECK_EQUAL(unit.type, "tmpfs");
+ BOOST_CHECK_EQUAL(unit.flags, 077);
+ BOOST_CHECK_EQUAL(unit.data, "fake");
}
BOOST_AUTO_TEST_CASE(DeclareLink)
{
- //TODO Fill after implementing
const std::string container = EXPECTED_DBUSES_NO_DBUS.begin()->first;
+ const std::string provisionConfigPath = getProvisionConfigPath(container);
ContainersManager cm(TEST_CONFIG_PATH);
DbusAccessory dbus(DbusAccessory::HOST_ID);
- BOOST_CHECK_EXCEPTION(dbus.callMethodDeclareLink("/fake/path1", container, "/fake/path2"),
- DbusException,
- expectedMessage("Not implemented"));
+ dbus.callMethodDeclareLink("/fake/path1", container, "/fake/path2");
+ dbus.callMethodDeclareLink("/fake/path2", container, "/fake/path2");
+
+ ContainerProvisioning config;
+ BOOST_REQUIRE_NO_THROW(loadFromFile(provisionConfigPath, config));
+ BOOST_REQUIRE_EQUAL(config.units.size(), 2);
+ BOOST_REQUIRE(config.units[0].is<ContainerProvisioning::Link>());
+ BOOST_REQUIRE(config.units[1].is<ContainerProvisioning::Link>());
+ const ContainerProvisioning::Link& unit = config.units[0].as<ContainerProvisioning::Link>();
+ BOOST_CHECK_EQUAL(unit.source, "/fake/path1");
+ BOOST_CHECK_EQUAL(unit.target, "/fake/path2");
}
BOOST_AUTO_TEST_CASE(LockUnlockContainerTest)