From 565cb660eed6dd13fc1846f294290cba505d220e Mon Sep 17 00:00:00 2001 From: groche97 Date: Thu, 7 Sep 2023 21:27:03 +0200 Subject: [PATCH] finish containers persistance --- Cargo.lock | 1 + Cargo.toml | 1 + src/conf/mod.rs | 19 ++++++++++------- src/conf/storage.rs | 1 + src/controller/mod.rs | 26 ++++++++++++++++-------- src/deploy/container.rs | 45 ++++++++++++++++++++++++----------------- 6 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b57a58..034e4e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1007,6 +1007,7 @@ dependencies = [ "env_logger", "fallible-iterator", "futures", + "log", "rusqlite", "serde", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 132abf2..0340466 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ tokio = { version = "1", features = ["full"] } rusqlite = { version = "0.29.0", features = ["bundled"] } actix-web = "4" env_logger = "*" +log = "*" serde = "*" fallible-iterator = "*" diff --git a/src/conf/mod.rs b/src/conf/mod.rs index beacc4d..1737077 100644 --- a/src/conf/mod.rs +++ b/src/conf/mod.rs @@ -14,6 +14,7 @@ pub struct ConfServer{ pub struct Instance { id: i64, + pub docker_id: String, pub ip: String, pub domain: String, pub image: i64, @@ -40,6 +41,7 @@ impl InstanceStorage { id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE); CREATE TABLE IF NOT EXISTS l_instances( id INTEGER PRIMARY KEY AUTOINCREMENT, + docker_id TEXT, ip TEXT, domain TEXT, image INTEGER, @@ -55,13 +57,14 @@ impl InstanceStorage { } fn load_instances(&mut self) -> Result> { - let mut stmt = self.con.prepare("select id, ip, domain, image from l_instances")?; + let mut stmt = self.con.prepare("select id, docker_id, ip, domain, image from l_instances")?; let mut rows = stmt.query([])?; rows.map(|r| Ok(Instance{ id: r.get::<_, i64>(0)?, - ip: r.get::<_, String>(1)?, - domain: r.get::<_, String>(2)?, - image: r.get::<_, i64>(3)?, + docker_id: r.get::<_, String>(1)?, + ip: r.get::<_, String>(2)?, + domain: r.get::<_, String>(3)?, + image: r.get::<_, i64>(4)?, })).collect() } @@ -95,14 +98,16 @@ impl InstanceStorage { }) } - pub fn new_instance(&mut self, ip: String, domain: String, image: i64) -> Result{ + pub fn new_instance(&mut self, docker_id: String, ip: String, domain: String, image: i64) -> Result{ //let image_id = self.create_or_get_image_id(image.clone(), 0)?; - let mut stmt = self.con.prepare("INSERT INTO l_instances(ip, domain, image) values(?1, ?2, ?3)")?; - stmt.execute([ip.clone(), + let mut stmt = self.con.prepare("INSERT INTO l_instances(docker_id, ip, domain, image) values(?1, ?2, ?3, ?4)")?; + stmt.execute([docker_id.clone(), + ip.clone(), domain.clone(), image.to_string()])?; Ok(Instance { id: image, + docker_id: docker_id, ip: ip, domain: domain, image: image, diff --git a/src/conf/storage.rs b/src/conf/storage.rs index 6907852..490da7e 100644 --- a/src/conf/storage.rs +++ b/src/conf/storage.rs @@ -40,6 +40,7 @@ impl MemStorage { pub fn new_instance(&mut self, container: Container) -> Result<(), Error> { let image_id = self.image_to_id(container.image.clone())?; let ins = self.storage.new_instance( + container.get_id(), container.ip.clone(), container.name.clone(), image_id)?; diff --git a/src/controller/mod.rs b/src/controller/mod.rs index 991ae62..84d707e 100644 --- a/src/controller/mod.rs +++ b/src/controller/mod.rs @@ -3,6 +3,7 @@ use crate::deploy; use crate::conf::storage::MemStorage; use crate::conf::Instance; use std::sync::Mutex; +use log::{error}; pub struct Controller { driver: Docker, @@ -24,7 +25,7 @@ impl Controller { } pub async fn create_container(&self, domain: String, ip: String, image: String) -> String { - match self.load_container(domain.clone(),ip.clone(),image.clone()).await { + match self.load_container(None,domain.clone(),ip.clone(),image.clone()).await { Ok(c) => { let ret = c.get_id(); self.storage.lock().unwrap().new_instance(c).unwrap(); @@ -37,28 +38,34 @@ impl Controller { pub async fn start_container_from_instance(&self, instance: Instance) { let image = match self.storage.lock().unwrap().id_to_image(instance.image.clone()) { Ok(i) => i, - Err(_e) => return, //meter logs aquĆ­ + Err(e) => { + log::error!("image not found: {}", e); + return + }, }; match self.load_container( + Some(instance.docker_id.clone()), instance.domain.clone(), instance.ip.clone(), image).await { Ok(c) => { self.storage.lock().unwrap().loaded_instance(instance, c); }, - Err(_e) => (), + Err(e) => log::error!("{}",e), } } - async fn load_container(&self, domain: String, + async fn load_container(&self, docker_id: Option, + domain: String, ip: String, image: String) -> Result { deploy::container::Container::new(self.driver.clone(), - domain.clone(), - ip.clone(), - image.clone(), + docker_id, + domain, + ip, + image, self.network.clone()).await } @@ -69,7 +76,10 @@ impl Controller { pub async fn load_all_instances(&self) -> bool { let data = match self.storage.lock().unwrap().get_instances_db() { Ok(d) => d, - Err(_e) => return false, + Err(e) => { + log::error!("instances can't be loaded: {}",e); + return false + }, }; println!("instances {}", data.len()); for instance in data { diff --git a/src/deploy/container.rs b/src/deploy/container.rs index 3b26bcf..23710d9 100644 --- a/src/deploy/container.rs +++ b/src/deploy/container.rs @@ -20,6 +20,7 @@ pub struct Container { impl Container { pub async fn new(docker: bollard::Docker, + docker_id: Option, name: String, ip: String, image: String, @@ -31,32 +32,34 @@ impl Container { image: image, net: net, start: false, - docker_id: None, + docker_id: docker_id, database_id: None, }; match container.start(docker).await { Ok(c) => { container.start=true; - container.docker_id = Some(c); Ok(container) } Err(e) => Err(e), } } - async fn start(&self, docker: bollard::Docker) -> Result{ - let id_container = match self.exist_container(docker.clone()).await? { - Some(id_ret) => id_ret, - None => docker.create_container(Some( + async fn start(&mut self, docker: bollard::Docker) -> Result{ + let ret = match &self.exist_container(docker.clone()).await? { + Some(_id) => true, + None => { + self.docker_id = Some(docker.create_container(Some( create_options(self.name.clone())), create_config(self.ip.clone(), self.net.clone(), self.image.clone())) - .await?.id, + .await?.id); + false + }, }; docker.start_container(&self.name, None::>).await?; - Ok(id_container) + Ok(ret) } pub fn get_id(&self) -> String { @@ -67,15 +70,21 @@ impl Container { } async fn exist_container(&self, docker: bollard::Docker) -> Result, Error> { - let list = docker.list_containers( - Some(create_search_container(self.name.clone())) - ).await?; - println!("{}", list.len()); - Ok (if list.len() > 0 { - list[0].id.clone() - } else { - None - }) + match &self.docker_id { + Some(_id) => { + let list = docker.list_containers( + Some(create_search_container(self.get_id().clone())) + ).await?; + Ok (if list.len() > 0 { + list[0].id.clone() + } else { + None + }) + } + + None => Ok(None), + } + } async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{ @@ -84,7 +93,7 @@ impl Container { } fn create_search_container(name: String) -> ListContainersOptions { let mut filters = HashMap::new(); - filters.insert("before".to_string(), vec![name]); + filters.insert("id".to_string(), vec![name]); ListContainersOptions{ all: true,