diff --git a/ckb-bin/src/lib.rs b/ckb-bin/src/lib.rs index e1c2a1cbf10..2df20d5a998 100644 --- a/ckb-bin/src/lib.rs +++ b/ckb-bin/src/lib.rs @@ -4,9 +4,6 @@ mod helper; mod setup_guard; mod subcommand; - -use std::fs::File; - use ckb_app_config::{cli, ExitCode, Setup}; use ckb_async_runtime::new_global_runtime; use ckb_build_info::Version; @@ -61,38 +58,45 @@ pub fn run_app(version: Version) -> Result<(), ExitCode> { .subcommand() .expect("SubcommandRequiredElseHelp"); - let run_in_daemon = cmd == cli::CMD_RUN && matches.get_flag(cli::ARG_DAEMON); - if run_in_daemon { - eprintln!("starting CKB in daemon mode ..."); - eprintln!("check status with: `ckb status`"); - eprintln!("stop daemon with: `ckb stop`"); - let stdout = File::create("/tmp/ckb-daemon.out")?; - let stderr = File::create("/tmp/ckb-daemon.err")?; - - let pwd = std::env::current_dir()?; - let daemon = Daemonize::new() - .pid_file("/tmp/ckb-daemon.pid") - .chown_pid_file(true) - .working_directory(pwd) - .stdout(stdout) - .stderr(stderr); - - match daemon.start() { - Ok(_) => { - eprintln!("Success, daemonized ..."); - run_app_inner(version, bin_name, cmd, matches) - } - Err(e) => { - eprintln!("daemonize error: {}", e); - Err(ExitCode::Failure) - } - } + if run_deamon(cmd, matches) { + run_in_daemon(version, bin_name, cmd, matches) } else { debug!("ckb version: {}", version); run_app_inner(version, bin_name, cmd, matches) } } +fn run_in_daemon( + version: Version, + bin_name: String, + cmd: &str, + matches: &ArgMatches, +) -> Result<(), ExitCode> { + eprintln!("starting CKB in daemon mode ..."); + eprintln!("check status with: `ckb status`"); + eprintln!("stop daemon with: `ckb stop`"); + + assert!(matches!(cmd, cli::CMD_RUN | cli::CMD_MINER)); + let cmd_name = if cmd == cli::CMD_RUN { "run" } else { "miner" }; + let pid_file = format!("/tmp/ckb-{}.pid", cmd_name); + let pwd = std::env::current_dir()?; + let daemon = Daemonize::new() + .pid_file(pid_file) + .chown_pid_file(true) + .working_directory(pwd); + + match daemon.start() { + Ok(_) => { + eprintln!("Success, daemonized ..."); + run_app_inner(version, bin_name, cmd, matches) + } + Err(e) => { + eprintln!("daemonize error: {}", e); + Err(ExitCode::Failure) + } + } +} + fn run_app_inner( version: Version, bin_name: String, @@ -117,6 +121,7 @@ fn run_app_inner( cli::CMD_STATS => subcommand::stats(setup.stats(matches)?, handle.clone()), cli::CMD_RESET_DATA => subcommand::reset_data(setup.reset_data(matches)?), cli::CMD_MIGRATE => subcommand::migrate(setup.migrate(matches)?), + cli::CMD_DAEMON => subcommand::daemon(setup.daemon(matches)?), _ => unreachable!(), }; @@ -133,6 +138,19 @@ fn run_app_inner( ret } +#[cfg(target_os = "windows")] +fn run_deamon(_cmd: &str, _matches: &ArgMatches) -> bool { + false +} + +#[cfg(not(target_os = "windows"))] +fn run_deamon(cmd: &str, matches: &ArgMatches) -> bool { + match cmd { + cli::CMD_RUN | cli::CMD_MINER => matches.get_flag(cli::ARG_DAEMON), + _ => false, + } +} + type Silent = bool; fn is_silent_logging(cmd: &str) -> Silent { diff --git a/ckb-bin/src/subcommand/mod.rs b/ckb-bin/src/subcommand/mod.rs index 6940ac17045..24ae7a16f2d 100644 --- a/ckb-bin/src/subcommand/mod.rs +++ b/ckb-bin/src/subcommand/mod.rs @@ -1,3 +1,4 @@ +mod daemon; mod export; mod import; mod init; @@ -10,6 +11,7 @@ mod reset_data; mod run; mod stats; +pub use self::daemon::daemon; pub use self::export::export; pub use self::import::import; pub use self::init::init; diff --git a/util/app-config/src/args.rs b/util/app-config/src/args.rs index 3f28c4b213f..4aa67dcbaef 100644 --- a/util/app-config/src/args.rs +++ b/util/app-config/src/args.rs @@ -17,6 +17,15 @@ pub struct ExportArgs { pub target: PathBuf, } +#[derive(Debug)] +/// Parsed command line arguments for `ckb daemon`. +pub struct DaemonArgs { + /// Check the daemon status + pub check: bool, + /// Stop daemon process + pub stop: bool, +} + /// Parsed command line arguments for `ckb import`. pub struct ImportArgs { /// Parsed `ckb.toml`. diff --git a/util/app-config/src/cli.rs b/util/app-config/src/cli.rs index a5527306948..c74a2304a4e 100644 --- a/util/app-config/src/cli.rs +++ b/util/app-config/src/cli.rs @@ -32,7 +32,8 @@ pub const CMD_GEN_SECRET: &str = "gen"; pub const CMD_FROM_SECRET: &str = "from-secret"; /// Subcommand `migrate`. pub const CMD_MIGRATE: &str = "migrate"; - +/// Subcommand `daemon` +pub const CMD_DAEMON: &str = "daemon"; /// Command line argument `--config-dir`. pub const ARG_CONFIG_DIR: &str = "config-dir"; /// Command line argument `--format`. @@ -113,6 +114,10 @@ pub const ARG_OVERWRITE_CHAIN_SPEC: &str = "overwrite-spec"; pub const ARG_ASSUME_VALID_TARGET: &str = "assume-valid-target"; /// Command line argument `--check`. pub const ARG_MIGRATE_CHECK: &str = "check"; +/// Command line argument `daemon --check` +pub const ARG_DAEMON_CHECK: &str = "check"; +/// Command line argument `daemon --stop` +pub const ARG_DAEMON_STOP: &str = "stop"; /// Command line arguments group `ba` for block assembler. const GROUP_BA: &str = "ba"; @@ -146,6 +151,7 @@ pub fn basic_app() -> Command { .subcommand(reset_data()) .subcommand(peer_id()) .subcommand(migrate()) + .subcommand(daemon()) } /// Parse the command line arguments by supplying the version information. @@ -211,18 +217,29 @@ fn run() -> Command { } fn miner() -> Command { - Command::new(CMD_MINER).about("Runs ckb miner").arg( - Arg::new(ARG_LIMIT) - .short('l') - .long(ARG_LIMIT) - .action(clap::ArgAction::Set) - .value_parser(clap::value_parser!(u128)) - .default_value("0") - .help( - "Exit after how many nonces found; \ + Command::new(CMD_MINER) + .about("Runs ckb miner") + .arg( + Arg::new(ARG_LIMIT) + .short('l') + .long(ARG_LIMIT) + .action(clap::ArgAction::Set) + .value_parser(clap::value_parser!(u128)) + .default_value("0") + .help( + "Exit after how many nonces found; \ 0 means the miner will never exit. [default: 0]", - ), - ) + ), + ) + .arg( + Arg::new(ARG_DAEMON) + .long(ARG_DAEMON) + .action(clap::ArgAction::SetTrue) + .help( + "Starts ckb as a daemon, \ + which will run in the background and output logs to the specified log file", + ), + ) } fn reset_data() -> Command { @@ -381,6 +398,24 @@ fn migrate() -> Command { ) } +fn daemon() -> Command { + Command::new(CMD_DAEMON) + .about("Runs ckb daemon command") + .arg( + Arg::new(ARG_DAEMON_CHECK) + .long(ARG_DAEMON_CHECK) + .action(clap::ArgAction::SetTrue) + .help("Check the daemon status"), + ) + .arg( + Arg::new(ARG_DAEMON_STOP) + .long(ARG_DAEMON_STOP) + .action(clap::ArgAction::SetTrue) + .conflicts_with(ARG_DAEMON_CHECK) + .help("Stop the daemon process, both the miner and the node"), + ) +} + fn list_hashes() -> Command { Command::new(CMD_LIST_HASHES) .about("Lists well known hashes") diff --git a/util/app-config/src/lib.rs b/util/app-config/src/lib.rs index 98ccb2d8cf7..9434e86a777 100644 --- a/util/app-config/src/lib.rs +++ b/util/app-config/src/lib.rs @@ -15,7 +15,7 @@ pub use app_config::{ AppConfig, CKBAppConfig, ChainConfig, LogConfig, MetricsConfig, MinerAppConfig, }; pub use args::{ - ExportArgs, ImportArgs, InitArgs, MigrateArgs, MinerArgs, PeerIDArgs, ReplayArgs, + DaemonArgs, ExportArgs, ImportArgs, InitArgs, MigrateArgs, MinerArgs, PeerIDArgs, ReplayArgs, ResetDataArgs, RunArgs, StatsArgs, }; pub use configs::*; @@ -219,6 +219,14 @@ impl Setup { }) } + /// Executes `ckb daemon`. + pub fn daemon(self, matches: &ArgMatches) -> Result { + let check = matches.get_flag(cli::ARG_DAEMON_CHECK); + let stop = matches.get_flag(cli::ARG_DAEMON_STOP); + + Ok(DaemonArgs { check, stop }) + } + /// Executes `ckb init`. pub fn init(matches: &ArgMatches) -> Result { if matches.contains_id("list-specs") {