[ui] Add auto-mount on first launch functionality #52
This commit is contained in:
		| @@ -124,6 +124,9 @@ private: | ||||
|                       bool background = false) const | ||||
|       -> std::vector<std::string>; | ||||
|  | ||||
|   [[nodiscard]] auto mount(provider_type prov, std::string_view name, | ||||
|                            const std::string &location) -> bool; | ||||
|  | ||||
|   void removed_expired_nonces(); | ||||
|  | ||||
|   void set_key_value(provider_type prov, std::string_view name, | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/atomic.hpp" | ||||
| #include <unordered_map> | ||||
|  | ||||
| namespace repertory::ui { | ||||
| class mgmt_app_config final { | ||||
| @@ -65,6 +66,9 @@ public: | ||||
|   [[nodiscard]] auto get_auto_start(provider_type prov, | ||||
|                                     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_launch_only() const -> bool { return launch_only_; } | ||||
|   | ||||
| @@ -293,6 +293,55 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) | ||||
|  | ||||
|   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_ = | ||||
|       std::make_unique<std::thread>([this]() { removed_expired_nonces(); }); | ||||
|  | ||||
| @@ -625,32 +674,21 @@ void handlers::handle_post_mount(const httplib::Request &req, | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   res.status = http_error_codes::ok; | ||||
|  | ||||
|   auto location = utils::path::absolute(req.get_param_value("location")); | ||||
|   auto unmount = utils::string::to_bool(req.get_param_value("unmount")); | ||||
|  | ||||
|   if (unmount) { | ||||
|     launch_process(prov, name, {"-unmount"}); | ||||
|   } else { | ||||
| #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); | ||||
|   if (mount(prov, name, location)) { | ||||
|     launch_process(prov, name, {"-status"}); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   res.status = http_error_codes::ok; | ||||
|   res.status = http_error_codes::internal_error; | ||||
| } | ||||
|  | ||||
| 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); | ||||
| } | ||||
|  | ||||
| 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() { | ||||
|   unique_mutex_lock lock(nonce_mtx_); | ||||
|   lock.unlock(); | ||||
|   | ||||
| @@ -142,6 +142,22 @@ auto mgmt_app_config::get_auto_start(provider_type prov, | ||||
|   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, | ||||
|                                          std::string_view name) const | ||||
|     -> std::string { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user