use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use utoipa::{IntoParams, ToSchema};
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
pub struct ContainerResourceLimits {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cpu: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum VolumeMountType {
Bind,
Volume,
Tmpfs,
}
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
pub struct VolumeMount {
#[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
pub mount_type: Option<VolumeMountType>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
pub target: String,
#[serde(default)]
pub readonly: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
pub struct HealthCheckRequest {
#[serde(rename = "type")]
pub check_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub port: Option<u16>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expect_status: Option<u16>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub command: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub interval: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timeout: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub retries: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub start_period: Option<String>,
}
#[derive(Debug, Deserialize, ToSchema)]
pub struct CreateContainerRequest {
pub image: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub pull_policy: Option<String>,
#[serde(default)]
pub env: HashMap<String, String>,
#[serde(default)]
pub command: Option<Vec<String>>,
#[serde(default)]
pub labels: HashMap<String, String>,
#[serde(default)]
pub resources: Option<ContainerResourceLimits>,
#[serde(default)]
pub volumes: Vec<VolumeMount>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<crate::spec::PortMapping>,
#[serde(default)]
pub work_dir: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub health_check: Option<HealthCheckRequest>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hostname: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub dns: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub extra_hosts: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub restart_policy: Option<crate::spec::ContainerRestartPolicy>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub networks: Vec<NetworkAttachmentRequest>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub registry_credential_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub registry_auth: Option<crate::spec::RegistryAuth>,
}
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
pub struct NetworkAttachmentRequest {
pub network: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub aliases: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv4_address: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ContainerInfo {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub image: String,
pub state: String,
pub labels: HashMap<String, String>,
pub created_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub pid: Option<u32>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<crate::spec::PortMapping>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub networks: Vec<NetworkAttachmentInfo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv4: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub health: Option<ContainerHealthInfo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub exit_code: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NetworkAttachmentInfo {
pub network: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub aliases: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv4: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ContainerHealthInfo {
pub status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub failing_streak: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub last_output: Option<String>,
}
#[derive(Debug, Deserialize, IntoParams)]
pub struct ListContainersQuery {
#[serde(default)]
pub label: Option<String>,
}
#[derive(Debug, Deserialize, IntoParams)]
pub struct ContainerLogQuery {
#[serde(default = "default_tail")]
pub tail: usize,
#[serde(default)]
pub follow: bool,
}
fn default_tail() -> usize {
100
}
#[derive(Debug, Deserialize, ToSchema)]
pub struct ContainerExecRequest {
pub command: Vec<String>,
}
#[derive(Debug, Default, Deserialize, IntoParams)]
pub struct ExecQuery {
#[serde(default)]
pub stream: bool,
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ContainerExecResponse {
pub exit_code: i32,
pub stdout: String,
pub stderr: String,
}
#[derive(Debug, Default, Deserialize, ToSchema)]
pub struct StopContainerRequest {
#[serde(default)]
pub timeout: Option<u64>,
}
#[derive(Debug, Default, Deserialize, ToSchema)]
pub struct RestartContainerRequest {
#[serde(default)]
pub timeout: Option<u64>,
}
#[derive(Debug, Default, Deserialize, ToSchema)]
pub struct KillContainerRequest {
#[serde(default)]
pub signal: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ContainerWaitResponse {
pub id: String,
pub exit_code: i32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub signal: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub finished_at: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct ContainerStatsResponse {
pub id: String,
pub cpu_usage_usec: u64,
pub memory_bytes: u64,
pub memory_limit: u64,
pub memory_percent: f64,
}
#[derive(Debug, Default, Deserialize, IntoParams)]
pub struct StatsQuery {
#[serde(default)]
pub stream: bool,
#[serde(default, alias = "interval_seconds")]
pub interval: Option<u32>,
}