use async_trait::async_trait;
use bollard::Docker;
use ironflow_core::error::OperationError;
use ironflow_core::operation::{Operation, OperationContext, TypedOperation};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::containers::DockerRef;
use crate::helpers::{docker_error, to_value};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemInfoOutput {
pub data: Value,
}
pub struct SystemInfo {
docker: Docker,
}
impl SystemInfo {
pub fn new(client: impl Into<DockerRef>) -> Self {
Self {
docker: client.into().0,
}
}
pub async fn run(&self, _ctx: &OperationContext) -> Result<SystemInfoOutput, OperationError> {
let info = self.docker.info().await.map_err(docker_error)?;
let data = serde_json::to_value(&info).map_err(|e| OperationError::External {
origin: "docker".to_string(),
message: e.to_string(),
})?;
Ok(SystemInfoOutput { data })
}
}
#[async_trait]
impl Operation for SystemInfo {
fn kind(&self) -> &str {
"docker"
}
async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
to_value(&self.run(ctx).await?)
}
fn input(&self) -> Option<Value> {
Some(serde_json::json!({ "operation": "system_info" }))
}
}
impl TypedOperation for SystemInfo {
type Output = SystemInfoOutput;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemVersionOutput {
pub data: Value,
}
pub struct SystemVersion {
docker: Docker,
}
impl SystemVersion {
pub fn new(client: impl Into<DockerRef>) -> Self {
Self {
docker: client.into().0,
}
}
pub async fn run(
&self,
_ctx: &OperationContext,
) -> Result<SystemVersionOutput, OperationError> {
let version = self.docker.version().await.map_err(docker_error)?;
let data = serde_json::to_value(&version).map_err(|e| OperationError::External {
origin: "docker".to_string(),
message: e.to_string(),
})?;
Ok(SystemVersionOutput { data })
}
}
#[async_trait]
impl Operation for SystemVersion {
fn kind(&self) -> &str {
"docker"
}
async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
to_value(&self.run(ctx).await?)
}
fn input(&self) -> Option<Value> {
Some(serde_json::json!({ "operation": "system_version" }))
}
}
impl TypedOperation for SystemVersion {
type Output = SystemVersionOutput;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemPingOutput {
pub response: String,
}
pub struct SystemPing {
docker: Docker,
}
impl SystemPing {
pub fn new(client: impl Into<DockerRef>) -> Self {
Self {
docker: client.into().0,
}
}
pub async fn run(&self, _ctx: &OperationContext) -> Result<SystemPingOutput, OperationError> {
let response = self.docker.ping().await.map_err(docker_error)?;
Ok(SystemPingOutput { response })
}
}
#[async_trait]
impl Operation for SystemPing {
fn kind(&self) -> &str {
"docker"
}
async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
to_value(&self.run(ctx).await?)
}
fn input(&self) -> Option<Value> {
Some(serde_json::json!({ "operation": "system_ping" }))
}
}
impl TypedOperation for SystemPing {
type Output = SystemPingOutput;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemDfOutput {
pub data: Value,
}
pub struct SystemDf {
docker: Docker,
}
impl SystemDf {
pub fn new(client: impl Into<DockerRef>) -> Self {
Self {
docker: client.into().0,
}
}
pub async fn run(&self, _ctx: &OperationContext) -> Result<SystemDfOutput, OperationError> {
let df = self
.docker
.df(None::<bollard::query_parameters::DataUsageOptions>)
.await
.map_err(docker_error)?;
let data = serde_json::to_value(&df).map_err(|e| OperationError::External {
origin: "docker".to_string(),
message: e.to_string(),
})?;
Ok(SystemDfOutput { data })
}
}
#[async_trait]
impl Operation for SystemDf {
fn kind(&self) -> &str {
"docker"
}
async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
to_value(&self.run(ctx).await?)
}
fn input(&self) -> Option<Value> {
Some(serde_json::json!({ "operation": "system_df" }))
}
}
impl TypedOperation for SystemDf {
type Output = SystemDfOutput;
}