test persistent config
							parent
							
								
									4ec5d66d25
								
							
						
					
					
						commit
						90b6b6913e
					
				| 
						 | 
					@ -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/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 (())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 (),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue