From: David Zafman Date: Thu, 4 Dec 2014 22:01:39 +0000 (-0800) Subject: ceph_objectstore_tool: Add --format and --pretty-format support X-Git-Tag: v0.92~32^2~7^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cca85a534fe488ae314400e8faad55a758609467;p=ceph.git ceph_objectstore_tool: Add --format and --pretty-format support --pretty-format defaults true Add --format so xml output can be requested --op list defaults to single line of json per object To override this more human readable output use --pretty-format=false Add testing of --op list special handling Signed-off-by: David Zafman --- diff --git a/src/test/ceph_objectstore_tool.py b/src/test/ceph_objectstore_tool.py index 096f524bb08cd..92c5ea782f653 100755 --- a/src/test/ceph_objectstore_tool.py +++ b/src/test/ceph_objectstore_tool.py @@ -465,7 +465,7 @@ def main(argv): osd = OSDS[0] # retrieve all objects from all PGs - cmd = (CFSD_PREFIX + "--op list").format(osd=osd) + cmd = (CFSD_PREFIX + "--op list --pretty-format=false").format(osd=osd) logging.debug(cmd); tmpfd = open(TMPFILE, "a") logging.debug(cmd) @@ -479,7 +479,7 @@ def main(argv): (pgid, jsondict) = json.loads(JSONOBJ[0])[0] # retrieve all objects in a given PG - cmd = (CFSD_PREFIX + "--op list --pgid {pg}").format(osd=osd, pg=pgid) + cmd = (CFSD_PREFIX + "--op list --pgid {pg} --pretty-format=false").format(osd=osd, pg=pgid) logging.debug(cmd); tmpfd = open(OTHERFILE, "a") logging.debug(cmd) @@ -498,7 +498,7 @@ def main(argv): ERRORS += 1 # retrieve all objects with a given name in a given PG - cmd = (CFSD_PREFIX + "--op list --pgid {pg} {object}").format(osd=osd, pg=pgid, object=jsondict['oid']) + cmd = (CFSD_PREFIX + "--op list --pgid {pg} {object} --pretty-format=false").format(osd=osd, pg=pgid, object=jsondict['oid']) logging.debug(cmd); tmpfd = open(OTHERFILE, "a") logging.debug(cmd) @@ -516,7 +516,7 @@ def main(argv): "from the first line of --op list --pgid {pg} {object}".format(pg=pgid, object=jsondict['oid'])) ERRORS += 1 - print "Test --op list by generating json for all objects" + print "Test --op list by generating json for all objects using default format" for pg in ALLPGS: OSDS = get_osds(pg, OSDDIR) for osd in OSDS: @@ -532,11 +532,12 @@ def main(argv): lines = get_lines(TMPFILE) JSONOBJ = sorted(set(lines)) for JSON in JSONOBJ: - for (pgid, jsondict) in json.loads(JSON): - db[jsondict['namespace']][jsondict['oid']]['json'] = json.dumps((pgid, jsondict)) - if string.find(jsondict['oid'], EC_NAME) == 0 and 'shard_id' not in jsondict: - logging.error("Malformed JSON {json}".format(json=JSON)) - ERRORS += 1 + (pgid, jsondict) = json.loads(JSON) + db[jsondict['namespace']][jsondict['oid']]['json'] = json.dumps((pgid, jsondict)) + # print db[jsondict['namespace']][jsondict['oid']]['json'] + if string.find(jsondict['oid'], EC_NAME) == 0 and 'shard_id' not in jsondict: + logging.error("Malformed JSON {json}".format(json=JSON)) + ERRORS += 1 # Test get-bytes print "Test get-bytes and set-bytes" diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index ebb0dfe17ec6a..ffe80afbb0910 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -458,14 +458,13 @@ struct pgid_object_list { _objects.push_back(make_pair(coll, ghobj)); } - void dump(Formatter *f) const { - bool terminal = isatty(STDOUT_FILENO); - if (!terminal) + void dump(Formatter *f, bool human_readable) const { + if (!human_readable) f->open_array_section("pgid_objects"); for (list >::const_iterator i = _objects.begin(); i != _objects.end(); i++) { - if (i != _objects.begin() && terminal) { + if (i != _objects.begin() && human_readable) { f->flush(cout); cout << std::endl; } @@ -481,7 +480,7 @@ struct pgid_object_list { f->close_section(); f->close_section(); } - if (!terminal) + if (!human_readable) f->close_section(); } }; @@ -508,8 +507,8 @@ struct lookup_ghobject : public action_on_object_t { return front; } - void dump(Formatter *f) const { - _objects.dump(f); + void dump(Formatter *f, bool human_readable) const { + _objects.dump(f, human_readable); } }; @@ -1631,7 +1630,7 @@ int do_import(ObjectStore *store, OSDSuperblock& sb) return 0; } -int do_list(ObjectStore *store, string pgidstr, string object, Formatter *formatter, bool debug) +int do_list(ObjectStore *store, string pgidstr, string object, Formatter *formatter, bool debug, bool human_readable) { int r; lookup_ghobject lookup(object); @@ -1644,7 +1643,7 @@ int do_list(ObjectStore *store, string pgidstr, string object, Formatter *format } if (r) return r; - lookup.dump(formatter); + lookup.dump(formatter, human_readable); formatter->flush(cout); cout << std::endl; return 0; @@ -2028,9 +2027,10 @@ void usage(po::options_description &desc) int main(int argc, char **argv) { - string dpath, jpath, pgidstr, op, file, object, objcmd, arg1, arg2, type; + string dpath, jpath, pgidstr, op, file, object, objcmd, arg1, arg2, type, format; spg_t pgid; ghobject_t ghobj; + bool pretty_format, human_readable; po::options_description desc("Allowed options"); desc.add_options() @@ -2047,6 +2047,10 @@ int main(int argc, char **argv) "Arg is one of [info, log, remove, export, import, list, list-lost, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects]") ("file", po::value(&file), "path of file to export or import") + ("pretty-format", po::value(&pretty_format)->default_value(true), + "Make json or xml output more readable") + ("format", po::value(&format)->default_value("json"), + "Output format which may be xml or json") ("debug", "Enable diagnostic output to stderr") ("skip-journal-replay", "Disable journal replay") ("skip-mount-omap", "Disable mounting of omap") @@ -2510,9 +2514,26 @@ int main(int argc, char **argv) goto out; } + // Special list handling. Treating pretty_format as human readable, + // with one object per line and not an enclosing array. + human_readable = pretty_format; if (op == "list") { - Formatter *formatter = new JSONFormatter(false); - r = do_list(fs, pgidstr, object, formatter, debug); + pretty_format = false; + } + + Formatter *formatter; + if (format == "xml") { + formatter = new XMLFormatter(pretty_format); + } else if (format == "json") { + formatter = new JSONFormatter(pretty_format); + } else { + cerr << "unrecognized format: " << format << std::endl; + ret = 1; + goto out; + } + + if (op == "list") { + r = do_list(fs, pgidstr, object, formatter, debug, human_readable); if (r) { cerr << "do_list failed with " << r << std::endl; ret = 1; @@ -2730,7 +2751,6 @@ int main(int argc, char **argv) usage(desc); } - Formatter *formatter = new JSONFormatter(true); bufferlist bl; map_epoch = PG::peek_map_epoch(fs, coll, infos_oid, &bl); if (debug)