phase01
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
[package]
|
||||
name = "gamepanel-daemon"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "GamePanel daemon - manages game server containers"
|
||||
|
||||
[dependencies]
|
||||
# gRPC
|
||||
tonic = "0.12"
|
||||
prost = "0.13"
|
||||
prost-types = "0.13"
|
||||
|
||||
# Async runtime
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
# Docker
|
||||
bollard = "0.18"
|
||||
|
||||
# Serialization
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
serde_yaml = "0.9"
|
||||
|
||||
# HTTP client (for CDN uploads, API callbacks)
|
||||
reqwest = { version = "0.12", features = ["json"] }
|
||||
|
||||
# Logging
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
||||
|
||||
# Error handling
|
||||
anyhow = "1"
|
||||
thiserror = "2"
|
||||
|
||||
# UUID
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.12"
|
||||
@@ -0,0 +1,4 @@
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_build::compile_protos("../../packages/proto/daemon.proto")?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
use anyhow::Result;
|
||||
use serde::Deserialize;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct DaemonConfig {
|
||||
pub api_url: String,
|
||||
pub node_token: String,
|
||||
#[serde(default = "default_grpc_port")]
|
||||
pub grpc_port: u16,
|
||||
#[serde(default)]
|
||||
pub docker: DockerConfig,
|
||||
#[serde(default = "default_data_path")]
|
||||
pub data_path: PathBuf,
|
||||
#[serde(default = "default_backup_path")]
|
||||
pub backup_path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct DockerConfig {
|
||||
#[serde(default = "default_docker_socket")]
|
||||
pub socket: String,
|
||||
#[serde(default = "default_docker_network")]
|
||||
pub network: String,
|
||||
#[serde(default = "default_docker_subnet")]
|
||||
pub network_subnet: String,
|
||||
}
|
||||
|
||||
impl Default for DockerConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
socket: default_docker_socket(),
|
||||
network: default_docker_network(),
|
||||
network_subnet: default_docker_subnet(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_grpc_port() -> u16 {
|
||||
50051
|
||||
}
|
||||
|
||||
fn default_data_path() -> PathBuf {
|
||||
PathBuf::from("/var/lib/gamepanel/servers")
|
||||
}
|
||||
|
||||
fn default_backup_path() -> PathBuf {
|
||||
PathBuf::from("/var/lib/gamepanel/backups")
|
||||
}
|
||||
|
||||
fn default_docker_socket() -> String {
|
||||
"/var/run/docker.sock".to_string()
|
||||
}
|
||||
|
||||
fn default_docker_network() -> String {
|
||||
"gamepanel_nw".to_string()
|
||||
}
|
||||
|
||||
fn default_docker_subnet() -> String {
|
||||
"172.18.0.0/16".to_string()
|
||||
}
|
||||
|
||||
impl DaemonConfig {
|
||||
pub fn load() -> Result<Self> {
|
||||
let config_path =
|
||||
std::env::var("DAEMON_CONFIG").unwrap_or_else(|_| "/etc/gamepanel/config.yml".into());
|
||||
|
||||
let content = std::fs::read_to_string(&config_path)
|
||||
.unwrap_or_else(|_| {
|
||||
tracing::warn!("Config file not found at {}, using defaults", config_path);
|
||||
// Minimal default config for development
|
||||
r#"
|
||||
api_url: "http://localhost:3000"
|
||||
node_token: "dev-token"
|
||||
grpc_port: 50051
|
||||
"#
|
||||
.to_string()
|
||||
});
|
||||
|
||||
let config: DaemonConfig = serde_yaml::from_str(&content)?;
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use anyhow::Result;
|
||||
use tracing::info;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
mod config;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Initialize logging
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
|
||||
)
|
||||
.init();
|
||||
|
||||
info!("GamePanel Daemon starting...");
|
||||
|
||||
let config = config::DaemonConfig::load()?;
|
||||
info!(grpc_port = config.grpc_port, "Configuration loaded");
|
||||
|
||||
// TODO: Initialize Docker client
|
||||
// TODO: Start gRPC server
|
||||
// TODO: Begin heartbeat loop
|
||||
|
||||
info!("GamePanel Daemon ready");
|
||||
|
||||
// Keep the process running
|
||||
tokio::signal::ctrl_c().await?;
|
||||
info!("Shutting down...");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user