test persistent config

main
_ 2021-04-28 21:52:43 -05:00
parent 4ec5d66d25
commit 90b6b6913e
7 changed files with 69 additions and 5 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
/*.tar.gz /*.tar.gz
/app_packages /app_packages
/config /config
/data
/ptth_server.toml /ptth_server.toml
/ptth_relay.toml /ptth_relay.toml
/ptth_build_L6KLMVS6/ /ptth_build_L6KLMVS6/

View File

@ -30,19 +30,31 @@ pub mod machine_editable {
use super::file::Server; use super::file::Server;
#[derive (Deserialize, Serialize)] #[derive (Default, Deserialize, Serialize)]
pub struct Config { pub struct Config {
pub servers: Vec <Server>, pub servers: Vec <Server>,
pub debug_toggle: bool,
} }
impl Config { impl Config {
pub async fn from_file (path: &Path) -> Result <Self, crate::ConfigError> pub fn from_file (path: &Path) -> Result <Self, crate::ConfigError>
{ {
let config_s = tokio::fs::read_to_string (path).await?; let config_s = std::fs::read_to_string (path)?;
let new_config: Config = toml::from_str (&config_s)?; let new_config: Config = toml::from_str (&config_s)?;
Ok (new_config) Ok (new_config)
} }
pub async fn save (&self, path: &Path) -> Result <(), crate::ConfigError> {
let s = toml::to_string (self)?;
// This is way easier in C++ but also not safe
let mut temp_path = path.file_name ().unwrap ().to_os_string ();
temp_path.push (".partial");
let temp_path = path.with_file_name (temp_path);
tokio::fs::write (&temp_path, &s).await?;
tokio::fs::rename (&temp_path, path).await?;
Ok (())
}
} }
} }

View File

@ -20,6 +20,9 @@ pub enum ConfigError {
#[error ("Bad server address")] #[error ("Bad server address")]
BadServerAddress, BadServerAddress,
#[error (transparent)]
TomlSerialization (#[from] toml::ser::Error),
#[error ("unknown config error")] #[error ("unknown config error")]
Unknown, Unknown,
} }

View File

@ -542,13 +542,36 @@ async fn handle_all (
ClientServerList => handle_server_list (state, handlebars).await?, ClientServerList => handle_server_list (state, handlebars).await?,
ClientUnregisteredServers => handle_unregistered_servers (state, handlebars).await?, ClientUnregisteredServers => handle_unregistered_servers (state, handlebars).await?,
Debug => { Debug => {
let s = handlebars.render ("debug", &())?; #[derive (Serialize)]
struct DebugPage {
persistent_toggle: bool,
}
let page;
{
let guard = state.me_config.read ().await;
page = DebugPage {
persistent_toggle: guard.debug_toggle,
};
}
let s = handlebars.render ("debug", &page)?;
ok_reply (s)? ok_reply (s)?
}, },
DebugEndlessSink => handle_endless_sink (req).await?, DebugEndlessSink => handle_endless_sink (req).await?,
DebugEndlessSource (throttle) => handle_endless_source (1, throttle).await?, DebugEndlessSource (throttle) => handle_endless_source (1, throttle).await?,
DebugGenKey => handle_gen_scraper_key (state).await?, DebugGenKey => handle_gen_scraper_key (state).await?,
DebugMysteriousError => return Err (RequestError::Mysterious), DebugMysteriousError => return Err (RequestError::Mysterious),
DebugToggle => {
trace! ("Toggling debug toggle");
{
let mut guard = state.me_config.write ().await;
guard.debug_toggle = ! guard.debug_toggle;
guard.save (Path::new ("data/ptth_relay_me_config.toml")).await.unwrap ();
}
error_reply (StatusCode::OK, "Toggled.")?
},
ErrorBadUriFormat => error_reply (StatusCode::BAD_REQUEST, "Bad URI format")?, ErrorBadUriFormat => error_reply (StatusCode::BAD_REQUEST, "Bad URI format")?,
ErrorCantPost => { ErrorCantPost => {
error! ("Can't POST {}", path); error! ("Can't POST {}", path);
@ -613,7 +636,7 @@ async fn reload_config (
let new_config = Config::from_file (config_reload_path).await?; let new_config = Config::from_file (config_reload_path).await?;
// Reload machine-editable config, if possible // Reload machine-editable config, if possible
let me_config = machine_editable::Config::from_file (Path::new ("data/ptth_relay_me_config.toml")).await.ok (); // let me_config = machine_editable::Config::from_file (Path::new ("data/ptth_relay_me_config.toml")).await.ok ();
let mut config = state.config.write ().await; let mut config = state.config.write ().await;

View File

@ -1,6 +1,7 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
convert::TryFrom, convert::TryFrom,
path::Path,
time::Instant, time::Instant,
}; };
@ -18,6 +19,7 @@ use crate::{
Config, Config,
RelayError, RelayError,
ShuttingDownError, ShuttingDownError,
config::machine_editable,
}; };
use ptth_core::{ use ptth_core::{
@ -76,6 +78,7 @@ impl Default for ServerStatus {
pub struct Relay { pub struct Relay {
pub (crate) config: RwLock <Config>, pub (crate) config: RwLock <Config>,
pub (crate) me_config: RwLock <machine_editable::Config>,
/// The parked clients or parked server, keyed by server /// The parked clients or parked server, keyed by server
@ -170,8 +173,20 @@ impl TryFrom <Config> for Relay {
fn try_from (config: Config) -> Result <Self, Self::Error> { fn try_from (config: Config) -> Result <Self, Self::Error> {
let (shutdown_watch_tx, shutdown_watch_rx) = watch::channel (false); let (shutdown_watch_tx, shutdown_watch_rx) = watch::channel (false);
let me_config = machine_editable::Config::default ();
let me_config = match machine_editable::Config::from_file (Path::new ("data/ptth_relay_me_config.toml"))
{
Err (e) => {
error! ("Can't load machine-editable config: {:?}", e);
me_config
},
Ok (x) => x,
};
Ok (Self { Ok (Self {
config: config.into (), config: config.into (),
me_config: me_config.into (),
request_rendezvous: Default::default (), request_rendezvous: Default::default (),
server_status: Default::default (), server_status: Default::default (),
response_rendezvous: Default::default (), response_rendezvous: Default::default (),

View File

@ -15,6 +15,7 @@ pub enum Route <'a> {
DebugEndlessSource (Option <usize>), DebugEndlessSource (Option <usize>),
DebugGenKey, DebugGenKey,
DebugMysteriousError, DebugMysteriousError,
DebugToggle,
ErrorBadUriFormat, ErrorBadUriFormat,
ErrorCantPost, ErrorCantPost,
ErrorMethodNotAllowed, ErrorMethodNotAllowed,
@ -41,6 +42,9 @@ pub fn route_url <'a> (method: &Method, path: &'a str) -> Route <'a> {
else if path == "/frontend/debug/endless_sink" { else if path == "/frontend/debug/endless_sink" {
Route::DebugEndlessSink Route::DebugEndlessSink
} }
else if path == "/frontend/debug/toggle" {
Route::DebugToggle
}
else { else {
Route::ErrorCantPost Route::ErrorCantPost
} }

View File

@ -52,5 +52,11 @@ Lorem ipsum dolor set amet
<p> <p>
<a href="endless_sink">Data sink (POST only)</a> <a href="endless_sink">Data sink (POST only)</a>
<p>Persistent toggle is <pre>{{persistent_toggle}}</pre></p>
<form action="toggle" method="post">
<input type="submit" value="Toggle">
</form>
</body> </body>
</html> </html>