Taking into account the provision configuration 07/31207/12
authorMateusz Malicki <m.malicki2@samsung.com>
Tue, 9 Dec 2014 14:56:40 +0000 (15:56 +0100)
committerJan Olszak <j.olszak@samsung.com>
Fri, 19 Dec 2014 15:08:14 +0000 (07:08 -0800)
[Feature]      Taking into account the provision configuration
[Cause]        N/A
[Solution]     N/A
[Verification] Build, install, run tests

Change-Id: I2b564bb3f9af2514781ff2233cabb7b1ca654e69

39 files changed:
client/vasum-client-impl.cpp
common/base-exception.cpp [new file with mode: 0644]
common/base-exception.hpp
common/utils/fs.cpp
common/utils/fs.hpp
server/CMakeLists.txt
server/configs/templates/template.conf
server/configs/zones/business.conf
server/configs/zones/private.conf
server/zone-config.hpp
server/zone-provision-config.hpp [moved from server/provisioning-config.hpp with 100% similarity]
server/zone-provision.cpp [new file with mode: 0644]
server/zone-provision.hpp [new file with mode: 0644]
server/zone.cpp
server/zone.hpp
server/zones-manager.cpp
tests/unit_tests/client/configs/ut-client/zones/console1-dbus.conf.in
tests/unit_tests/client/configs/ut-client/zones/console2-dbus.conf.in
tests/unit_tests/client/configs/ut-client/zones/console3-dbus.conf.in
tests/unit_tests/server/configs/ut-server/zones/zone1.conf
tests/unit_tests/server/configs/ut-server/zones/zone2.conf
tests/unit_tests/server/configs/ut-server/zones/zone3.conf
tests/unit_tests/server/configs/ut-zone-admin/zones/buggy.conf
tests/unit_tests/server/configs/ut-zone-admin/zones/missing.conf
tests/unit_tests/server/configs/ut-zone-admin/zones/test-no-shutdown.conf
tests/unit_tests/server/configs/ut-zone-admin/zones/test.conf
tests/unit_tests/server/configs/ut-zone/zones/buggy.conf
tests/unit_tests/server/configs/ut-zone/zones/test-dbus.conf.in
tests/unit_tests/server/configs/ut-zone/zones/test.conf
tests/unit_tests/server/configs/ut-zones-manager/templates/template.conf.in
tests/unit_tests/server/configs/ut-zones-manager/zones/console1-dbus.conf.in
tests/unit_tests/server/configs/ut-zones-manager/zones/console1.conf
tests/unit_tests/server/configs/ut-zones-manager/zones/console2-dbus.conf.in
tests/unit_tests/server/configs/ut-zones-manager/zones/console2.conf
tests/unit_tests/server/configs/ut-zones-manager/zones/console3-dbus.conf.in
tests/unit_tests/server/configs/ut-zones-manager/zones/console3.conf
tests/unit_tests/server/ut-zone-provision.cpp [new file with mode: 0644]
tests/unit_tests/server/ut-zones-manager.cpp
zone-daemon/CMakeLists.txt

index 23270e4..2aa923d 100644 (file)
@@ -322,7 +322,7 @@ VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* keys, VsmArrayString* valu
     assert(keys);
     assert(values);
 
