finish containers persistance
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1007,6 +1007,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"fallible-iterator",
|
||||
"futures",
|
||||
"log",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"tokio",
|
||||
|
||||
@@ -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 = "*"
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,15 +70,21 @@ impl Container {
|
||||
}
|
||||
|
||||
async fn exist_container(&self, docker: bollard::Docker) -> Result<Option<String>, 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<String> {
|
||||
let mut filters = HashMap::new();
|
||||
filters.insert("before".to_string(), vec![name]);
|
||||
filters.insert("id".to_string(), vec![name]);
|
||||
|
||||
ListContainersOptions{
|
||||
all: true,
|
||||
|
||||
Reference in New Issue
Block a user