Skip to content

Commit dd3629a

Browse files
committed
FEAT: Docker actions
1 parent f03eb33 commit dd3629a

7 files changed

Lines changed: 146 additions & 19 deletions

File tree

src/events/docker.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
use bollard::secret::{ContainerInspectResponse, ContainerSummary};
12
use serde::{Deserialize, Serialize};
23

34
#[derive(Serialize, Deserialize, Debug)]
45
#[serde(tag = "type")]
56
pub enum DockerEvent {
67
DockerStatus { data: DockerStatusData },
7-
DockerContainersRestart { data: DockerContainersRestartData }
8+
DockerContainerList { data: DockerContainerListData },
9+
DockerContainerInspect { data: DockerContainerInspectData },
10+
DockerContainerStart { data: DockerContainerStartData },
11+
DockerContainerRestart { data: DockerContainerRestartData },
12+
DockerContainerStop { data: DockerContainerStopData }
813
}
914

1015
#[derive(Serialize, Deserialize, Debug)]
@@ -13,7 +18,32 @@ pub struct DockerStatusData {
1318
}
1419

1520
#[derive(Serialize, Deserialize, Debug)]
16-
pub struct DockerContainersRestartData {
17-
#[serde(rename = "containerId")]
21+
pub struct DockerContainerListData {
22+
pub containers: Option<Vec<ContainerSummary>>
23+
}
24+
25+
#[derive(Serialize, Deserialize, Debug)]
26+
pub struct DockerContainerInspectData {
27+
#[serde(rename = "containerId", alias = "ID")]
28+
pub container_id: Option<String>,
29+
30+
pub container: Option<ContainerInspectResponse>
31+
}
32+
33+
#[derive(Serialize, Deserialize, Debug)]
34+
pub struct DockerContainerStartData {
35+
#[serde(rename = "containerId", alias = "ID")]
36+
pub container_id: Option<String>
37+
}
38+
39+
#[derive(Serialize, Deserialize, Debug)]
40+
pub struct DockerContainerRestartData {
41+
#[serde(rename = "containerId", alias = "ID")]
42+
pub container_id: Option<String>
43+
}
44+
45+
#[derive(Serialize, Deserialize, Debug)]
46+
pub struct DockerContainerStopData {
47+
#[serde(rename = "containerId", alias = "ID")]
1848
pub container_id: Option<String>
1949
}

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
mod events;
2-
mod datas;
2+
mod serializers;
33
mod webtransport;
44
mod services;
55

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use serde_json::{json, Value};
33

44
use super::EventDTO;
55

6+
67
impl EventDTO for ContainerSummary {
78
fn to_json(&self) -> Value {
89
json!({
@@ -24,6 +25,6 @@ impl EventDTO for ContainerSummary {
2425

2526
impl EventDTO for Vec<ContainerSummary> {
2627
fn to_json(&self) -> Value {
27-
json!(self.iter().map(|f| f.to_json()).collect::<Vec<Value>>())
28+
json!(self.iter().map(|container| container.to_json()).collect::<Vec<Value>>())
2829
}
2930
}
File renamed without changes.

src/services/docker.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,22 @@ use futures::StreamExt;
55
use serde_json::json;
66
use tokio::sync::broadcast;
77

8-
use crate::{datas::SendEvent, events::{docker::{DockerEvent, DockerStatusData}, Event}};
8+
use crate::{events::{docker::{DockerEvent, DockerStatusData}, Event}, serializers::SendEvent};
99

1010
const INTERVAL: Duration = Duration::from_secs(10);
1111

12+
pub fn format_docker_event_value(s: &str) -> String {
13+
let mut chars = s.chars();
14+
match chars.next() {
15+
None => String::new(),
16+
Some(first_char) => {
17+
let first_char_uppercase = first_char.to_uppercase().collect::<String>();
18+
let rest_lowercase = chars.as_str().to_lowercase();
19+
format!("{}{}", first_char_uppercase, rest_lowercase)
20+
}
21+
}
22+
}
23+
1224
pub fn get_docker_client() -> Result<Docker, Error> {
1325
Docker::connect_with_socket_defaults()
1426
}
@@ -34,15 +46,23 @@ pub async fn listen_docker_events(mut tx: broadcast::Sender<String>) {
3446

3547
while let Some(event) = events.next().await {
3648
match event {
37-
Ok(event) => {
38-
let event_str = json!(event).to_string();
39-
40-
match tx.send(event_str){
41-
Ok(_) => {},
49+
Ok(event) => {
50+
let event_action = format!("Docker{}{}", format_docker_event_value(&event.typ.clone().unwrap().to_string()), format_docker_event_value(&event.action.clone().unwrap().to_string()));
51+
let event_json = json!({
52+
"type": event_action,
53+
"data": &event.actor
54+
}).to_string();
55+
let docker_event: Event = match serde_json::from_str(&event_json) {
56+
Ok(docker_event) => docker_event,
4257
Err(error) => {
43-
log::error!("Failed to send Docker event: {:?}", error);
58+
log::error!("Failed to parse Docker event [{}]: {:?}", event_action, error);
59+
continue;
4460
}
4561
};
62+
63+
log::info!("Received Docker event: {:?}", docker_event);
64+
65+
tx.send_event(docker_event).await;
4666
}
4767
Err(error) => {
4868
log::error!("Failed to receive Docker event: {:?}", error);

src/webtransport/docker.rs

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{datas::SendEvent, events::{docker::{DockerContainersRestartData, DockerEvent, DockerStatusData}, Event}, services::docker};
1+
use crate::{events::{docker::{DockerContainerInspectData, DockerContainerListData, DockerContainerRestartData, DockerEvent, DockerStatusData}, Event}, serializers::SendEvent, services::docker};
22

33
pub async fn handle_message(send_stream: &mut wtransport::SendStream, event: &DockerEvent) {
44
match event {
@@ -8,14 +8,90 @@ pub async fn handle_message(send_stream: &mut wtransport::SendStream, event: &Do
88
status: Some(docker::ping().await)
99
}
1010
})).await;
11-
log::info!("{:?}", Event::Docker(DockerEvent::DockerContainersRestart {
12-
data: DockerContainersRestartData {
11+
log::info!("{:?}", Event::Docker(DockerEvent::DockerContainerRestart {
12+
data: DockerContainerRestartData {
1313
container_id: Some("container_id".to_string()),
1414
}
1515
}));
1616
},
17-
DockerEvent::DockerContainersRestart { data } => {
18-
log::info!("Restarting containers: {:?}", data);
19-
}
17+
DockerEvent::DockerContainerList { .. } => {
18+
let containers = match docker::get_containers().await {
19+
Ok(containers) => containers,
20+
Err(error) => {
21+
log::error!("Failed to get containers: {:?}", error);
22+
send_stream.send_event(Event::Docker(DockerEvent::DockerStatus {
23+
data: DockerStatusData {
24+
status: Some(docker::ping().await)
25+
}
26+
})).await;
27+
Vec::new()
28+
}
29+
};
30+
31+
send_stream.send_event(Event::Docker(DockerEvent::DockerContainerList {
32+
data: DockerContainerListData {
33+
containers: Some(containers)
34+
}
35+
})).await;
36+
},
37+
DockerEvent::DockerContainerInspect { data } => {
38+
match &data.container_id {
39+
Some(container_id) => {
40+
let container = match docker::get_container(&container_id).await {
41+
Ok(container) => container,
42+
Err(error) => {
43+
log::error!("Failed to inspect container: {:?}", error);
44+
return;
45+
}
46+
};
47+
48+
send_stream.send_event(Event::Docker(DockerEvent::DockerContainerInspect {
49+
data: DockerContainerInspectData {
50+
container_id: Some(container_id.clone()),
51+
container: Some(container)
52+
}
53+
})).await;
54+
},
55+
None => {
56+
log::error!("No container ID provided");
57+
}
58+
}
59+
},
60+
DockerEvent::DockerContainerStart { data } => {
61+
match &data.container_id {
62+
Some(container_id) => {
63+
if let Err(error) = docker::start_container(&container_id).await {
64+
log::error!("Failed to start container: {:?}", error);
65+
}
66+
},
67+
None => {
68+
log::error!("No container ID provided");
69+
}
70+
}
71+
},
72+
DockerEvent::DockerContainerRestart { data } => {
73+
match &data.container_id {
74+
Some(container_id) => {
75+
if let Err(error) = docker::restart_container(&container_id).await {
76+
log::error!("Failed to restart container: {:?}", error);
77+
}
78+
},
79+
None => {
80+
log::error!("No container ID provided");
81+
}
82+
}
83+
},
84+
DockerEvent::DockerContainerStop { data } => {
85+
match &data.container_id {
86+
Some(container_id) => {
87+
if let Err(error) = docker::stop_container(&container_id).await {
88+
log::error!("Failed to stop container: {:?}", error);
89+
}
90+
},
91+
None => {
92+
log::error!("No container ID provided");
93+
}
94+
}
95+
},
2096
}
2197
}

src/webtransport/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ async fn handle_bidirectionnal(connection: Connection, tx: broadcast::Sender<Str
150150
});
151151

152152
tokio::spawn(async move {
153-
let mut buffer = [0; 1024];
153+
let mut buffer = [0; 4096];
154154
loop {
155155
match recv_stream.read(&mut buffer).await {
156156
Ok(Some(0)) => {

0 commit comments

Comments
 (0)