start diesel setup
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
|
.env
|
||||||
|
tmp/
|
||||||
|
|||||||
920
Cargo.lock
generated
920
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "minecraft_proxy"
|
name = "dockermcmgr"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = "1.13.2"
|
async-std = "1.13.2"
|
||||||
|
bollard = "0.21.0"
|
||||||
|
diesel = { version = "2.3.9", features = ["postgres", "r2d2"] }
|
||||||
|
diesel-enum = "0.2.1"
|
||||||
json = "0.12.4"
|
json = "0.12.4"
|
||||||
|
serde = "1.0.228"
|
||||||
|
thiserror = "2.0.18"
|
||||||
tokio = { version = "1.52.1", features = ["net", "rt", "macros", "signal"] }
|
tokio = { version = "1.52.1", features = ["net", "rt", "macros", "signal"] }
|
||||||
|
|||||||
9
diesel.toml
Normal file
9
diesel.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "src/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[migrations_directory]
|
||||||
|
dir = "migrations"
|
||||||
0
migrations/.diesel_lock
Normal file
0
migrations/.diesel_lock
Normal file
0
migrations/.keep
Normal file
0
migrations/.keep
Normal file
6
migrations/00000000000000_diesel_initial_setup/down.sql
Normal file
6
migrations/00000000000000_diesel_initial_setup/down.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||||
|
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
||||||
36
migrations/00000000000000_diesel_initial_setup/up.sql
Normal file
36
migrations/00000000000000_diesel_initial_setup/up.sql
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Sets up a trigger for the given table to automatically set a column called
|
||||||
|
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||||
|
-- in the modified columns)
|
||||||
|
--
|
||||||
|
-- # Example
|
||||||
|
--
|
||||||
|
-- ```sql
|
||||||
|
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||||
|
--
|
||||||
|
-- SELECT diesel_manage_updated_at('users');
|
||||||
|
-- ```
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||||
|
BEGIN
|
||||||
|
IF (
|
||||||
|
NEW IS DISTINCT FROM OLD AND
|
||||||
|
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||||
|
) THEN
|
||||||
|
NEW.updated_at := current_timestamp;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
1
migrations/2026-05-28-142613-0000_servers/down.sql
Normal file
1
migrations/2026-05-28-142613-0000_servers/down.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE servers
|
||||||
9
migrations/2026-05-28-142613-0000_servers/up.sql
Normal file
9
migrations/2026-05-28-142613-0000_servers/up.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE "servers" (
|
||||||
|
"id" int PRIMARY KEY,
|
||||||
|
"name" varchar(255) UNIQUE NOT NULL,
|
||||||
|
"volume_path" varchar(255) UNIQUE NOT NULL,
|
||||||
|
"last_login" timestamp,
|
||||||
|
"container_id" varchar(30),
|
||||||
|
"status" int2 NOT NULL DEFAULT 0,
|
||||||
|
"redirect_ip" int
|
||||||
|
);
|
||||||
16
src/lib.rs
16
src/lib.rs
@ -1,6 +1,20 @@
|
|||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
|
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
|
||||||
|
use diesel::PgConnection;
|
||||||
|
use diesel::r2d2::{
|
||||||
|
Pool,
|
||||||
|
ConnectionManager
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub mod schema;
|
||||||
|
|
||||||
|
|
||||||
pub static mut DOCKER: LazyLock<Docker> = LazyLock::new(|| Docker::connect_with_local_defaults().expect("Failed to connect to the docker socket") );
|
pub static mut DOCKER: LazyLock<Docker> = LazyLock::new(|| Docker::connect_with_local_defaults().expect("Failed to connect to the docker socket") );
|
||||||
|
|
||||||
pub static mut DB_CONN: LazyLock<
|
|
||||||
|
|||||||
64
src/main.rs
64
src/main.rs
@ -1,25 +1,69 @@
|
|||||||
//use tokio::net::TcpListener;
|
//use tokio::net::TcpListener;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use bollard::{
|
||||||
|
query_parameters::{
|
||||||
|
ListImagesOptionsBuilder,
|
||||||
|
ListContainersOptionsBuilder,
|
||||||
|
CreateContainerOptionsBuilder
|
||||||
|
},
|
||||||
|
models::{
|
||||||
|
ContainerCreateBody
|
||||||
|
},
|
||||||
|
Docker
|
||||||
|
};
|
||||||
|
|
||||||
//mod minecraft;
|
//mod minecraft;
|
||||||
//use minecraft::process_mc_socket;
|
//use minecraft::process_mc_socket;
|
||||||
|
|
||||||
//mod rpc;
|
//mod rpc;
|
||||||
//use rpc::process_rpc_socket;
|
//use rpc::process_rpc_socket;
|
||||||
//
|
|
||||||
|
|
||||||
|
use diesel::{prelude::*, r2d2::{ConnectionManager, Pool}};
|
||||||
|
|
||||||
|
mod models;
|
||||||
|
|
||||||
|
use dockermcmgr::schema;
|
||||||
|
|
||||||
|
use crate::models::{ Servers, CreateServer };
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
pub mod status;
|
||||||
|
|
||||||
|
use status::ServerStatus;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub mod server;
|
fn get_connection_pool() -> Pool<ConnectionManager<PgConnection>> {
|
||||||
use async_std::sync::{Mutex, Arc};
|
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||||
use server::Server;
|
|
||||||
use server::ServerStatus;
|
|
||||||
|
|
||||||
mod serverList;
|
|
||||||
|
|
||||||
|
let manager = ConnectionManager::<PgConnection>::new(&database_url);
|
||||||
|
Pool::builder()
|
||||||
|
.build(manager)
|
||||||
|
.unwrap_or_else(|_| panic!("Error creating pool for {}", database_url))
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() -> io::Result<()> {
|
async fn main() -> io::Result<()> {
|
||||||
|
// let conn = DB_CONN.get().expect("failed to get the connection from the pool");
|
||||||
|
let pool = get_connection_pool();
|
||||||
|
|
||||||
|
let conn = &mut pool.get().unwrap();
|
||||||
|
|
||||||
|
let servers = schema::servers::table.select(Servers::as_select()).load(conn);
|
||||||
|
println!("servers : {:?}", servers);
|
||||||
|
|
||||||
|
let new_server = CreateServer {
|
||||||
|
name: "potato",
|
||||||
|
volume_path: "potato2",
|
||||||
|
last_login: None,
|
||||||
|
container_id: None,
|
||||||
|
status: ServerStatus::Stopped,
|
||||||
|
redirect_ip: None
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
/*
|
/*
|
||||||
println!("{:?}", docker);
|
println!("{:?}", docker);
|
||||||
@ -50,12 +94,6 @@ async fn main() -> io::Result<()> {
|
|||||||
|
|
||||||
let start_res = docker.start_container("rust-created-container", None).await;
|
let start_res = docker.start_container("rust-created-container", None).await;
|
||||||
*/
|
*/
|
||||||
// let docker_conn = bollard::Docker::connect_with_local_defaults().expect("Failed to connect to the docker socket");
|
|
||||||
// *crate::server::DOCKER.lock().unwrap() = Some(docker_conn);
|
|
||||||
// let srv = Server { container_name: "something".to_string(), server_name: "potato".to_string(), server_id: 1, status: ServerStatus::Running };
|
|
||||||
// srv.start();
|
|
||||||
//
|
|
||||||
// Ok(())
|
|
||||||
/*
|
/*
|
||||||
let mc_listener = TcpListener::bind("0.0.0.0:25565").await?;
|
let mc_listener = TcpListener::bind("0.0.0.0:25565").await?;
|
||||||
let rpc_listener = TcpListener::bind("0.0.0.0:8080").await?;
|
let rpc_listener = TcpListener::bind("0.0.0.0:8080").await?;
|
||||||
|
|||||||
33
src/models.rs
Normal file
33
src/models.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
use diesel::prelude::*;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::status::ServerStatus;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Queryable, Selectable, Debug)]
|
||||||
|
#[diesel(table_name = dockermcmgr::schema::servers)]
|
||||||
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
|
pub struct Servers {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub volume_path: String,
|
||||||
|
pub last_login: Option<SystemTime>,
|
||||||
|
pub container_id: Option<String>,
|
||||||
|
pub status: i16,
|
||||||
|
pub redirect_ip: Option<i32>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Deserialize, Insertable)]
|
||||||
|
#[diesel(table_name = dockermcmgr::schema::servers)]
|
||||||
|
pub struct CreateServer<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub volume_path: &'a str,
|
||||||
|
pub last_login: Option<SystemTime>,
|
||||||
|
pub container_id: Option<&'a str>,
|
||||||
|
pub status: ServerStatus,
|
||||||
|
pub redirect_ip: Option<i32>
|
||||||
|
}
|
||||||
16
src/schema.rs
Normal file
16
src/schema.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
servers (id) {
|
||||||
|
id -> Int4,
|
||||||
|
#[max_length = 255]
|
||||||
|
name -> Varchar,
|
||||||
|
#[max_length = 255]
|
||||||
|
volume_path -> Varchar,
|
||||||
|
last_login -> Nullable<Timestamp>,
|
||||||
|
#[max_length = 30]
|
||||||
|
container_id -> Nullable<Varchar>,
|
||||||
|
status -> Int2,
|
||||||
|
redirect_ip -> Nullable<Int4>,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +0,0 @@
|
|||||||
mod server;
|
|
||||||
pub use server::Server;
|
|
||||||
|
|
||||||
mod status;
|
|
||||||
pub use status::ServerStatus;
|
|
||||||
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
use bollard::{
|
|
||||||
query_parameters::{
|
|
||||||
ListImagesOptionsBuilder,
|
|
||||||
ListContainersOptionsBuilder,
|
|
||||||
CreateContainerOptionsBuilder
|
|
||||||
},
|
|
||||||
models::{
|
|
||||||
ContainerCreateBody
|
|
||||||
},
|
|
||||||
Docker
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::server::ServerStatus;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Server {
|
|
||||||
pub container_name: String,
|
|
||||||
pub server_name: String,
|
|
||||||
pub server_id: u64,
|
|
||||||
|
|
||||||
pub status: ServerStatus,
|
|
||||||
pub docker: Docker
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Server {
|
|
||||||
pub async fn new(name: String, id: u64) -> Self {
|
|
||||||
let docker = Docker::connect_with_local_defaults().expect("Failed to connect to the docker socket");
|
|
||||||
Self {
|
|
||||||
|
|
||||||
container_name: "idk".to_string(),
|
|
||||||
server_name: name,
|
|
||||||
server_id: id,
|
|
||||||
|
|
||||||
status: ServerStatus::Stopped,
|
|
||||||
docker
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn start(&self) -> Result<(), String> {
|
|
||||||
let options = ListImagesOptionsBuilder::default()
|
|
||||||
.all(true)
|
|
||||||
.build();
|
|
||||||
let images = self.docker.list_images(Some(options)).await.unwrap();
|
|
||||||
println!("\n\nimages : {:?}", images);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum ServerStatus {
|
|
||||||
Running,
|
|
||||||
Starting,
|
|
||||||
Stopped,
|
|
||||||
Archived
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
mod serverList;
|
|
||||||
pub use serverList::*;
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
use crate::server::Server;
|
|
||||||
use async_std::sync::{Mutex, Arc};
|
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
pub static SERVER_LIST: LazyLock<Mutex<HashMap<u64, Arc<Mutex<Server>>>>> = LazyLock::new(|| Mutex::new(HashMap::new()));
|
|
||||||
|
|
||||||
pub async fn get(id: u64) -> Option<Arc<Mutex<Server>>> {
|
|
||||||
let server_list = SERVER_LIST.lock().await;
|
|
||||||
match server_list.get(&id) {
|
|
||||||
Some(found) => { Some(found.clone()) },
|
|
||||||
None => { None }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// (*SERVER_LIST.lock().await).push(Arc::new(Mutex::new(Server::new("test".to_string(), 1u64).await)));
|
|
||||||
46
src/status.rs
Normal file
46
src/status.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize, diesel::expression::AsExpression, diesel::deserialize::FromSqlRow)]
|
||||||
|
#[diesel(sql_type = diesel::sql_types::SmallInt)]
|
||||||
|
pub enum ServerStatus {
|
||||||
|
Archived,
|
||||||
|
Stopped,
|
||||||
|
Stopping,
|
||||||
|
Starting,
|
||||||
|
Running,
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<DB: diesel::backend::Backend> diesel::serialize::ToSql<diesel::sql_types::SmallInt, DB> for ServerStatus
|
||||||
|
where
|
||||||
|
<DB as diesel::backend::Backend>::RawValue: for<'a> diesel::serialize::ToSql<diesel::sql_types::SmallInt, DB<'a>> + ?Sized,
|
||||||
|
{
|
||||||
|
fn to_sql<'b>(&'b self, out: &mut diesel::serialize::Output<'b, '_, DB>) -> diesel::serialize::Result<diesel::serialize::IsNull> {
|
||||||
|
let val = match self {
|
||||||
|
ServerStatus::Archived => 0i16,
|
||||||
|
ServerStatus::Stopped => 1i16,
|
||||||
|
ServerStatus::Stopping => 2i16,
|
||||||
|
ServerStatus::Starting => 3i16,
|
||||||
|
ServerStatus::Running => 4i16,
|
||||||
|
ServerStatus::Unknown => -1i16,
|
||||||
|
};
|
||||||
|
diesel::serialize::ToSql::<diesel::sql_types::SmallInt, DB>::to_sql(&val, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<DB: diesel::backend::Backend> diesel::deserialize::FromSql<diesel::sql_types::SmallInt, DB> for ServerStatus
|
||||||
|
where
|
||||||
|
<DB as diesel::backend::Backend>::RawValue: for<'a> diesel::deserialize::FromSql<'a, diesel::sql_types::SmallInt, DB> + ?Sized,
|
||||||
|
{
|
||||||
|
fn from_sql(bytes: <DB as diesel::backend::Backend>::RawValue<'_>) -> diesel::deserialize::Result<Self> {
|
||||||
|
let val = i16::from_sql(bytes)?;
|
||||||
|
match val {
|
||||||
|
0 => Ok(ServerStatus::Archived),
|
||||||
|
1 => Ok(ServerStatus::Stopped),
|
||||||
|
2 => Ok(ServerStatus::Stopping),
|
||||||
|
3 => Ok(ServerStatus::Starting),
|
||||||
|
4 => Ok(ServerStatus::Running),
|
||||||
|
_ => Ok(ServerStatus::Unknown),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user