diff --git a/backend/community_settings_srv/build_arm64.sh b/backend/community_settings_srv/build_arm64.sh new file mode 100755 index 0000000..7010ff6 --- /dev/null +++ b/backend/community_settings_srv/build_arm64.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +cargo build --release --target aarch64-unknown-linux-musl diff --git a/backend/community_settings_srv/src/api/get_game.rs b/backend/community_settings_srv/src/api/get_game.rs index ec19424..cbfb95f 100644 --- a/backend/community_settings_srv/src/api/get_game.rs +++ b/backend/community_settings_srv/src/api/get_game.rs @@ -88,6 +88,7 @@ pub async fn get_setting_by_app_id_handler( cli: web::Data<&'static Cli>, ) -> std::io::Result { let id: u32 = *id; + #[cfg(debug_assertions)] println!("Accept: {}", accept.to_string()); let preferred = accept.preference(); if super::is_mime_type_ron_capable(&preferred) { diff --git a/backend/community_settings_srv/src/api/save_setting.rs b/backend/community_settings_srv/src/api/save_setting.rs index 173364f..ae41e3e 100644 --- a/backend/community_settings_srv/src/api/save_setting.rs +++ b/backend/community_settings_srv/src/api/save_setting.rs @@ -73,13 +73,13 @@ pub async fn save_setting_handler( } #[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained { - std::os::windows::fs::symlink_file(&path_ron, app_id_folder.join(&filename_ron))?; - std::os::windows::fs::symlink_file(&path_json, app_id_folder.join(&filename_json))?; + std::os::windows::fs::symlink_file(&path_ron, app_id_folder.join(&filename_ron).canonicalize()?)?; + std::os::windows::fs::symlink_file(&path_json, app_id_folder.join(&filename_json).canonicalize()?)?; } #[cfg(target_family = "unix")] { - std::os::unix::fs::symlink(&path_ron, app_id_folder.join(&filename_ron))?; - std::os::unix::fs::symlink(&path_json, app_id_folder.join(&filename_json))?; + std::os::unix::fs::symlink(&path_ron, app_id_folder.join(&filename_ron).canonicalize()?)?; + std::os::unix::fs::symlink(&path_json, app_id_folder.join(&filename_json).canonicalize()?)?; } // create symlinks for user id folder @@ -89,13 +89,13 @@ pub async fn save_setting_handler( } #[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained { - std::os::windows::fs::symlink_file(&path_ron, user_id_folder.join(&filename_ron))?; - std::os::windows::fs::symlink_file(&path_json, user_id_folder.join(&filename_json))?; + std::os::windows::fs::symlink_file(&path_ron, user_id_folder.join(&filename_ron).canonicalize()?)?; + std::os::windows::fs::symlink_file(&path_json, user_id_folder.join(&filename_json).canonicalize()?)?; } #[cfg(target_family = "unix")] { - std::os::unix::fs::symlink(&path_ron, user_id_folder.join(&filename_ron))?; - std::os::unix::fs::symlink(&path_json, user_id_folder.join(&filename_json))?; + std::os::unix::fs::symlink(&path_ron, user_id_folder.join(&filename_ron).canonicalize()?)?; + std::os::unix::fs::symlink(&path_json, user_id_folder.join(&filename_json).canonicalize()?)?; } // create symlinks for each tag @@ -106,13 +106,13 @@ pub async fn save_setting_handler( } #[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained { - std::os::windows::fs::symlink_file(&path_ron, tag_folder.join(&filename_ron))?; - std::os::windows::fs::symlink_file(&path_json, tag_folder.join(&filename_json))?; + std::os::windows::fs::symlink_file(&path_ron, tag_folder.join(&filename_ron).canonicalize()?)?; + std::os::windows::fs::symlink_file(&path_json, tag_folder.join(&filename_json).canonicalize()?)?; } #[cfg(target_family = "unix")] { - std::os::unix::fs::symlink(&path_ron, tag_folder.join(&filename_ron))?; - std::os::unix::fs::symlink(&path_json, tag_folder.join(&filename_json))?; + std::os::unix::fs::symlink(&path_ron, tag_folder.join(&filename_ron).canonicalize()?)?; + std::os::unix::fs::symlink(&path_json, tag_folder.join(&filename_json).canonicalize()?)?; } } diff --git a/backend/community_settings_srv/src/cli.rs b/backend/community_settings_srv/src/cli.rs index b787355..5a05e14 100644 --- a/backend/community_settings_srv/src/cli.rs +++ b/backend/community_settings_srv/src/cli.rs @@ -14,6 +14,10 @@ pub struct Cli { /// Log file location #[arg(short, long, default_value = "/tmp/powertools_community_settings_srv.log")] pub log: std::path::PathBuf, + + /// Perform maintenance tasks + #[arg(short, long)] + pub fix: bool, } impl Cli { diff --git a/backend/community_settings_srv/src/file_util.rs b/backend/community_settings_srv/src/file_util.rs index 670c608..1272a0c 100644 --- a/backend/community_settings_srv/src/file_util.rs +++ b/backend/community_settings_srv/src/file_util.rs @@ -36,6 +36,71 @@ pub fn build_folder_layout(root: impl AsRef) -> std::io::Result<()> { Ok(()) } +pub fn fix_symlinks(root: impl AsRef) -> std::io::Result<()> { + log::info!("root setttings folder: {} aka {} (absolute)", root.as_ref().display(), root.as_ref().canonicalize()?.display()); + for dir_entry in root.as_ref() + .join(SETTING_FOLDER) + .join(APP_ID_FOLDER) + .read_dir()? { + let dir_entry = dir_entry?; + if dir_entry.file_type()?.is_dir() { + make_symlinks_absolute_in_dir(root.as_ref(), dir_entry.path())?; + } + } + for dir_entry in root.as_ref() + .join(SETTING_FOLDER) + .join(USER_ID_FOLDER) + .read_dir()? { + let dir_entry = dir_entry?; + if dir_entry.file_type()?.is_dir() { + make_symlinks_absolute_in_dir(root.as_ref(), dir_entry.path())?; + } + } + for dir_entry in root.as_ref() + .join(SETTING_FOLDER) + .join(TAG_FOLDER).read_dir()? { + let dir_entry = dir_entry?; + if dir_entry.file_type()?.is_dir() { + make_symlinks_absolute_in_dir(root.as_ref(), dir_entry.path())?; + } + } + + Ok(()) +} + +fn make_symlinks_absolute_in_dir(root: impl AsRef, dir: impl AsRef) -> std::io::Result<()> { + let abs_root = root.as_ref().canonicalize()?; + assert!(abs_root.is_absolute()); + for dir_entry in dir.as_ref() + .read_dir()? { + let dir_entry = dir_entry?; + if dir_entry.file_type()?.is_symlink() { + let path = dir_entry.path(); + let link_path = path.read_link()?; + if !link_path.is_absolute() { + let new_link = abs_root.join( + link_path.strip_prefix(&root).expect("Symlinked path does not begin with root settings folder") + ); + log::info!("Fixing {} -> {} to -> {}", path.display(), link_path.display(), new_link.display()); + std::fs::remove_file(&path)?; + #[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained + { + std::os::windows::fs::symlink_file(new_link, &path)?; + } + #[cfg(target_family = "unix")] + { + std::os::unix::fs::symlink(new_link, &path)?; + } + }else { + log::info!("Found already-absolute symlink {} -> {}", path.display(), link_path.display()); + } + } else { + log::info!("Found non-symlink {}: {:?}", dir_entry.path().display(), dir_entry.file_type()?); + } + } + Ok(()) +} + pub fn filename(id: u128, ext: &str) -> String { format!("{}.{}", id, ext) } diff --git a/backend/community_settings_srv/src/main.rs b/backend/community_settings_srv/src/main.rs index 2753bfa..a2dd153 100644 --- a/backend/community_settings_srv/src/main.rs +++ b/backend/community_settings_srv/src/main.rs @@ -29,6 +29,13 @@ async fn main() -> std::io::Result<()> { log::debug!("Building folder layout (if not exists) at: {}", &args.folder.display()); file_util::build_folder_layout(&args.folder)?; + // fix things + if args.fix { + log::debug!("Fixing old symlinks"); + file_util::fix_symlinks(&args.folder)?; + return Ok(()) + } + let leaked_args: &'static cli::Cli = Box::leak::<'static>(Box::new(args)); HttpServer::new(move || { App::new()