fix some database managements
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1005,8 +1005,10 @@ dependencies = [
|
|||||||
"actix-web",
|
"actix-web",
|
||||||
"bollard",
|
"bollard",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"fallible-iterator",
|
||||||
"futures",
|
"futures",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ 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 = "*"
|
||||||
|
serde = "*"
|
||||||
|
fallible-iterator = "*"
|
||||||
|
|
||||||
[target.x86_64-unknown-linux-gnu]
|
[target.x86_64-unknown-linux-gnu]
|
||||||
rustflags = [
|
rustflags = [
|
||||||
|
|||||||
100
src/conf/mod.rs
100
src/conf/mod.rs
@@ -1,6 +1,7 @@
|
|||||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
|
||||||
use rusqlite::{Connection, Result};
|
use rusqlite::{Connection, Result};
|
||||||
use std::collections::hash_map::HashMap;
|
use fallible_iterator::FallibleIterator;
|
||||||
|
|
||||||
|
pub mod storage;
|
||||||
|
|
||||||
const PATH: &str = "mdeploy.db";
|
const PATH: &str = "mdeploy.db";
|
||||||
|
|
||||||
@@ -11,16 +12,15 @@ pub struct ConfServer{
|
|||||||
ip_base_limit: u8,
|
ip_base_limit: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MInstance {
|
pub struct Instance {
|
||||||
id: i64,
|
id: i64,
|
||||||
ip: String,
|
pub ip: String,
|
||||||
image: i64,
|
pub domain: String,
|
||||||
|
pub image: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InstanceStorage {
|
pub struct InstanceStorage {
|
||||||
con: Connection,
|
con: Connection,
|
||||||
instances: HashMap<String, MInstance>,
|
|
||||||
images: HashMap<String, i64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstanceStorage {
|
impl InstanceStorage {
|
||||||
@@ -28,8 +28,6 @@ impl InstanceStorage {
|
|||||||
let con = Connection::open(PATH)?;
|
let con = Connection::open(PATH)?;
|
||||||
let ret = Self {
|
let ret = Self {
|
||||||
con : con,
|
con : con,
|
||||||
instances: HashMap::new(),
|
|
||||||
images: HashMap::new(),
|
|
||||||
};
|
};
|
||||||
ret.create_table()?;
|
ret.create_table()?;
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
@@ -45,75 +43,87 @@ impl InstanceStorage {
|
|||||||
ip TEXT,
|
ip TEXT,
|
||||||
domain TEXT,
|
domain TEXT,
|
||||||
image INTEGER,
|
image INTEGER,
|
||||||
FOREIGN KEY(INTEGER) REFERENCES images(id));
|
FOREIGN KEY(image) REFERENCES images(id));
|
||||||
COMMIT;"
|
COMMIT;"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_image(&self, image: String) -> Result<()>{
|
fn insert_image(&self, image: String) -> Result<()>{
|
||||||
let mut stmt = self.con.prepare("INSERT INTO images values(?1)")?;
|
let mut stmt = self.con.prepare("INSERT INTO images(name) values(?1)")?;
|
||||||
stmt.execute([image])?;
|
stmt.execute([image])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_instances(&mut self) -> Result<()> {
|
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, ip, domain, image from l_instances")?;
|
||||||
let mut rows = stmt.query([])?;
|
let mut rows = stmt.query([])?;
|
||||||
for row in rows.next()? {
|
rows.map(|r| Ok(Instance{
|
||||||
let mut domain = row.get::<_, String>(2)?;
|
id: r.get::<_, i64>(0)?,
|
||||||
self.instances.insert(domain, MInstance {
|
ip: r.get::<_, String>(1)?,
|
||||||
id: row.get::<_, i64>(0)?,
|
domain: r.get::<_, String>(2)?,
|
||||||
ip: row.get::<_, String>(1)?,
|
image: r.get::<_, i64>(3)?,
|
||||||
image: row.get::<_, i64>(3)?
|
})).collect()
|
||||||
,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_images(&mut self) -> Result<()> {
|
fn load_images(&mut self) -> Result<Vec<(String, i64)>> {
|
||||||
let mut stmt = self.con.prepare("select id, name from images")?;
|
let mut stmt = self.con.prepare("select id, name from images")?;
|
||||||
let mut rows = stmt.query([])?;
|
let mut rows = stmt.query([])?;
|
||||||
for row in rows.next()? {
|
rows.map(|row| Ok((row.get::<_, String>(1)?, row.get::<_, i64>(0)?))).collect()
|
||||||
self.images.insert(row.get::<_, String>(1)?, row.get::<_, i64>(0)?);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_image_id(&self, image: String) -> Result<i64> {
|
fn get_image_id(&self, image: String) -> Result<Option<i64>> {
|
||||||
let mut stmt = self.con.prepare("select id from images where name = ?1")?;
|
let mut stmt = self.con.prepare("select id from images where name = ?1")?;
|
||||||
let mut rows = stmt.query([image])?;
|
let mut rows = stmt.query([image])?;
|
||||||
let id = rows.next()?.unwrap().get::<_, i64>(0)?;
|
Ok(match rows.next()? {
|
||||||
Ok(id)
|
Some(i) => Some(i.get::<_, i64>(0)?),
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_instance_id(&self, domain: String) -> Result<i64> {
|
pub fn get_image_name(&self, id: i64) -> Result<String> {
|
||||||
|
let mut stmt = self.con.prepare("select name from images where id = ?1")?;
|
||||||
|
let mut rows = stmt.query([id])?;
|
||||||
|
Ok(rows.next()?.unwrap().get::<_, String>(0)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_instance_id(&self, domain: String) -> Result<Option<i64>> {
|
||||||
let mut stmt = self.con.prepare("select id from l_instances where domain = ?1")?;
|
let mut stmt = self.con.prepare("select id from l_instances where domain = ?1")?;
|
||||||
let mut rows = stmt.query([domain])?;
|
let mut rows = stmt.query([domain])?;
|
||||||
let id = rows.next()?.unwrap().get::<_, i64>(0)?;
|
Ok(match rows.next()? {
|
||||||
Ok(id)
|
Some(i) => Some(i.get::<_, i64>(0)?),
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_instance(&mut self, domain: String, image: String, ip: String) -> Result<i64>{
|
pub fn new_instance(&mut self, 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 values(?1, ?2, ?3)")?;
|
let mut stmt = self.con.prepare("INSERT INTO l_instances(ip, domain, image) values(?1, ?2, ?3)")?;
|
||||||
stmt.execute([ip.clone(), image, image_id.to_string()])?;
|
stmt.execute([ip.clone(),
|
||||||
let instance_id = self.get_instance_id(domain.clone())?;
|
domain.clone(),
|
||||||
self.instances.insert(domain.clone(), MInstance{
|
image.to_string()])?;
|
||||||
id: instance_id,
|
Ok(Instance {
|
||||||
|
id: image,
|
||||||
ip: ip,
|
ip: ip,
|
||||||
image: image_id
|
domain: domain,
|
||||||
});
|
image: image,
|
||||||
Ok(instance_id)
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn image_to_id(&self, image: String) -> Result<i64> {
|
||||||
|
self.create_or_get_image_id(image, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_or_get_image_id(&self, image: String, mut depth: i64) -> Result<i64> {
|
fn create_or_get_image_id(&self, image: String, mut depth: i64) -> Result<i64> {
|
||||||
if depth > 0 {
|
if depth > 1 {
|
||||||
return Err(rusqlite::Error::QueryReturnedNoRows);
|
return Err(rusqlite::Error::QueryReturnedNoRows);
|
||||||
}
|
}
|
||||||
depth+=1;
|
depth+=1;
|
||||||
match self.get_image_id(image.clone()) {
|
match self.get_image_id(image.clone()) {
|
||||||
Ok(id) => Ok(id),
|
Ok(Some(id)) => Ok(id),
|
||||||
|
Ok(None) => {
|
||||||
|
self.insert_image(image.clone())?;
|
||||||
|
self.create_or_get_image_id(image, depth)
|
||||||
|
}
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
self.insert_image(image.clone())?;
|
self.insert_image(image.clone())?;
|
||||||
self.create_or_get_image_id(image, depth)
|
self.create_or_get_image_id(image, depth)
|
||||||
|
|||||||
58
src/conf/storage.rs
Normal file
58
src/conf/storage.rs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
use std::collections::hash_map::HashMap;
|
||||||
|
use rusqlite::Error;
|
||||||
|
use crate::deploy::container::Container;
|
||||||
|
use crate::conf::InstanceStorage;
|
||||||
|
use crate::conf::Instance;
|
||||||
|
|
||||||
|
pub struct MemStorage {
|
||||||
|
containers: Vec<(Instance, Option<Container>)>,
|
||||||
|
images: HashMap<String, i64>,
|
||||||
|
storage: InstanceStorage,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemStorage {
|
||||||
|
pub fn new() -> Result<Self, Error> {
|
||||||
|
let mut storage = InstanceStorage::new()?;
|
||||||
|
let images = storage.load_images()?
|
||||||
|
.into_iter().map(|image|(image.0, image.1))
|
||||||
|
.collect::<HashMap<_, _>>();
|
||||||
|
Ok(Self{
|
||||||
|
containers: Vec::new(),
|
||||||
|
images: images,
|
||||||
|
storage: storage,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn image_to_id(&mut self, image: String) -> Result<i64, Error> {
|
||||||
|
match self.images.get(&mut image.clone()) {
|
||||||
|
Some(id) => Ok(*id),
|
||||||
|
None => {
|
||||||
|
let id = self.storage.image_to_id(image.clone())?;
|
||||||
|
self.images.insert(image, id.clone());
|
||||||
|
Ok(id)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id_to_image(&mut self, image: i64) -> Result<String, Error>{
|
||||||
|
self.storage.get_image_name(image)
|
||||||
|
}
|
||||||
|
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.ip.clone(),
|
||||||
|
container.name.clone(),
|
||||||
|
image_id)?;
|
||||||
|
self.containers.push((ins, Some(container)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn loaded_instance(&mut self, ins: Instance, container: Container) {
|
||||||
|
self.containers.push((ins, Some(container)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_instances_db(&mut self) -> Result<Vec<Instance>, Error> {
|
||||||
|
self.storage.load_instances()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,27 +1,82 @@
|
|||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use crate::deploy;
|
use crate::deploy;
|
||||||
|
use crate::conf::storage::MemStorage;
|
||||||
|
use crate::conf::Instance;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
pub struct Controller {
|
pub struct Controller {
|
||||||
driver: Docker,
|
driver: Docker,
|
||||||
network: String,
|
network: String,
|
||||||
|
storage: Mutex<MemStorage>,
|
||||||
|
started: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controller {
|
impl Controller {
|
||||||
pub async fn new(driver: Docker, network: String, range: String) -> Result<Self, bollard::errors::Error>{
|
pub async fn new(driver: Docker, network: String, range: String) -> Result<Self, bollard::errors::Error>{
|
||||||
deploy::network::Network::new(driver.clone(), network.clone(), range).await?;
|
deploy::network::Network::new(driver.clone(), network.clone(), range).await?;
|
||||||
Ok(Controller {
|
let cont = Self {
|
||||||
driver: driver,
|
driver: driver,
|
||||||
network: network,
|
network: network,
|
||||||
})
|
storage: Mutex::new(MemStorage::new().unwrap()),
|
||||||
|
started: false,
|
||||||
|
};
|
||||||
|
Ok(cont)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_container(&self, domain: String, ip: String) -> String {
|
pub async fn create_container(&self, domain: String, ip: String, image: String) -> String {
|
||||||
match deploy::container::Container::new(self.driver.clone(),
|
match self.load_container(domain.clone(),ip.clone(),image.clone()).await {
|
||||||
domain,
|
Ok(c) => {
|
||||||
ip,
|
let ret = c.get_id();
|
||||||
self.network.clone()).await {
|
self.storage.lock().unwrap().new_instance(c).unwrap();
|
||||||
Ok(c) => c.get_id(),
|
ret
|
||||||
Err(e) => "error creating container".to_string(),
|
},
|
||||||
|
Err(_e) => "error creating container".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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í
|
||||||
|
};
|
||||||
|
match self.load_container(
|
||||||
|
instance.domain.clone(),
|
||||||
|
instance.ip.clone(),
|
||||||
|
image).await {
|
||||||
|
Ok(c) => {
|
||||||
|
self.storage.lock().unwrap().loaded_instance(instance, c);
|
||||||
|
},
|
||||||
|
Err(_e) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn load_container(&self, 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(),
|
||||||
|
self.network.clone()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn is_started(&self) -> bool {
|
||||||
|
self.started
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
println!("instances {}", data.len());
|
||||||
|
for instance in data {
|
||||||
|
self.start_container_from_instance(instance).await;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//pub async fn stop_container(&self, )
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,58 @@
|
|||||||
use bollard::container::{StartContainerOptions, CreateContainerOptions, Config, NetworkingConfig, ListContainersOptions};
|
use bollard::container::{StartContainerOptions,
|
||||||
|
StopContainerOptions,
|
||||||
|
CreateContainerOptions,
|
||||||
|
Config,
|
||||||
|
NetworkingConfig,
|
||||||
|
ListContainersOptions};
|
||||||
use bollard::models::{EndpointSettings, EndpointIpamConfig};
|
use bollard::models::{EndpointSettings, EndpointIpamConfig};
|
||||||
use bollard::errors::Error;
|
use bollard::errors::Error;
|
||||||
use std::collections::hash_map::HashMap;
|
use std::collections::hash_map::HashMap;
|
||||||
|
|
||||||
pub struct Container {
|
pub struct Container {
|
||||||
name: String,
|
pub name: String, //Must be the domain name
|
||||||
start: bool,
|
pub start: bool,
|
||||||
ip: String,
|
pub ip: String,
|
||||||
net: String,
|
pub image: String,
|
||||||
id: Option<String>,
|
pub net: String,
|
||||||
|
pub docker_id: Option<String>,
|
||||||
|
pub database_id: Option<i64>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Container {
|
impl Container {
|
||||||
pub async fn new(docker: bollard::Docker,
|
pub async fn new(docker: bollard::Docker,
|
||||||
name: String,
|
name: String,
|
||||||
ip: String,
|
ip: String,
|
||||||
|
image: String,
|
||||||
net: String) -> Result<Container, Error> {
|
net: String) -> Result<Container, Error> {
|
||||||
|
|
||||||
let mut container = Container {
|
let mut container = Container {
|
||||||
name: name,
|
name: name,
|
||||||
ip: ip,
|
ip: ip,
|
||||||
|
image: image,
|
||||||
net: net,
|
net: net,
|
||||||
start: false,
|
start: false,
|
||||||
id: None,
|
docker_id: None,
|
||||||
|
database_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match container.create(docker).await {
|
match container.start(docker).await {
|
||||||
Ok(c) => {
|
Ok(c) => {
|
||||||
container.start=true;
|
container.start=true;
|
||||||
container.id = Some(c);
|
container.docker_id = Some(c);
|
||||||
Ok(container)
|
Ok(container)
|
||||||
}
|
}
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create(&self, docker: bollard::Docker) -> Result<String, Error>{
|
async fn start(&self, docker: bollard::Docker) -> Result<String, Error>{
|
||||||
let id_container = match self.exist_container(docker.clone()).await? {
|
let id_container = match self.exist_container(docker.clone()).await? {
|
||||||
Some(id_ret) => id_ret,
|
Some(id_ret) => id_ret,
|
||||||
None => docker.create_container(Some(
|
None => docker.create_container(Some(
|
||||||
create_options(self.name.clone())),
|
create_options(self.name.clone())),
|
||||||
create_config(self.ip.clone(), self.net.clone()))
|
create_config(self.ip.clone(),
|
||||||
|
self.net.clone(),
|
||||||
|
self.image.clone()))
|
||||||
.await?.id,
|
.await?.id,
|
||||||
};
|
};
|
||||||
docker.start_container(&self.name, None::<StartContainerOptions<String>>).await?;
|
docker.start_container(&self.name, None::<StartContainerOptions<String>>).await?;
|
||||||
@@ -48,7 +60,7 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_id(&self) -> String {
|
pub fn get_id(&self) -> String {
|
||||||
match &self.id {
|
match &self.docker_id {
|
||||||
Some(id) => id.clone(),
|
Some(id) => id.clone(),
|
||||||
None => String::from(""),
|
None => String::from(""),
|
||||||
}
|
}
|
||||||
@@ -58,17 +70,21 @@ impl Container {
|
|||||||
let list = docker.list_containers(
|
let list = docker.list_containers(
|
||||||
Some(create_search_container(self.name.clone()))
|
Some(create_search_container(self.name.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 {
|
||||||
None
|
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> {
|
fn create_search_container(name: String) -> ListContainersOptions<String> {
|
||||||
let mut filters = HashMap::new();
|
let mut filters = HashMap::new();
|
||||||
filters.insert("name".to_string(), vec![name]);
|
filters.insert("before".to_string(), vec![name]);
|
||||||
|
|
||||||
ListContainersOptions{
|
ListContainersOptions{
|
||||||
all: true,
|
all: true,
|
||||||
@@ -77,7 +93,7 @@ fn create_search_container(name: String) -> ListContainersOptions<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_config(ip: String, net: String) -> Config<String> {
|
fn create_config(ip: String, net: String, image: String) -> Config<String> {
|
||||||
let endpoint = EndpointSettings {
|
let endpoint = EndpointSettings {
|
||||||
ipam_config: Some(EndpointIpamConfig{
|
ipam_config: Some(EndpointIpamConfig{
|
||||||
ipv4_address: Some(ip),
|
ipv4_address: Some(ip),
|
||||||
@@ -92,7 +108,7 @@ fn create_config(ip: String, net: String) -> Config<String> {
|
|||||||
};
|
};
|
||||||
let env = vec!["EULA=TRUE".to_string()];
|
let env = vec!["EULA=TRUE".to_string()];
|
||||||
Config {
|
Config {
|
||||||
image: Some("itzg/minecraft-server:latest".to_string()),
|
image: Some(image),
|
||||||
env: Some(env),
|
env: Some(env),
|
||||||
networking_config: Some(net),
|
networking_config: Some(net),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -105,3 +121,9 @@ fn create_options(name: String) -> CreateContainerOptions<String> {
|
|||||||
platform: None,
|
platform: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stop_options() -> StopContainerOptions{
|
||||||
|
StopContainerOptions {
|
||||||
|
t: 30,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};
|
use actix_web::{get, post, put, web, App, HttpResponse, HttpServer, Responder};
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
|
use serde::Deserialize;
|
||||||
use env_logger;
|
use env_logger;
|
||||||
|
|
||||||
use crate::controller::Controller;
|
use crate::controller::Controller;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct ConainerParams {
|
||||||
|
name: String,
|
||||||
|
ip: String,
|
||||||
|
image: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn hello() -> impl Responder {
|
async fn hello() -> impl Responder {
|
||||||
HttpResponse::Ok().body("Hello world!")
|
HttpResponse::Ok().body("Hello world!")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/create")]
|
#[put("/container")]
|
||||||
async fn create(controller: web::Data<Controller>) -> impl Responder {
|
async fn create_container(controller: web::Data<Controller>,
|
||||||
controller.create_container("container1".to_string(), "172.20.0.5".to_string()).await
|
params: web::Query<ConainerParams>) -> impl Responder {
|
||||||
|
controller.create_container(params.name.clone(), params.ip.clone(), params.image.clone()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/echo")]
|
#[post("/echo")]
|
||||||
@@ -34,13 +43,15 @@ pub async fn start() -> std::io::Result<()> {
|
|||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => panic!("error: {}",e),
|
Err(e) => panic!("error: {}",e),
|
||||||
};
|
};
|
||||||
|
controller.load_all_instances().await;
|
||||||
let data = web::Data::new(controller);
|
let data = web::Data::new(controller);
|
||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
|
.wrap(actix_web::middleware::Logger::default())
|
||||||
.app_data(data.clone())
|
.app_data(data.clone())
|
||||||
.service(hello)
|
.service(hello)
|
||||||
.service(create)
|
.service(create_container)
|
||||||
.service(echo)
|
.service(echo)
|
||||||
.route("/hey", web::get().to(manual_hello))
|
.route("/hey", web::get().to(manual_hello))
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user