feat(dwarfsck): first part of dwarfsck json output

This commit is contained in:
Marcus Holland-Moritz 2023-12-19 15:54:41 +01:00
parent ad9bae8618
commit 819547ecee
7 changed files with 112 additions and 4 deletions

View File

@ -82,6 +82,10 @@ class filesystem_v2 {
impl_->dump(os, detail_level);
}
folly::dynamic info_as_dynamic(int detail_level) const {
return impl_->info_as_dynamic(detail_level);
}
folly::dynamic metadata_as_dynamic() const {
return impl_->metadata_as_dynamic();
}
@ -191,6 +195,7 @@ class filesystem_v2 {
virtual ~impl() = default;
virtual void dump(std::ostream& os, int detail_level) const = 0;
virtual folly::dynamic info_as_dynamic(int detail_level) const = 0;
virtual folly::dynamic metadata_as_dynamic() const = 0;
virtual std::string serialize_metadata_as_json(bool simple) const = 0;
virtual void

View File

@ -27,6 +27,8 @@
#include <string>
#include <vector>
#include <folly/dynamic.h>
#include "dwarfs/options.h"
#include "dwarfs/gen-cpp2/history_types.h"
@ -43,6 +45,7 @@ class history {
void append(std::optional<std::vector<std::string>> args);
std::vector<uint8_t> serialize() const;
void dump(std::ostream& os) const;
folly::dynamic as_dynamic() const;
private:
thrift::history::history history_;

View File

@ -66,6 +66,10 @@ class metadata_v2 {
impl_->dump(os, detail_level, fsinfo, icb);
}
folly::dynamic info_as_dynamic(int detail_level) const {
return impl_->info_as_dynamic(detail_level);
}
folly::dynamic as_dynamic() const { return impl_->as_dynamic(); }
std::string serialize_as_json(bool simple) const {
@ -157,6 +161,8 @@ class metadata_v2 {
std::ostream& os, int detail_level, filesystem_info const& fsinfo,
std::function<void(const std::string&, uint32_t)> const& icb) const = 0;
virtual folly::dynamic info_as_dynamic(int detail_level) const = 0;
virtual folly::dynamic as_dynamic() const = 0;
virtual std::string serialize_as_json(bool simple) const = 0;

View File

@ -225,6 +225,10 @@ class filesystem_parser {
return fmt::format("{0}.{1} [{2}]", major_, minor_, version_);
}
int major_version() const { return major_; }
int minor_version() const { return minor_; }
int header_version() const { return version_; }
file_off_t image_offset() const { return image_offset_; }
bool has_checksums() const { return version_ >= 2; }
@ -355,6 +359,7 @@ class filesystem_ final : public filesystem_v2::impl {
std::shared_ptr<performance_monitor const> perfmon);
void dump(std::ostream& os, int detail_level) const override;
folly::dynamic info_as_dynamic(int detail_level) const override;
folly::dynamic metadata_as_dynamic() const override;
std::string serialize_metadata_as_json(bool simple) const override;
void walk(std::function<void(dir_entry_view)> const& func) const override;
@ -503,7 +508,8 @@ filesystem_<LoggerPolicy>::filesystem_(
PERFMON_CLS_TIMER_INIT(open)
PERFMON_CLS_TIMER_INIT(read)
PERFMON_CLS_TIMER_INIT(readv_iovec)
PERFMON_CLS_TIMER_INIT(readv_future) { // clang-format on
PERFMON_CLS_TIMER_INIT(readv_future) // clang-format on
{
block_cache cache(lgr, mm_, options.block_cache);
if (parser_.has_index()) {
@ -730,6 +736,21 @@ void filesystem_<LoggerPolicy>::dump(std::ostream& os, int detail_level) const {
});
}
template <typename LoggerPolicy>
folly::dynamic
filesystem_<LoggerPolicy>::info_as_dynamic(int detail_level) const {
folly::dynamic info = folly::dynamic::object;
info["version"] = folly::dynamic::object("major", parser_.major_version())(
"minor", parser_.minor_version())("header", parser_.header_version());
info["image_offset"] = parser_.image_offset();
info["history"] = history_.as_dynamic();
info.update(meta_.info_as_dynamic(detail_level));
return info;
}
template <typename LoggerPolicy>
folly::dynamic filesystem_<LoggerPolicy>::metadata_as_dynamic() const {
return meta_.as_dynamic();

View File

@ -111,4 +111,62 @@ void history::dump(std::ostream& os) const {
}
}
folly::dynamic history::as_dynamic() const {
folly::dynamic dyn = folly::dynamic::array;
for (auto const& histent : *history_.entries()) {
folly::dynamic entry = folly::dynamic::object;
auto const& version = histent.version().value();
entry["libdwarfs_version"] = folly::dynamic::object
// clang-format off
("major", version.major().value())
("minor", version.minor().value())
("patch", version.patch().value())
("is_release", version.is_release().value())
// clang-format on
;
auto& version_dyn = entry["libdwarfs_version"];
if (version.git_rev().has_value()) {
version_dyn["git_rev"] = version.git_rev().value();
}
if (version.git_branch().has_value()) {
version_dyn["git_branch"] = version.git_branch().value();
}
if (version.git_desc().has_value()) {
version_dyn["git_desc"] = version.git_desc().value();
}
entry["system_id"] = histent.system_id().value();
entry["compiler_id"] = histent.compiler_id().value();
if (histent.arguments().has_value()) {
folly::dynamic args = folly::dynamic::array;
for (auto const& arg : histent.arguments().value()) {
args.push_back(arg);
}
entry["arguments"] = std::move(args);
}
if (histent.timestamp().has_value()) {
entry["timestamp"] = folly::dynamic::object
// clang-format off
("epoch", histent.timestamp().value())
("local", fmt::format("{:%Y-%m-%dT%H:%M:%S}",
fmt::localtime(histent.timestamp().value())))
// clang-format on
;
}
dyn.push_back(std::move(entry));
}
return dyn;
}
} // namespace dwarfs

View File

@ -413,6 +413,8 @@ class metadata_ final : public metadata_v2::impl {
std::function<void(const std::string&, uint32_t)> const& icb)
const override;
folly::dynamic info_as_dynamic(int detail_level) const override;
folly::dynamic as_dynamic() const override;
std::string serialize_as_json(bool simple) const override;
@ -917,6 +919,16 @@ void metadata_<LoggerPolicy>::dump(
}
}
template <typename LoggerPolicy>
folly::dynamic
metadata_<LoggerPolicy>::info_as_dynamic(int detail_level) const {
folly::dynamic info = folly::dynamic::object;
if (detail_level > 2) {
info["metadata"] = as_dynamic();
}
return info;
}
// TODO: can we move this to dir_entry_view?
template <typename LoggerPolicy>
void metadata_<LoggerPolicy>::dump(

View File

@ -77,9 +77,12 @@ int dwarfsck_main(int argc, sys_char** argv) {
("check-integrity",
po::value<bool>(&check_integrity)->zero_tokens(),
"check integrity of each block")
("json",
("fast",
po::value<bool>(&check_integrity)->zero_tokens(),
"don't even verify block checksums")
("json,j",
po::value<bool>(&json)->zero_tokens(),
"print metadata in JSON format")
"print information in JSON format")
("export-metadata",
po::value<std::string>(&export_metadata),
"export raw metadata as JSON to file")
@ -138,7 +141,7 @@ int dwarfsck_main(int argc, sys_char** argv) {
of.close();
} else if (json) {
filesystem_v2 fs(lgr, mm, fsopts);
std::cout << folly::toPrettyJson(fs.metadata_as_dynamic()) << "\n";
std::cout << folly::toPrettyJson(fs.info_as_dynamic(detail)) << "\n";
} else if (print_header) {
if (auto hdr = filesystem_v2::header(mm, fsopts.image_offset)) {
#ifdef _WIN32