#[cfg(feature = "swarm")]
mod common;
#[cfg(feature = "swarm")]
use clap::Parser;
#[cfg(feature = "swarm")]
use common::new_docker;
#[cfg(feature = "swarm")]
#[derive(Parser)]
pub struct Opts {
#[command(subcommand)]
subcmd: Cmd,
}
#[cfg(feature = "swarm")]
#[derive(Parser)]
enum Cmd {
Delete {
service: String,
},
Inspect {
service: String,
},
List {
#[arg(long)]
with_status: bool,
},
Logs {
service: String,
#[arg(long)]
stdout: bool,
#[arg(long)]
stderr: bool,
},
}
#[cfg(feature = "swarm")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let docker = new_docker()?;
let opts: Opts = Opts::parse();
match opts.subcmd {
Cmd::Delete { service } => {
if let Err(e) = docker.services().get(&service).delete().await {
eprintln!("Error: {}", e)
}
}
Cmd::Inspect { service } => {
match docker.services().get(&service).inspect().await {
Ok(service) => println!("{:#?}", service),
Err(e) => eprintln!("Error: {}", e),
};
}
Cmd::List { with_status } => {
use docker_api::opts::ServiceListOpts;
match docker
.services()
.list(&ServiceListOpts::builder().status(with_status).build())
.await
{
Ok(services) => {
for s in services {
println!("{:#?}", s)
}
}
Err(e) => eprintln!("Error: {}", e),
}
}
Cmd::Logs {
service,
stdout,
stderr,
} => {
use docker_api::opts::LogsOpts;
use futures::StreamExt;
let service = docker.services().get(&service);
let logs_stream =
service.logs(&LogsOpts::builder().stdout(stdout).stderr(stderr).build());
let logs: Vec<_> = logs_stream
.map(|chunk| match chunk {
Ok(chunk) => chunk.to_vec(),
Err(e) => {
eprintln!("Error: {}", e);
vec![]
}
})
.collect::<Vec<_>>()
.await
.into_iter()
.flatten()
.collect::<Vec<_>>();
print!("{}", String::from_utf8_lossy(&logs));
}
}
Ok(())
}
#[cfg(not(feature = "swarm"))]
fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}