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