mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-11 08:01:13 +00:00
add new ec2 instance types clean up testing config document the libraries a bit clean up main update sysinfo and otel update client resolver 3.0 resolver v3 prog clean up gitignore implement periphery resolver v3 clean up core read api v3 more prog execute api missing apis compiling 1.16.13 work on more granular traits prog on crud
417 lines
10 KiB
Rust
417 lines
10 KiB
Rust
use anyhow::{anyhow, Context};
|
|
use command::run_komodo_command;
|
|
use futures::future::join_all;
|
|
use komodo_client::entities::{
|
|
docker::container::{Container, ContainerListItem, ContainerStats},
|
|
to_komodo_name,
|
|
update::Log,
|
|
};
|
|
use periphery_client::api::container::*;
|
|
use resolver_api::Resolve;
|
|
|
|
use crate::{
|
|
docker::{container_stats, docker_client, stop_container_command},
|
|
helpers::log_grep,
|
|
};
|
|
|
|
// ======
|
|
// READ
|
|
// ======
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for InspectContainer {
|
|
#[instrument(name = "InspectContainer", level = "debug")]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Container> {
|
|
Ok(docker_client().inspect_container(&self.name).await?)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for GetContainerLog {
|
|
#[instrument(name = "GetContainerLog", level = "debug")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
let GetContainerLog {
|
|
name,
|
|
tail,
|
|
timestamps,
|
|
} = self;
|
|
let timestamps =
|
|
timestamps.then_some(" --timestamps").unwrap_or_default();
|
|
let command =
|
|
format!("docker logs {name} --tail {tail}{timestamps}");
|
|
Ok(
|
|
run_komodo_command("get container log", None, command, false)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for GetContainerLogSearch {
|
|
#[instrument(name = "GetContainerLogSearch", level = "debug")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
let GetContainerLogSearch {
|
|
name,
|
|
terms,
|
|
combinator,
|
|
invert,
|
|
timestamps,
|
|
} = self;
|
|
let grep = log_grep(&terms, combinator, invert);
|
|
let timestamps =
|
|
timestamps.then_some(" --timestamps").unwrap_or_default();
|
|
let command = format!(
|
|
"docker logs {name} --tail 5000{timestamps} 2>&1 | {grep}"
|
|
);
|
|
Ok(
|
|
run_komodo_command(
|
|
"get container log grep",
|
|
None,
|
|
command,
|
|
false,
|
|
)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for GetContainerStats {
|
|
#[instrument(name = "GetContainerStats", level = "debug")]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<ContainerStats> {
|
|
let error = anyhow!("no stats matching {}", self.name);
|
|
let mut stats = container_stats(Some(self.name)).await?;
|
|
let stats = stats.pop().ok_or(error)?;
|
|
Ok(stats)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for GetContainerStatsList {
|
|
#[instrument(name = "GetContainerStatsList", level = "debug")]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Vec<ContainerStats>> {
|
|
Ok(container_stats(None).await?)
|
|
}
|
|
}
|
|
|
|
// =========
|
|
// ACTIONS
|
|
// =========
|
|
|
|
impl Resolve<super::Args> for StartContainer {
|
|
#[instrument(name = "StartContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
Ok(
|
|
run_komodo_command(
|
|
"docker start",
|
|
None,
|
|
format!("docker start {}", self.name),
|
|
false,
|
|
)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for RestartContainer {
|
|
#[instrument(name = "RestartContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
Ok(
|
|
run_komodo_command(
|
|
"docker restart",
|
|
None,
|
|
format!("docker restart {}", self.name),
|
|
false,
|
|
)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for PauseContainer {
|
|
#[instrument(name = "PauseContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
Ok(
|
|
run_komodo_command(
|
|
"docker pause",
|
|
None,
|
|
format!("docker pause {}", self.name),
|
|
false,
|
|
)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl Resolve<super::Args> for UnpauseContainer {
|
|
#[instrument(name = "UnpauseContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
Ok(
|
|
run_komodo_command(
|
|
"docker unpause",
|
|
None,
|
|
format!("docker unpause {}", self.name),
|
|
false,
|
|
)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for StopContainer {
|
|
#[instrument(name = "StopContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
let StopContainer { name, signal, time } = self;
|
|
let command = stop_container_command(&name, signal, time);
|
|
let log =
|
|
run_komodo_command("docker stop", None, command, false).await;
|
|
if log.stderr.contains("unknown flag: --signal") {
|
|
let command = stop_container_command(&name, None, time);
|
|
let mut log =
|
|
run_komodo_command("docker stop", None, command, false).await;
|
|
log.stderr = format!(
|
|
"old docker version: unable to use --signal flag{}",
|
|
if !log.stderr.is_empty() {
|
|
format!("\n\n{}", log.stderr)
|
|
} else {
|
|
String::new()
|
|
}
|
|
);
|
|
Ok(log)
|
|
} else {
|
|
Ok(log)
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for RemoveContainer {
|
|
#[instrument(name = "RemoveContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
let RemoveContainer { name, signal, time } = self;
|
|
let stop_command = stop_container_command(&name, signal, time);
|
|
let command =
|
|
format!("{stop_command} && docker container rm {name}");
|
|
let log = run_komodo_command(
|
|
"docker stop and remove",
|
|
None,
|
|
command,
|
|
false,
|
|
)
|
|
.await;
|
|
if log.stderr.contains("unknown flag: --signal") {
|
|
let stop_command = stop_container_command(&name, None, time);
|
|
let command =
|
|
format!("{stop_command} && docker container rm {name}");
|
|
let mut log =
|
|
run_komodo_command("docker stop", None, command, false).await;
|
|
log.stderr = format!(
|
|
"old docker version: unable to use --signal flag{}",
|
|
if !log.stderr.is_empty() {
|
|
format!("\n\n{}", log.stderr)
|
|
} else {
|
|
String::new()
|
|
}
|
|
);
|
|
Ok(log)
|
|
} else {
|
|
Ok(log)
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for RenameContainer {
|
|
#[instrument(name = "RenameContainer")]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
let RenameContainer {
|
|
curr_name,
|
|
new_name,
|
|
} = self;
|
|
let new = to_komodo_name(&new_name);
|
|
let command = format!("docker rename {curr_name} {new}");
|
|
Ok(
|
|
run_komodo_command("docker rename", None, command, false).await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for PruneContainers {
|
|
#[instrument(name = "PruneContainers", skip_all)]
|
|
async fn resolve(self, _: &super::Args) -> serror::Result<Log> {
|
|
let command = String::from("docker container prune -f");
|
|
Ok(
|
|
run_komodo_command("prune containers", None, command, false)
|
|
.await,
|
|
)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for StartAllContainers {
|
|
#[instrument(name = "StartAllContainers", skip_all)]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Vec<Log>> {
|
|
let containers = docker_client()
|
|
.list_containers()
|
|
.await
|
|
.context("failed to list all containers on host")?;
|
|
let futures = containers.iter().filter_map(
|
|
|ContainerListItem { name, labels, .. }| {
|
|
if labels.contains_key("komodo.skip") {
|
|
return None;
|
|
}
|
|
let command = format!("docker start {name}");
|
|
Some(async move {
|
|
run_komodo_command(&command.clone(), None, command, false)
|
|
.await
|
|
})
|
|
},
|
|
);
|
|
Ok(join_all(futures).await)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for RestartAllContainers {
|
|
#[instrument(name = "RestartAllContainers", skip_all)]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Vec<Log>> {
|
|
let containers = docker_client()
|
|
.list_containers()
|
|
.await
|
|
.context("failed to list all containers on host")?;
|
|
let futures = containers.iter().filter_map(
|
|
|ContainerListItem { name, labels, .. }| {
|
|
if labels.contains_key("komodo.skip") {
|
|
return None;
|
|
}
|
|
let command = format!("docker restart {name}");
|
|
Some(async move {
|
|
run_komodo_command(&command.clone(), None, command, false)
|
|
.await
|
|
})
|
|
},
|
|
);
|
|
Ok(join_all(futures).await)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for PauseAllContainers {
|
|
#[instrument(name = "PauseAllContainers", skip_all)]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Vec<Log>> {
|
|
let containers = docker_client()
|
|
.list_containers()
|
|
.await
|
|
.context("failed to list all containers on host")?;
|
|
let futures = containers.iter().filter_map(
|
|
|ContainerListItem { name, labels, .. }| {
|
|
if labels.contains_key("komodo.skip") {
|
|
return None;
|
|
}
|
|
let command = format!("docker pause {name}");
|
|
Some(async move {
|
|
run_komodo_command(&command.clone(), None, command, false)
|
|
.await
|
|
})
|
|
},
|
|
);
|
|
Ok(join_all(futures).await)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for UnpauseAllContainers {
|
|
#[instrument(name = "UnpauseAllContainers", skip_all)]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Vec<Log>> {
|
|
let containers = docker_client()
|
|
.list_containers()
|
|
.await
|
|
.context("failed to list all containers on host")?;
|
|
let futures = containers.iter().filter_map(
|
|
|ContainerListItem { name, labels, .. }| {
|
|
if labels.contains_key("komodo.skip") {
|
|
return None;
|
|
}
|
|
let command = format!("docker unpause {name}");
|
|
Some(async move {
|
|
run_komodo_command(&command.clone(), None, command, false)
|
|
.await
|
|
})
|
|
},
|
|
);
|
|
Ok(join_all(futures).await)
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
impl Resolve<super::Args> for StopAllContainers {
|
|
#[instrument(name = "StopAllContainers", skip_all)]
|
|
async fn resolve(
|
|
self,
|
|
_: &super::Args,
|
|
) -> serror::Result<Vec<Log>> {
|
|
let containers = docker_client()
|
|
.list_containers()
|
|
.await
|
|
.context("failed to list all containers on host")?;
|
|
let futures = containers.iter().filter_map(
|
|
|ContainerListItem { name, labels, .. }| {
|
|
if labels.contains_key("komodo.skip") {
|
|
return None;
|
|
}
|
|
Some(async move {
|
|
run_komodo_command(
|
|
&format!("docker stop {name}"),
|
|
None,
|
|
stop_container_command(name, None, None),
|
|
false,
|
|
)
|
|
.await
|
|
})
|
|
},
|
|
);
|
|
Ok(join_all(futures).await)
|
|
}
|
|
}
|