-    GVariant* out;
+    GVariant* out = NULL;
     VsmStatus ret = callMethod(HOST_INTERFACE,
                                api::host::METHOD_GET_ZONE_DBUSES,
                                NULL,
@@ -343,7 +343,7 @@ VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept
 {
     assert(array);
 
-    GVariant* out;
+    GVariant* out = NULL;
     VsmStatus ret = callMethod(HOST_INTERFACE,
                                api::host::METHOD_GET_ZONE_ID_LIST,
                                NULL,
diff --git a/common/base-exception.cpp b/common/base-exception.cpp
new file mode 100644 (file)
index 0000000..bcfe600
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  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   Vasum base exception implementation
+ */
+
+#include "base-exception.hpp"
+
+#include <string>
+#include <cstring>
+#include <cerrno>
+
+namespace vasum {
+
+const int ERROR_MESSAGE_BUFFER_CAPACITY = 256;
+
+std::string getSystemErrorMessage()
+{
+    char buf[ERROR_MESSAGE_BUFFER_CAPACITY];
+    return strerror_r(errno, buf, sizeof(buf));
+}
+
+} // namespace vasum
index d501e3d..3969404 100644 (file)
@@ -41,6 +41,11 @@ struct VasumException: public std::runtime_error {
     VasumException(const std::string& error = "") : std::runtime_error(error) {}
 };
 
+/**
+ * Return string describing error number
+ * it is wrapper for strerror_r
+ */
+std::string getSystemErrorMessage();
 
 } // namespace vasum
 
index 3330cbf..763bdfe 100644 (file)
 #include <sys/mount.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include <iostream>
 
 
+namespace fs = boost::filesystem;
+
 namespace vasum {
 namespace utils {
 
@@ -140,6 +143,36 @@ bool mountRun(const std::string& path)
            || utils::mountTmpfs(path, RUN_MOUNT_POINT_FLAGS, RUN_MOUNT_POINT_OPTIONS_NO_SMACK);
 }
 
+bool mount(const std::string& source,
+           const std::string& target,
+           const std::string& filesystemtype,
+           unsigned long mountflags,
+           const std::string& data)
+{
+    int ret = ::mount(source.c_str(),
+                      target.c_str(),
+                      filesystemtype.c_str(),
+                      mountflags,
+                      data.c_str());
+    if (ret < 0) {
+        LOGE("Mount operation failure: "
+             << "source path: "
+             << source
+             << ", target path: "
+             << target
+             << ", filesystemtype: "
+             << filesystemtype
+             << ", mountflags: "
+             << mountflags
+             << ", data: "
+             << data
+             << ", msg: "
+             << getSystemErrorMessage());
+        return false;
+    }
+    return true;
+}
+
 bool umount(const std::string& path)
 {
     if (::umount(path.c_str()) != 0) {
@@ -181,7 +214,6 @@ bool moveFile(const std::string& src, const std::string& dst)
 {
     bool bResult;
 
-    namespace fs = boost::filesystem;
     boost::system::error_code error;
 
     // The destination has to be a full path (including a file name)
@@ -218,8 +250,6 @@ namespace {
 
 bool copyDirContentsRec(const boost::filesystem::path& src, const boost::filesystem::path& dst)
 {
-    namespace fs = boost::filesystem;
-
     try {
         for (fs::directory_iterator file(src);
              file != fs::directory_iterator();
@@ -274,26 +304,34 @@ bool copyDirContentsRec(const boost::filesystem::path& src, const boost::filesys
     return true;
 }
 
+boost::filesystem::perms getPerms(const mode_t& mode)
+{
+    return static_cast<boost::filesystem::perms>(mode);
+}
+
+bool copySmackLabel(const std::string& /* src */, const std::string& /* dst */)
+{
+    //TODO: fill copySmackLabel function
+    return true;
+}
+
+
 } // namespace
 
 bool copyDirContents(const std::string& src, const std::string& dst)
 {
-    namespace fs = boost::filesystem;
-
     return copyDirContentsRec(fs::path(src), fs::path(dst));
 }
 
 bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem::perms mode)
 {
-    namespace fs = boost::filesystem;
-
     fs::path dirPath(path);
-    boost::system::error_code ec;
+    boost::system::error_code errorCode;
     bool runDirCreated = false;
     if (!fs::exists(dirPath)) {
-        if (!fs::create_directory(dirPath, ec)) {
+        if (!fs::create_directory(dirPath, errorCode)) {
             LOGE("Failed to create directory '" << path << "': "
-                 << ec.message());
+                 << errorCode.message());
             return false;
         }
         runDirCreated = true;
@@ -303,10 +341,10 @@ bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem:
     }
 
     // set permissions
-    fs::permissions(dirPath, mode, ec);
+    fs::permissions(dirPath, mode, errorCode);
     if (fs::status(dirPath).permissions() != mode) {
         LOGE("Failed to set permissions to '" << path << "': "
-             << ec.message());
+             << errorCode.message());
         return false;
     }
 
@@ -323,10 +361,36 @@ bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem:
     return true;
 }
 
-bool createEmptyDir(const std::string& path)
+bool createDirs(const std::string& path, mode_t mode)
 {
-    namespace fs = boost::filesystem;
+    boost::filesystem::perms perms = getPerms(mode);
+    std::vector<fs::path> dirs;
+    fs::path prefix;
+    fs::path dirPath = fs::path(path);
+    for (const auto dir : dirPath) {
+        prefix /= dir;
+        if (!fs::exists(prefix)) {
+            bool created = createDir(prefix.string(), -1, -1, perms);
+            if (created) {
+                dirs.push_back(prefix);
+            } else {
+                LOGE("Failed to create dir");
+                for (auto dir = dirs.rbegin(); dir != dirs.rend(); ++dir) {
+                    boost::system::error_code errorCode;
+                    fs::remove(*dir, errorCode);
+                    if (errorCode) {
+                        LOGE("Error during cleaning: dir: " << *dir << ", msg: " << errorCode.message());
+                    }
+                }
+                return false;
+            }
+        }
+    }
+    return true;
+}
 
+bool createEmptyDir(const std::string& path)
+{
     fs::path dirPath(path);
     boost::system::error_code ec;
     bool cleanDirCreated = false;
@@ -353,5 +417,95 @@ bool createEmptyDir(const std::string& path)
     return true;
 }
 
+bool createFile(const std::string& path, int flags, mode_t mode)
+{
+    // TODO: Check if we really need *flags* in the API
+    int ret = ::open(path.c_str(), flags, mode);
+    if (ret < 0) {
+        LOGE("Failed to create file: path=host:"
+             << path
+             << ", msg: "
+             << getSystemErrorMessage());
+        return false;
+    }
+    close(ret);
+    return true;
+}
+
+bool createFifo(const std::string& path, mode_t mode)
+{
+   int ret = ::mkfifo(path.c_str(), mode);
+   if (ret < 0) {
+       LOGE("Failed to make fifo: path=host:" << path);
+       return false;
+   }
+   return true;
+}
+
+bool copyFile(const std::string& src, const std::string& dest)
+{
+    boost::system::error_code errorCode;
+    fs::copy_file(src, dest, errorCode);
+    if (errorCode) {
+        LOGE("Failed to copy file: msg: "
+             << errorCode.message()
+             << ", path=host:"
+             << src
+             << ", path=host:"
+             << dest);
+        return false;
+    }
+    bool retSmack = copySmackLabel(src, dest);
+    if (!retSmack) {
+        LOGE("Failed to copy file: msg: (can't copy smacklabel) "
+             << ", path=host:"
+             << src
+             << ", path=host:"
+             << dest);
+        fs::remove(src, errorCode);
+        if (errorCode) {
+            LOGE("Failed to clean after copy failure: path=host:"
+                 << src
+                 << ", msg: "
+                 << errorCode.message());
+        }
+        return false;
+    }
+    return true;
+}
+
+bool createLink(const std::string& src, const std::string& dest)
+{
+    int retLink = ::link(src.c_str(), dest.c_str());
+    if (retLink < 0) {
+        LOGE("Failed to hard link: path=host:"
+             << src
+             << ", path=host:"
+             << dest
+             << ", msg:"
+             << getSystemErrorMessage());
+        return false;
+    }
+    bool retSmack = copySmackLabel(src, dest);
+    if (!retSmack) {
+        LOGE("Failed to copy smack label: path=host:"
+              << src
+              << ", path=host:"
+              << dest);
+        boost::system::error_code ec;
+        fs::remove(dest, ec);
+        if (!ec) {
+            LOGE("Failed to clean after hard link creation failure: path=host:"
+                 << src
+                 << ", to: "
+                 << dest
+                 << ", msg: "
+                 << ec.message());
+        }
+        return false;
+    }
+    return true;
+}
+
 } // namespace utils
 } // namespace vasum
index 35000c6..b00f95a 100644 (file)
@@ -70,6 +70,15 @@ bool listDir(const std::string& path, std::vector<std::string>& files);
 bool mountRun(const std::string& path);
 
 /**
+ * Creates mount point
+ */
+bool mount(const std::string& source,
+           const std::string& target,
+           const std::string& filesystemtype,
+           unsigned long mountflags,
+           const std::string& data);
+
+/**
  * Umounts a filesystem
  */
 bool umount(const std::string& path);
@@ -102,12 +111,36 @@ bool copyDirContents(const std::string& src, const std::string& dst);
 bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem::perms mode);
 
 /**
+ * Recursively creates a directory with specific permissions set.
+ */
+bool createDirs(const std::string& path, mode_t mode);
+
+/**
  * Creates an empty directory, ready to serve as mount point.
  * Succeeds either if path did not exist and was created successfully, or if already existing dir
  * under the same path is empty and is not a mount point.
  */
 bool createEmptyDir(const std::string& path);
 
+/**
+ * Creates an empty file
+ */
+bool createFile(const std::string& path, int flags, mode_t mode);
+
+/**
+ * Creates an FIFO special file
+ */
+bool createFifo(const std::string& path, mode_t mode);
+
+/**
+ * Copy an file
+ */
+bool copyFile(const std::string& src, const std::string& dest);
+
+/**
+ * Create hard link
+ */
+bool createLink(const std::string& src, const std::string& dest);
 
 } // namespace utils
 } // namespace vasum
index 8c7604a..adfef3e 100644 (file)
@@ -34,6 +34,7 @@ PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0 libsystemd-journal libsy
                   libcap-ng libLogger libSimpleDbus libConfig)
 
 INCLUDE_DIRECTORIES(${COMMON_FOLDER})
+INCLUDE_DIRECTORIES(${CLIENT_FOLDER})
 INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 TARGET_LINK_LIBRARIES(${SERVER_CODENAME} ${SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES})
 
index fa6ef5c..e011a64 100644 (file)
@@ -12,5 +12,9 @@
     "enableDbusIntegration" : true,
     "runMountPoint" : "~NAME~/run",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : [ "/tmp/",
+                            "/run/",
+                            "/opt/usr/data/",
+                            "/opt/usr/dbsapce/" ]
 }
