[ui] Add auto-mount on first launch functionality #52
This commit is contained in:
		| @@ -124,6 +124,9 @@ private: | |||||||
|                       bool background = false) const |                       bool background = false) const | ||||||
|       -> std::vector<std::string>; |       -> std::vector<std::string>; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto mount(provider_type prov, std::string_view name, | ||||||
|  |                            const std::string &location) -> bool; | ||||||
|  |  | ||||||
|   void removed_expired_nonces(); |   void removed_expired_nonces(); | ||||||
|  |  | ||||||
|   void set_key_value(provider_type prov, std::string_view name, |   void set_key_value(provider_type prov, std::string_view name, | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ | |||||||
|  |  | ||||||
| #include "types/repertory.hpp" | #include "types/repertory.hpp" | ||||||
| #include "utils/atomic.hpp" | #include "utils/atomic.hpp" | ||||||
|  | #include <unordered_map> | ||||||
|  |  | ||||||
| namespace repertory::ui { | namespace repertory::ui { | ||||||
| class mgmt_app_config final { | class mgmt_app_config final { | ||||||
| @@ -65,6 +66,9 @@ public: | |||||||
|   [[nodiscard]] auto get_auto_start(provider_type prov, |   [[nodiscard]] auto get_auto_start(provider_type prov, | ||||||
|                                     std::string_view name) const -> bool; |                                     std::string_view name) const -> bool; | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto get_auto_start_list() const | ||||||
|  |       -> std::unordered_map<provider_type, std::vector<std::string>>; | ||||||
|  |  | ||||||
|   [[nodiscard]] auto get_hidden() const -> bool { return hidden_; } |   [[nodiscard]] auto get_hidden() const -> bool { return hidden_; } | ||||||
|  |  | ||||||
|   [[nodiscard]] auto get_launch_only() const -> bool { return launch_only_; } |   [[nodiscard]] auto get_launch_only() const -> bool { return launch_only_; } | ||||||
|   | |||||||
| @@ -293,6 +293,55 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) | |||||||
|  |  | ||||||
|   event_system::instance().start(); |   event_system::instance().start(); | ||||||
|  |  | ||||||
|  |   std::jthread auto_mount([this]() { | ||||||
|  |     for (const auto &[prov, names] : config_->get_auto_start_list()) { | ||||||
|  |       for (const auto &name : names) { | ||||||
|  |         try { | ||||||
|  |           auto location = config_->get_mount_location(prov, name); | ||||||
|  |           if (location.empty()) { | ||||||
|  |             utils::error::raise_error(function_name, | ||||||
|  |                                       utils::error::create_error_message({ | ||||||
|  |                                           "failed to auto-mount", | ||||||
|  |                                           "provider", | ||||||
|  |                                           provider_type_to_string(prov), | ||||||
|  |                                           "name", | ||||||
|  |                                           name, | ||||||
|  |                                           "location is empty", | ||||||
|  |                                       })); | ||||||
|  |           } else if (not mount(prov, name, location)) { | ||||||
|  |             utils::error::raise_error(function_name, | ||||||
|  |                                       utils::error::create_error_message({ | ||||||
|  |                                           "failed to auto-mount", | ||||||
|  |                                           "provider", | ||||||
|  |                                           provider_type_to_string(prov), | ||||||
|  |                                           "name", | ||||||
|  |                                           name, | ||||||
|  |                                           "mount failed", | ||||||
|  |                                       })); | ||||||
|  |           } | ||||||
|  |         } catch (const std::exception &e) { | ||||||
|  |           utils::error::raise_error(function_name, e, | ||||||
|  |                                     utils::error::create_error_message({ | ||||||
|  |                                         "failed to auto-mount", | ||||||
|  |                                         "provider", | ||||||
|  |                                         provider_type_to_string(prov), | ||||||
|  |                                         "name", | ||||||
|  |                                         name, | ||||||
|  |                                     })); | ||||||
|  |         } catch (...) { | ||||||
|  |           utils::error::raise_error(function_name, "unknown error", | ||||||
|  |                                     utils::error::create_error_message({ | ||||||
|  |                                         "failed to auto-mount", | ||||||
|  |                                         "provider", | ||||||
|  |                                         provider_type_to_string(prov), | ||||||
|  |                                         "name", | ||||||
|  |                                         name, | ||||||
|  |                                     })); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   nonce_thread_ = |   nonce_thread_ = | ||||||
|       std::make_unique<std::thread>([this]() { removed_expired_nonces(); }); |       std::make_unique<std::thread>([this]() { removed_expired_nonces(); }); | ||||||
|  |  | ||||||
| @@ -625,32 +674,21 @@ void handlers::handle_post_mount(const httplib::Request &req, | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   res.status = http_error_codes::ok; | ||||||
|  |  | ||||||
|   auto location = utils::path::absolute(req.get_param_value("location")); |   auto location = utils::path::absolute(req.get_param_value("location")); | ||||||
|   auto unmount = utils::string::to_bool(req.get_param_value("unmount")); |   auto unmount = utils::string::to_bool(req.get_param_value("unmount")); | ||||||
|  |  | ||||||
|   if (unmount) { |   if (unmount) { | ||||||
|     launch_process(prov, name, {"-unmount"}); |     launch_process(prov, name, {"-unmount"}); | ||||||
|   } else { |     return; | ||||||
| #if defined(_WIN32) |  | ||||||
|     if (utils::file::directory{location}.exists()) { |  | ||||||
| #else  // !defined(_WIN32) |  | ||||||
|     if (not utils::file::directory{location}.exists()) { |  | ||||||
| #endif // defined(_WIN32) |  | ||||||
|       config_->set_mount_location(prov, name, ""); |  | ||||||
|       res.status = http_error_codes::internal_error; |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     config_->set_mount_location(prov, name, location); |  | ||||||
|  |  | ||||||
|     static std::mutex mount_mtx; |  | ||||||
|     mutex_lock lock(mount_mtx); |  | ||||||
|  |  | ||||||
|     launch_process(prov, name, {location}, true); |  | ||||||
|     launch_process(prov, name, {"-status"}); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   res.status = http_error_codes::ok; |   if (mount(prov, name, location)) { | ||||||
|  |     launch_process(prov, name, {"-status"}); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   res.status = http_error_codes::internal_error; | ||||||
| } | } | ||||||
|  |  | ||||||
| void handlers::handle_put_set_value_by_name(const httplib::Request &req, | void handlers::handle_put_set_value_by_name(const httplib::Request &req, | ||||||
| @@ -821,6 +859,27 @@ auto handlers::launch_process(provider_type prov, std::string_view name, | |||||||
|                               false); |                               false); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | auto handlers::mount(provider_type prov, std::string_view name, | ||||||
|  |                      const std::string &location) -> bool { | ||||||
|  | #if defined(_WIN32) | ||||||
|  |   if (utils::file::directory{location}.exists()) { | ||||||
|  | #else  // !defined(_WIN32) | ||||||
|  |   if (not utils::file::directory{location}.exists()) { | ||||||
|  | #endif // defined(_WIN32) | ||||||
|  |  | ||||||
|  |     config_->set_mount_location(prov, name, ""); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   config_->set_mount_location(prov, name, location); | ||||||
|  |  | ||||||
|  |   static std::mutex mount_mtx; | ||||||
|  |   mutex_lock lock(mount_mtx); | ||||||
|  |  | ||||||
|  |   launch_process(prov, name, {location}, true); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| void handlers::removed_expired_nonces() { | void handlers::removed_expired_nonces() { | ||||||
|   unique_mutex_lock lock(nonce_mtx_); |   unique_mutex_lock lock(nonce_mtx_); | ||||||
|   lock.unlock(); |   lock.unlock(); | ||||||
|   | |||||||
| @@ -142,6 +142,22 @@ auto mgmt_app_config::get_auto_start(provider_type prov, | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | auto mgmt_app_config::get_auto_start_list() const | ||||||
|  |     -> std::unordered_map<provider_type, std::vector<std::string>> { | ||||||
|  |   std::unordered_map<provider_type, std::vector<std::string>> ret; | ||||||
|  |  | ||||||
|  |   recur_mutex_lock lock(mtx_); | ||||||
|  |   for (const auto &prov_pair : mount_auto_start_) { | ||||||
|  |     for (const auto &pair : prov_pair.second) { | ||||||
|  |       if (pair.second) { | ||||||
|  |         ret[prov_pair.first].emplace_back(pair.first); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
| auto mgmt_app_config::get_mount_location(provider_type prov, | auto mgmt_app_config::get_mount_location(provider_type prov, | ||||||
|                                          std::string_view name) const |                                          std::string_view name) const | ||||||
|     -> std::string { |     -> std::string { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user