main.rs (3467B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use clap::Parser as _; 18 use taler_api::api::TalerRouter as _; 19 use taler_build::long_version; 20 use taler_common::{CommonArgs, cli::ConfigCmd, config::Config, taler_main}; 21 use taler_wise::{ 22 api, 23 config::ServeCfg, 24 constants::CONFIG_SOURCE, 25 db::{dbinit, pool}, 26 setup::{self}, 27 worker::run_worker, 28 }; 29 30 #[derive(clap::Parser, Debug)] 31 #[command(long_version = long_version(), about, long_about = None)] 32 struct Args { 33 #[clap(flatten)] 34 common: CommonArgs, 35 36 #[command(subcommand)] 37 cmd: Command, 38 } 39 40 #[derive(clap::Subcommand, Debug)] 41 enum Command { 42 /// Initialize taler-wise database 43 Dbinit { 44 /// Reset database (DANGEROUS: All existing data is lost) 45 #[arg(short, long)] 46 reset: bool, 47 }, 48 /// Check taler-wise config 49 Setup, 50 /// Run taler-wise worker 51 Worker { 52 /// Execute once and return 53 #[arg(short, long)] 54 transient: bool, 55 }, 56 /// Run taler-wise HTTP server 57 Serve { 58 /// Check whether an API is in use (if it's useful to start the HTTP 59 /// server). Exit with 0 if at least one API is enabled, otherwise 1 60 #[arg(long)] 61 check: bool, 62 }, 63 #[command(subcommand)] 64 Config(ConfigCmd), 65 } 66 67 async fn run(cmd: Command, cfg: &Config) -> anyhow::Result<()> { 68 match cmd { 69 Command::Dbinit { reset } => { 70 dbinit(cfg, reset).await?; 71 } 72 Command::Setup => { 73 let client = http_client::client(); 74 setup::setup(cfg, &client).await? 75 } 76 Command::Serve { check } => { 77 if check { 78 let cfg = ServeCfg::parse(cfg)?; 79 if cfg.revenue.is_none() 80 && cfg.wire_gateway.is_none() 81 && cfg.observability.is_none() 82 { 83 std::process::exit(1); 84 } 85 } else { 86 let pool = pool(cfg).await?; 87 let cfg = ServeCfg::parse(cfg)?; 88 api::start( 89 pool, 90 &cfg.name, 91 cfg.balances, 92 &cfg.wire_gateway, 93 &cfg.revenue, 94 &cfg.observability, 95 ) 96 .await 97 .serve(&cfg.serve, None) 98 .await?; 99 } 100 } 101 Command::Worker { transient } => { 102 let pool = pool(cfg).await?; 103 let client = http_client::client(); 104 run_worker(cfg, &pool, &client, transient).await?; 105 } 106 Command::Config(cmd) => cmd.run(cfg)?, 107 } 108 Ok(()) 109 } 110 111 fn main() { 112 let args = Args::parse(); 113 taler_main(CONFIG_SOURCE, args.common, async |cfg| { 114 run(args.cmd, cfg).await 115 }); 116 }