index 6a4bc50..74c3bad 100644 (file)
@@ -12,5 +12,9 @@
     "switchToDefaultAfterTimeout" : true,
     "runMountPoint" : "business/run",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : [ "/tmp/",
+                            "/run/",
+                            "/opt/usr/data/",
+                            "/opt/usr/dbsapce/" ]
 }
index 2a1147f..ffb7e85 100644 (file)
@@ -12,5 +12,9 @@
     "switchToDefaultAfterTimeout" : true,
     "runMountPoint" : "private/run",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : [ "/tmp/",
+                            "/run/",
+                            "/opt/usr/data/",
+                            "/opt/usr/dbsapce/" ]
 }
index b801af8..f92ca8f 100644 (file)
@@ -112,6 +112,11 @@ struct ZoneConfig {
      */
     std::vector<std::string> permittedToRecv;
 
+    /**
+     * Valid hard link prefixes.
+     */
+    std::vector<std::string> validLinkPrefixes;
+
     CONFIG_REGISTER
     (
         name,
@@ -127,7 +132,8 @@ struct ZoneConfig {
         cpuQuotaBackground,
         runMountPoint,
         permittedToSend,
-        permittedToRecv
+        permittedToRecv,
+        validLinkPrefixes
     )
 };
 
diff --git a/server/zone-provision.cpp b/server/zone-provision.cpp
new file mode 100644 (file)
index 0000000..3bff4b5
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ *  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   Implementation of class for managing zone provsion
+ */
+
+#include "config.hpp"
+
+#include "zone-provision.hpp"
+#include "zone-provision-config.hpp"
+
+#include "logger/logger.hpp"
+#include "utils/fs.hpp"
+#include "utils/exception.hpp"
+#include "config/manager.hpp"
+#include "vasum-client.h"
+
+#include <boost/filesystem.hpp>
+
+#include <string>
+#include <fcntl.h>
+
+namespace fs = boost::filesystem;
+
+namespace vasum {
+
+namespace {
+
+const std::string ZONE_PROVISION_FILE = "provision.conf";
+
+void declareUnit(const std::string& file, ZoneProvisioning::Unit&& unit)
+{
+     // TODO: Add to the dynamic configuration
+    ZoneProvisioning config;
+    if (fs::exists(file)) {
+        config::loadFromFile(file, config);
+    }
+    config.units.push_back(std::move(unit));
+    config::saveToFile(file, config);
+}
+
+} // namespace
+
+ZoneProvision::ZoneProvision(const std::string& zonePath,
+                             const std::vector<std::string>& validLinkPrefixes)
+{
+    mProvisionFile = (fs::path(zonePath) / fs::path(ZONE_PROVISION_FILE)).string();
+    mRootPath = (zonePath / fs::path("rootfs")).string();
+    mValidLinkPrefixes = validLinkPrefixes;
+}
+
+std::string ZoneProvision::getRootPath() const
+{
+    return mRootPath;
+}
+
+
+void ZoneProvision::declareFile(const int32_t& type,
+                                const std::string& path,
+                                const int32_t& flags,
+                                const int32_t& mode)
+{
+    ZoneProvisioning::Unit unit;
+    unit.set(ZoneProvisioning::File({type, path, flags, mode}));
+
+    declareUnit(mProvisionFile, std::move(unit));
+}
+
+void ZoneProvision::declareMount(const std::string& source,
+                                 const std::string& target,
+                                 const std::string& type,
+                                 const int64_t& flags,
+                                 const std::string& data)
+{
+    ZoneProvisioning::Unit unit;
+    unit.set(ZoneProvisioning::Mount({source, target, type, flags, data}));
+
+    declareUnit(mProvisionFile, std::move(unit));
+}
+
+void ZoneProvision::declareLink(const std::string& source,
+                                const std::string& target)
+{
+    ZoneProvisioning::Unit unit;
+    unit.set(ZoneProvisioning::Link({source, target}));
+
+    declareUnit(mProvisionFile, std::move(unit));
+}
+
+void ZoneProvision::start() noexcept
+{
+    if (fs::exists(mProvisionFile)) {
+        config::loadFromFile(mProvisionFile, mProvisioningConfig);
+        for (const auto& unit : mProvisioningConfig.units) {
+            try {
+                if (unit.is<ZoneProvisioning::File>()) {
+                    file(unit.as<ZoneProvisioning::File>());
+                } else if (unit.is<ZoneProvisioning::Mount>()) {
+                    mount(unit.as<ZoneProvisioning::Mount>());
+                } else if (unit.is<ZoneProvisioning::Link>()) {
+                    link(unit.as<ZoneProvisioning::Link>());
+                }
+            } catch (std::exception& ex) {
+                LOGE("Provsion error: " << ex.what());
+            }
+        }
+    }
+}
+
+void ZoneProvision::stop() noexcept
+{
+    for (auto it = mProvisioningConfig.units.rbegin();
+         it != mProvisioningConfig.units.rend();
+         ++it) {
+        if (it->is<ZoneProvisioning::Mount>()) {
+            umount(it->as<ZoneProvisioning::Mount>());
+        }
+    }
+}
+
+void ZoneProvision::file(const ZoneProvisioning::File& config)
+{
+    bool ret = false;
+    const fs::path hostPath = fs::path(mRootPath) / fs::path(config.path);
+    switch (config.type) {
+        case VSMFILE_DIRECTORY:
+            ret = utils::createDirs(hostPath.string(), config.mode);
+            if (!ret) {
+                throw UtilsException("Can't create dir: " + hostPath.string());
+            }
+            break;
+
+        case VSMFILE_FIFO:
+            ret = utils::createFifo(hostPath.string(), config.mode);
+            if (!ret) {
+                throw UtilsException("Failed to make fifo: " + config.path);
+            }
+            break;
+
+        case VSMFILE_REGULAR:
+            if ((config.flags & O_CREAT)) {
+                ret = utils::createFile(hostPath.string(), config.flags, config.mode);
+                if (!ret) {
+                    throw UtilsException("Failed to create file: " + config.path);
+                }
+            } else {
+                ret = utils::copyFile(config.path, hostPath.string());
+                if (!ret) {
+                    throw UtilsException("Failed to copy file: " + config.path);
+                }
+            }
+            break;
+    }
+}
+
+void ZoneProvision::mount(const ZoneProvisioning::Mount& config)
+{
+    const fs::path hostPath = fs::path(mRootPath) / fs::path(config.target);
+    bool ret = utils::mount(config.source,
+                            hostPath.string(),
+                            config.type,
+                            config.flags,
+                            config.data);
+    if (!ret) {
+        throw UtilsException("Mount operation failure - source : " + config.source);
+    }
+}
+
+void ZoneProvision::umount(const ZoneProvisioning::Mount& config)
+{
+    const fs::path hostPath = fs::path(mRootPath) / fs::path(config.target);
+    utils::umount(hostPath.string());
+}
+
+void ZoneProvision::link(const ZoneProvisioning::Link& config)
+{
+    const std::string srcHostPath = fs::path(config.source).normalize().string();
+    for (const std::string& prefix : mValidLinkPrefixes) {
+        if (prefix.length() <= srcHostPath.length()
+            && srcHostPath.compare(0, prefix.length(), prefix) == 0) {
+
+            const fs::path destHostPath = fs::path(mRootPath) / fs::path(config.target);
+            bool ret = utils::createLink(srcHostPath, destHostPath.string());
+            if (!ret) {
+                throw UtilsException("Failed to create hard link: " +  config.source);
+            }
+            return;
+        }
+    }
+    LOGE("Failed to create hard link: path=host: "
+         << srcHostPath
+         << ", msg: Path prefix is not valid path");
+    throw UtilsException("Failed to hard link: path prefix is not valid");
+}
+
+} // namespace vasum
diff --git a/server/zone-provision.hpp b/server/zone-provision.hpp
new file mode 100644 (file)
index 0000000..d7cc1e4
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  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 managing zone provision
+ */
+
+
+#ifndef SERVER_ZONE_PROVISION_HPP
+#define SERVER_ZONE_PROVISION_HPP
+
+#include "zone-provision-config.hpp"
+
+#include <string>
+#include <vector>
+
+namespace vasum {
+
+
+/**
+ * Class is responsible for prepare filesystem for zone
+ * It allows to create directories, files, mount points and copying files from host
+ */
+class ZoneProvision {
+
+public:
+    /**
+     * ZoneProvision constructor
+     * @param zonesPath directory where zones are defined (lxc configs, rootfs etc)
+     */
+    ZoneProvision(const std::string& zonePath,
+                  const std::vector<std::string>& validLinkPrefixes);
+
+    /**
+     * Declare file, directory or pipe that will be created while zone 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 zone 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 zone startup
+     */
+    void declareLink(const std::string& source,
+                     const std::string& target);
+
+   /**
+     * Get zone root path
+     */
+    std::string getRootPath() const;
+
+    void start() noexcept;
+    void stop() noexcept;
+
+private:
+    ZoneProvisioning mProvisioningConfig;
+    std::string mRootPath;
+    std::string mProvisionFile;
+    std::vector<std::string> mValidLinkPrefixes;
+
+    void mount(const ZoneProvisioning::Mount& config);
+    void umount(const ZoneProvisioning::Mount& config);
+    void file(const ZoneProvisioning::File& config);
+    void link(const ZoneProvisioning::Link& config);
+};
+
+
+} // namespace vasum
+
+#endif // SERVER_ZONE_PROVISION_HPP
index 199ecff..f6fb188 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "zone.hpp"
 #include "base-exception.hpp"
-#include "provisioning-config.hpp"
 
 #include "logger/logger.hpp"
 #include "utils/paths.hpp"
@@ -38,7 +37,6 @@
 #include <string>
 #include <thread>
 
-
 namespace vasum {
 
 namespace fs = boost::filesystem;
@@ -50,18 +48,6 @@ typedef std::lock_guard<std::recursive_mutex> Lock;
 // 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 ZONE_PROVISION_FILE = "provision.conf";
-
-void declareUnit(const std::string& file, ZoneProvisioning::Unit&& unit)
-{
-     // TODO: Add to the dynamic configuration
-    ZoneProvisioning config;
-    if (fs::exists(file)) {
-        config::loadFromFile(file, config);
-    }
-    config.units.push_back(std::move(unit));
-    config::saveToFile(file, config);
-}
 
 } // namespace
 
@@ -86,8 +72,8 @@ Zone::Zone(const utils::Worker::Pointer& worker,
     }
 
     mAdmin.reset(new ZoneAdmin(zonesPath, lxcTemplatePrefix, mConfig));
-    const fs::path baseProvision = fs::path(zonesPath) / mAdmin->getId();
-    mProvisionConfig = fs::absolute(ZONE_PROVISION_FILE, baseProvision).string();
+    const fs::path zonePath = fs::path(zonesPath) / mAdmin->getId();
+    mProvision.reset(new ZoneProvision(zonePath.string(), mConfig.validLinkPrefixes));
 }
 
 Zone::~Zone()
