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 crate::config::{self, Config};
use crate::config::{self, Config, Server as ConfigServer};
use crate::mc::server_properties;
use crate::proto;
use crate::service;
@ -120,7 +120,7 @@ fn rewrite_server_properties(config: &Config) {
}
// Ensure server directory is set, it must exist
let dir = match &config.server.directory {
let dir = match ConfigServer::server_directory(config) {
Some(dir) => dir,
None => {
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::io;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use clap::ArgMatches;
use serde::Deserialize;
@ -63,6 +63,12 @@ pub fn load(matches: &ArgMatches) -> Config {
/// Configuration.
#[derive(Debug, Deserialize)]
pub struct Config {
/// Configuration path if known.
///
/// Should be used as base directory for filesystem operations.
#[serde(skip)]
pub path: Option<PathBuf>,
/// Public configuration.
#[serde(default)]
pub public: Public,
@ -101,9 +107,9 @@ pub struct Config {
impl Config {
/// Load configuration from file.
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> {
let data = fs::read(path)?;
let config: Config = toml::from_slice(&data)?;
pub fn load(path: PathBuf) -> Result<Self, io::Error> {
let data = fs::read(&path)?;
let mut config: Config = toml::from_slice(&data)?;
// Show warning if config version is problematic
match &config.config.version {
@ -118,6 +124,7 @@ impl Config {
Ok(true) => {}
},
}
config.path.replace(path);
Ok(config)
}
@ -152,8 +159,10 @@ impl Default for Public {
#[derive(Debug, Deserialize)]
pub struct Server {
/// Server directory.
///
/// Private because you should use `Server::server_directory()` instead.
#[serde(default = "option_pathbuf_dot")]
pub directory: Option<PathBuf>,
directory: Option<PathBuf>,
/// Start command.
pub command: String,
@ -194,6 +203,23 @@ pub struct Server {
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.
#[derive(Debug, Deserialize)]
#[serde(default)]

View File

@ -11,39 +11,39 @@ const EOL: &str = "\r\n";
/// Try to rewrite changes in server.properties file in dir.
///
/// 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() {
return;
}
// Ensure directory exists
if !dir.is_dir() {
if !dir.as_ref().is_dir() {
warn!(target: "lazymc",
"Not rewriting {} file, configured server directory doesn't exist: {}",
FILE,
dir.to_str().unwrap_or("?")
dir.as_ref().to_str().unwrap_or("?")
);
return;
}
// Rewrite file
rewrite_file(&dir.join(FILE), changes)
rewrite_file(dir.as_ref().join(FILE), changes)
}
/// Try to rewrite changes in server.properties file.
///
/// 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() {
return;
}
// File must exist
if !file.is_file() {
if !file.as_ref().is_file() {
warn!(target: "lazymc",
"Not writing {} file, not found at: {}",
FILE,
file.to_str().unwrap_or("?"),
file.as_ref().to_str().unwrap_or("?"),
);
return;
}

View File

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

View File

@ -6,7 +6,7 @@ use std::time::Duration;
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
use crate::config::Config;
use crate::config::{Config, Server as ConfigServer};
use crate::mc::ban;
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
let dir = match &config.server.directory {
let dir = match ConfigServer::server_directory(&config) {
Some(dir) => dir,
None => {
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::net::TcpStream;
use crate::config::*;
use crate::config::{Config, Server as ConfigServer};
use crate::join;
use crate::mc::favicon;
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.
async fn server_favicon(config: &Config) -> String {
// Get server dir
let dir = match config.server.directory.as_ref() {
let dir = match ConfigServer::server_directory(config) {
Some(dir) => dir,
None => return favicon::default_favicon(),
};