finish containers persistance

This commit is contained in:
2023-09-07 21:27:03 +02:00
parent d0f75d89a8
commit 565cb660ee
6 changed files with 60 additions and 33 deletions

1
Cargo.lock generated
View File

@@ -1007,6 +1007,7 @@ dependencies = [
"env_logger", "env_logger",
"fallible-iterator", "fallible-iterator",
"futures", "futures",
"log",
"rusqlite", "rusqlite",
"serde", "serde",
"tokio", "tokio",

View File

@@ -10,6 +10,7 @@ tokio = { version = "1", features = ["full"] }
rusqlite = { version = "0.29.0", features = ["bundled"] } rusqlite = { version = "0.29.0", features = ["bundled"] }
actix-web = "4" actix-web = "4"
env_logger = "*" env_logger = "*"
log = "*"
serde = "*" serde = "*"
fallible-iterator = "*" fallible-iterator = "*"

View File

@@ -14,6 +14,7 @@ pub struct ConfServer{
pub struct Instance { pub struct Instance {
id: i64, id: i64,
pub docker_id: String,
pub ip: String, pub ip: String,
pub domain: String, pub domain: String,
pub image: i64, pub image: i64,
@@ -40,6 +41,7 @@ impl InstanceStorage {
id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE); id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE);
CREATE TABLE IF NOT EXISTS l_instances( CREATE TABLE IF NOT EXISTS l_instances(
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
docker_id TEXT,
ip TEXT, ip TEXT,
domain TEXT, domain TEXT,
image INTEGER, image INTEGER,
@@ -55,13 +57,14 @@ impl InstanceStorage {
} }
fn load_instances(&mut self) -> Result<Vec<Instance>> { fn load_instances(&mut self) -> Result<Vec<Instance>> {
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([])?; let mut rows = stmt.query([])?;
rows.map(|r| Ok(Instance{ rows.map(|r| Ok(Instance{
id: r.get::<_, i64>(0)?, id: r.get::<_, i64>(0)?,
ip: r.get::<_, String>(1)?, docker_id: r.get::<_, String>(1)?,
domain: r.get::<_, String>(2)?, ip: r.get::<_, String>(2)?,
image: r.get::<_, i64>(3)?, domain: r.get::<_, String>(3)?,
image: r.get::<_, i64>(4)?,
})).collect() })).collect()
} }
@@ -95,14 +98,16 @@ impl InstanceStorage {
}) })
} }
pub fn new_instance(&mut self, ip: String, domain: String, image: i64) -> Result<Instance>{ pub fn new_instance(&mut self, docker_id: String, ip: String, domain: String, image: i64) -> Result<Instance>{
//let image_id = self.create_or_get_image_id(image.clone(), 0)?; //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)")?; let mut stmt = self.con.prepare("INSERT INTO l_instances(docker_id, ip, domain, image) values(?1, ?2, ?3, ?4)")?;
stmt.execute([ip.clone(), stmt.execute([docker_id.clone(),
ip.clone(),
domain.clone(), domain.clone(),
image.to_string()])?; image.to_string()])?;
Ok(Instance { Ok(Instance {
id: image, id: image,
docker_id: docker_id,
ip: ip, ip: ip,
domain: domain, domain: domain,
image: image, image: image,

View File

@@ -40,6 +40,7 @@ impl MemStorage {
pub fn new_instance(&mut self, container: Container) -> Result<(), Error> { pub fn new_instance(&mut self, container: Container) -> Result<(), Error> {
let image_id = self.image_to_id(container.image.clone())?; let image_id = self.image_to_id(container.image.clone())?;
let ins = self.storage.new_instance( let ins = self.storage.new_instance(
container.get_id(),
container.ip.clone(), container.ip.clone(),
container.name.clone(), container.name.clone(),
image_id)?; image_id)?;

View File

@@ -3,6 +3,7 @@ use crate::deploy;
use crate::conf::storage::MemStorage; use crate::conf::storage::MemStorage;
use crate::conf::Instance; use crate::conf::Instance;
use std::sync::Mutex; use std::sync::Mutex;
use log::{error};
pub struct Controller { pub struct Controller {
driver: Docker, driver: Docker,
@@ -24,7 +25,7 @@ impl Controller {
} }
pub async fn create_container(&self, domain: String, ip: String, image: String) -> String { 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) => { Ok(c) => {
let ret = c.get_id(); let ret = c.get_id();
self.storage.lock().unwrap().new_instance(c).unwrap(); self.storage.lock().unwrap().new_instance(c).unwrap();
@@ -37,28 +38,34 @@ impl Controller {
pub async fn start_container_from_instance(&self, instance: Instance) { pub async fn start_container_from_instance(&self, instance: Instance) {
let image = match self.storage.lock().unwrap().id_to_image(instance.image.clone()) { let image = match self.storage.lock().unwrap().id_to_image(instance.image.clone()) {
Ok(i) => i, Ok(i) => i,
Err(_e) => return, //meter logs aquí Err(e) => {
log::error!("image not found: {}", e);
return
},
}; };
match self.load_container( match self.load_container(
Some(instance.docker_id.clone()),
instance.domain.clone(), instance.domain.clone(),
instance.ip.clone(), instance.ip.clone(),
image).await { image).await {
Ok(c) => { Ok(c) => {
self.storage.lock().unwrap().loaded_instance(instance, 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<String>,
domain: String,
ip: String, ip: String,
image: String) -> Result<deploy::container::Container, image: String) -> Result<deploy::container::Container,
bollard::errors::Error> bollard::errors::Error>
{ {
deploy::container::Container::new(self.driver.clone(), deploy::container::Container::new(self.driver.clone(),
domain.clone(), docker_id,
ip.clone(), domain,
image.clone(), ip,
image,
self.network.clone()).await self.network.clone()).await
} }
@@ -69,7 +76,10 @@ impl Controller {
pub async fn load_all_instances(&self) -> bool { pub async fn load_all_instances(&self) -> bool {
let data = match self.storage.lock().unwrap().get_instances_db() { let data = match self.storage.lock().unwrap().get_instances_db() {
Ok(d) => d, Ok(d) => d,
Err(_e) => return false, Err(e) => {
log::error!("instances can't be loaded: {}",e);
return false
},
}; };
println!("instances {}", data.len()); println!("instances {}", data.len());
for instance in data { for instance in data {

View File

@@ -20,6 +20,7 @@ pub struct Container {
impl Container { impl Container {
pub async fn new(docker: bollard::Docker, pub async fn new(docker: bollard::Docker,
docker_id: Option<String>,
name: String, name: String,
ip: String, ip: String,
image: String, image: String,
@@ -31,32 +32,34 @@ impl Container {
image: image, image: image,
net: net, net: net,
start: false, start: false,
docker_id: None, docker_id: docker_id,
database_id: None, database_id: None,
}; };
match container.start(docker).await { match container.start(docker).await {
Ok(c) => { Ok(c) => {
container.start=true; container.start=true;
container.docker_id = Some(c);
Ok(container) Ok(container)
} }
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
async fn start(&self, docker: bollard::Docker) -> Result<String, Error>{ async fn start(&mut self, docker: bollard::Docker) -> Result<bool, Error>{
let id_container = match self.exist_container(docker.clone()).await? { let ret = match &self.exist_container(docker.clone()).await? {
Some(id_ret) => id_ret, Some(_id) => true,
None => docker.create_container(Some( None => {
self.docker_id = Some(docker.create_container(Some(
create_options(self.name.clone())), create_options(self.name.clone())),
create_config(self.ip.clone(), create_config(self.ip.clone(),
self.net.clone(), self.net.clone(),
self.image.clone())) self.image.clone()))
.await?.id, .await?.id);
false
},
}; };
docker.start_container(&self.name, None::<StartContainerOptions<String>>).await?; docker.start_container(&self.name, None::<StartContainerOptions<String>>).await?;
Ok(id_container) Ok(ret)
} }
pub fn get_id(&self) -> String { pub fn get_id(&self) -> String {
@@ -67,15 +70,21 @@ impl Container {
} }
async fn exist_container(&self, docker: bollard::Docker) -> Result<Option<String>, Error> { async fn exist_container(&self, docker: bollard::Docker) -> Result<Option<String>, Error> {
let list = docker.list_containers( match &self.docker_id {
Some(create_search_container(self.name.clone())) Some(_id) => {
).await?; let list = docker.list_containers(
println!("{}", list.len()); Some(create_search_container(self.get_id().clone()))
Ok (if list.len() > 0 { ).await?;
list[0].id.clone() Ok (if list.len() > 0 {
} else { list[0].id.clone()
None } else {
}) None
})
}
None => Ok(None),
}
} }
async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{ async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{
@@ -84,7 +93,7 @@ impl Container {
} }
fn create_search_container(name: String) -> ListContainersOptions<String> { fn create_search_container(name: String) -> ListContainersOptions<String> {
let mut filters = HashMap::new(); let mut filters = HashMap::new();
filters.insert("before".to_string(), vec![name]); filters.insert("id".to_string(), vec![name]);
ListContainersOptions{ ListContainersOptions{
all: true, all: true,