cloud-init allows to specify mountpoints via its configuration.
This commit implements actual mount action. Only NFS mountpoints are
assumed, as so far this is also the only supported filesystem.

Signed-off-by: Justin Cinkelj <justin.cink...@xlab.si>
---
 modules/cloud-init/cloud-init.cc | 57 ++++++++++++++++++++++++++++++++++++++++
 modules/cloud-init/cloud-init.hh | 14 ++++++++++
 modules/cloud-init/main.cc       |  1 +
 3 files changed, 72 insertions(+)

diff --git a/modules/cloud-init/cloud-init.cc b/modules/cloud-init/cloud-init.cc
index 5ca5785..6cf9b42 100644
--- a/modules/cloud-init/cloud-init.cc
+++ b/modules/cloud-init/cloud-init.cc
@@ -168,6 +168,63 @@ void script_module::wait()
     }
 }
 
+/*
+Mount NFS mountpoint specified via cloud-init.
+
+Cloud-init config snippet:
+mounts:
+ - [ nfs://192.168.122.1/ggg, /ggg, auto, uid=0 ]
+
+This results in running command
+/tools/mount-nfs.so nfs://192.168.122.1/ggg/?uid=0 /ggg
+*/
+void mount_module::yaml_to_request(const YAML::Node& node, 
http::server::request& req)
+{
+    std::string method = "PUT";
+    std::string nfs_server = node[0].as<string>();
+    std::string mount_point = node[1].as<string>();
+    // node[2] is "auto" flag - we ignore it
+    std::string options = "";
+    if (node.size() >= 4) {
+        options = node[3].as<string>();
+    }
+
+    http::server::header param;
+    param.name = "command";
+    param.value = "/tools/mount-nfs.so";
+    param.value += " " + nfs_server;
+    if (options.size() > 0) {
+        param.value += "/?" + options;
+    }
+    param.value += " " + mount_point;
+    req.query_parameters.push_back(param);
+    //fprintf(stderr, "MNT: param name='%s' value='%s'", param.name.c_str(), 
param.value.c_str());
+    req.method = method;
+    req.uri = "/app";
+}
+
+void mount_module::do_api(http::server::request& req)
+{
+    http::server::reply rep;
+
+    httpserver::global_server::get_routes().handle(req.uri, req, rep);
+
+    if (rep.status != 200) {
+        throw osvinit_exception(rep.content);
+    }
+}
+
+void mount_module::handle(const YAML::Node& doc)
+{
+    for (auto& node : doc) {
+        http::server::request req;
+        yaml_to_request(node, req);
+        if (!req.uri.empty()) {
+            do_api(req);
+        }
+    }
+}
+
 void osvinit::add_module(std::shared_ptr<config_module> module)
 {
     _modules[module->get_label()] = module;
diff --git a/modules/cloud-init/cloud-init.hh b/modules/cloud-init/cloud-init.hh
index 4bdae59..f25bb4c 100644
--- a/modules/cloud-init/cloud-init.hh
+++ b/modules/cloud-init/cloud-init.hh
@@ -120,6 +120,20 @@ private:
     std::thread t;
 };
 
+class mount_module : public config_module {
+public:
+    virtual void handle(const YAML::Node& node) override;
+
+    virtual std::string get_label() override
+    {
+        return "mounts";
+    }
+private:
+
+    void do_api(http::server::request& api);
+    void yaml_to_request(const YAML::Node& node, http::server::request& req);
+};
+
 }
 
 #endif /* OSVINIT_HH_ */
diff --git a/modules/cloud-init/main.cc b/modules/cloud-init/main.cc
index 3b4c6d4..ac609aa 100644
--- a/modules/cloud-init/main.cc
+++ b/modules/cloud-init/main.cc
@@ -97,6 +97,7 @@ int main(int argc, char* argv[])
         osvinit init(config.count("skip-error") > 0, 
config.count("force-probe") > 0);
         auto scripts = make_shared<script_module>();
         init.add_module(scripts);
+        init.add_module(make_shared<mount_module>());
         init.add_module(make_shared<files_module>());
         init.add_module(make_shared<server_module>());
         init.add_module(make_shared<include_module>(init));
-- 
2.5.5

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to