This commit is contained in:
hibna
2026-02-21 13:02:41 +03:00
commit 2215003a4d
59 changed files with 6100 additions and 0 deletions
+39
View File
@@ -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"
+4
View File
@@ -0,0 +1,4 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("../../packages/proto/daemon.proto")?;
Ok(())
}
+83
View File
@@ -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)
}
}
+32
View File
@@ -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(())
}