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",
"fallible-iterator",
"futures",
"log",
"rusqlite",
"serde",
"tokio",

View File

@@ -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 = "*"

View File

@@ -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<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([])?;
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<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 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,

View File

@@ -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)?;

View File

@@ -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<String>,
domain: String,
ip: String,
image: String) -> Result<deploy::container::Container,
bollard::errors::Error>
{
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 {

View File

@@ -20,6 +20,7 @@ pub struct Container {
impl Container {
pub async fn new(docker: bollard::Docker,
docker_id: Option<String>,
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<String, Error>{
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<bool, Error>{
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::<StartContainerOptions<String>>).await?;
Ok(id_container)
Ok(ret)
}
pub fn get_id(&self) -> String {
@@ -67,10 +70,11 @@ impl Container {
}
async fn exist_container(&self, docker: bollard::Docker) -> Result<Option<String>, Error> {
match &self.docker_id {
Some(_id) => {
let list = docker.list_containers(
Some(create_search_container(self.name.clone()))
Some(create_search_container(self.get_id().clone()))
).await?;
println!("{}", list.len());
Ok (if list.len() > 0 {
list[0].id.clone()
} else {
@@ -78,13 +82,18 @@ impl Container {
})
}
None => Ok(None),
}
}
async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{
docker.stop_container(self.name.as_str(), Some(stop_options())).await
}
}
fn create_search_container(name: String) -> ListContainersOptions<String> {
let mut filters = HashMap::new();
filters.insert("before".to_string(), vec![name]);
filters.insert("id".to_string(), vec![name]);
ListContainersOptions{
all: true,