add remove mount capabilities to cli and ui #62
This commit is contained in:
@@ -42,7 +42,7 @@ public:
|
|||||||
~lock_data();
|
~lock_data();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string data_directory;
|
std::string data_directory_;
|
||||||
std::string mutex_id_;
|
std::string mutex_id_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -50,12 +50,12 @@ private:
|
|||||||
int lock_status_{EWOULDBLOCK};
|
int lock_status_{EWOULDBLOCK};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] auto get_state_directory() -> std::string;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_lock_data_file() const -> std::string;
|
[[nodiscard]] auto get_lock_data_file() const -> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto get_lock_file() const -> std::string;
|
[[nodiscard]] auto get_lock_file() const -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_state_directory() const -> std::string;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] static auto wait_for_lock(int handle,
|
[[nodiscard]] static auto wait_for_lock(int handle,
|
||||||
std::uint8_t retry_count = 30U)
|
std::uint8_t retry_count = 30U)
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ struct rpc_host_info {
|
|||||||
std::string user;
|
std::string user;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class rpc_response_type {
|
enum class rpc_response_type : std::uint8_t {
|
||||||
success,
|
success,
|
||||||
config_value_not_found,
|
config_value_not_found,
|
||||||
http_error,
|
http_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpc_response {
|
struct rpc_response final {
|
||||||
rpc_response_type response_type;
|
rpc_response_type response_type;
|
||||||
json data;
|
json data;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ lock_data::lock_data(std::string data_directory, provider_type prov,
|
|||||||
std::string_view unique_id)
|
std::string_view unique_id)
|
||||||
: data_directory_(std::move(data_directory)),
|
: data_directory_(std::move(data_directory)),
|
||||||
mutex_id_(create_lock_id(prov, unique_id)) {
|
mutex_id_(create_lock_id(prov, unique_id)) {
|
||||||
handle_ = open(get_lock_file().c_str(), O_CREAT | O_RDWR, S_IWUSR | S_IRUSR);
|
handle_ =
|
||||||
|
::open(get_lock_file().c_str(), O_CREAT | O_RDWR, S_IWUSR | S_IRUSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_data::~lock_data() { release(); }
|
lock_data::~lock_data() { release(); }
|
||||||
@@ -72,7 +73,7 @@ auto lock_data::get_lock_file() const -> std::string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock_data::get_mount_state(json &mount_state) -> bool {
|
auto lock_data::get_mount_state(json &mount_state) -> bool {
|
||||||
auto handle = open(get_lock_data_file().c_str(), O_RDWR, S_IWUSR | S_IRUSR);
|
auto handle = ::open(get_lock_data_file().c_str(), O_RDWR, S_IWUSR | S_IRUSR);
|
||||||
if (handle == -1) {
|
if (handle == -1) {
|
||||||
mount_state = {
|
mount_state = {
|
||||||
{"Active", false},
|
{"Active", false},
|
||||||
@@ -93,14 +94,14 @@ auto lock_data::get_mount_state(json &mount_state) -> bool {
|
|||||||
{"PID", -1},
|
{"PID", -1},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
flock(handle, LOCK_UN);
|
::flock(handle, LOCK_UN);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(handle);
|
::close(handle);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock_data::get_state_directory() -> std::string {
|
auto lock_data::get_state_directory() const -> std::string {
|
||||||
return utils::path::absolute(data_directory_ + "/state");
|
return utils::path::absolute(data_directory_ + "/state");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ void lock_data::release() {
|
|||||||
flock(handle_, LOCK_UN);
|
flock(handle_, LOCK_UN);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(handle_);
|
::close(handle_);
|
||||||
handle_ = -1;
|
handle_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ auto lock_data::set_mount_state(bool active, std::string_view mount_location,
|
|||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
auto handle =
|
auto handle =
|
||||||
open(get_lock_data_file().c_str(), O_CREAT | O_RDWR, S_IWUSR | S_IRUSR);
|
::open(get_lock_data_file().c_str(), O_CREAT | O_RDWR, S_IWUSR | S_IRUSR);
|
||||||
if (handle == -1) {
|
if (handle == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -172,10 +173,10 @@ auto lock_data::set_mount_state(bool active, std::string_view mount_location,
|
|||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
flock(handle, LOCK_UN);
|
::flock(handle, LOCK_UN);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(handle);
|
::close(handle);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#ifndef REPERTORY_INCLUDE_CLI_ACTIONS_HPP_
|
#ifndef REPERTORY_INCLUDE_CLI_ACTIONS_HPP_
|
||||||
#define REPERTORY_INCLUDE_CLI_ACTIONS_HPP_
|
#define REPERTORY_INCLUDE_CLI_ACTIONS_HPP_
|
||||||
|
|
||||||
|
#include "cli/common.hpp"
|
||||||
|
|
||||||
#include "cli/check_version.hpp"
|
#include "cli/check_version.hpp"
|
||||||
#include "cli/display_config.hpp"
|
#include "cli/display_config.hpp"
|
||||||
#include "cli/drive_information.hpp"
|
#include "cli/drive_information.hpp"
|
||||||
|
|||||||
@@ -49,15 +49,16 @@ check_version(const std::string &data_directory, provider_type prov,
|
|||||||
auto client_version = utils::get_version_number(project_get_version());
|
auto client_version = utils::get_version_number(project_get_version());
|
||||||
auto res = client.check_version(client_version, min_version);
|
auto res = client.check_version(client_version, min_version);
|
||||||
return cli::handle_error(
|
return cli::handle_error(
|
||||||
res == api_error::success || res == api_error::incompatible_version
|
res == api_error::success ? exit_code::success
|
||||||
? res
|
: res == api_error::incompatible_version
|
||||||
|
? exit_code::incompatible_version
|
||||||
: exit_code::communication_error,
|
: exit_code::communication_error,
|
||||||
fmt::format("required|{}|actual|{}", min_version, client_version));
|
fmt::format("required|{}|actual|{}", min_version, client_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prov != provider_type::sia) {
|
if (prov != provider_type::sia) {
|
||||||
return cli::handle_error(
|
return cli::handle_error(
|
||||||
api_error::success,
|
exit_code::success,
|
||||||
fmt::format("version not required|provider|",
|
fmt::format("version not required|provider|",
|
||||||
app_config::get_provider_display_name(prov)));
|
app_config::get_provider_display_name(prov)));
|
||||||
}
|
}
|
||||||
@@ -69,7 +70,7 @@ check_version(const std::string &data_directory, provider_type prov,
|
|||||||
std::string required_version;
|
std::string required_version;
|
||||||
std::string returned_version;
|
std::string returned_version;
|
||||||
if (provider.check_version(required_version, returned_version)) {
|
if (provider.check_version(required_version, returned_version)) {
|
||||||
return cli::handle_error(api_error::success,
|
return cli::handle_error(exit_code::success,
|
||||||
fmt::format("required|{}|actual|{}",
|
fmt::format("required|{}|actual|{}",
|
||||||
required_version, returned_version));
|
required_version, returned_version));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ using remote_instance = repertory::remote_fuse::i_remote_instance;
|
|||||||
namespace repertory::cli {
|
namespace repertory::cli {
|
||||||
[[nodiscard]] inline auto handle_error(exit_code code, std::string_view msg)
|
[[nodiscard]] inline auto handle_error(exit_code code, std::string_view msg)
|
||||||
-> exit_code {
|
-> exit_code {
|
||||||
fmt::println("{}", code);
|
fmt::println("{}", static_cast<std::int32_t>(code));
|
||||||
fmt::println("{}", msg);
|
fmt::println("{}", msg);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ namespace repertory::cli {
|
|||||||
[[nodiscard]] inline auto handle_error(exit_code code,
|
[[nodiscard]] inline auto handle_error(exit_code code,
|
||||||
rpc_response_type response_type,
|
rpc_response_type response_type,
|
||||||
std::string_view msg) -> exit_code {
|
std::string_view msg) -> exit_code {
|
||||||
fmt::println("{}", response_type);
|
fmt::println("{}", static_cast<std::uint8_t>(response_type));
|
||||||
fmt::println("{}", msg);
|
fmt::println("{}", msg);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ namespace repertory::cli::actions {
|
|||||||
if (lock_res == lock_result::success) {
|
if (lock_res == lock_result::success) {
|
||||||
app_config config(prov, data_directory);
|
app_config config(prov, data_directory);
|
||||||
const auto cfg = config.get_json();
|
const auto cfg = config.get_json();
|
||||||
|
|
||||||
return cli::handle_error(exit_code::success, cfg.dump(2));
|
return cli::handle_error(exit_code::success, cfg.dump(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ remove(std::vector<const char *> /* args */, const std::string &data_directory,
|
|||||||
return cli::handle_error(
|
return cli::handle_error(
|
||||||
exit_code::remove_failed,
|
exit_code::remove_failed,
|
||||||
fmt::format("failed to remove provider|type|{}|id|{}|directory|",
|
fmt::format("failed to remove provider|type|{}|id|{}|directory|",
|
||||||
app_config::get_provider_name(prov), unique_id),
|
app_config::get_provider_name(prov), unique_id,
|
||||||
data_directory);
|
data_directory));
|
||||||
}
|
}
|
||||||
} // namespace repertory::cli::actions
|
} // namespace repertory::cli::actions
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ unmount(std::vector<const char *> /* args */, const std::string &data_directory,
|
|||||||
std::string user, std::string password) -> exit_code {
|
std::string user, std::string password) -> exit_code {
|
||||||
constexpr const std::uint8_t retry_count{30U};
|
constexpr const std::uint8_t retry_count{30U};
|
||||||
|
|
||||||
auto ret{exit_code::success};
|
|
||||||
auto port{app_config::default_api_port(prov)};
|
auto port{app_config::default_api_port(prov)};
|
||||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||||
data_directory);
|
data_directory);
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "utils/cli_utils.hpp"
|
#include "utils/cli_utils.hpp"
|
||||||
#include "utils/error_utils.hpp"
|
#include "utils/error_utils.hpp"
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
#include "utils/path.hpp"
|
|
||||||
|
|
||||||
namespace repertory::ui {
|
namespace repertory::ui {
|
||||||
[[nodiscard]] auto ui_main(const std::vector<const char *> &args) -> int {
|
[[nodiscard]] auto ui_main(const std::vector<const char *> &args) -> int {
|
||||||
|
|||||||
@@ -539,6 +539,8 @@ void ui_server::handle_get_mount_location(const httplib::Request &req,
|
|||||||
|
|
||||||
void ui_server::handle_get_mount_status(const httplib::Request &req,
|
void ui_server::handle_get_mount_status(const httplib::Request &req,
|
||||||
httplib::Response &res) const {
|
httplib::Response &res) const {
|
||||||
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
auto name = req.get_param_value("name");
|
auto name = req.get_param_value("name");
|
||||||
auto prov = provider_type_from_string(req.get_param_value("type"));
|
auto prov = provider_type_from_string(req.get_param_value("type"));
|
||||||
|
|
||||||
@@ -548,6 +550,14 @@ void ui_server::handle_get_mount_status(const httplib::Request &req,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lines = launch_process(prov, name, {"-status"});
|
auto lines = launch_process(prov, name, {"-status"});
|
||||||
|
if (lines.at(0U) != "0") {
|
||||||
|
throw utils::error::create_exception(function_name, {
|
||||||
|
"command failed",
|
||||||
|
lines.at(0U),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.erase(lines.begin());
|
||||||
|
|
||||||
auto result = nlohmann::json::parse(utils::string::join(lines, '\n'));
|
auto result = nlohmann::json::parse(utils::string::join(lines, '\n'));
|
||||||
if (result.at("Location").get<std::string>().empty()) {
|
if (result.at("Location").get<std::string>().empty()) {
|
||||||
|
|||||||
@@ -23,86 +23,93 @@
|
|||||||
|
|
||||||
#include "platform/platform.hpp"
|
#include "platform/platform.hpp"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
[[nodiscard]] auto get_lock_test_dir() -> std::string {
|
||||||
|
return repertory::utils::path::combine(repertory::test::get_test_output_dir(),
|
||||||
|
{"lock"});
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
TEST(lock_data_test, lock_and_unlock) {
|
TEST(lock_data_test, lock_and_unlock) {
|
||||||
{
|
{
|
||||||
lock_data l(provider_type::sia, "1");
|
lock_data lock(get_lock_test_dir(), provider_type::sia, "1");
|
||||||
EXPECT_EQ(lock_result::success, l.grab_lock());
|
EXPECT_EQ(lock_result::success, lock.grab_lock());
|
||||||
|
|
||||||
std::thread([]() {
|
std::thread([]() {
|
||||||
lock_data l2(provider_type::sia, "1");
|
lock_data lock2(get_lock_test_dir(), provider_type::sia, "1");
|
||||||
EXPECT_EQ(lock_result::locked, l2.grab_lock(10));
|
EXPECT_EQ(lock_result::locked, lock2.grab_lock(10));
|
||||||
}).join();
|
}).join();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::thread([]() {
|
std::thread([]() {
|
||||||
lock_data l(provider_type::sia, "1");
|
lock_data lock(get_lock_test_dir(), provider_type::sia, "1");
|
||||||
EXPECT_EQ(lock_result::success, l.grab_lock(10));
|
EXPECT_EQ(lock_result::success, lock.grab_lock(10));
|
||||||
}).join();
|
}).join();
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
lock_data l2(provider_type::remote, "1");
|
lock_data lock2(get_lock_test_dir(), provider_type::remote, "1");
|
||||||
EXPECT_EQ(lock_result::success, l2.grab_lock());
|
EXPECT_EQ(lock_result::success, lock2.grab_lock());
|
||||||
|
|
||||||
lock_data l3(provider_type::remote, "2");
|
lock_data lock3(get_lock_test_dir(), provider_type::remote, "2");
|
||||||
EXPECT_EQ(lock_result::success, l3.grab_lock());
|
EXPECT_EQ(lock_result::success, lock3.grab_lock());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
TEST(lock_data_test, set_and_unset_mount_state) {
|
TEST(lock_data_test, set_and_unset_mount_state) {
|
||||||
lock_data l(provider_type::sia, "1");
|
lock_data lock(get_lock_test_dir(), provider_type::sia, "1");
|
||||||
EXPECT_TRUE(l.set_mount_state(true, "C:", 99));
|
EXPECT_TRUE(lock.set_mount_state(true, "C:", 99));
|
||||||
|
|
||||||
lock_data l2(provider_type::remote, "1");
|
lock_data lock2(get_lock_test_dir(), provider_type::remote, "1");
|
||||||
EXPECT_TRUE(l2.set_mount_state(true, "D:", 97));
|
EXPECT_TRUE(lock2.set_mount_state(true, "D:", 97));
|
||||||
|
|
||||||
lock_data l3(provider_type::remote, "2");
|
lock_data lock3(get_lock_test_dir(), provider_type::remote, "2");
|
||||||
EXPECT_TRUE(l3.set_mount_state(true, "E:", 96));
|
EXPECT_TRUE(lock3.set_mount_state(true, "E:", 96));
|
||||||
|
|
||||||
json mount_state;
|
json mount_state;
|
||||||
EXPECT_TRUE(l.get_mount_state(mount_state));
|
EXPECT_TRUE(lock.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":true,"Location":"C:","PID":99})",
|
EXPECT_STREQ(R"({"Active":true,"Location":"C:","PID":99})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
|
|
||||||
EXPECT_TRUE(l2.get_mount_state(mount_state));
|
EXPECT_TRUE(lock2.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":true,"Location":"D:","PID":97})",
|
EXPECT_STREQ(R"({"Active":true,"Location":"D:","PID":97})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
|
|
||||||
EXPECT_TRUE(l3.get_mount_state(mount_state));
|
EXPECT_TRUE(lock3.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":true,"Location":"E:","PID":96})",
|
EXPECT_STREQ(R"({"Active":true,"Location":"E:","PID":96})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
|
|
||||||
EXPECT_TRUE(l.set_mount_state(false, "C:", 99));
|
EXPECT_TRUE(lock.set_mount_state(false, "C:", 99));
|
||||||
EXPECT_TRUE(l2.set_mount_state(false, "D:", 98));
|
EXPECT_TRUE(lock2.set_mount_state(false, "D:", 98));
|
||||||
EXPECT_TRUE(l3.set_mount_state(false, "E:", 97));
|
EXPECT_TRUE(lock3.set_mount_state(false, "E:", 97));
|
||||||
|
|
||||||
EXPECT_TRUE(l.get_mount_state(mount_state));
|
EXPECT_TRUE(lock.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
|
|
||||||
EXPECT_TRUE(l2.get_mount_state(mount_state));
|
EXPECT_TRUE(lock2.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
|
|
||||||
EXPECT_TRUE(l3.get_mount_state(mount_state));
|
EXPECT_TRUE(lock3.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
TEST(lock_data_test, set_and_unset_mount_state) {
|
TEST(lock_data_test, set_and_unset_mount_state) {
|
||||||
lock_data l(provider_type::sia, "1");
|
lock_data lock(get_lock_test_dir(), provider_type::sia, "1");
|
||||||
EXPECT_TRUE(l.set_mount_state(true, "/mnt/1", 99));
|
EXPECT_TRUE(lock.set_mount_state(true, "/mnt/1", 99));
|
||||||
|
|
||||||
json mount_state;
|
json mount_state;
|
||||||
EXPECT_TRUE(l.get_mount_state(mount_state));
|
EXPECT_TRUE(lock.get_mount_state(mount_state));
|
||||||
|
|
||||||
EXPECT_STREQ(R"({"Active":true,"Location":"/mnt/1","PID":99})",
|
EXPECT_STREQ(R"({"Active":true,"Location":"/mnt/1","PID":99})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
|
|
||||||
EXPECT_TRUE(l.set_mount_state(false, "/mnt/1", 99));
|
EXPECT_TRUE(lock.set_mount_state(false, "/mnt/1", 99));
|
||||||
|
|
||||||
EXPECT_TRUE(l.get_mount_state(mount_state));
|
EXPECT_TRUE(lock.get_mount_state(mount_state));
|
||||||
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
EXPECT_STREQ(R"({"Active":false,"Location":"","PID":-1})",
|
||||||
mount_state.dump().c_str());
|
mount_state.dump().c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user