@@ -123,6 +109,7 @@ int Zone::getPrivilege() const
 void Zone::start()
 {
     Lock lock(mReconnectMutex);
+    mProvision->start();
     if (mConfig.enableDbusIntegration) {
         mConnectionTransport.reset(new ZoneConnectionTransport(mRunMountPoint));
     }
@@ -162,6 +149,7 @@ void Zone::stop()
     disconnect();
     mAdmin->stop();
     mConnectionTransport.reset();
+    mProvision->stop();
 }
 
 void Zone::connect()
@@ -211,6 +199,12 @@ int Zone::getVT() const
     return mConfig.vt;
 }
 
+std::string Zone::getRootPath() const
+{
+    return mProvision->getRootPath();
+}
+
+
 bool Zone::activateVT()
 {
     Lock lock(mReconnectMutex);
@@ -399,35 +393,26 @@ void Zone::proxyCallAsync(const std::string& busName,
 }
 
 void Zone::declareFile(const int32_t& type,
-                            const std::string& path,
-                            const int32_t& flags,
-                            const int32_t& mode)
+                       const std::string& path,
+                       const int32_t& flags,
+                       const int32_t& mode)
 {
-    ZoneProvisioning::Unit unit;
-    unit.set(std::move(ZoneProvisioning::File({type, path, flags, mode})));
-
-    declareUnit(mProvisionConfig, std::move(unit));
+    mProvision->declareFile(type, path, flags, mode);
 }
 
 void Zone::declareMount(const std::string& source,
-                             const std::string& target,
-                             const std::string& type,
-                             const int64_t& flags,
-                             const std::string& data)
+                        const std::string& target,
+                        const std::string& type,
+                        const int64_t& flags,
+                        const std::string& data)
 {
-    ZoneProvisioning::Unit unit;
-    unit.set(std::move(ZoneProvisioning::Mount({source, target, type, flags, data})));
-
-    declareUnit(mProvisionConfig, std::move(unit));
+    mProvision->declareMount(source, target, type, flags, data);
 }
 
 void Zone::declareLink(const std::string& source,
-                            const std::string& target)
+                       const std::string& target)
 {
-    ZoneProvisioning::Unit unit;
-    unit.set(std::move(ZoneProvisioning::Link({source, target})));
-
-    declareUnit(mProvisionConfig, std::move(unit));
+    mProvision->declareLink(source, target);
 }
 
 } // namespace vasum
