use clap::Parser;
mod errors;
use errors::CliError;
use tabular::{row, Table};
use reqwest::{blocking::Client, StatusCode};
use solarlib::planet::Planet;
/// Manage solard and homeworld instances
#[derive(Parser)]
#[clap(author, version, about)]
struct Args {
/// The solard server to connect to
server: String,
/// The action to be taken
#[clap(subcommand)]
action: Action
}
#[derive(clap::Subcommand)]
enum Action {
/// List planets on the server
List,
/// Shuts down a virtual machine
Stop {
/// The UUID of the machine to stop
uuid: String,
},
Start {
/// The UUID of the machine to start
uuid: String,
},
Pause {
/// The UUID of the machine to pause
uuid: String,
},
}
fn main() {
color_eyre::install().unwrap();
let args = Args::parse();
let client = reqwest::blocking::Client::new();
let root = args.server.clone();
match args.action {
Action::List => {
list(args, client).unwrap();
},
Action::Stop { uuid } => {
stop(root, client, uuid).unwrap();
},
Action::Start { uuid } => {
start(root, client, uuid).unwrap();
},
Action::Pause { uuid } => {
pause(root, client, uuid).unwrap();
}
};
}
fn list(a: Args, c: Client) -> Result<(), CliError> {
let res: Vec<Planet> = c.get(format!("http://{}/planets/list", a.server)).send()?.json()?;
let mut table = Table::new("{:<} {:<} {:<}");
table.add_row(row!(
"name", "uuid", "status")
);
for p in res {
table.add_row(row!(
&p.name,
&p.uuid,
if p.orbiting { "Running" } else { "Not running" },
));
}
println!("{}", table);
Ok(())
}
fn stop(server: String, c: Client, u: String) -> Result<(), CliError> {
let res = c.post(format!("http://{}/planets/{}/shutdown", server, u)).send()?;
match res.status() {
StatusCode::OK => {
println!("Stopped.");
},
_ => {
return Err(CliError::Cli(format!("Could not stop VM: {}", res.text()?)));
},
};
Ok(())
}
fn start(server: String, c: Client, u: String) -> Result<(), CliError> {
let res = c.post(format!("http://{}/planets/{}/start", server, u)).send()?;
match res.status() {
StatusCode::OK => {
println!("Started.");
},
_ => {
return Err(CliError::Cli(format!("Could not start VM: {}", res.text()?)));
},
};
Ok(())
}
fn pause(server: String, c: Client, u: String) -> Result<(), CliError> {
let res = c.post(format!("http://{}/planets/{}/pause", server, u)).send()?;
match res.status() {
StatusCode::OK => {
println!("Paused.");
},
_ => {
return Err(CliError::Cli(format!("Could not pause VM: {}", res.text()?)));
},
};
Ok(())
}