Make server directory relative to configuration file directory

This commit is contained in:
timvisee 2021-11-24 13:53:38 +01:00
parent ee21eb45fd
commit cf0e3ef15b
No known key found for this signature in database
GPG Key ID: B8DB720BC383E172
6 changed files with 46 additions and 20 deletions

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use clap::ArgMatches; use clap::ArgMatches;
use crate::config::{self, Config}; use crate::config::{self, Config, Server as ConfigServer};
use crate::mc::server_properties; use crate::mc::server_properties;
use crate::proto; use crate::proto;
use crate::service; use crate::service;
@ -120,7 +120,7 @@ fn rewrite_server_properties(config: &Config) {
} }
// Ensure server directory is set, it must exist // Ensure server directory is set, it must exist
let dir = match &config.server.directory { let dir = match ConfigServer::server_directory(config) {
Some(dir) => dir, Some(dir) => dir,
None => { None => {
warn!(target: "lazymc", "Not rewriting {} file, server directory not configured (server.directory)", server_properties::FILE); warn!(target: "lazymc", "Not rewriting {} file, server directory not configured (server.directory)", server_properties::FILE);

View File

@ -1,7 +1,7 @@
use std::fs; use std::fs;
use std::io; use std::io;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::path::{Path, PathBuf}; use std::path::PathBuf;
use clap::ArgMatches; use clap::ArgMatches;
use serde::Deserialize; use serde::Deserialize;
@ -63,6 +63,12 @@ pub fn load(matches: &ArgMatches) -> Config {
/// Configuration. /// Configuration.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Config { pub struct Config {
/// Configuration path if known.
///
/// Should be used as base directory for filesystem operations.
#[serde(skip)]
pub path: Option<PathBuf>,
/// Public configuration. /// Public configuration.
#[serde(default)] #[serde(default)]
pub public: Public, pub public: Public,
@ -101,9 +107,9 @@ pub struct Config {
impl Config { impl Config {
/// Load configuration from file. /// Load configuration from file.
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> { pub fn load(path: PathBuf) -> Result<Self, io::Error> {
let data = fs::read(path)?; let data = fs::read(&path)?;
let config: Config = toml::from_slice(&data)?; let mut config: Config = toml::from_slice(&data)?;
// Show warning if config version is problematic // Show warning if config version is problematic
match &config.config.version { match &config.config.version {
@ -118,6 +124,7 @@ impl Config {
Ok(true) => {} Ok(true) => {}
}, },
} }
config.path.replace(path);
Ok(config) Ok(config)
} }
@ -152,8 +159,10 @@ impl Default for Public {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Server { pub struct Server {
/// Server directory. /// Server directory.
///
/// Private because you should use `Server::server_directory()` instead.
#[serde(default = "option_pathbuf_dot")] #[serde(default = "option_pathbuf_dot")]
pub directory: Option<PathBuf>, directory: Option<PathBuf>,
/// Start command. /// Start command.
pub command: String, pub command: String,
@ -194,6 +203,23 @@ pub struct Server {
pub send_proxy_v2: bool, pub send_proxy_v2: bool,
} }
impl Server {
/// Get the server directory.
///
/// This does not check whether it exists.
pub fn server_directory(config: &Config) -> Option<PathBuf> {
if config.server.directory.is_none() {
return None;
}
// Get directory, relative to config directory if known
match config.path.as_ref().and_then(|p| p.parent()) {
Some(config_dir) => Some(config_dir.join(config.server.directory.as_ref().unwrap())),
None => config.server.directory.clone(),
}
}
}
/// Time configuration. /// Time configuration.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(default)] #[serde(default)]

View File

@ -11,39 +11,39 @@ const EOL: &str = "\r\n";
/// Try to rewrite changes in server.properties file in dir. /// Try to rewrite changes in server.properties file in dir.
/// ///
/// Prints an error and stops on failure. /// Prints an error and stops on failure.
pub fn rewrite_dir(dir: &Path, changes: HashMap<&str, String>) { pub fn rewrite_dir<P: AsRef<Path>>(dir: P, changes: HashMap<&str, String>) {
if changes.is_empty() { if changes.is_empty() {
return; return;
} }
// Ensure directory exists // Ensure directory exists
if !dir.is_dir() { if !dir.as_ref().is_dir() {
warn!(target: "lazymc", warn!(target: "lazymc",
"Not rewriting {} file, configured server directory doesn't exist: {}", "Not rewriting {} file, configured server directory doesn't exist: {}",
FILE, FILE,
dir.to_str().unwrap_or("?") dir.as_ref().to_str().unwrap_or("?")
); );
return; return;
} }
// Rewrite file // Rewrite file
rewrite_file(&dir.join(FILE), changes) rewrite_file(dir.as_ref().join(FILE), changes)
} }
/// Try to rewrite changes in server.properties file. /// Try to rewrite changes in server.properties file.
/// ///
/// Prints an error and stops on failure. /// Prints an error and stops on failure.
pub fn rewrite_file(file: &Path, changes: HashMap<&str, String>) { pub fn rewrite_file<P: AsRef<Path>>(file: P, changes: HashMap<&str, String>) {
if changes.is_empty() { if changes.is_empty() {
return; return;
} }
// File must exist // File must exist
if !file.is_file() { if !file.as_ref().is_file() {
warn!(target: "lazymc", warn!(target: "lazymc",
"Not writing {} file, not found at: {}", "Not writing {} file, not found at: {}",
FILE, FILE,
file.to_str().unwrap_or("?"), file.as_ref().to_str().unwrap_or("?"),
); );
return; return;
} }

View File

@ -12,7 +12,7 @@ use tokio::sync::Semaphore;
use tokio::sync::{Mutex, RwLock, RwLockReadGuard}; use tokio::sync::{Mutex, RwLock, RwLockReadGuard};
use tokio::time; use tokio::time;
use crate::config::Config; use crate::config::{Config, Server as ConfigServer};
use crate::mc::ban::{BannedIp, BannedIps}; use crate::mc::ban::{BannedIp, BannedIps};
use crate::os; use crate::os;
@ -421,7 +421,7 @@ pub async fn invoke_server_cmd(
cmd.kill_on_drop(true); cmd.kill_on_drop(true);
// Set working directory // Set working directory
if let Some(ref dir) = config.server.directory { if let Some(ref dir) = ConfigServer::server_directory(&config) {
cmd.current_dir(dir); cmd.current_dir(dir);
} }

View File

@ -6,7 +6,7 @@ use std::time::Duration;
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
use crate::config::Config; use crate::config::{Config, Server as ConfigServer};
use crate::mc::ban; use crate::mc::ban;
use crate::server::Server; use crate::server::Server;
@ -23,7 +23,7 @@ pub fn service(config: Arc<Config>, server: Arc<Server>) {
} }
// Ensure server directory is set, it must exist // Ensure server directory is set, it must exist
let dir = match &config.server.directory { let dir = match ConfigServer::server_directory(&config) {
Some(dir) => dir, Some(dir) => dir,
None => { None => {
warn!(target: "lazymc", "Not blocking banned IPs, server directory not configured, unable to find {} file", ban::FILE); warn!(target: "lazymc", "Not blocking banned IPs, server directory not configured, unable to find {} file", ban::FILE);

View File

@ -12,7 +12,7 @@ use tokio::fs;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use crate::config::*; use crate::config::{Config, Server as ConfigServer};
use crate::join; use crate::join;
use crate::mc::favicon; use crate::mc::favicon;
use crate::proto::action; use crate::proto::action;
@ -260,7 +260,7 @@ async fn server_status(client_info: &ClientInfo, config: &Config, server: &Serve
/// This always returns a favicon, returning the default one if none is set. /// This always returns a favicon, returning the default one if none is set.
async fn server_favicon(config: &Config) -> String { async fn server_favicon(config: &Config) -> String {
// Get server dir // Get server dir
let dir = match config.server.directory.as_ref() { let dir = match ConfigServer::server_directory(config) {
Some(dir) => dir, Some(dir) => dir,
None => return favicon::default_favicon(), None => return favicon::default_favicon(),
}; };