class Command {
public:
+ // do sth [mandatory]
virtual void execute() = 0;
+
+ // roll-back execute() action [optional]
+ virtual void revert() {}
};
} // namespace lxcpp
-#endif // LXCPP_COMMANDS_COMMAND_HPP
\ No newline at end of file
+#endif // LXCPP_COMMANDS_COMMAND_HPP
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Add new provisioned file/dir/link/mount command
+ */
+
+#include "lxcpp/commands/provision.hpp"
+#include "lxcpp/container.hpp"
+#include "lxcpp/provision-config.hpp"
+
+namespace lxcpp {
+
+void Provisions::execute()
+{
+ for(const auto & file : mConfig.mProvisions.files) {
+ ProvisionFile(mConfig, file).execute();
+ }
+
+ for(const auto & mount : mConfig.mProvisions.mounts) {
+ ProvisionMount(mConfig, mount).execute();
+ }
+
+ for(const auto & link : mConfig.mProvisions.links) {
+ ProvisionLink(mConfig, link).execute();
+ }
+}
+void Provisions::revert()
+{
+ for(const auto & file : mConfig.mProvisions.files) {
+ ProvisionFile(mConfig, file).revert();
+ }
+
+ for(const auto & mount : mConfig.mProvisions.mounts) {
+ ProvisionMount(mConfig, mount).revert();
+ }
+
+ for(const auto & link : mConfig.mProvisions.links) {
+ ProvisionLink(mConfig, link).revert();
+ }
+}
+
+
+void ProvisionFile::execute()
+{
+ // MJK TODO: add file
+}
+void ProvisionFile::revert()
+{
+ // MJK TODO: remove file from container
+}
+
+
+void ProvisionMount::execute()
+{
+ // MJK TODO: add mount
+}
+void ProvisionMount::revert()
+{
+ // MJK TODO: remove mount from container
+}
+
+
+void ProvisionLink::execute()
+{
+ // MJK TODO: add link
+}
+void ProvisionLink::revert()
+{
+ // MJK TODO: remove link from container
+}
+
+} // namespace lxcpp
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Add new provisioned file/dir/link/mount command
+ */
+
+#ifndef LXCPP_COMMAND_PROVISION_HPP
+#define LXCPP_COMMAND_PROVISION_HPP
+
+#include "lxcpp/commands/command.hpp"
+#include "lxcpp/container-config.hpp"
+#include "lxcpp/provision-config.hpp"
+
+#include <sys/types.h>
+
+namespace lxcpp {
+
+class Provisions final: Command {
+public:
+ /**
+ * Runs call in the container's context
+ *
+ * Add/remove all file/fifo/dir/mount/link provisions to/from the container
+ */
+ Provisions(ContainerConfig &config) : mConfig(config)
+ {
+ }
+
+ void execute();
+ void revert();
+
+private:
+ ContainerConfig& mConfig;
+};
+
+
+class ProvisionFile final: Command {
+public:
+ /**
+ * Runs call in the container's context
+ *
+ * Add/remove new file/fifo/dir provision to/from the container
+ */
+ ProvisionFile(ContainerConfig &config, const provision::File &file) :
+ mConfig(config), mFile(file)
+ {
+ }
+
+ void execute();
+ void revert();
+
+private:
+ ContainerConfig& mConfig;
+ const provision::File& mFile;
+};
+
+class ProvisionMount final: Command {
+public:
+ /**
+ * Runs call in the container's context
+ *
+ * Add/remove new mount provision to/from the container
+ */
+ ProvisionMount(ContainerConfig &config, const provision::Mount &mount) :
+ mConfig(config), mMount(mount)
+ {
+ }
+
+ void execute();
+ void revert();
+
+private:
+ ContainerConfig& mConfig;
+ const provision::Mount& mMount;
+};
+
+class ProvisionLink final: Command {
+public:
+ /**
+ * Runs call in the container's context
+ *
+ * Add/remove link provision to/from the container
+ */
+ ProvisionLink(ContainerConfig &config, const provision::Link &link) :
+ mConfig(config), mLink(link)
+ {
+ }
+
+ void execute();
+ void revert();
+
+private:
+ ContainerConfig& mConfig;
+ const provision::Link& mLink;
+};
+
+} // namespace lxcpp
+
+#endif // LXCPP_COMMAND_PROVISION_HPP
#include "lxcpp/logger-config.hpp"
#include "lxcpp/network-config.hpp"
#include "lxcpp/terminal-config.hpp"
+#include "lxcpp/provision-config.hpp"
#include <config/config.hpp>
#include <config/fields.hpp>
*/
int mNamespaces;
+ /**
+ * available files/dirs/mounts/links
+ *
+ * Set: by container provision manipulation methods
+ * Get: getFiles(), getMounts(), getLinks()
+ */
+ ProvisionConfig mProvisions;
+
ContainerConfig() : mGuardPid(-1), mInitPid(-1), mNamespaces(0) {}
CONFIG_REGISTER
mInit,
mLogger,
mTerminals,
- mNamespaces
+ mNamespaces,
+ mProvisions
)
};
#include "lxcpp/commands/start.hpp"
#include "lxcpp/commands/stop.hpp"
#include "lxcpp/commands/prep-host-terminal.hpp"
+#include "lxcpp/commands/provision.hpp"
#include "logger/logger.hpp"
#include "utils/exception.hpp"
void ContainerImpl::stop()
{
- // TODO: things to do when shuttting down the container:
+ // TODO: things to do when shutting down the container:
// - close PTY master FDs from the config so we won't keep PTYs open
Stop stop(mConfig);
console.execute();
}
+bool ContainerImpl::isRunning() const
+{
+ // TODO: race condition may occur, sync needed
+ return getInitPid() != -1;
+}
+
void ContainerImpl::addInterfaceConfig(const std::string& hostif,
const std::string& zoneif,
InterfaceType type,
ni.delInetAddr(addr);
}
+void ContainerImpl::declareFile(const provision::File::Type type,
+ const std::string& path,
+ const int32_t flags,
+ const int32_t mode)
+{
+ provision::File newFile({type, path, flags, mode});
+ mConfig.mProvisions.addFile(newFile);
+ // TODO: update guard config
+
+ if (isRunning()) {
+ ProvisionFile fileCmd(mConfig, newFile);
+ fileCmd.execute();
+ }
+}
+
+const FileVector& ContainerImpl::getFiles() const
+{
+ return mConfig.mProvisions.getFiles();
+}
+
+void ContainerImpl::removeFile(const provision::File& item)
+{
+ mConfig.mProvisions.removeFile(item);
+
+ if (isRunning()) {
+ ProvisionFile fileCmd(mConfig, item);
+ fileCmd.revert();
+ }
+}
+
+void ContainerImpl::declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t flags,
+ const std::string& data)
+{
+ provision::Mount newMount({source, target, type, flags, data});
+ mConfig.mProvisions.addMount(newMount);
+ // TODO: update guard config
+
+ if (isRunning()) {
+ ProvisionMount mountCmd(mConfig, newMount);
+ mountCmd.execute();
+ }
+}
+
+const MountVector& ContainerImpl::getMounts() const
+{
+ return mConfig.mProvisions.getMounts();
+}
+
+void ContainerImpl::removeMount(const provision::Mount& item)
+{
+ mConfig.mProvisions.removeMount(item);
+
+ if (isRunning()) {
+ ProvisionMount mountCmd(mConfig, item);
+ mountCmd.revert();
+ }
+}
+
+void ContainerImpl::declareLink(const std::string& source,
+ const std::string& target)
+{
+ provision::Link newLink({source, target});
+ mConfig.mProvisions.addLink(newLink);
+ // TODO: update guard config
+
+ if (isRunning()) {
+ ProvisionLink linkCmd(mConfig, newLink);
+ linkCmd.execute();
+ }
+}
+
+const LinkVector& ContainerImpl::getLinks() const
+{
+ return mConfig.mProvisions.getLinks();
+}
+
+void ContainerImpl::removeLink(const provision::Link& item)
+{
+ mConfig.mProvisions.removeLink(item);
+
+ if (isRunning()) {
+ ProvisionLink linkCmd(mConfig, item);
+ linkCmd.revert();
+ }
+}
+
} // namespace lxcpp
void attach(const std::vector<std::string>& argv,
const std::string& cwdInContainer);
void console();
+ bool isRunning() const;
// Network interfaces setup/config
/**
void addInetAddr(const std::string& ifname, const InetAddr& addr);
void delInetAddr(const std::string& ifname, const InetAddr& addr);
+ // Provisioning
+ void declareFile(const provision::File::Type type,
+ const std::string& path,
+ const int32_t flags,
+ const int32_t mode);
+ const FileVector& getFiles() const;
+ void removeFile(const provision::File& item);
+
+ void declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t flags,
+ const std::string& data);
+ const MountVector& getMounts() const;
+ void removeMount(const provision::Mount& item);
+
+ void declareLink(const std::string& source,
+ const std::string& target);
+ const LinkVector& getLinks() const;
+ void removeLink(const provision::Link& item);
+
private:
ContainerConfig mConfig;
};
#define LXCPP_CONTAINER_HPP
#include "lxcpp/network-config.hpp"
+#include "lxcpp/provision-config.hpp"
#include "lxcpp/logger-config.hpp"
#include <sys/types.h>
virtual void attach(const std::vector<std::string>& argv,
const std::string& cwdInContainer) = 0;
virtual void console() = 0;
+ virtual bool isRunning() const = 0;
// Network interfaces setup/config
virtual void addInterfaceConfig(const std::string& hostif,
virtual void setDown(const std::string& ifname) = 0;
virtual void addInetAddr(const std::string& ifname, const InetAddr& addr) = 0;
virtual void delInetAddr(const std::string& ifname, const InetAddr& addr) = 0;
+
+ // Provisioning
+ virtual void declareFile(const provision::File::Type type,
+ const std::string& path,
+ const int32_t flags,
+ const int32_t mode) = 0;
+ virtual const FileVector& getFiles() const = 0;
+ virtual void removeFile(const provision::File& item) = 0;
+
+ virtual void declareMount(const std::string& source,
+ const std::string& target,
+ const std::string& type,
+ const int64_t flags,
+ const std::string& data) = 0;
+ virtual const MountVector& getMounts() const = 0;
+ virtual void removeMount(const provision::Mount& item) = 0;
+
+ virtual void declareLink(const std::string& source,
+ const std::string& target) = 0;
+ virtual const LinkVector& getLinks() const = 0;
+ virtual void removeLink(const provision::Link& item) = 0;
};
} // namespace lxcpp
: Exception(message) {}
};
+struct ProvisionException: public Exception {
+ explicit ProvisionException(const std::string& message = "Provision error")
+ : Exception(message) {}
+};
+
} // namespace lxcpp
#endif // LXCPP_EXCEPTION_HPP
#include "lxcpp/guard/guard.hpp"
#include "lxcpp/process.hpp"
#include "lxcpp/commands/prep-guest-terminal.hpp"
+#include "lxcpp/commands/provision.hpp"
#include "config/manager.hpp"
#include "logger/logger.hpp"
// TODO: container preparation part 2
+ Provisions provisions(config);
+ provisions.execute();
+
PrepGuestTerminal terminals(config.mTerminals);
terminals.execute();
int status = lxcpp::waitpid(initPid);
LOGD("Init exited with status: " << status);
+
+ // TODO: cleanup after child exits
+ Provisions provisions(mConfig);
+ provisions.revert();
+
return status;
}
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Provisioning configuration
+ */
+
+#include <vector>
+#include <string>
+#include "lxcpp/container-config.hpp"
+
+using namespace lxcpp;
+using namespace provision;
+
+void ProvisionConfig::addFile(const File& newFile)
+{
+ auto it = std::find(files.begin(), files.end(), newFile);
+ if (it != files.end()) {
+ const std::string msg =
+ "Can't add file. Provision already exists: " + newFile.getId();
+ LOGE(msg);
+ throw ProvisionException(msg);
+ }
+ files.push_back(newFile);
+}
+
+const FileVector& ProvisionConfig::getFiles() const
+{
+ return files;
+}
+
+void ProvisionConfig::removeFile(const File& item)
+{
+ const auto it = std::find(files.begin(), files.end(), item);
+ if (it == files.end()) {
+ const std::string msg = "Can't find provision: " + item.getId();
+ LOGE(msg);
+ throw ProvisionException(msg);
+ }
+ files.erase(it);
+}
+
+
+void ProvisionConfig::addMount(const Mount& newMount)
+{
+ auto it = std::find(mounts.begin(), mounts.end(), newMount);
+ if (it != mounts.end()) {
+ const std::string msg =
+ "Can't add mount. Provision already exists: " + newMount.getId();
+ LOGE(msg);
+ throw ProvisionException(msg);
+ }
+ mounts.push_back(newMount);
+}
+
+const MountVector& ProvisionConfig::getMounts() const
+{
+ return mounts;
+}
+
+void ProvisionConfig::removeMount(const Mount& item)
+{
+ const auto it = std::find(mounts.begin(), mounts.end(), item);
+ if (it == mounts.end()) {
+ const std::string msg = "Can't find provision: " + item.getId();
+ LOGE(msg);
+ throw ProvisionException(msg);
+ }
+ mounts.erase(it);
+}
+
+
+void ProvisionConfig::addLink(const Link& newLink)
+{
+ auto it = std::find(links.begin(), links.end(), newLink);
+ if (it != links.end()) {
+ const std::string msg =
+ "Can't add link. Provision already exists: " + newLink.getId();
+ LOGE(msg);
+ throw ProvisionException(msg);
+ }
+ links.push_back(newLink);
+}
+
+const LinkVector& ProvisionConfig::getLinks() const
+{
+ return links;
+}
+
+void ProvisionConfig::removeLink(const Link& item)
+{
+ const auto it = std::find(links.begin(), links.end(), item);
+ if (it == links.end()) {
+ const std::string msg = "Can't find provision: " + item.getId();
+ LOGE(msg);
+ throw ProvisionException(msg);
+ }
+ links.erase(it);
+}
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Provisioning configuration
+ */
+
+#ifndef LXCPP_PROVISION_CONFIG_HPP
+#define LXCPP_PROVISION_CONFIG_HPP
+
+#include "config/config.hpp"
+#include "config/fields.hpp"
+#include "config/fields-union.hpp"
+
+#include <vector>
+#include <string>
+#include <string.h>
+
+namespace lxcpp {
+namespace provision {
+
+typedef std::string ProvisionID;
+
+/**
+ * Provision configuration items
+ */
+struct File
+{
+ enum class Type : int
+ {
+ DIRECTORY,
+ FIFO,
+ REGULAR
+ };
+
+ ProvisionID getId() const
+ {
+ return "file " +
+ path + " " +
+ std::to_string(static_cast<int>(type)) + " " +
+ std::to_string(flags) + " " +
+ std::to_string(mode);
+ }
+
+ Type type;
+ std::string path;
+ std::int32_t flags;
+ std::int32_t mode;
+
+ CONFIG_REGISTER
+ (
+ type,
+ path,
+ flags,
+ mode
+ )
+
+ bool operator==(const File& m) const
+ {
+ return ((m.type == type) && (m.path == path) &&
+ (m.flags == flags) && (m.mode == mode));
+ }
+};
+
+struct Mount
+{
+ ProvisionID getId() const
+ {
+ return "mount " +
+ source + " " +
+ target + " " +
+ type + " " +
+ std::to_string(flags) + " " +
+ data;
+ }
+
+ std::string source;
+ std::string target;
+ std::string type;
+ std::int64_t flags;
+ std::string data;
+
+ CONFIG_REGISTER
+ (
+ source,
+ target,
+ type,
+ flags,
+ data
+ )
+
+ bool operator==(const Mount& m) const
+ {
+ return ((m.source == source) && (m.target == target) && (m.type == type) &&
+ (m.flags == flags) && (m.data == data));
+ }
+};
+
+struct Link
+{
+ ProvisionID getId() const
+ {
+ return "link " + source + " " + target;
+ }
+
+ std::string source;
+ std::string target;
+
+ CONFIG_REGISTER
+ (
+ source,
+ target
+ )
+
+ bool operator==(const Link& m) const
+ {
+ return ((m.source == source) && (m.target == target));
+ }
+};
+} // namespace provision
+
+typedef std::vector<provision::File> FileVector;
+typedef std::vector<provision::Mount> MountVector;
+typedef std::vector<provision::Link> LinkVector;
+
+struct ProvisionConfig
+{
+ FileVector files;
+ MountVector mounts;
+ LinkVector links;
+
+ void addFile(const provision::File& newFile);
+ const FileVector& getFiles() const;
+ void removeFile(const provision::File& item);
+
+ void addMount(const provision::Mount& newMount);
+ const MountVector& getMounts() const;
+ void removeMount(const provision::Mount& item);
+
+ void addLink(const provision::Link& newLink);
+ const LinkVector& getLinks() const;
+ void removeLink(const provision::Link& item);
+
+ CONFIG_REGISTER
+ (
+ files,
+ mounts,
+ links
+ )
+};
+
+} // namespace lxcpp
+
+#endif // LXCPP_PROVISION_CONFIG_HPP
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Unit tests of lxcpp provisioning
+ */
+
+#include "config.hpp"
+#include "config/manager.hpp"
+#include "lxcpp/lxcpp.hpp"
+#include "lxcpp/container.hpp"
+#include "lxcpp/container-config.hpp"
+#include "lxcpp/provision-config.hpp"
+#include "ut.hpp"
+#include "utils/scoped-dir.hpp"
+#include <iostream>
+
+namespace {
+
+using namespace lxcpp;
+using namespace config;
+using namespace provision;
+
+const std::string TEST_DIR = "/tmp/ut-provisioning";
+const std::string ROOT_DIR = TEST_DIR + "/root";
+
+struct Fixture {
+ Fixture() : mTestPath(ROOT_DIR) {
+ container = std::unique_ptr<Container>(createContainer("ProvisioningTester", ROOT_DIR));
+ }
+ ~Fixture() {}
+
+ std::unique_ptr<Container> container;
+ utils::ScopedDir mTestPath;
+};
+
+} // namespace
+
+
+BOOST_FIXTURE_TEST_SUITE(LxcppProvisioningSuite, Fixture)
+
+BOOST_AUTO_TEST_CASE(ListProvisionsEmptyContainer)
+{
+ BOOST_REQUIRE(container->getFiles().size() == 0);
+ BOOST_REQUIRE(container->getMounts().size() == 0);
+ BOOST_REQUIRE(container->getLinks().size() == 0);
+}
+
+BOOST_AUTO_TEST_CASE(AddDeclareFile)
+{
+ container->declareFile(File::Type::FIFO, "path", 0747, 0777);
+ container->declareFile(File::Type::REGULAR, "path", 0747, 0777);
+
+ std::vector<File> fileList = container->getFiles();
+ BOOST_REQUIRE_EQUAL(fileList.size(), 2);
+
+ BOOST_REQUIRE(fileList[0].type == File::Type::FIFO);
+ BOOST_REQUIRE(fileList[0].path == "path");
+ BOOST_REQUIRE(fileList[0].flags == 0747);
+ BOOST_REQUIRE(fileList[0].mode == 0777);
+ BOOST_REQUIRE(fileList[1].type == File::Type::REGULAR);
+
+ BOOST_REQUIRE_NO_THROW(container->removeFile(fileList[0]));
+ BOOST_REQUIRE_EQUAL(container->getFiles().size(), 1);
+ File dummyFile({File::Type::FIFO, "dummy", 1, 2});
+ BOOST_REQUIRE_THROW(container->removeFile(dummyFile), ProvisionException);
+ BOOST_REQUIRE_NO_THROW(container->removeFile(fileList[1]));
+ BOOST_REQUIRE_EQUAL(container->getFiles().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(AddDeclareMount)
+{
+ container->declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake");
+ container->declareMount("/fake/path2", "/fake/path2", "tmpfs", 077, "fake");
+ BOOST_CHECK_THROW(container->declareMount("/fake/path2", "/fake/path2", "tmpfs", 077, "fake"),
+ ProvisionException);
+
+ std::vector<Mount> mountList = container->getMounts();
+ BOOST_REQUIRE_EQUAL(mountList.size(), 2);
+
+ BOOST_REQUIRE(mountList[0].source == "/fake/path1");
+ BOOST_REQUIRE(mountList[0].target == "/fake/path2");
+ BOOST_REQUIRE(mountList[0].type == "tmpfs");
+ BOOST_REQUIRE(mountList[0].flags == 077);
+ BOOST_REQUIRE(mountList[0].data == "fake");
+
+ BOOST_REQUIRE(mountList[1].source == "/fake/path2");
+ BOOST_REQUIRE(mountList[1].target == "/fake/path2");
+ BOOST_REQUIRE(mountList[1].type == "tmpfs");
+ BOOST_REQUIRE(mountList[1].flags == 077);
+ BOOST_REQUIRE(mountList[1].data == "fake");
+
+ BOOST_REQUIRE_NO_THROW(container->removeMount(mountList[0]));
+ BOOST_REQUIRE_EQUAL(container->getMounts().size(), 1);
+ Mount dummyMount({"a", "b", "c", 1, "d"});
+ BOOST_REQUIRE_THROW(container->removeMount(dummyMount), ProvisionException);
+ BOOST_REQUIRE_NO_THROW(container->removeMount(mountList[1]));
+ BOOST_REQUIRE_EQUAL(container->getMounts().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(AddDeclareLink)
+{
+ container->declareLink("/fake/path1", "/fake/path2");
+ container->declareLink("/fake/path2", "/fake/path2");
+ BOOST_CHECK_THROW(container->declareLink("/fake/path2", "/fake/path2"),
+ ProvisionException);
+
+ std::vector<Link> linkList = container->getLinks();
+ BOOST_REQUIRE_EQUAL(linkList.size(), 2);
+
+ BOOST_REQUIRE(linkList[0].source == "/fake/path1");
+ BOOST_REQUIRE(linkList[0].target == "/fake/path2");
+ BOOST_REQUIRE(linkList[1].source == "/fake/path2");
+ BOOST_REQUIRE(linkList[1].target == "/fake/path2");
+
+ BOOST_REQUIRE_NO_THROW(container->removeLink(linkList[0]));
+ BOOST_REQUIRE_EQUAL(container->getLinks().size(), 1);
+ Link dummyLink({"a", "b"});
+ BOOST_REQUIRE_THROW(container->removeLink(dummyLink), ProvisionException);
+ BOOST_REQUIRE_NO_THROW(container->removeLink(linkList[1]));
+ BOOST_REQUIRE_EQUAL(container->getLinks().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(ProvisioningConfigSerialization)
+{
+ std::string tmpConfigFile = "/tmp/fileconfig.conf";
+ std::string tmpConfigMount = "/tmp/mountconfig.conf";
+ std::string tmpConfigLink = "/tmp/linkconfig.conf";
+
+ File saved_file ({File::Type::REGULAR, "path", 0747, 0777});
+ Mount saved_mount({"/fake/path1", "/fake/path2", "tmpfs", 077, "fake"});
+ Link saved_link ({"/fake/path1", "/fake/path2"});
+ config::saveToJsonFile(tmpConfigFile, saved_file);
+ config::saveToJsonFile(tmpConfigMount, saved_mount);
+ config::saveToJsonFile(tmpConfigLink, saved_link);
+
+ File loaded_file;
+ Mount loaded_mount;
+ Link loaded_link;
+ config::loadFromJsonFile(tmpConfigFile, loaded_file);
+ config::loadFromJsonFile(tmpConfigMount, loaded_mount);
+ config::loadFromJsonFile(tmpConfigLink, loaded_link);
+ BOOST_REQUIRE(saved_file == loaded_file);
+ BOOST_REQUIRE(saved_mount == loaded_mount);
+ BOOST_REQUIRE(saved_link == loaded_link);
+}
+
+BOOST_AUTO_TEST_SUITE_END()