finish containers persistance
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1007,6 +1007,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"futures",
|
"futures",
|
||||||
|
"log",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|||||||
@@ -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 = "*"
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)?;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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,10 +70,11 @@ 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> {
|
||||||
|
match &self.docker_id {
|
||||||
|
Some(_id) => {
|
||||||
let list = docker.list_containers(
|
let list = docker.list_containers(
|
||||||
Some(create_search_container(self.name.clone()))
|
Some(create_search_container(self.get_id().clone()))
|
||||||
).await?;
|
).await?;
|
||||||
println!("{}", list.len());
|
|
||||||
Ok (if list.len() > 0 {
|
Ok (if list.len() > 0 {
|
||||||
list[0].id.clone()
|
list[0].id.clone()
|
||||||
} else {
|
} else {
|
||||||
@@ -78,13 +82,18 @@ impl Container {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{
|
async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{
|
||||||
docker.stop_container(self.name.as_str(), Some(stop_options())).await
|
docker.stop_container(self.name.as_str(), Some(stop_options())).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user