assert(keys);
assert(values);
- GVariant* out;
+ GVariant* out = NULL;
VsmStatus ret = callMethod(HOST_INTERFACE,
api::host::METHOD_GET_ZONE_DBUSES,
NULL,
{
assert(array);
- GVariant* out;
+ GVariant* out = NULL;
VsmStatus ret = callMethod(HOST_INTERFACE,
api::host::METHOD_GET_ZONE_ID_LIST,
NULL,
--- /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 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
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
#include <sys/mount.h>
#include <sys/types.h>
#include <unistd.h>
+#include <fcntl.h>
#include <iostream>
+namespace fs = boost::filesystem;
+
namespace vasum {
namespace utils {
|| 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) {
{
bool bResult;
- namespace fs = boost::filesystem;
boost::system::error_code error;
// The destination has to be a full path (including a file name)
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();
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;
}
// 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;
}
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;
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
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);
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
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})
"enableDbusIntegration" : true,
"runMountPoint" : "~NAME~/run",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : [ "/tmp/",
+ "/run/",
+ "/opt/usr/data/",
+ "/opt/usr/dbsapce/" ]
}
"switchToDefaultAfterTimeout" : true,
"runMountPoint" : "business/run",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : [ "/tmp/",
+ "/run/",
+ "/opt/usr/data/",
+ "/opt/usr/dbsapce/" ]
}
"switchToDefaultAfterTimeout" : true,
"runMountPoint" : "private/run",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : [ "/tmp/",
+ "/run/",
+ "/opt/usr/data/",
+ "/opt/usr/dbsapce/" ]
}
*/
std::vector<std::string> permittedToRecv;
+ /**
+ * Valid hard link prefixes.
+ */
+ std::vector<std::string> validLinkPrefixes;
+
CONFIG_REGISTER
(
name,
cpuQuotaBackground,
runMountPoint,
permittedToSend,
- permittedToRecv
+ permittedToRecv,
+ validLinkPrefixes
)
};
--- /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 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
--- /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 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
#include "zone.hpp"
#include "base-exception.hpp"
-#include "provisioning-config.hpp"
#include "logger/logger.hpp"
#include "utils/paths.hpp"
#include <string>
#include <thread>
-
namespace vasum {
namespace fs = boost::filesystem;
// 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
}
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()
void Zone::start()
{
Lock lock(mReconnectMutex);
+ mProvision->start();
if (mConfig.enableDbusIntegration) {
mConnectionTransport.reset(new ZoneConnectionTransport(mRunMountPoint));
}
disconnect();
mAdmin->stop();
mConnectionTransport.reset();
+ mProvision->stop();
}
void Zone::connect()
return mConfig.vt;
}
+std::string Zone::getRootPath() const
+{
+ return mProvision->getRootPath();
+}
+
+
bool Zone::activateVT()
{
Lock lock(mReconnectMutex);
}
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
#include "zone-admin.hpp"
#include "zone-connection.hpp"
#include "zone-connection-transport.hpp"
+#include "zone-provision.hpp"
#include "utils/worker.hpp"
#include <string>
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;
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;
DbusStateChangedCallback mDbusStateChangedCallback;
std::string mDbusAddress;
std::string mRunMountPoint;
- std::string mProvisionConfig;
void onNameLostCallback();
void reconnectHandler();
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,
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console1-dbus",
"permittedToSend" : [ "/tmp/.*", "/etc/secret2" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console2-dbus",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ]
+ "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console3-dbus",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zone-test-dbus",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [],
- "permittedToRecv" : []
+ "permittedToRecv" : [],
+ "validLinkPrefixes" : [ "/tmp" ]
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/~NAME~",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console1-dbus",
"permittedToSend" : [ "/tmp/.*", "/etc/secret2" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console2-dbus",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ]
+ "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "/tmp/ut-run/ut-zones-manager-console3-dbus",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
"cpuQuotaBackground" : 1000,
"runMountPoint" : "",
"permittedToSend" : [ "/tmp/.*" ],
- "permittedToRecv" : [ "/tmp/.*" ]
+ "permittedToRecv" : [ "/tmp/.*" ],
+ "validLinkPrefixes" : []
}
--- /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 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()
#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"
#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_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:
}
- 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)
{
{}
};
-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
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);
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")