add remove feature
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1004,6 +1004,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"bollard",
|
"bollard",
|
||||||
|
"derive_more",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"futures",
|
"futures",
|
||||||
|
|||||||
@@ -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 = "*"
|
||||||
|
derive_more = "*"
|
||||||
log = "*"
|
log = "*"
|
||||||
serde = "*"
|
serde = "*"
|
||||||
fallible-iterator = "*"
|
fallible-iterator = "*"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ pub struct ConfServer{
|
|||||||
ip_base_limit: u8,
|
ip_base_limit: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
id: i64,
|
id: i64,
|
||||||
pub docker_id: String,
|
pub docker_id: String,
|
||||||
@@ -114,6 +115,11 @@ impl InstanceStorage {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_instance(&mut self, id: String) -> Result<usize> {
|
||||||
|
let mut stmt = self.con.prepare("DELETE from l_instances where id=?1")?;
|
||||||
|
stmt.execute([id])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn image_to_id(&self, image: String) -> Result<i64> {
|
pub fn image_to_id(&self, image: String) -> Result<i64> {
|
||||||
self.create_or_get_image_id(image, 0)
|
self.create_or_get_image_id(image, 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ impl MemStorage {
|
|||||||
pub fn id_to_image(&mut self, image: i64) -> Result<String, Error>{
|
pub fn id_to_image(&mut self, image: i64) -> Result<String, Error>{
|
||||||
self.storage.get_image_name(image)
|
self.storage.get_image_name(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
||||||
@@ -48,6 +49,37 @@ impl MemStorage {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn search_instance(&self, name: String) -> Option<Container> {
|
||||||
|
for cont in &self.containers {
|
||||||
|
if cont.0.domain == name { return cont.1.clone(); }
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop_instance(&mut self, name: String) -> Option<Container> {
|
||||||
|
for cont in &mut self.containers {
|
||||||
|
if cont.0.domain == name {
|
||||||
|
return cont.1.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_instance(&mut self, name: String) -> Option<(Instance, Option<Container>)> {
|
||||||
|
for i in 0..self.containers.len() {
|
||||||
|
match self.containers.get(i) {
|
||||||
|
Some(c) => {
|
||||||
|
if c.0.domain == name {
|
||||||
|
self.storage.remove_instance(c.0.id.to_string().clone());
|
||||||
|
return Some(self.containers.remove(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn loaded_instance(&mut self, ins: Instance, container: Container) {
|
pub fn loaded_instance(&mut self, ins: Instance, container: Container) {
|
||||||
self.containers.push((ins, Some(container)));
|
self.containers.push((ins, Some(container)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
|
use bollard::errors::Error;
|
||||||
use crate::deploy;
|
use crate::deploy;
|
||||||
|
use crate::deploy::container::Container;
|
||||||
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};
|
use log::error;
|
||||||
|
|
||||||
pub struct Controller {
|
pub struct Controller {
|
||||||
driver: Docker,
|
driver: Docker,
|
||||||
@@ -25,21 +27,30 @@ 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 {
|
||||||
|
let is_stored = self.storage.lock().unwrap().search_instance(domain.clone());
|
||||||
|
match is_stored {
|
||||||
|
Some(c) => match c.docker_id {
|
||||||
|
Some(id) => id,
|
||||||
|
None => "Container without docker_id".to_string()
|
||||||
|
},
|
||||||
|
None => {
|
||||||
match self.load_container(None,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();
|
log::debug!("poisoned: {}",self.storage.is_poisoned());
|
||||||
self.storage.lock().unwrap().new_instance(c).unwrap();
|
self.storage.try_lock().unwrap().new_instance(c.clone()).unwrap();
|
||||||
ret
|
c.get_id()
|
||||||
},
|
},
|
||||||
Err(_e) => "error creating container".to_string(),
|
Err(_e) => "error creating container".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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) => {
|
Err(e) => {
|
||||||
log::error!("image not found: {}", e);
|
error!("image not found: {}", e);
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -51,7 +62,7 @@ impl Controller {
|
|||||||
Ok(c) => {
|
Ok(c) => {
|
||||||
self.storage.lock().unwrap().loaded_instance(instance, c);
|
self.storage.lock().unwrap().loaded_instance(instance, c);
|
||||||
},
|
},
|
||||||
Err(e) => log::error!("{}",e),
|
Err(e) => error!("{}",e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +88,7 @@ impl Controller {
|
|||||||
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) => {
|
Err(e) => {
|
||||||
log::error!("instances can't be loaded: {}",e);
|
error!("instances can't be loaded: {}",e);
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -88,5 +99,44 @@ impl Controller {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub async fn stop_container(&self, )
|
async fn stop_given_container(&self, container:Container) -> Result<String, Error> {
|
||||||
|
match container.stop(&self.driver).await {
|
||||||
|
Ok(_i) => Ok(container.get_id()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn prune_given_container(&self, container:Container) -> Result<String, Error> {
|
||||||
|
match container.remove(&self.driver).await {
|
||||||
|
Ok(_i) => Ok(container.get_id()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn stop_container(&self, domain: String) -> Result<String, Error> {
|
||||||
|
match self.storage.lock().unwrap().stop_instance(domain) {
|
||||||
|
Some(c) => {
|
||||||
|
self.stop_given_container(c).await
|
||||||
|
},
|
||||||
|
None => Err(Error::DockerResponseServerError {
|
||||||
|
status_code: 404, message: "container not found".to_string()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_container(&self, domain: String) -> Result<String, Error> {
|
||||||
|
match self.storage.lock().unwrap().remove_instance(domain) {
|
||||||
|
Some(data) => {
|
||||||
|
match data.1 {
|
||||||
|
Some(c) => self.prune_given_container(c).await,
|
||||||
|
None => Ok(data.0.docker_id),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => Err(Error::DockerResponseServerError {
|
||||||
|
status_code: 404, message: "container not found".to_string()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
src/deploy/bind.rs
Normal file
18
src/deploy/bind.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
use std::vec;
|
||||||
|
use std::fs::{create_dir, canonicalize};
|
||||||
|
|
||||||
|
const BASE_PATH : &str = "mrdeploy_data/";
|
||||||
|
|
||||||
|
pub fn generate_bindpaths(mut name: String) -> Vec<String>{
|
||||||
|
name.insert_str(0,BASE_PATH);
|
||||||
|
let path = match canonicalize(name.clone()) {
|
||||||
|
Ok(p) => String::from(p.to_str().unwrap()),
|
||||||
|
Err(_e) => name,
|
||||||
|
};
|
||||||
|
vec![format!("{}:{}", path, "/data")]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_fs(mut name: String) -> Result<(), std::io::Error> {
|
||||||
|
name.insert_str(0,BASE_PATH);
|
||||||
|
create_dir(name)
|
||||||
|
}
|
||||||
@@ -1,13 +1,17 @@
|
|||||||
use bollard::container::{StartContainerOptions,
|
use bollard::container::{StartContainerOptions,
|
||||||
StopContainerOptions,
|
StopContainerOptions,
|
||||||
CreateContainerOptions,
|
CreateContainerOptions,
|
||||||
|
RemoveContainerOptions,
|
||||||
Config,
|
Config,
|
||||||
NetworkingConfig,
|
NetworkingConfig,
|
||||||
ListContainersOptions};
|
ListContainersOptions};
|
||||||
use bollard::models::{EndpointSettings, EndpointIpamConfig};
|
use bollard::models::{EndpointSettings, EndpointIpamConfig, HostConfig};
|
||||||
use bollard::errors::Error;
|
use bollard::errors::{Error, Error::IOError};
|
||||||
|
use std::io::ErrorKind::AlreadyExists;
|
||||||
use std::collections::hash_map::HashMap;
|
use std::collections::hash_map::HashMap;
|
||||||
|
use crate::deploy::bind;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Container {
|
pub struct Container {
|
||||||
pub name: String, //Must be the domain name
|
pub name: String, //Must be the domain name
|
||||||
pub start: bool,
|
pub start: bool,
|
||||||
@@ -35,7 +39,6 @@ impl Container {
|
|||||||
docker_id: docker_id,
|
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;
|
||||||
@@ -46,12 +49,22 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn start(&mut self, docker: bollard::Docker) -> Result<bool, Error>{
|
async fn start(&mut self, docker: bollard::Docker) -> Result<bool, Error>{
|
||||||
let ret = match &self.exist_container(docker.clone()).await? {
|
match bind::check_fs(self.name.clone()) {
|
||||||
Some(_id) => true,
|
Ok(_r) => (),
|
||||||
|
Err(ref e) if e.kind() == AlreadyExists => (),
|
||||||
|
Err(e) => return Err(IOError { err: e }),
|
||||||
|
}
|
||||||
|
let ret = match self.exist_container(docker.clone()).await? {
|
||||||
|
Some(id) => {
|
||||||
|
self.docker_id=Some(id);
|
||||||
|
true
|
||||||
|
},
|
||||||
None => {
|
None => {
|
||||||
|
log::info!("creating container with name: {}", self.name);
|
||||||
self.docker_id = Some(docker.create_container(Some(
|
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.name.clone(),
|
||||||
|
self.ip.clone(),
|
||||||
self.net.clone(),
|
self.net.clone(),
|
||||||
self.image.clone()))
|
self.image.clone()))
|
||||||
.await?.id);
|
.await?.id);
|
||||||
@@ -70,30 +83,40 @@ 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.get_id().clone()))
|
Some(create_search_container(self.name.clone()))
|
||||||
).await?;
|
).await?;
|
||||||
Ok (if list.len() > 0 {
|
let mut comparable_name = self.name.clone();
|
||||||
list[0].id.clone()
|
comparable_name.insert_str(0, "/");
|
||||||
} else {
|
for cs in list {
|
||||||
None
|
match cs.names {
|
||||||
})
|
Some(names) => {
|
||||||
|
for name in names {
|
||||||
|
if name == comparable_name {
|
||||||
|
return Ok(cs.id.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
None => Ok(None),
|
pub async fn stop(&self, docker: &bollard::Docker) -> Result<(), Error>{
|
||||||
|
docker.stop_container(self.name.as_str(), Some(create_stop_options())).await
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
pub async fn remove(&self, docker: &bollard::Docker) -> Result<String, Error> {
|
||||||
|
docker.remove_container(self.get_id().as_str(), Some(create_remove_option())).await?;
|
||||||
async fn stop(&self, docker: bollard::Docker) -> Result<(), Error>{
|
Ok(self.docker_id.clone().unwrap())
|
||||||
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("id".to_string(), vec![name]);
|
filters.insert("name".to_string(), vec![name]);
|
||||||
|
|
||||||
ListContainersOptions{
|
ListContainersOptions{
|
||||||
all: true,
|
all: true,
|
||||||
@@ -102,7 +125,7 @@ fn create_search_container(name: String) -> ListContainersOptions<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_config(ip: String, net: String, image: String) -> Config<String> {
|
fn create_config(name: String, 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),
|
||||||
@@ -119,11 +142,19 @@ fn create_config(ip: String, net: String, image: String) -> Config<String> {
|
|||||||
Config {
|
Config {
|
||||||
image: Some(image),
|
image: Some(image),
|
||||||
env: Some(env),
|
env: Some(env),
|
||||||
|
host_config: Some(create_hostconfig(name)),
|
||||||
networking_config: Some(net),
|
networking_config: Some(net),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_hostconfig(name: String) -> HostConfig {
|
||||||
|
HostConfig {
|
||||||
|
binds: Some(bind::generate_bindpaths(name.clone())),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_options(name: String) -> CreateContainerOptions<String> {
|
fn create_options(name: String) -> CreateContainerOptions<String> {
|
||||||
CreateContainerOptions{
|
CreateContainerOptions{
|
||||||
name: name,
|
name: name,
|
||||||
@@ -131,8 +162,15 @@ fn create_options(name: String) -> CreateContainerOptions<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_options() -> StopContainerOptions{
|
fn create_stop_options() -> StopContainerOptions {
|
||||||
StopContainerOptions {
|
StopContainerOptions {
|
||||||
t: 30,
|
t: 30,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_remove_option() -> RemoveContainerOptions {
|
||||||
|
RemoveContainerOptions{
|
||||||
|
force: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
pub mod container;
|
pub mod container;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
|
mod bind;
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
use actix_web::{get, post, put, web, App, HttpResponse, HttpServer, Responder};
|
use actix_web::{get, patch, post, put, delete, web, App, HttpResponse, HttpServer, Responder};
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
|
use derive_more::{Display, Error};
|
||||||
|
use log::info;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use env_logger;
|
use env_logger;
|
||||||
|
|
||||||
use crate::controller::Controller;
|
use crate::controller::Controller;
|
||||||
|
|
||||||
|
#[derive(Debug, Display, Error)]
|
||||||
|
#[display(fmt = "my error: {}", name)]
|
||||||
|
pub struct ReturnedError {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl actix_web::error::ResponseError for ReturnedError{}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct ConainerParams {
|
struct ConainerParams {
|
||||||
name: String,
|
name: String,
|
||||||
@@ -12,6 +22,11 @@ struct ConainerParams {
|
|||||||
image: String,
|
image: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct ConainerStopParams {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn hello() -> impl Responder {
|
async fn hello() -> impl Responder {
|
||||||
HttpResponse::Ok().body("Hello world!")
|
HttpResponse::Ok().body("Hello world!")
|
||||||
@@ -23,6 +38,24 @@ async fn create_container(controller: web::Data<Controller>,
|
|||||||
controller.create_container(params.name.clone(), params.ip.clone(), params.image.clone()).await
|
controller.create_container(params.name.clone(), params.ip.clone(), params.image.clone()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[patch("/container/stop")]
|
||||||
|
async fn stop_container(controller: web::Data<Controller>,
|
||||||
|
params: web::Query<ConainerStopParams>) -> Result<String, ReturnedError> {
|
||||||
|
match controller.stop_container(params.name.clone()).await {
|
||||||
|
Ok(response) => Ok(response),
|
||||||
|
Err(e) => Err(ReturnedError { name: e.to_string()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[delete("/container")]
|
||||||
|
async fn delete_container(controller: web::Data<Controller>,
|
||||||
|
params: web::Query<ConainerStopParams>) -> Result<String, ReturnedError> {
|
||||||
|
match controller.delete_container(params.name.clone()).await {
|
||||||
|
Ok(response) => Ok(response),
|
||||||
|
Err(e) => Err(ReturnedError { name: e.to_string()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/echo")]
|
#[post("/echo")]
|
||||||
async fn echo(req_body: String) -> impl Responder {
|
async fn echo(req_body: String) -> impl Responder {
|
||||||
HttpResponse::Ok().body(req_body)
|
HttpResponse::Ok().body(req_body)
|
||||||
@@ -37,6 +70,7 @@ pub async fn start() -> std::io::Result<()> {
|
|||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(e) => panic!("error:{}",e.to_string()),
|
Err(e) => panic!("error:{}",e.to_string()),
|
||||||
};
|
};
|
||||||
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
|
||||||
let controller = match Controller::new(docker,
|
let controller = match Controller::new(docker,
|
||||||
"customnetwork".to_string(),
|
"customnetwork".to_string(),
|
||||||
"172.20.0.0/24".to_string()).await {
|
"172.20.0.0/24".to_string()).await {
|
||||||
@@ -45,13 +79,14 @@ pub async fn start() -> std::io::Result<()> {
|
|||||||
};
|
};
|
||||||
controller.load_all_instances().await;
|
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"));
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(actix_web::middleware::Logger::default())
|
.wrap(actix_web::middleware::Logger::default())
|
||||||
.app_data(data.clone())
|
.app_data(data.clone())
|
||||||
.service(hello)
|
.service(hello)
|
||||||
.service(create_container)
|
.service(create_container)
|
||||||
|
.service(stop_container)
|
||||||
|
.service(delete_container)
|
||||||
.service(echo)
|
.service(echo)
|
||||||
.route("/hey", web::get().to(manual_hello))
|
.route("/hey", web::get().to(manual_hello))
|
||||||
})
|
})
|
||||||
@@ -59,3 +94,7 @@ pub async fn start() -> std::io::Result<()> {
|
|||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user