]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
config: expand any config variable in config
authorSage Weil <sage@inktank.com>
Fri, 8 Jun 2012 19:45:30 +0000 (12:45 -0700)
committerSage Weil <sage@inktank.com>
Tue, 12 Jun 2012 18:50:54 +0000 (11:50 -0700)
This is currently broken wrt 'foo' vs 'foo_bar', but otherwise works.

Signed-off-by: Sage Weil <sage@inktank.com>
src/common/config.cc
src/test/daemon_config.cc

index 7784338892217e19409f4ae4f90b58ab90793267..fcbf61a53bf406bdb034f541c1e8c5a81571c31c 100644 (file)
@@ -875,21 +875,30 @@ void md_config_t::expand_all_meta()
   }
 }
 
-bool md_config_t::expand_meta(std::string &val) const
+bool md_config_t::expand_meta(std::string &origval) const
 {
   assert(lock.is_locked());
   bool found_meta = false;
+
+  set<string> resolved;
+
+  string::size_type sz;
+  string val = origval;
+
+ restart:
+  sz = val.size();
   string out;
-  string::size_type sz = val.size();
   out.reserve(sz);
+
   for (string::size_type s = 0; s < sz; ) {
     if (val[s] != '$') {
       out += val[s++];
       continue;
     }
     string::size_type rem = sz - (s + 1);
-    int i;
-    for (i = 0; i < NUM_CONF_METAVARIABLES; ++i) {
+
+    // special metavariable?
+    for (int i = 0; i < NUM_CONF_METAVARIABLES; ++i) {
       size_t clen = strlen(CONF_METAVARIABLES[i]);
       if (rem < clen)
        continue;
@@ -910,14 +919,43 @@ bool md_config_t::expand_meta(std::string &val) const
       else
        assert(0); // unreachable
       found_meta = true;
-      break;
-    }
-    if (i == NUM_CONF_METAVARIABLES)
-      out += val[s++];
-    else
       s += strlen(CONF_METAVARIABLES[i]) + 1;
-  }
-  val = out;
+      out += val.substr(s);
+      val = out;
+      goto restart;
+    }
+
+    // config option?
+    for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) {
+      config_option *opt = &config_optionsp[i];
+      size_t clen = strlen(opt->name);
+      if (rem < clen)
+       continue;
+      if (strncmp(val.c_str() + s + 1, opt->name, clen))
+       continue;
+
+      // avoid loops
+      if (resolved.count(opt->name))
+       continue;       // loop; skip
+      resolved.insert(opt->name);
+
+      found_meta = true;
+      char *vv = NULL;
+      _get_val(opt->name, &vv, -1);
+      out += vv;
+      s += strlen(opt->name) + 1;
+      out += val.substr(s);
+      //cout << "val '" << val << "' s " << s << " out '" << out << "' after sub " << opt->name << " -> " << vv << std::endl;
+      val = out;
+      free(vv);
+      goto restart;
+    }
+
+    // pass it thru
+    out += val[s++];
+  }
+  //cout << "done '" << origval << "' -> '" << out << "'" << std::endl;
+  origval = out;
   return found_meta;
 }
 
index e85de9485d90f447b3e7749a8f5fe30a41eb23af..9eaf6614bcbbd351b9413d63d57aea697f6102a1 100644 (file)
@@ -38,6 +38,42 @@ TEST(DaemonConfig, SimpleSet) {
   ASSERT_EQ(string("21"), string(buf));
 }
 
+TEST(DaemonConfig, Substitution) {
+  int ret;
+  ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
+  ret = g_ceph_context->_conf->set_val("host", "foo");
+  ASSERT_EQ(ret, 0);
+  ret = g_ceph_context->_conf->set_val("public_network", "bar$hostbaz", false);
+  ASSERT_EQ(ret, 0);
+  g_ceph_context->_conf->apply_changes(NULL);
+  char buf[128];
+  memset(buf, 0, sizeof(buf));
+  char *tmp = buf;
+  ret = g_ceph_context->_conf->get_val("public_network", &tmp, sizeof(buf));
+  ASSERT_EQ(ret, 0);
+  ASSERT_EQ(string("barfoobaz"), string(buf));
+}
+
+TEST(DaemonConfig, SubstitutionLoop) {
+  int ret;
+  ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
+  ret = g_ceph_context->_conf->set_val("host", "foo$public_network", false);
+  ASSERT_EQ(ret, 0);
+  ret = g_ceph_context->_conf->set_val("public_network", "bar$host", false);
+  ASSERT_EQ(ret, 0);
+  g_ceph_context->_conf->apply_changes(NULL);
+  char buf[128], buf2[128];
+  memset(buf, 0, sizeof(buf));
+  memset(buf2, 0, sizeof(buf2));
+  char *tmp = buf;
+  char *tmp2 = buf;
+  ret = g_ceph_context->_conf->get_val("host", &tmp, sizeof(buf));
+  ASSERT_EQ(ret, 0);
+  ret = g_ceph_context->_conf->get_val("public_network", &tmp2, sizeof(buf));
+  ASSERT_EQ(ret, 0);
+  ASSERT_TRUE(strchr(buf, '$') || strchr(buf2, '$'));
+}
+
 TEST(DaemonConfig, ArgV) {
   ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
                                       "false"));