Skip to content

Commit

Permalink
Small improvements and typos
Browse files Browse the repository at this point in the history
  • Loading branch information
svenrademakers committed Aug 18, 2023
1 parent 1a9a173 commit 2d08bbd
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 27 deletions.
24 changes: 11 additions & 13 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
use clap::{Args, Parser, Subcommand, ValueEnum};
use std::path::PathBuf;

/// Commandline interface that controls turing-pi's BMC. An ethernet
/// connection to the board is required in order for this tool to function. All
/// commands are persisted by the BMC. Please be aware that if no hostname is
/// specified, it will try to resolve the hostname by testing a predefined sequence
/// of options.
/// Commandline interface that controls turing-pi's BMC. The BMC must be connected to a network
/// that is reachable over TCP/IP in order for this tool to function. All commands are persisted by
/// the BMC. Please be aware that if no hostname is specified, it will try to resolve the hostname
/// by testing a predefined sequence of options.
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true, arg_required_else_help = true)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
#[arg(
help = "Optional turing-pi host to connect to. Host will be determind given the following order:
1. Explicitly passed via the Cli
help = "Optional Turing-pi host to connect to. Host will be determind given the following order:
1. Explicitly passed via the CLI
2. Using hostname 'turing-pi.local'
3. First host to respond to redfish service discovery
"
)]
#[arg(default_value = "turingpi.local", long, global = true)]
Expand All @@ -29,18 +27,18 @@ pub struct Cli {

#[derive(Subcommand)]
pub enum Commands {
/// Power or reset specific nodes.
/// Power on/off or reset specific nodes.
Power(PowerArgs),
/// Change the USB device/host configuration. The USB-bus can only be routed to one
/// node simultaniously.
/// node simultaneously.
Usb(UsbArgs),
/// Upgrade the firmware of the BMC
Firmware(FirmwareArgs),
/// Flash a given node
Flash(FlashArgs),
/// configure the on-board ethernet switch.
/// configure the on-board Ethernet switch.
Eth(EthArgs),
/// [deprecated] forward a uart command or get a line from the serial.
/// Read or write over UART
Uart(UartArgs),
}

Expand All @@ -67,7 +65,7 @@ pub enum PowerCmd {

#[derive(Args, Clone)]
pub struct EthArgs {
/// reset ethernet switch
/// Reset ethernet switch
#[arg(short, long)]
pub reset: bool,
}
Expand Down
18 changes: 10 additions & 8 deletions src/legacy_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl LegacyHandler {

/// Handler for CLI commands. Responses are printed to stdout and need to be formatted
/// using the json format with a key `response`.
pub async fn handle_cmd(mut self, command: Commands) -> anyhow::Result<()> {
pub async fn handle_cmd(mut self, command: &Commands) -> anyhow::Result<()> {
let form = match command {
Commands::Power(args) => self.handle_power_nodes(args)?,
Commands::Usb(args) => self.handle_usb(args)?,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl LegacyHandler {
})
}

fn handle_uart(&mut self, args: UartArgs) -> anyhow::Result<Option<Form>> {
fn handle_uart(&mut self, args: &UartArgs) -> anyhow::Result<Option<Form>> {
let mut serializer = self.url.query_pairs_mut();
if args.action == GetSet::Get {
serializer
Expand All @@ -91,23 +91,25 @@ impl LegacyHandler {
.append_pair("opt", "set")
.append_pair("type", "uart")
.append_pair("node", &(args.node - 1).to_string())
.append_pair("cmd", &args.cmd.unwrap());
.append_pair("cmd", args.cmd.as_ref().unwrap());
}
Ok(None)
}

fn handle_eth(&mut self, args: EthArgs) -> anyhow::Result<Option<Form>> {
fn handle_eth(&mut self, args: &EthArgs) -> anyhow::Result<Option<Form>> {
if args.reset {
self.url
.query_pairs_mut()
.append_pair("opt", "set")
.append_pair("type", "network")
.append_pair("cmd", "reset");
} else {
bail!("eth subcommand called without any actions");
}
Ok(None)
}

async fn handle_firmware(&mut self, args: FirmwareArgs) -> anyhow::Result<Option<Form>> {
async fn handle_firmware(&mut self, args: &FirmwareArgs) -> anyhow::Result<Option<Form>> {
let file_name = args
.file
.file_name()
Expand All @@ -121,7 +123,7 @@ impl LegacyHandler {
Ok(Some(reqwest::multipart::Form::new().part("file", part)))
}

async fn handle_flash(&mut self, args: FlashArgs) -> anyhow::Result<Option<Form>> {
async fn handle_flash(&mut self, args: &FlashArgs) -> anyhow::Result<Option<Form>> {
let mut serializer = self.url.query_pairs_mut();
serializer
.append_pair("opt", "set")
Expand All @@ -147,7 +149,7 @@ impl LegacyHandler {
}
}

fn handle_usb(&mut self, args: UsbArgs) -> anyhow::Result<Option<Form>> {
fn handle_usb(&mut self, args: &UsbArgs) -> anyhow::Result<Option<Form>> {
if args.bmc {
bail!("--bmc argument not implemented yet!");
}
Expand Down Expand Up @@ -177,7 +179,7 @@ impl LegacyHandler {
Ok(None)
}

fn handle_power_nodes(&mut self, args: PowerArgs) -> anyhow::Result<Option<Form>> {
fn handle_power_nodes(&mut self, args: &PowerArgs) -> anyhow::Result<Option<Form>> {
let mut serializer = self.url.query_pairs_mut();
if args.cmd == PowerCmd::Get {
serializer
Expand Down
24 changes: 18 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,40 @@ async fn main() -> ExitCode {
return ExitCode::SUCCESS;
}

if let Err(e) = execute_cli_command(cli).await {
println!("{e}");
if let Err(e) = execute_cli_command(&cli).await {
match e.downcast_ref::<reqwest::Error>() {
Some(error) if error.is_connect() => {
println!(
"Cannot connect to `{}`",
error
.url()
.map(|u| u.host_str())
.flatten()
.unwrap_or(&cli.host.unwrap())
);
}
_ => println!("{e}"),
}
return ExitCode::FAILURE;
}

ExitCode::SUCCESS
}

async fn execute_cli_command(cli: Cli) -> anyhow::Result<()> {
let command = cli.command.ok_or_else(|| {
async fn execute_cli_command(cli: &Cli) -> anyhow::Result<()> {
let command = cli.command.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"subcommand must be specified!\n\n{}",
Cli::command().render_help()
)
})?;

// validate host input
let host = url::Host::parse(&cli.host.expect("host has a default set"))
let host = url::Host::parse(cli.host.as_ref().expect("host has a default set"))
.map_err(|_| anyhow!("please enter a valid hostname"))?;

LegacyHandler::new(host.to_string(), cli.json)
.await?
.handle_cmd(command)
.handle_cmd(&command)
.await
}

0 comments on commit 2d08bbd

Please sign in to comment.