index fba9399..dd0daca 100644 (file)
@@ -30,6 +30,7 @@
 #include "zone-admin.hpp"
 #include "zone-connection.hpp"
 #include "zone-connection-transport.hpp"
+#include "zone-provision.hpp"
 #include "utils/worker.hpp"
 
 #include <string>
@@ -254,6 +255,11 @@ public:
     void declareLink(const std::string& source,
                      const std::string& target);
 
+   /**
+     * Get zone root path
+     */
+    std::string getRootPath() const;
+
 private:
     utils::Worker::Pointer mWorker;
     ZoneConfig mConfig;
@@ -262,6 +268,7 @@ private:
     std::unique_ptr<ZoneConnectionTransport> mConnectionTransport;
     std::unique_ptr<ZoneAdmin> mAdmin;
     std::unique_ptr<ZoneConnection> mConnection;
+    std::unique_ptr<ZoneProvision> mProvision;
     mutable std::recursive_mutex mReconnectMutex;
     NotifyActiveZoneCallback mNotifyCallback;
     DisplayOffCallback mDisplayOffCallback;
@@ -270,7 +277,6 @@ private:
     DbusStateChangedCallback mDbusStateChangedCallback;
     std::string mDbusAddress;
     std::string mRunMountPoint;
-    std::string mProvisionConfig;
 
     void onNameLostCallback();
     void reconnectHandler();
index eafbe4b..1f9bef0 100644 (file)
@@ -628,15 +628,12 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id,
         result->setError(api::ERROR_INTERNAL, "Unrecognized state of zone");
         return;
     }
-    const auto zonePath = boost::filesystem::absolute(id, mConfig.zonesPath);
-    const auto rootfsDir = boost::filesystem::path("rootfs");
-    const auto rootfsPath = zonePath / rootfsDir;
 
     result->set(g_variant_new("((siss))",
                               id.c_str(),
                               zone->getVT(),
                               state,
-                              rootfsPath.string().c_str()));
+                              zone->getRootPath().c_str()));
 }
 
 void ZonesManager::handleDeclareFileCall(const std::string& zone,
index 72fbdbf..46fb716 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zones-manager-console1-dbus",
     "permittedToSend" : [ "/tmp/.*", "/etc/secret2" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index 1386878..260d01f 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zones-manager-console2-dbus",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ]
+    "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ],
+    "validLinkPrefixes" : []
 }
index f91754f..e20ffe9 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zones-manager-console3-dbus",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index 898eef2..2c2ccde 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index 8f4687a..1d500a7 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index fdb958f..a9856c7 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index 320dc00..e96dca8 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index 9aaf464..9a5ec68 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index b3b0141..be05697 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index ae046e5..45213d7 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index 55586b4..eaf0811 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index 4f8e6db..e4a18fa 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zone-test-dbus",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : []
 }
