From: Sage Weil Date: Sat, 6 Jan 2018 17:19:43 +0000 (-0600) Subject: mon/ConfigMonitor: "ceph config assimilate-conf" X-Git-Tag: wip-pdonnell-testing-20180317.202121~121^2~84 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=a012d99e06038f4b1b033a45f8216c74e56d658e;p=ceph-ci.git mon/ConfigMonitor: "ceph config assimilate-conf" Inject as much of a ceph.conf file as we can; spit we can't take back out to stdout. Signed-off-by: Sage Weil --- diff --git a/src/mon/ConfigMap.h b/src/mon/ConfigMap.h index 60cdc68d02a..02b4d9d9e7c 100644 --- a/src/mon/ConfigMap.h +++ b/src/mon/ConfigMap.h @@ -92,6 +92,20 @@ struct ConfigMap { std::map by_type; std::map by_id; + Section *find_section(const std::string& name) { + if (name == "global") { + return &global; + } + auto i = by_type.find(name); + if (i != by_type.end()) { + return &i->second; + } + i = by_id.find(name); + if (i != by_id.end()) { + return &i->second; + } + return nullptr; + } void clear() { global.clear(); by_type.clear(); diff --git a/src/mon/ConfigMonitor.cc b/src/mon/ConfigMonitor.cc index 78e27ae56ef..a4a1921ccc3 100644 --- a/src/mon/ConfigMonitor.cc +++ b/src/mon/ConfigMonitor.cc @@ -300,6 +300,7 @@ bool ConfigMonitor::prepare_command(MonOpRequestRef op) string prefix; cmd_getval(g_ceph_context, cmdmap, "prefix", prefix); + bufferlist odata; if (prefix == "config set" || prefix == "config rm") { @@ -336,13 +337,92 @@ bool ConfigMonitor::prepare_command(MonOpRequestRef op) pending[key] = boost::none; } goto update; + } else if (prefix == "config assimilate-conf") { + ConfFile cf; + deque errors; + bufferlist bl = m->get_data(); + err = cf.parse_bufferlist(&bl, &errors, &ss); + if (err < 0) { + ss << "parse errors: " << errors; + goto reply; + } + bool updated = false; + ostringstream newconf; + for (auto i = cf.sections_begin(); i != cf.sections_end(); ++i) { + string section = i->first; + const ConfSection& s = i->second; + dout(20) << __func__ << " [" << section << "]" << dendl; + bool did_section = false; + for (auto& j : s.lines) { + Option::value_t real_value; + string value; + string errstr; + if (!j.key.size()) { + continue; + } + // a known and worthy option? + const Option *o = g_conf->find_option(j.key); + if (!o || + o->flags & Option::FLAG_NO_MON_UPDATE) { + goto skip; + } + // normalize + err = o->parse_value(j.val, &real_value, &errstr, &value); + if (err < 0) { + dout(20) << __func__ << " failed to parse " << j.key << " = '" + << j.val << "'" << dendl; + goto skip; + } + // does it conflict with an existing value? + { + const Section *s = config_map.find_section(section); + if (s) { + auto k = s->options.find(j.key); + if (k != s->options.end()) { + if (value != k->second.raw_value) { + dout(20) << __func__ << " have " << j.key + << " = " << k->second.raw_value + << " (not " << value << ")" << dendl; + goto skip; + } + dout(20) << __func__ << " already have " << j.key + << " = " << k->second.raw_value << dendl; + continue; + } + } + } + dout(20) << __func__ << " add " << j.key << " = " << value + << " (" << j.val << ")" << dendl; + { + string key = section + "/" + j.key; + bufferlist bl; + bl.append(value); + pending[key] = bl; + updated = true; + } + continue; + + skip: + dout(20) << __func__ << " skip " << j.key << " = " << value + << " (" << j.val << ")" << dendl; + if (!did_section) { + newconf << "\n[" << section << "]\n"; + did_section = true; + } + newconf << "\t" << j.key << " = " << j.val << "\n"; + } + } + odata.append(newconf.str()); + if (updated) { + goto update; + } } else { ss << "unknown command " << prefix; err = -EINVAL; } reply: - mon->reply_command(op, err, ss.str(), get_last_committed()); + mon->reply_command(op, err, ss.str(), odata, get_last_committed()); return false; update: @@ -350,7 +430,7 @@ update: wait_for_finished_proposal( op, new Monitor::C_Command( - mon, op, 0, ss.str(), + mon, op, 0, ss.str(), odata, get_last_committed() + 1)); return true; } diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index ad6048d5d74..51ec38d9aca 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -1114,3 +1114,6 @@ COMMAND("config help " \ "name=key,type=CephString", "Describe a configuration option", "config", "r", "cli,rest") +COMMAND("config assimilate-conf", + "Assimilate options from a conf, and return a new, minimal conf file", + "config", "rw", "cli,rest")