lxcpp: provisioning implementation (part 2) 24/49724/14
authorMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Mon, 19 Oct 2015 12:03:14 +0000 (14:03 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Fri, 23 Oct 2015 08:56:00 +0000 (01:56 -0700)
[Feature]       Provisioning implementation for lxcpp: commands.
[Cause]         N/A
[Solution]      N/A
[Verification]  Build, install, run tests

Change-Id: I3089059c5c4491553a4f45876f372ccb6daab3bb

common/utils/fs.cpp
common/utils/fs.hpp
libs/lxcpp/commands/provision.cpp
libs/lxcpp/commands/provision.hpp

index 454ea4c..bae21f5 100644 (file)
@@ -163,6 +163,15 @@ void assertIsDir(const std::string& path)
     }
 }
 
+void assertIsAbsolute(const std::string& path)
+{
+    if (!fs::path(path).is_absolute()) {
+        const std::string msg = "Given path '" + path + "' must be absolute!";
+        LOGE(msg);
+        throw UtilsException(msg);
+    }
+}
+
 
 namespace {
 // NOTE: Should be the same as in systemd/src/core/mount-setup.c
index 2237450..2b95073 100644 (file)
@@ -70,6 +70,11 @@ bool isCharDevice(const std::string& path);
 void assertIsDir(const std::string& path);
 
 /**
+ * Checks if path is absolute
+ */
+void assertIsAbsolute(const std::string& path);
+
+/**
  * List all (including '.' and '..' entries) dir entries
  */
 bool listDir(const std::string& path, std::vector<std::string>& files);
index ba97393..d03d8c8 100644 (file)
 #include "lxcpp/commands/provision.hpp"
 #include "lxcpp/container.hpp"
 #include "lxcpp/provision-config.hpp"
+#include "lxcpp/filesystem.hpp"
+#include "utils/fs.hpp"
+#include <boost/filesystem.hpp>
+#include <sys/mount.h>
+
+// TODO: Cleanup file/path handling
 
 namespace lxcpp {
 
+namespace fs = boost::filesystem;
+
 void Provisions::execute()
 {
     for(const auto & file : mConfig.mProvisions.files) {
@@ -56,34 +64,97 @@ void Provisions::revert()
     }
 }
 
+ProvisionFile::ProvisionFile(ContainerConfig &config, const provision::File &file)
+    : mConfig(config), mFile(file)
+{
+    utils::assertIsAbsolute(file.path);
+}
 
 void ProvisionFile::execute()
 {
-    // MJK TODO: add file
+    using namespace provision;
+    const fs::path hostPath = fs::path(mConfig.mRootPath) / fs::path(mFile.path);
+
+    switch (mFile.type) {
+    case File::Type::DIRECTORY:
+        if (!utils::createDirs(hostPath.string(), mFile.mode)) {
+            const std::string msg = "Can't create dir: " + hostPath.string();
+            LOGE(msg);
+            throw ProvisionException(msg);
+        }
+        break;
+
+    case File::Type::FIFO:
+        if (!utils::createFifo(hostPath.string(), mFile.mode)) {
+            const std::string msg = "Failed to make fifo: " + mFile.path;
+            LOGE(msg);
+            throw ProvisionException(msg);
+        }
+        break;
+
+    case File::Type::REGULAR:
+        if ((mFile.flags & O_CREAT)) {
+            if (!utils::createFile(hostPath.string(), mFile.flags, mFile.mode)) {
+                const std::string msg = "Failed to create file: " + mFile.path;
+                LOGE(msg);
+                throw ProvisionException(msg);
+            }
+        } else {
+            if (!utils::copyFile(mFile.path, hostPath.string())) {
+                const std::string msg = "Failed to copy file: " + mFile.path;
+                LOGE(msg);
+                throw ProvisionException(msg);
+            }
+        }
+        break;
+    }
 }
 void ProvisionFile::revert()
 {
-    // MJK TODO: remove file from container
+    // TODO decision: should remove the file?
 }
 
 
+ProvisionMount::ProvisionMount(ContainerConfig &config, const provision::Mount &mount)
+    : mConfig(config), mMount(mount)
+{
+    utils::assertIsAbsolute(mount.target);
+}
+
 void ProvisionMount::execute()
 {
-    // MJK TODO: add mount
+    const fs::path hostPath = fs::path(mConfig.mRootPath) / fs::path(mMount.target);
+
+    lxcpp::mount(mMount.source, hostPath.string(), mMount.type, mMount.flags, mMount.data);
 }
 void ProvisionMount::revert()
 {
-    // MJK TODO: remove mount from container
+    const fs::path hostPath = fs::path(mConfig.mRootPath) / fs::path(mMount.target);
+
+    lxcpp::umount(hostPath.string(), MNT_DETACH);
 }
 
 
+ProvisionLink::ProvisionLink(ContainerConfig &config, const provision::Link &link)
+    : mConfig(config), mLink(link)
+{
+    utils::assertIsAbsolute(link.target);
+}
+
 void ProvisionLink::execute()
 {
-    // MJK TODO: add link
+    const std::string srcHostPath = fs::path(mLink.source).normalize().string();
+    const fs::path destHostPath = fs::path(mConfig.mRootPath) / fs::path(mLink.target);
+
+    if (!utils::createLink(srcHostPath, destHostPath.string())) {
+        const std::string msg = "Failed to create hard link: " +  mLink.source;
+        LOGE(msg);
+        throw ProvisionException(msg);
+    }
 }
 void ProvisionLink::revert()
 {
-    // MJK TODO: remove link from container
+    // TODO decision: should remove the link?
 }
 
 } // namespace lxcpp
index 0b7411a..350e967 100644 (file)
@@ -58,10 +58,7 @@ public:
     *
     * Add/remove new file/fifo/dir provision to/from the container
     */
-    ProvisionFile(ContainerConfig &config, const provision::File &file) :
-        mConfig(config), mFile(file)
-    {
-    }
+    ProvisionFile(ContainerConfig &config, const provision::File &file);
 
     void execute();
     void revert();
@@ -78,10 +75,7 @@ public:
     *
     * Add/remove new mount provision to/from the container
     */
-    ProvisionMount(ContainerConfig &config, const provision::Mount &mount) :
-        mConfig(config), mMount(mount)
-    {
-    }
+    ProvisionMount(ContainerConfig &config, const provision::Mount &mount);
 
     void execute();
     void revert();
@@ -98,10 +92,7 @@ public:
     *
     * Add/remove link provision to/from the container
     */
-    ProvisionLink(ContainerConfig &config, const provision::Link &link) :
-        mConfig(config), mLink(link)
-    {
-    }
+    ProvisionLink(ContainerConfig &config, const provision::Link &link);
 
     void execute();
     void revert();