index a8f9692..4386c8c 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [],
-    "permittedToRecv" : []
+    "permittedToRecv" : [],
+    "validLinkPrefixes" : [ "/tmp" ]
 }
index 15185d6..7c2f5e4 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/~NAME~",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index 72fbdbf..46fb716 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zones-manager-console1-dbus",
     "permittedToSend" : [ "/tmp/.*", "/etc/secret2" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index 3e88c3d..41071ad 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index 1386878..260d01f 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zones-manager-console2-dbus",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ]
+    "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ],
+    "validLinkPrefixes" : []
 }
index 22f7a39..f152092 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index f91754f..e20ffe9 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "/tmp/ut-run/ut-zones-manager-console3-dbus",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
index 2f99f23..4979dd2 100644 (file)
@@ -12,5 +12,6 @@
     "cpuQuotaBackground" : 1000,
     "runMountPoint" : "",
     "permittedToSend" : [ "/tmp/.*" ],
-    "permittedToRecv" : [ "/tmp/.*" ]
+    "permittedToRecv" : [ "/tmp/.*" ],
+    "validLinkPrefixes" : []
 }
diff --git a/tests/unit_tests/server/ut-zone-provision.cpp b/tests/unit_tests/server/ut-zone-provision.cpp
new file mode 100644 (file)
index 0000000..6a6e4ef
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ *  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   Unit tests of the ZoneProvsion class
+ */
+
+#include "config.hpp"
+#include "ut.hpp"
+
+#include "zone.hpp"
+
+#include "utils/glib-loop.hpp"
+#include "utils/scoped-dir.hpp"
+#include "config/manager.hpp"
+#include "zone-provision-config.hpp"
+#include "vasum-client.h"
+
+#include <memory>
+#include <string>
+
+#include <boost/filesystem.hpp>
+#include <sys/mount.h>
+#include <fcntl.h>
+
+using namespace vasum;
+using namespace config;
+
+namespace fs = boost::filesystem;
+
+namespace {
+
+const std::string PROVISON_CONFIG_FILE = "provision.conf";
+const std::string ZONE = "ut-zone-test";
+const fs::path TEST_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zone/zones/test.conf";
+const fs::path ZONES_PATH = "/tmp/ut-zones";
+const fs::path LXC_TEMPLATES_PATH = VSM_TEST_LXC_TEMPLATES_INSTALL_DIR;
+const fs::path ZONE_PATH = ZONES_PATH / fs::path(ZONE);
+const fs::path PROVISION_FILE_PATH = ZONE_PATH / fs::path(PROVISON_CONFIG_FILE);
+const fs::path ROOTFS_PATH = ZONE_PATH / fs::path("rootfs");
+
+struct Fixture {
+    utils::ScopedGlibLoop mLoop;
+    utils::ScopedDir mZonesPathGuard;
+    utils::ScopedDir mRunGuard;
+    utils::ScopedDir mRootfsPath;
+
+    Fixture()
+        : mZonesPathGuard(ZONES_PATH.string())
+        , mRunGuard("/tmp/ut-run")
+        , mRootfsPath(ROOTFS_PATH.string())
+    {
+    }
+
+    std::unique_ptr<Zone> create(const std::string& configPath)
+    {
+        return std::unique_ptr<Zone>(new Zone(utils::Worker::create(),
+                                              ZONES_PATH.string(),
+                                              configPath,
+                                              LXC_TEMPLATES_PATH.string(),
+                                              ""));
+    }
+};
+
+} // namespace
+
+
+BOOST_FIXTURE_TEST_SUITE(ZoneProvisionSuite, Fixture)
+
+BOOST_AUTO_TEST_CASE(FileTest)
+{
+    //TODO: Test Fifo
+    const fs::path regularFile = fs::path("/opt/usr/data/ut-regular-file");
+    const fs::path copyFile = PROVISION_FILE_PATH;
+
+    ZoneProvisioning config;
+    ZoneProvisioning::Unit unit;
+    unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+                                    regularFile.parent_path().string(),
+                                    0,
+                                    0777}));
+    config.units.push_back(unit);
+
+    unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+                                    regularFile.string(),
+                                    O_CREAT,
+                                    0777}));
+    config.units.push_back(unit);
+
+    unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+                                    copyFile.parent_path().string(),
+                                    0,
+                                    0777}));
+    config.units.push_back(unit);
+    unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+                                    copyFile.string(),
+                                    0,
+                                    0777}));
+    config.units.push_back(unit);
+    config::saveToFile(PROVISION_FILE_PATH.string(), config);
+    auto c = create(TEST_CONFIG_PATH.string());
+    c->start();
+
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / regularFile.parent_path()));
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / regularFile));
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / copyFile.parent_path()));
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / copyFile));
+
+    c->stop();
+}
+
+BOOST_AUTO_TEST_CASE(MountTest)
+{
+    //TODO: Test Fifo
+    const fs::path mountTarget = fs::path("/opt/usr/data/ut-from-host-provision");
+    const fs::path mountSource = fs::path("/tmp/ut-provision");
+    const fs::path sharedFile = fs::path("ut-regular-file");
+
+    utils::ScopedDir provisionfs(mountSource.string());
+
+
+    ZoneProvisioning config;
+    ZoneProvisioning::Unit unit;
+    unit.set(ZoneProvisioning::File({VSMFILE_DIRECTORY,
+                                    mountTarget.string(),
+                                    0,
+                                    0777}));
+    config.units.push_back(unit);
+    unit.set(ZoneProvisioning::Mount({mountSource.string(),
+                                      mountTarget.string(),
+                                      "",
+                                      MS_BIND,
+                                      ""}));
+    config.units.push_back(unit);
+    unit.set(ZoneProvisioning::File({VSMFILE_REGULAR,
+                                    (mountTarget / sharedFile).string(),
+                                    O_CREAT,
+                                    0777}));
+    config.units.push_back(unit);
+
+    config::saveToFile(PROVISION_FILE_PATH.string(), config);
+    auto c = create(TEST_CONFIG_PATH.string());
+    c->start();
+
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / mountTarget));
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / mountTarget / sharedFile));
+    BOOST_CHECK(fs::exists(mountSource / sharedFile));
+
+    c->stop();
+}
+
+BOOST_AUTO_TEST_CASE(LinkTest)
+{
+    const fs::path linkFile = fs::path("/ut-from-host-provision.conf");
+
+    ZoneProvisioning config;
+    ZoneProvisioning::Unit unit;
+
+    unit.set(ZoneProvisioning::Link({PROVISION_FILE_PATH.string(),
+                                     linkFile.string()}));
+    config.units.push_back(unit);
+    config::saveToFile(PROVISION_FILE_PATH.string(), config);
+    auto c = create(TEST_CONFIG_PATH.string());
+    c->start();
+
+    BOOST_CHECK(fs::exists(ROOTFS_PATH / linkFile));
+
+    c->stop();
+}
+
+BOOST_AUTO_TEST_CASE(DeclareFile)
+{
+    ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+    zoneProvision.declareFile(1, "path", 0747, 0777);
+    zoneProvision.declareFile(2, "path", 0747, 0777);
+
+    ZoneProvisioning config;
+    BOOST_REQUIRE_NO_THROW(loadFromFile(PROVISION_FILE_PATH.string(), config));
+    BOOST_REQUIRE_EQUAL(config.units.size(), 2);
+    BOOST_REQUIRE(config.units[0].is<ZoneProvisioning::File>());
+    BOOST_REQUIRE(config.units[1].is<ZoneProvisioning::File>());
+    const ZoneProvisioning::File& unit = config.units[0].as<ZoneProvisioning::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)
+{
+    ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+    zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake");
+    zoneProvision.declareMount("/fake/path2", "/fake/path2", "tmpfs", 077, "fake");
+
+    ZoneProvisioning config;
+    BOOST_REQUIRE_NO_THROW(loadFromFile(PROVISION_FILE_PATH.string(), config));
+    BOOST_REQUIRE_EQUAL(config.units.size(), 2);
+    BOOST_REQUIRE(config.units[0].is<ZoneProvisioning::Mount>());
+    BOOST_REQUIRE(config.units[1].is<ZoneProvisioning::Mount>());
+    const ZoneProvisioning::Mount& unit = config.units[0].as<ZoneProvisioning::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)
+{
+    ZoneProvision zoneProvision(ZONE_PATH.string(), {});
+    zoneProvision.declareLink("/fake/path1", "/fake/path2");
+    zoneProvision.declareLink("/fake/path2", "/fake/path2");
+
+    ZoneProvisioning config;
+    BOOST_REQUIRE_NO_THROW(loadFromFile(PROVISION_FILE_PATH.string(), config));
+    BOOST_REQUIRE_EQUAL(config.units.size(), 2);
+    BOOST_REQUIRE(config.units[0].is<ZoneProvisioning::Link>());
+    BOOST_REQUIRE(config.units[1].is<ZoneProvisioning::Link>());
+    const ZoneProvisioning::Link& unit = config.units[0].as<ZoneProvisioning::Link>();
+    BOOST_CHECK_EQUAL(unit.source, "/fake/path1");
+    BOOST_CHECK_EQUAL(unit.target, "/fake/path2");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
index 4db9434..3c62478 100644 (file)
@@ -27,9 +27,6 @@
 #include "ut.hpp"
 
 #include "zones-manager.hpp"
-#include "zones-manager-config.hpp"
-#include "zone-config.hpp"
-#include "provisioning-config.hpp"
 #include "zone-dbus-definitions.hpp"
 #include "host-dbus-definitions.hpp"
 #include "test-dbus-definitions.hpp"
@@ -40,7 +37,6 @@
 #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"
@@ -82,7 +78,6 @@ const std::string FILE_CONTENT = "File content\n"
                                  "Line 2\n";
 const std::string NON_EXISTANT_ZONE_ID = "NON_EXISTANT_ZONE_ID";
 const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf
-const std::string PROVISON_CONFIG_FILE = "provision.conf";
 
 class DbusAccessory {
 public:
@@ -314,67 +309,6 @@ public:
 
     }
 
-    void callMethodDeclareFile(const std::string& zone,
-                               const int32_t& type,
-                               const std::string& path,
-                               const int32_t& flags,
-                               const int32_t& mode)
-    {
-        assert(isHost());
-        GVariant* parameters = g_variant_new("(sisii)",
-                                             zone.c_str(),
-                                             type,
-                                             path.c_str(),
-                                             flags,
-                                             mode);
-        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
-                                                 api::host::OBJECT_PATH,
-                                                 api::host::INTERFACE,
-                                                 api::host::METHOD_DECLARE_FILE,
-                                                 parameters,
-                                                 "()");
-    }
-
-    void callMethodDeclareMount(const std::string& source,
-                                const std::string& zone,
-                                const std::string& target,
-                                const std::string& type,
-                                const uint64_t& flags,
-                                const std::string& data)
-    {
-        assert(isHost());
-        GVariant* parameters = g_variant_new("(ssssts)",
-                                             source.c_str(),
-                                             zone.c_str(),
-                                             target.c_str(),
-                                             type.c_str(),
-                                             flags,
-                                             data.c_str());
-        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
-                                                 api::host::OBJECT_PATH,
-                                                 api::host::INTERFACE,
-                                                 api::host::METHOD_DECLARE_MOUNT,
-                                                 parameters,
-                                                 "()");
-    }
-
-    void callMethodDeclareLink(const std::string& source,
-                               const std::string& zone,
-                               const std::string& target)
-    {
-        assert(isHost());
-        GVariant* parameters = g_variant_new("(sss)",
-                                             source.c_str(),
-                                             zone.c_str(),
-                                             target.c_str());
-        GVariantPtr result = mClient->callMethod(api::host::BUS_NAME,
-                                                 api::host::OBJECT_PATH,
-                                                 api::host::INTERFACE,
-                                                 api::host::METHOD_DECLARE_LINK,
-                                                 parameters,
-                                                 "()");
-    }
-
     void callAsyncMethodCreateZone(const std::string& id,
                                         const VoidResultCallback& result)
     {
@@ -477,26 +411,6 @@ struct Fixture {
     {}
 };
 
-std::string getProvisionConfigPath(const std::string& zone)
-{
-    namespace fs = boost::filesystem;
-    ZonesManagerConfig managerConfig;
-    loadFromFile(TEST_CONFIG_PATH, managerConfig);
-    for (const auto& zonesPath : managerConfig.zoneConfigs) {
-        ZoneConfig zoneConfig;
-        const fs::path configConfigPath = fs::absolute(zonesPath,
-                                                       fs::path(TEST_CONFIG_PATH).parent_path());
-
-        loadFromFile(configConfigPath.string(), zoneConfig);
-        if (zoneConfig.name == zone) {
-            const fs::path base = fs::path(managerConfig.zonesPath) / fs::path(zone);
-            return fs::absolute(PROVISON_CONFIG_FILE, base).string();
-        }
-    }
-    BOOST_FAIL("There is no provision config file for " + zone);
-    return std::string();
-}
-
 } // namespace
 
 
