sapling/eden/mononoke/cmds/configlint.rs
Mark Thomas 6ad7e5c96e metaconfig/parser: use free functions for loading configuration
Summary:
Replace the use of `RepoConfigs::read*` associated functions with free
functions.  These didn't really need to be associated functions (and in the
case of the common and storage configs, really didn't belong there either).

Reviewed By: krallin

Differential Revision: D21837270

fbshipit-source-id: 2dc73a880ed66e11ea484b88b749582ebdf8a73f
2020-06-02 09:30:03 -07:00

96 lines
2.7 KiB
Rust

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
use anyhow::{bail, Result};
use fbinit::FacebookInit;
use itertools::Itertools;
use std::collections::BTreeMap;
use cmdlib::args;
#[fbinit::main]
fn main(fb: FacebookInit) -> Result<()> {
let matches = args::MononokeApp::new("Lint Mononoke config files")
.with_advanced_args_hidden()
.build()
.version("0.0.0")
.about("Check Mononoke server configs for syntax and sanity.")
.args_from_usage(
r#"
-q --quiet 'Only print errors'
-v --verbose 'Dump content of configs'
"#,
)
.get_matches();
let quiet = matches.is_present("quiet");
let verbose = matches.is_present("verbose");
// Most of the work is done here - this validates that the files are present,
// are correctly formed, and have the right fields (not too many, not too few).
let configs = match args::load_repo_configs(fb, &matches) {
Err(err) => {
eprintln!("Error loading configs: {:#?}", err);
return Err(err);
}
Ok(configs) => configs,
};
if verbose {
println!("Configs:\n{:#?}", configs)
}
// Keep track of what repo ids we've seen
let mut repoids = BTreeMap::<_, Vec<_>>::new();
// Have we seen something suspect?
let mut bad = false;
for (name, config) in &configs.repos {
let (isbad, locality) = match (
config.storage_config.metadata.is_local(),
config.storage_config.blobstore.is_local(),
) {
(true, true) => (false, "local"),
(false, false) => (false, "remote"),
(true, false) => (true, "MIXED - local DB, remote blobstore"),
(false, true) => (true, "MIXED - remote DB, local blobstore"),
};
bad |= isbad;
repoids
.entry(config.repoid)
.and_modify(|names| names.push(name.as_str()))
.or_insert(vec![name.as_str()]);
if isbad || !quiet {
println!(
"Repo {}: {} - enabled: {:?} locality: {}",
config.repoid, name, config.enabled, locality
);
}
}
for (id, names) in repoids {
assert!(!names.is_empty());
if names.len() > 1 {
eprintln!(
"ERROR: Repo Id {} used for repos: {}",
id,
names.into_iter().join(", ")
);
bad = true;
}
}
if bad {
bail!("Anomaly detected")
} else {
Ok(())
}
}