Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

forest-cli db subcommands migration #3355

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
- `fetch-params`
- `snapshot fetch`
- `snapshot validate`
- [#3355](https://github.com/ChainSafe/forest/pull/3355) Moved commands
- `forest-cli db stats` to `forest-tool db stats`
- `forest-cli db clean` to `forest-tool db destroy`

### Added

Expand Down
2 changes: 1 addition & 1 deletion scripts/db_params_hyperfine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ hyperfine \
./target/release/forest \
--chain ${CHAIN} --config /tmp/forest.conf --rpc false --no-gc --encrypt-keystore false --halt-after-import \
--import-snapshot ${SNAPSHOT}; \
./target/release/forest-cli --chain ${CHAIN} db clean --force"
./target/release/forest-tool db destroy --chain ${CHAIN} --force"
2 changes: 1 addition & 1 deletion scripts/gen_coverage_report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cov forest --chain calibnet --encrypt-keystore false --import-snapshot "$SNAPSHO
cov forest-cli sync wait
cov forest-cli sync status
cov forest-cli --chain calibnet db gc
cov forest-cli --chain calibnet db stats
cov forest-tool db stats --chain calibnet
cov forest-cli snapshot export
cov forest-cli snapshot export
cov forest-cli attach --exec 'showPeers()'
Expand Down
6 changes: 3 additions & 3 deletions scripts/tests/forest_cli_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ function num-files-here() {

"$FOREST_TOOL_PATH" fetch-params --keys

: "cleaning an empty database doesn't fail (see #2811)"
"$FOREST_CLI_PATH" --chain calibnet db clean --force
"$FOREST_CLI_PATH" --chain calibnet db clean --force
: "destroying an empty database doesn't fail (see #2811)"
"$FOREST_TOOL_PATH" db destroy --chain calibnet --force
"$FOREST_TOOL_PATH" db destroy --chain calibnet --force


: fetch snapshot
Expand Down
2 changes: 1 addition & 1 deletion scripts/tests/harness.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function forest_download_and_import_snapshot {

function forest_check_db_stats {
echo "Checking DB stats"
$FOREST_CLI_PATH --chain calibnet db stats
$FOREST_TOOL_PATH db stats --chain calibnet
}

function forest_query_epoch {
Expand Down
7 changes: 7 additions & 0 deletions src/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ macro_rules! bail_moved_cmd {
$src
)
};
($src:literal, $dst:literal) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does it have to be a macro?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a personal preference here. At some point I believe this code will be deleted anyway, once users have migrated to the new binaries.

anyhow::bail!(
"Invalid subcommand: {}. It has been moved to forest-tool {}.",
$src,
$dst
)
};
}

pub fn main<ArgT>(args: impl IntoIterator<Item = ArgT>) -> anyhow::Result<()>
Expand Down
42 changes: 4 additions & 38 deletions src/cli/subcommands/db_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@

use std::sync::Arc;

use crate::cli_shared::{chain_path, cli::Config};
use crate::db::db_engine::db_root;
use crate::cli_shared::cli::Config;
use crate::rpc_api::progress_api::GetProgressType;
use crate::rpc_client::{db_ops::db_gc, progress_ops::get_progress};
use crate::utils::io::ProgressBar;
use chrono::Utc;
use clap::Subcommand;
use tracing::error;

use crate::cli::subcommands::{handle_rpc_err, prompt_confirm};
use crate::cli::subcommands::handle_rpc_err;

#[derive(Debug, Subcommand)]
pub enum DBCommands {
Expand All @@ -31,15 +29,7 @@ pub enum DBCommands {
impl DBCommands {
pub async fn run(&self, config: &Config) -> anyhow::Result<()> {
match self {
Self::Stats => {
use human_repr::HumanCount;

let dir = db_root(&chain_path(config));
println!("Database path: {}", dir.display());
let size = fs_extra::dir::get_size(dir).unwrap_or_default();
println!("Database size: {}", size.human_count_bytes());
Ok(())
}
Self::Stats => crate::bail_moved_cmd!("db stats"),
Self::GC => {
let start = Utc::now();

Expand Down Expand Up @@ -81,31 +71,7 @@ impl DBCommands {

Ok(())
}
Self::Clean { force } => {
let dir = chain_path(config);
if !dir.is_dir() {
println!(
"Aborted. Database path {} is not a valid directory",
dir.display()
);
return Ok(());
}
println!("Deleting {}", dir.display());
if !force && !prompt_confirm() {
println!("Aborted.");
return Ok(());
}
match fs_extra::dir::remove(&dir) {
Ok(_) => {
println!("Deleted {}", dir.display());
Ok(())
}
Err(err) => {
error!("{err}");
Ok(())
}
}
}
Self::Clean { force: _ } => crate::bail_moved_cmd!("db clean", "db destroy"),
}
}
}
2 changes: 1 addition & 1 deletion src/cli/subcommands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ pub(super) fn print_stdout(out: String) {
.unwrap();
}

fn prompt_confirm() -> bool {
pub fn prompt_confirm() -> bool {
print!("Do you want to continue? [y/n] ");
std::io::stdout().flush().unwrap();
let mut line = String::new();
Expand Down
1 change: 1 addition & 0 deletions src/tool/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ where
Subcommand::Snapshot(cmd) => cmd.run().await,
Subcommand::Fetch(cmd) => cmd.run().await,
Subcommand::Archive(cmd) => cmd.run().await,
Subcommand::DB(cmd) => cmd.run().await,
}
})
}
84 changes: 84 additions & 0 deletions src/tool/subcommands/db_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2019-2023 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use super::read_config;
use crate::cli::subcommands::prompt_confirm;
use crate::cli_shared::chain_path;
use crate::db::db_engine::db_root;
use crate::networks::NetworkChain;
use clap::Subcommand;
use tracing::error;

#[derive(Debug, Subcommand)]
pub enum DBCommands {
/// Show DB stats
Stats {
/// Optional TOML file containing forest daemon configuration
#[arg(short, long)]
config: Option<String>,
/// Optional chain, will override the chain section of configuration file if used
#[arg(long)]
chain: Option<NetworkChain>,
},
/// DB destruction
Destroy {
/// Answer yes to all forest-cli yes/no questions without prompting
#[arg(long)]
force: bool,
/// Optional TOML file containing forest daemon configuration
#[arg(short, long)]
config: Option<String>,
/// Optional chain, will override the chain section of configuration file if used
#[arg(long)]
chain: Option<NetworkChain>,
},
}

impl DBCommands {
pub async fn run(&self) -> anyhow::Result<()> {
match self {
Self::Stats { config, chain } => {
use human_repr::HumanCount;

let config = read_config(config, chain)?;

let dir = db_root(&chain_path(&config));
println!("Database path: {}", dir.display());
let size = fs_extra::dir::get_size(dir).unwrap_or_default();
println!("Database size: {}", size.human_count_bytes());
Ok(())
}
Self::Destroy {
force,
config,
chain,
} => {
let config = read_config(config, chain)?;

let dir = chain_path(&config);
if !dir.is_dir() {
println!(
"Aborted. Database path {} is not a valid directory",
dir.display()
);
return Ok(());
}
println!("Deleting {}", dir.display());
if !force && !prompt_confirm() {
println!("Aborted.");
return Ok(());
}
match fs_extra::dir::remove(&dir) {
Ok(_) => {
println!("Deleted {}", dir.display());
Ok(())
}
Err(err) => {
error!("{err}");
Ok(())
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/tool/subcommands/fetch_params_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct FetchCommands {

impl FetchCommands {
pub async fn run(&self) -> anyhow::Result<()> {
let config = read_config(&self.config)?;
let config = read_config(&self.config, &None)?;

let sizes = if self.all {
SectorSizeOpt::All
Expand Down
24 changes: 21 additions & 3 deletions src/tool/subcommands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@

pub mod archive_cmd;
pub mod benchmark_cmd;
pub mod db_cmd;
pub mod fetch_params_cmd;
pub mod snapshot_cmd;

use crate::cli_shared::cli::HELP_MESSAGE;
use crate::cli_shared::cli::*;
use crate::networks::{ChainConfig, NetworkChain};
use crate::utils::version::FOREST_VERSION_STRING;
use crate::utils::{io::read_file_to_string, io::read_toml};
use clap::Parser;
use std::sync::Arc;

/// Command-line options for the `forest-tool` binary
#[derive(Parser)]
Expand Down Expand Up @@ -39,16 +42,31 @@ pub enum Subcommand {
/// Manage archives
#[command(subcommand)]
Archive(archive_cmd::ArchiveCommands),

/// Database management
#[command(subcommand)]
DB(db_cmd::DBCommands),
}

fn read_config(config: &Option<String>) -> anyhow::Result<Config> {
Ok(match find_config_path(config) {
fn read_config(config: &Option<String>, chain: &Option<NetworkChain>) -> anyhow::Result<Config> {
let path = find_config_path(config);
let mut cfg: Config = match &path {
Some(path) => {
// Read from config file
let toml = read_file_to_string(path.to_path_buf())?;
// Parse and return the configuration file
read_toml(&toml)?
}
None => Config::default(),
})
};

// Override config with chain if some
match chain {
Some(NetworkChain::Mainnet) => cfg.chain = Arc::new(ChainConfig::mainnet()),
Some(NetworkChain::Calibnet) => cfg.chain = Arc::new(ChainConfig::calibnet()),
Some(NetworkChain::Devnet(_)) => cfg.chain = Arc::new(ChainConfig::devnet()),
None => (),
}

Ok(cfg)
}