From: Justin Cinkelj <justin.cink...@xlab.si>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

command line: run simple scripts

runcript option is added to command line parser to allow running
simple one-line scripts. Say VM image has file named "/zpool-list" with
content "/zpool.so list". Then
run.py -e "runscript /zpool-list; /cli/cli.so"
is equivalent to
run.py -e "/zpool.so list; /cli/cli.so"

Usecase of this patch is for example HDFS. There we have one java
program, which can be run as (one) namenode or as (multiple) datanodes.
We whish to provide convinient shortcut for selection of the two distinc
java commandline parameters. So we put all required parameters into
two script-like files, and user only has to select one of them.

The need for this arose from using OSv on openstack. We build image
with capstan, and at build time we do not know what purpose it will serve
(e.g namenode or datanode). With pre-prepared run configuration/script
we ensure correct mandatory parameters are supplied (and that they
are in sync between namenode and datanodes).

Signed-off-by: Justin Cinkelj <justin.cink...@xlab.si>
Message-Id: <1479825169-15499-2-git-send-email-justin.cink...@xlab.si>

---
diff --git a/core/commands.cc b/core/commands.cc
--- a/core/commands.cc
+++ b/core/commands.cc
@@ -7,6 +7,8 @@
  */

 #include <iterator>
+#include <fstream>
+#include <osv/debug.hh>

 #include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
@@ -65,7 +67,7 @@ struct commands : qi::grammar<sciter,
 };

 std::vector<std::vector<std::string> >
-parse_command_line(const std::string line, bool &ok)
+parse_command_line_min(const std::string line, bool &ok)
 {
     std::vector<std::vector<std::string> > result;

@@ -81,6 +83,57 @@ parse_command_line(const std::string line, bool &ok)
     return result;
 }

+/*
+If cmd starts with "runcript file", read content of file and
+update cmd with the content.
+ok flag is set to false on parse error, and left unchanged otherwise.
+*/
+void runscript_expand(std::vector<std::string>& cmd, bool &ok)
+{
+    if (cmd[0] == "runscript") {
+        if (cmd.size()<2) {
+            puts("Failed expanding runscript - filename missing.");
+            ok = false;
+            return;
+        }
+        auto fn = cmd[1];
+
+        std::ifstream in(fn);
+        std::string line;
+        // only first line up to \n is used.
+        getline(in, line);
+        std::vector<std::vector<std::string> > result;
+        bool ok2;
+        result = parse_command_line_min(line, ok2);
+ debug("runscript expand fn='%s' line='%s'\n", fn.c_str(), line.c_str());
+        if (ok2 == false) {
+ printf("Failed expanding runscript file='%s' line='%s'.\n", fn.c_str(), line.c_str());
+            ok = false;
+        }
+        else {
+            cmd = result[0];
+        }
+    }
+}
+
+std::vector<std::vector<std::string>>
+parse_command_line(const std::string line,  bool &ok)
+{
+    std::vector<std::vector<std::string> > result;
+    result = parse_command_line_min(line, ok);
+
+    /*
+    If command starts with runscript, we need to read actual command to
+    execute from the given file.
+    */
+    std::vector<std::vector<std::string>>::iterator cmd_iter;
+ for (cmd_iter=result.begin(); ok && cmd_iter!=result.end(); cmd_iter++) {
+        runscript_expand(*cmd_iter, ok);
+    }
+
+    return result;
+}
+
// std::string is not fully functional when parse_cmdline is used for the first // time. So let's go for a more traditional memory management to avoid testing
 // early / not early, etc

--
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