@@ -1093,71 +1007,6 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
     BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), "");
 }
 
-BOOST_AUTO_TEST_CASE(DeclareFile)
-{
-    const std::string zone = EXPECTED_DBUSES_NO_DBUS.begin()->first;
-    const std::string provisionConfigPath =  getProvisionConfigPath(zone);
-
-    ZonesManager cm(TEST_CONFIG_PATH);
-    DbusAccessory dbus(DbusAccessory::HOST_ID);
-    dbus.callMethodDeclareFile(zone, 1, "path", 0747, 0777);
-    dbus.callMethodDeclareFile(zone, 2, "path", 0747, 0777);
-
-    ZoneProvisioning config;
-    BOOST_REQUIRE_NO_THROW(loadFromFile(provisionConfigPath, config));
-    BOOST_REQUIRE_EQUAL(config.units.size(), 2);
-    BOOST_REQUIRE(config.units[0].is<ZoneProvisioning::File>());
-    BOOST_REQUIRE(config.units[1].is<ZoneProvisioning::File>());
-    const ZoneProvisioning::File& unit = config.units[0].as<ZoneProvisioning::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)
-{
-    const std::string zone = EXPECTED_DBUSES_NO_DBUS.begin()->first;
-    const std::string provisionConfigPath =  getProvisionConfigPath(zone);
-
-    ZonesManager cm(TEST_CONFIG_PATH);
-    DbusAccessory dbus(DbusAccessory::HOST_ID);
-    dbus.callMethodDeclareMount("/fake/path1", zone, "/fake/path2", "tmpfs", 077, "fake");
-    dbus.callMethodDeclareMount("/fake/path2", zone, "/fake/path2", "tmpfs", 077, "fake");
-
-    ZoneProvisioning config;
-    BOOST_REQUIRE_NO_THROW(loadFromFile(provisionConfigPath, config));
-    BOOST_REQUIRE_EQUAL(config.units.size(), 2);
-    BOOST_REQUIRE(config.units[0].is<ZoneProvisioning::Mount>());
-    BOOST_REQUIRE(config.units[1].is<ZoneProvisioning::Mount>());
-    const ZoneProvisioning::Mount& unit = config.units[0].as<ZoneProvisioning::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)
-{
-    const std::string zone = EXPECTED_DBUSES_NO_DBUS.begin()->first;
-    const std::string provisionConfigPath =  getProvisionConfigPath(zone);
-
-    ZonesManager cm(TEST_CONFIG_PATH);
-    DbusAccessory dbus(DbusAccessory::HOST_ID);
-    dbus.callMethodDeclareLink("/fake/path1", zone, "/fake/path2");
-    dbus.callMethodDeclareLink("/fake/path2", zone, "/fake/path2");
-
-    ZoneProvisioning config;
-    BOOST_REQUIRE_NO_THROW(loadFromFile(provisionConfigPath, config));
-    BOOST_REQUIRE_EQUAL(config.units.size(), 2);
-    BOOST_REQUIRE(config.units[0].is<ZoneProvisioning::Link>());
-    BOOST_REQUIRE(config.units[1].is<ZoneProvisioning::Link>());
-    const ZoneProvisioning::Link& unit = config.units[0].as<ZoneProvisioning::Link>();
-    BOOST_CHECK_EQUAL(unit.source, "/fake/path1");
-    BOOST_CHECK_EQUAL(unit.target, "/fake/path2");
-}
-
 BOOST_AUTO_TEST_CASE(LockUnlockZoneTest)
 {
     ZonesManager cm(TEST_DBUS_CONFIG_PATH);
index 3fd611f..50bfa1a 100644 (file)
@@ -22,7 +22,8 @@ MESSAGE(STATUS "Generating makefile for the Zone Daemon...")
 FILE(GLOB project_SRCS *.cpp *.hpp)
 FILE(GLOB common_SRCS ${COMMON_FOLDER}/dbus/*.cpp  ${COMMON_FOLDER}/dbus/*.hpp
                       ${COMMON_FOLDER}/log/*.cpp   ${COMMON_FOLDER}/log/*.hpp
-                      ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/utils/*.hpp)
+                      ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/utils/*.hpp
+                      ${COMMON_FOLDER}/*.cpp)
 
 ## Setup target ################################################################
 SET(ZONE_DAEMON_CODENAME "${PROJECT_NAME}-zone-daemon")