[add remove mount capabilities to cli and ui #62] [refactor cli messages and error handling]
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
* Fixed intermittent client hang on remote mount server disconnect
|
||||
* Implemented POSIX-compliant `unlink()` with FUSE `hard_remove`
|
||||
* Open handles remain valid after `unlink()`
|
||||
* Refactored CLI messages and error handling to use common methods
|
||||
|
||||
## v2.0.7-release
|
||||
|
||||
|
@@ -30,7 +30,8 @@ class i_provider;
|
||||
|
||||
class lock_data final {
|
||||
public:
|
||||
lock_data(provider_type prov, std::string_view unique_id);
|
||||
lock_data(std::string data_directory, provider_type prov,
|
||||
std::string_view unique_id);
|
||||
|
||||
lock_data(const lock_data &) = delete;
|
||||
lock_data(lock_data &&) = delete;
|
||||
@@ -41,6 +42,7 @@ public:
|
||||
~lock_data();
|
||||
|
||||
private:
|
||||
std::string data_directory;
|
||||
std::string mutex_id_;
|
||||
|
||||
private:
|
||||
@@ -48,7 +50,7 @@ private:
|
||||
int lock_status_{EWOULDBLOCK};
|
||||
|
||||
private:
|
||||
[[nodiscard]] static auto get_state_directory() -> std::string;
|
||||
[[nodiscard]] auto get_state_directory() -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_lock_data_file() const -> std::string;
|
||||
|
||||
|
@@ -30,7 +30,8 @@ class i_provider;
|
||||
|
||||
class lock_data final {
|
||||
public:
|
||||
explicit lock_data(provider_type prov, std::string unique_id);
|
||||
explicit lock_data(std::string data_directory, provider_type prov,
|
||||
std::string unique_id);
|
||||
lock_data(const lock_data &) = delete;
|
||||
lock_data(lock_data &&) = delete;
|
||||
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
auto operator=(lock_data &&) -> lock_data & = delete;
|
||||
|
||||
private:
|
||||
std::string dir_id_;
|
||||
std::string mutex_id_;
|
||||
HANDLE mutex_handle_{INVALID_HANDLE_VALUE};
|
||||
DWORD mutex_state_{WAIT_FAILED};
|
||||
|
@@ -207,7 +207,8 @@ enum class exit_code : std::int32_t {
|
||||
exception = -20,
|
||||
provider_offline = -21,
|
||||
ui_failed = -22,
|
||||
remove_failed = -23
|
||||
remove_failed = -23,
|
||||
mount_not_found = -24,
|
||||
};
|
||||
|
||||
enum http_error_codes : std::int32_t {
|
||||
|
@@ -49,6 +49,7 @@ inline const option pin_file_option = {"-pf", "--pin_file"};
|
||||
inline const option pinned_status_option = {"-ps", "--pinned_status"};
|
||||
inline const option password_option = {"-pw", "--password"};
|
||||
inline const option remote_mount_option = {"-rm", "--remote_mount"};
|
||||
inline const option remove_option = {"-rp", "--remove"};
|
||||
inline const option set_option = {"-set", "--set"};
|
||||
inline const option status_option = {"-status", "--status"};
|
||||
inline const option test_option = {"-test", "--test"};
|
||||
@@ -80,6 +81,7 @@ inline const std::vector<option> option_list = {
|
||||
pin_file_option,
|
||||
pinned_status_option,
|
||||
remote_mount_option,
|
||||
remove_option,
|
||||
set_option,
|
||||
status_option,
|
||||
test_option,
|
||||
|
@@ -36,8 +36,10 @@
|
||||
#include "utils/unix.hpp"
|
||||
|
||||
namespace repertory {
|
||||
lock_data::lock_data(provider_type prov, std::string_view unique_id)
|
||||
: mutex_id_(create_lock_id(prov, unique_id)) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -99,13 +101,7 @@ auto lock_data::get_mount_state(json &mount_state) -> bool {
|
||||
}
|
||||
|
||||
auto lock_data::get_state_directory() -> std::string {
|
||||
#if defined(__APPLE__)
|
||||
return utils::path::absolute("~/Library/Application Support/" +
|
||||
std::string{REPERTORY_DATA_NAME} + "/state");
|
||||
#else // !defined(__APPLE__)
|
||||
return utils::path::absolute("~/.local/" + std::string{REPERTORY_DATA_NAME} +
|
||||
"/state");
|
||||
#endif // defined(__APPLE__)
|
||||
return utils::path::absolute(data_directory_ + "/state");
|
||||
}
|
||||
|
||||
auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
|
||||
|
@@ -26,13 +26,27 @@
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/types/filesystem_item_added.hpp"
|
||||
#include "providers/i_provider.hpp"
|
||||
#include "utils/collection.hpp"
|
||||
#include "utils/config.hpp"
|
||||
#include "utils/error_utils.hpp"
|
||||
#include "utils/hash.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace {
|
||||
[[nodiscard]] auto create_lock_key(std::string_view dir_id,
|
||||
std::string_view mutex_id) -> std::string {
|
||||
return fmt::format(R"(SOFTWARE\{}\Lock\{}\{})",
|
||||
repertory::REPERTORY_DATA_NAME, dir_id, mutex_id)
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace repertory {
|
||||
lock_data::lock_data(provider_type prov, std::string unique_id)
|
||||
: mutex_id_(create_lock_id(prov, unique_id)),
|
||||
lock_data::lock_data(std::string_view data_directory, provider_type prov,
|
||||
std::string unique_id)
|
||||
: dir_id_(
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_blake2b_64(
|
||||
utils::string::to_lower(data_directory)))),
|
||||
mutex_id_(create_lock_id(prov, unique_id)),
|
||||
mutex_handle_(::CreateMutex(nullptr, FALSE,
|
||||
create_lock_id(prov, unique_id).c_str())) {}
|
||||
|
||||
@@ -43,10 +57,8 @@ auto lock_data::get_current_mount_state(json &mount_state) -> bool {
|
||||
|
||||
HKEY key{};
|
||||
if (::RegOpenKeyEx(HKEY_CURRENT_USER,
|
||||
fmt::format(R"(SOFTWARE\{}\Mounts\{})",
|
||||
REPERTORY_DATA_NAME, mutex_id_)
|
||||
.c_str(),
|
||||
0, KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) {
|
||||
create_lock_key(dir_id_, mutex_id_).c_str(), 0,
|
||||
KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -150,10 +162,8 @@ auto lock_data::set_mount_state(bool active, std::string_view mount_location,
|
||||
|
||||
HKEY key{};
|
||||
if (::RegCreateKeyExA(HKEY_CURRENT_USER,
|
||||
fmt::format(R"(SOFTWARE\{}\Mounts\{})",
|
||||
REPERTORY_DATA_NAME, mutex_id_)
|
||||
.c_str(),
|
||||
0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key,
|
||||
create_lock_key(dir_id_, mutex_id_).c_str(), 0, nullptr,
|
||||
0, KEY_ALL_ACCESS, nullptr, &key,
|
||||
nullptr) != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
@@ -162,11 +172,10 @@ auto lock_data::set_mount_state(bool active, std::string_view mount_location,
|
||||
if (mount_location.empty() && not active) {
|
||||
::RegCloseKey(key);
|
||||
|
||||
if (::RegCreateKeyExA(
|
||||
HKEY_CURRENT_USER,
|
||||
fmt::format(R"(SOFTWARE\{}\Mounts)", REPERTORY_DATA_NAME).c_str(),
|
||||
0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key,
|
||||
nullptr) != ERROR_SUCCESS) {
|
||||
if (::RegCreateKeyExA(HKEY_CURRENT_USER,
|
||||
create_lock_key(dir_id_, mutex_id_).c_str(), 0,
|
||||
nullptr, 0, KEY_ALL_ACCESS, nullptr, &key,
|
||||
nullptr) != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "cli/open_files.hpp"
|
||||
#include "cli/pin_file.hpp"
|
||||
#include "cli/pinned_status.hpp"
|
||||
#include "cli/remove.hpp"
|
||||
#include "cli/set.hpp"
|
||||
#include "cli/status.hpp"
|
||||
#include "cli/test.hpp"
|
||||
@@ -55,26 +56,66 @@ struct option_hasher {
|
||||
|
||||
inline const std::unordered_map<utils::cli::option, action, option_hasher>
|
||||
option_actions = {
|
||||
{utils::cli::options::display_config_option,
|
||||
cli::actions::display_config},
|
||||
{utils::cli::options::drive_information_option,
|
||||
cli::actions::drive_information},
|
||||
{utils::cli::options::get_directory_items_option,
|
||||
cli::actions::get_directory_items},
|
||||
{utils::cli::options::get_item_info_option,
|
||||
cli::actions::get_item_info},
|
||||
{utils::cli::options::get_option, cli::actions::get},
|
||||
{utils::cli::options::get_pinned_files_option,
|
||||
cli::actions::get_pinned_files},
|
||||
{utils::cli::options::open_files_option, cli::actions::open_files},
|
||||
{utils::cli::options::pin_file_option, cli::actions::pin_file},
|
||||
{utils::cli::options::pinned_status_option,
|
||||
cli::actions::pinned_status},
|
||||
{utils::cli::options::set_option, cli::actions::set},
|
||||
{utils::cli::options::status_option, cli::actions::status},
|
||||
{utils::cli::options::test_option, cli::actions::test},
|
||||
{utils::cli::options::unmount_option, cli::actions::unmount},
|
||||
{utils::cli::options::unpin_file_option, cli::actions::unpin_file},
|
||||
{
|
||||
utils::cli::options::display_config_option,
|
||||
cli::actions::display_config,
|
||||
},
|
||||
{
|
||||
utils::cli::options::drive_information_option,
|
||||
cli::actions::drive_information,
|
||||
},
|
||||
{
|
||||
utils::cli::options::get_directory_items_option,
|
||||
cli::actions::get_directory_items,
|
||||
},
|
||||
{
|
||||
utils::cli::options::get_item_info_option,
|
||||
cli::actions::get_item_info,
|
||||
},
|
||||
{
|
||||
utils::cli::options::get_option,
|
||||
cli::actions::get,
|
||||
},
|
||||
{
|
||||
utils::cli::options::get_pinned_files_option,
|
||||
cli::actions::get_pinned_files,
|
||||
},
|
||||
{
|
||||
utils::cli::options::open_files_option,
|
||||
cli::actions::open_files,
|
||||
},
|
||||
{
|
||||
utils::cli::options::pin_file_option,
|
||||
cli::actions::pin_file,
|
||||
},
|
||||
{
|
||||
utils::cli::options::pinned_status_option,
|
||||
cli::actions::pinned_status,
|
||||
},
|
||||
{
|
||||
utils::cli::options::remove_option,
|
||||
cli::actions::remove,
|
||||
},
|
||||
{
|
||||
utils::cli::options::set_option,
|
||||
cli::actions::set,
|
||||
},
|
||||
{
|
||||
utils::cli::options::status_option,
|
||||
cli::actions::status,
|
||||
},
|
||||
{
|
||||
utils::cli::options::test_option,
|
||||
cli::actions::test,
|
||||
},
|
||||
{
|
||||
utils::cli::options::unmount_option,
|
||||
cli::actions::unmount,
|
||||
},
|
||||
{
|
||||
utils::cli::options::unpin_file_option,
|
||||
cli::actions::unpin_file,
|
||||
},
|
||||
};
|
||||
|
||||
[[nodiscard]] inline auto
|
||||
|
@@ -32,6 +32,11 @@ namespace repertory::cli::actions {
|
||||
check_version(const std::string &data_directory, provider_type prov,
|
||||
const std::string &remote_host, std::uint16_t remote_port)
|
||||
-> exit_code {
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (prov == provider_type::remote) {
|
||||
app_config config(prov, data_directory);
|
||||
auto remote_cfg = config.get_remote_config();
|
||||
@@ -43,25 +48,18 @@ check_version(const std::string &data_directory, provider_type prov,
|
||||
std::uint32_t min_version{};
|
||||
auto client_version = utils::get_version_number(project_get_version());
|
||||
auto res = client.check_version(client_version, min_version);
|
||||
if (res == api_error::success) {
|
||||
fmt::println("0\nSuccess:\n\tRequired: {}\n\tActual: {}", min_version,
|
||||
client_version);
|
||||
} else {
|
||||
fmt::println("1\nFailed:\n\tRequired: {}\n\tActual: {}", min_version,
|
||||
client_version);
|
||||
}
|
||||
|
||||
return res == api_error::success ? exit_code::success
|
||||
: res == api_error::incompatible_version
|
||||
? exit_code::incompatible_version
|
||||
: exit_code::communication_error;
|
||||
return cli::handle_error(
|
||||
res == api_error::success || res == api_error::incompatible_version
|
||||
? res
|
||||
: exit_code::communication_error,
|
||||
fmt::format("required|{}|actual|{}", min_version, client_version));
|
||||
}
|
||||
|
||||
if (prov != provider_type::sia) {
|
||||
fmt::println(
|
||||
"0\nSuccess:\n\tNo specific version is required for {} providers",
|
||||
app_config::get_provider_display_name(prov));
|
||||
return exit_code::success;
|
||||
return cli::handle_error(
|
||||
api_error::success,
|
||||
fmt::format("version not required|provider|",
|
||||
app_config::get_provider_display_name(prov)));
|
||||
}
|
||||
|
||||
app_config config(prov, data_directory);
|
||||
@@ -71,14 +69,14 @@ 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)) {
|
||||
fmt::println("0\nSuccess:\n\tRequired: {}\n\tActual: {}", required_version,
|
||||
returned_version);
|
||||
return exit_code::success;
|
||||
return cli::handle_error(api_error::success,
|
||||
fmt::format("required|{}|actual|{}",
|
||||
required_version, returned_version));
|
||||
}
|
||||
|
||||
fmt::println("1\nFailed:\n\tRequired: {}\n\tActual: {}", required_version,
|
||||
returned_version);
|
||||
return exit_code::incompatible_version;
|
||||
return cli::handle_error(
|
||||
exit_code::incompatible_version,
|
||||
fmt::format("required|{}|actual|{}", required_version, returned_version));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/path.hpp"
|
||||
#include "utils/string.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
@@ -56,4 +57,34 @@ using remote_drive = repertory::remote_fuse::remote_fuse_drive;
|
||||
using remote_instance = repertory::remote_fuse::i_remote_instance;
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
namespace repertory::cli {
|
||||
[[nodiscard]] inline auto handle_error(exit_code code, std::string_view msg)
|
||||
-> exit_code {
|
||||
fmt::println("{}", code);
|
||||
fmt::println("{}", msg);
|
||||
return code;
|
||||
}
|
||||
|
||||
[[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("{}", msg);
|
||||
return code;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline auto check_data_directory(std::string_view data_directory,
|
||||
provider_type prov)
|
||||
-> exit_code {
|
||||
auto full_directory = data_directory.empty()
|
||||
? app_config::default_data_directory(prov)
|
||||
: utils::path::absolute(data_directory);
|
||||
if (not utils::file::directory{full_directory}.exists()) {
|
||||
return handle_error(exit_code::mount_not_found, "failed: mount not found");
|
||||
}
|
||||
|
||||
return exit_code::success;
|
||||
}
|
||||
} // namespace repertory::cli
|
||||
|
||||
#endif // REPERTORY_INCLUDE_CLI_COMMON_HPP_
|
||||
|
@@ -31,27 +31,36 @@ namespace repertory::cli::actions {
|
||||
const std::string &unique_id,
|
||||
std::string user, std::string password)
|
||||
-> exit_code {
|
||||
lock_data lock(prov, unique_id);
|
||||
const auto res = lock.grab_lock(1U);
|
||||
if (res == lock_result::success) {
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto lock_res = lock.grab_lock(1U);
|
||||
if (lock_res == lock_result::success) {
|
||||
app_config config(prov, data_directory);
|
||||
const auto cfg = config.get_json();
|
||||
std::cout << 0 << std::endl;
|
||||
std::cout << cfg.dump(2) << std::endl;
|
||||
} else if (res == lock_result::locked) {
|
||||
|
||||
return cli::handle_error(exit_code::success, cfg.dump(2));
|
||||
}
|
||||
|
||||
if (lock_res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_config();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
|
||||
return exit_code::success;
|
||||
return cli::handle_error(exit_code::lock_failed, "failed to get mount lock");
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -30,28 +30,27 @@ drive_information(std::vector<const char *> /* args */,
|
||||
const std::string &data_directory, provider_type prov,
|
||||
const std::string &unique_id, std::string user,
|
||||
std::string password) -> exit_code {
|
||||
auto ret = exit_code::success;
|
||||
|
||||
lock_data lock(prov, unique_id);
|
||||
const auto res = lock.grab_lock(1U);
|
||||
if (res == lock_result::locked) {
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto lock_res = lock.grab_lock(1U);
|
||||
if (lock_res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_drive_information();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << app_config::get_provider_display_name(prov)
|
||||
<< " is not mounted." << std::endl;
|
||||
ret = exit_code::not_mounted;
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cli::handle_error(
|
||||
exit_code::not_mounted,
|
||||
fmt::format("{} is not mounted",
|
||||
app_config::get_provider_display_name(prov)));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -27,39 +27,49 @@
|
||||
namespace repertory::cli::actions {
|
||||
[[nodiscard]] inline auto get(std::vector<const char *> args,
|
||||
const std::string &data_directory,
|
||||
provider_type prov,
|
||||
const std::string &unique_id, std::string user,
|
||||
std::string password) -> exit_code {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::get_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
lock_data lock(prov, unique_id);
|
||||
const auto res = lock.grab_lock(1);
|
||||
if (res == lock_result::success) {
|
||||
app_config config(prov, data_directory);
|
||||
const auto value = config.get_value_by_name(data);
|
||||
std::cout << (value.empty()
|
||||
? static_cast<int>(
|
||||
rpc_response_type::config_value_not_found)
|
||||
: 0)
|
||||
<< std::endl;
|
||||
std::cout << json({{"value", value}}).dump(2) << std::endl;
|
||||
} else if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.get_config_value_by_name(data);
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
}
|
||||
provider_type prov, const std::string &unique_id,
|
||||
std::string user, std::string password)
|
||||
-> exit_code {
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
std::string data;
|
||||
ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::get_option, data);
|
||||
if (ret != exit_code::success) {
|
||||
return cli::handle_error(exit_code::invalid_syntax, "missing option name");
|
||||
}
|
||||
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto lock_res = lock.grab_lock(1);
|
||||
if (lock_res == lock_result::success) {
|
||||
app_config config(prov, data_directory);
|
||||
const auto value = config.get_value_by_name(data);
|
||||
return cli::handle_error(exit_code::success,
|
||||
value.empty()
|
||||
? rpc_response_type::config_value_not_found
|
||||
: rpc_response_type::success,
|
||||
json({{"value", value}}).dump(2));
|
||||
}
|
||||
|
||||
if (lock_res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_config_value_by_name(data);
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
|
||||
return cli::handle_error(exit_code::lock_failed, "failed to get mount lock");
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -33,24 +33,22 @@ get_directory_items(std::vector<const char *> args,
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::get_directory_items_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.get_directory_items(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
if (ret != exit_code::success) {
|
||||
return cli::handle_error(exit_code::invalid_syntax, "missing api path");
|
||||
}
|
||||
|
||||
return ret;
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_directory_items(data);
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -32,24 +32,22 @@ get_item_info(std::vector<const char *> args, const std::string &data_directory,
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::get_item_info_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.get_item_info(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
if (ret != exit_code::success) {
|
||||
return cli::handle_error(exit_code::invalid_syntax, "missing api path");
|
||||
}
|
||||
|
||||
return ret;
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_item_info(data);
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -31,23 +31,18 @@ namespace repertory::cli::actions {
|
||||
const std::string & /* unique_id */,
|
||||
std::string user,
|
||||
std::string password) -> exit_code {
|
||||
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);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_pinned_files();
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -39,7 +39,7 @@ template <typename drive> inline void help(std::vector<const char *> args) {
|
||||
"information"
|
||||
<< std::endl;
|
||||
std::cout << " -na,--name [name] Unique configuration "
|
||||
"name [Required for Encrypt, S3 and Sia]"
|
||||
"name [Required for Encrypt, S3 and Sia providers]"
|
||||
<< std::endl;
|
||||
std::cout << " -s3,--s3 Enables S3 mode"
|
||||
<< std::endl;
|
||||
@@ -67,6 +67,9 @@ template <typename drive> inline void help(std::vector<const char *> args) {
|
||||
<< std::endl;
|
||||
std::cout << " -rm,--remote_mount [host/ip:port] Enables remote mount mode"
|
||||
<< std::endl;
|
||||
std::cout << " -rp,--remove Remove existing provider "
|
||||
"configuration"
|
||||
<< std::endl;
|
||||
std::cout << " -pf,--pin_file [API path] Pin a file to cache to "
|
||||
"prevent eviction"
|
||||
<< std::endl;
|
||||
|
@@ -36,7 +36,16 @@ mount(std::vector<const char *> args, std::string data_directory,
|
||||
orig_args.emplace_back(arg);
|
||||
}
|
||||
|
||||
lock_data global_lock(provider_type::unknown, "global");
|
||||
auto has_gc_option =
|
||||
utils::cli::has_option(args, utils::cli::options::generate_config_option);
|
||||
if (has_gc_option) {
|
||||
auto res = cli::check_data_directory(data_directory, prov);
|
||||
if (res != exit_code::success) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
lock_data global_lock(data_directory, provider_type::unknown, "global");
|
||||
{
|
||||
auto lock_result = global_lock.grab_lock(100U);
|
||||
if (lock_result != lock_result::success) {
|
||||
@@ -45,7 +54,7 @@ mount(std::vector<const char *> args, std::string data_directory,
|
||||
}
|
||||
}
|
||||
|
||||
lock_data lock(prov, unique_id);
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto lock_result = lock.grab_lock();
|
||||
if (lock_result == lock_result::locked) {
|
||||
std::cerr << app_config::get_provider_display_name(prov)
|
||||
@@ -58,8 +67,7 @@ mount(std::vector<const char *> args, std::string data_directory,
|
||||
return exit_code::lock_failed;
|
||||
}
|
||||
|
||||
if (utils::cli::has_option(args,
|
||||
utils::cli::options::generate_config_option)) {
|
||||
if (has_gc_option) {
|
||||
app_config config(prov, data_directory);
|
||||
if (prov == provider_type::remote) {
|
||||
auto remote_config = config.get_remote_config();
|
||||
@@ -106,7 +114,7 @@ mount(std::vector<const char *> args, std::string data_directory,
|
||||
global_lock.release();
|
||||
|
||||
mount_result = utils::run_process_elevated(args);
|
||||
lock_data prov_lock(prov, unique_id);
|
||||
lock_data prov_lock(data_directory, prov, unique_id);
|
||||
if (prov_lock.grab_lock() == lock_result::success) {
|
||||
if (not prov_lock.set_mount_state(false, "", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
|
@@ -30,27 +30,27 @@ open_files(std::vector<const char *> /* args */,
|
||||
const std::string &data_directory, provider_type prov,
|
||||
const std::string &unique_id, std::string user, std::string password)
|
||||
-> exit_code {
|
||||
auto ret = exit_code::success;
|
||||
lock_data lock(prov, unique_id);
|
||||
const auto res = lock.grab_lock(1U);
|
||||
if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.get_open_files();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << app_config::get_provider_display_name(prov)
|
||||
<< " is not mounted." << std::endl;
|
||||
ret = exit_code::not_mounted;
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto lock_res = lock.grab_lock(1U);
|
||||
if (lock_res != lock_result::locked) {
|
||||
return cli::handle_error(
|
||||
exit_code::not_mounted,
|
||||
fmt::format("{} is not mounted",
|
||||
app_config::get_provider_display_name(prov)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.get_open_files();
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -32,24 +32,22 @@ pin_file(std::vector<const char *> args, const std::string &data_directory,
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::pin_file_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.pin_file(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::pin_failed;
|
||||
}
|
||||
if (ret != exit_code::success) {
|
||||
return cli::handle_error(exit_code::invalid_syntax, "missing api path");
|
||||
}
|
||||
|
||||
return ret;
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.pin_file(data);
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -32,24 +32,22 @@ pinned_status(std::vector<const char *> args, const std::string &data_directory,
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::pinned_status_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.pinned_status(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
if (ret != exit_code::success) {
|
||||
return cli::handle_error(exit_code::invalid_syntax, "missing api path");
|
||||
}
|
||||
|
||||
return ret;
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.pinned_status(data);
|
||||
return cli::handle_error(exit_code::success, response.response_type,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -31,12 +31,16 @@ namespace repertory::cli::actions {
|
||||
remove(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
provider_type prov, const std::string &unique_id, std::string /* user */,
|
||||
std::string /* password */) -> exit_code {
|
||||
lock_data lock(prov, unique_id);
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto res = lock.grab_lock(1);
|
||||
if (res != lock_result::success) {
|
||||
std::cout << static_cast<std::int32_t>(exit_code::lock_failed) << std::endl;
|
||||
std::cerr << "FATAL: Unable to get provider lock" << std::endl;
|
||||
return exit_code::lock_failed;
|
||||
return cli::handle_error(exit_code::lock_failed,
|
||||
"failed to get mount lock");
|
||||
}
|
||||
|
||||
auto trash_path = utils::path::combine(
|
||||
@@ -50,15 +54,17 @@ remove(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
utils::generate_secure_random<data_buffer>(4U))),
|
||||
});
|
||||
if (utils::file::directory{data_directory}.move_to(trash_path)) {
|
||||
fmt::println("0");
|
||||
fmt::println("successfully removed provider|type|{}|id|{}",
|
||||
app_config::get_provider_name(prov), unique_id);
|
||||
return exit_code::success;
|
||||
return cli::handle_error(
|
||||
exit_code::success,
|
||||
fmt::format("successfully removed provider|type|{}|id|{}",
|
||||
app_config::get_provider_name(prov), unique_id));
|
||||
}
|
||||
|
||||
std::cout << static_cast<std::int32_t>(exit_code::remove_failed) << std::endl;
|
||||
std::cerr << "FATAL: Failed to remove|" << data_directory << std::endl;
|
||||
return exit_code::remove_failed;
|
||||
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);
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -30,48 +30,55 @@ namespace repertory::cli::actions {
|
||||
provider_type prov, const std::string &unique_id,
|
||||
std::string user, std::string password)
|
||||
-> exit_code {
|
||||
auto ret = exit_code::success;
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto data = utils::cli::parse_option(args, "-set", 2U);
|
||||
if (data.empty()) {
|
||||
data = utils::cli::parse_option(args, "--set", 2U);
|
||||
if (data.empty()) {
|
||||
ret = exit_code::invalid_syntax;
|
||||
std::cerr << "Invalid syntax for '-set'" << std::endl;
|
||||
}
|
||||
}
|
||||
if (ret == exit_code::success) {
|
||||
lock_data lock(prov, unique_id);
|
||||
const auto res = lock.grab_lock(1U);
|
||||
if (res == lock_result::success) {
|
||||
app_config config(prov, data_directory);
|
||||
const auto value = config.set_value_by_name(data[0U], data[1U]);
|
||||
const auto notFound = value.empty() && not data[1U].empty();
|
||||
ret = notFound ? exit_code::set_option_not_found : exit_code::success;
|
||||
std::cout << (notFound ? static_cast<int>(
|
||||
rpc_response_type::config_value_not_found)
|
||||
: 0)
|
||||
<< std::endl;
|
||||
std::cout << json({{"value", value}}).dump(2) << std::endl;
|
||||
} else if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.set_config_value_by_name(data[0U], data[1U]);
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
ret = response.response_type == rpc_response_type::config_value_not_found
|
||||
? exit_code::set_option_not_found
|
||||
: response.response_type == rpc_response_type::success
|
||||
? exit_code::success
|
||||
: exit_code::communication_error;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (data.empty()) {
|
||||
return cli::handle_error(exit_code::invalid_syntax,
|
||||
"missing option name or option data");
|
||||
}
|
||||
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
auto lock_res = lock.grab_lock(1U);
|
||||
if (lock_res == lock_result::success) {
|
||||
app_config config(prov, data_directory);
|
||||
auto value = config.set_value_by_name(data[0U], data[1U]);
|
||||
auto notFound = value.empty() && not data[1U].empty();
|
||||
return cli::handle_error(
|
||||
notFound ? exit_code::set_option_not_found : exit_code::success,
|
||||
notFound ? rpc_response_type::config_value_not_found
|
||||
: rpc_response_type::success,
|
||||
json({{"value", value}}).dump(2));
|
||||
}
|
||||
|
||||
if (lock_res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.set_config_value_by_name(data[0U], data[1U]);
|
||||
return cli::handle_error(
|
||||
response.response_type == rpc_response_type::config_value_not_found
|
||||
? exit_code::set_option_not_found
|
||||
: response.response_type == rpc_response_type::success
|
||||
? exit_code::success
|
||||
: exit_code::communication_error,
|
||||
response.response_type, response.data.dump(2));
|
||||
}
|
||||
|
||||
return cli::handle_error(exit_code::lock_failed, "failed to get mount lock");
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -25,24 +25,23 @@
|
||||
#include "cli/common.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
[[nodiscard]] inline auto status(std::vector<const char *> /* args */,
|
||||
const std::string & /*data_directory*/,
|
||||
provider_type prov,
|
||||
const std::string &unique_id,
|
||||
std::string /* user */,
|
||||
std::string /* password */) -> exit_code {
|
||||
auto ret = exit_code::success;
|
||||
lock_data lock(prov, unique_id);
|
||||
[[nodiscard]] inline auto
|
||||
status(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
provider_type prov, const std::string &unique_id, std::string /* user */,
|
||||
std::string /* password */) -> exit_code {
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
lock_data lock(data_directory, prov, unique_id);
|
||||
[[maybe_unused]] auto status = lock.grab_lock(10U);
|
||||
json mount_state;
|
||||
if (lock.get_mount_state(mount_state)) {
|
||||
std::cout << mount_state.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cout << "{}" << std::endl;
|
||||
ret = exit_code::failed_to_get_mount_state;
|
||||
return cli::handle_error(exit_code::success, mount_state.dump(2));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cli::handle_error(exit_code::failed_to_get_mount_state, "{}");
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -29,17 +29,21 @@ namespace repertory::cli::actions {
|
||||
test(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
provider_type prov, const std::string & /*unique_id*/,
|
||||
std::string /*user*/, std::string /*password*/) -> exit_code {
|
||||
app_config config(prov, data_directory);
|
||||
auto ret = cli::check_data_directory(data_directory, prov);
|
||||
if (ret != exit_code::success) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
app_config config(prov, data_directory);
|
||||
auto is_online{
|
||||
(prov == provider_type::remote)
|
||||
? remote_client(config).check() == 0
|
||||
: create_provider(prov, config)->is_online(),
|
||||
};
|
||||
|
||||
fmt::println("{}\nProvider is {}!", utils::string::from_bool(not is_online),
|
||||
is_online ? "online" : "offline");
|
||||
return is_online ? exit_code::success : exit_code::provider_offline;
|
||||
return cli::handle_error(
|
||||
is_online ? exit_code::success : exit_code::provider_offline,
|
||||
fmt::format("provider is {}", is_online ? "online" : "offline"));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -35,10 +35,12 @@ unmount(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
auto port{app_config::default_api_port(prov)};
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.unmount();
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
auto orig_response{response};
|
||||
@@ -48,28 +50,29 @@ unmount(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
response.response_type == rpc_response_type::success;
|
||||
++retry) {
|
||||
std::this_thread::sleep_for(1s);
|
||||
response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.unmount();
|
||||
std::cout << "." << std::flush;
|
||||
}
|
||||
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cerr << " failed! mount still active" << std::endl;
|
||||
ret = exit_code::mount_active;
|
||||
} else {
|
||||
std::cout << " done!" << std::endl;
|
||||
std::cout << static_cast<int>(orig_response.response_type) << std::endl;
|
||||
std::cout << orig_response.data.dump(2) << std::endl;
|
||||
std::cout << "failed!" << std::endl;
|
||||
return cli::handle_error(exit_code::mount_active,
|
||||
"mount is still active");
|
||||
}
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::communication_error;
|
||||
|
||||
std::cout << " done!" << std::endl;
|
||||
return cli::handle_error(exit_code::success, orig_response.response_type,
|
||||
orig_response.data.dump(2));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cli::handle_error(exit_code::communication_error,
|
||||
response.response_type, response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -32,24 +32,24 @@ unpin_file(std::vector<const char *> args, const std::string &data_directory,
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
args, repertory::utils::cli::options::unpin_file_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user})
|
||||
.unpin_file(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::unpin_failed;
|
||||
}
|
||||
if (ret != exit_code::success) {
|
||||
return cli::handle_error(exit_code::invalid_syntax, "missing api path");
|
||||
}
|
||||
|
||||
return ret;
|
||||
auto port = app_config::default_api_port(prov);
|
||||
utils::cli::get_api_authentication_data(user, password, port, prov,
|
||||
data_directory);
|
||||
auto response = client({
|
||||
.host = "localhost",
|
||||
.password = password,
|
||||
.port = port,
|
||||
.user = user,
|
||||
})
|
||||
.unpin_file(data);
|
||||
return cli::handle_error(response.response_type == rpc_response_type::success
|
||||
? exit_code::success
|
||||
: exit_code::unpin_failed,
|
||||
response.data.dump(2));
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@@ -938,7 +938,8 @@ void ui_server::start() {
|
||||
nonce_thread_ =
|
||||
std::make_unique<std::thread>([this]() { removed_expired_nonces(); });
|
||||
|
||||
lock_data ui_lock(provider_type::unknown, "ui");
|
||||
lock_data ui_lock(app_config::get_root_data_directory(),
|
||||
provider_type::unknown, "ui");
|
||||
auto res = ui_lock.grab_lock(1U);
|
||||
if (res != lock_result::success) {
|
||||
notify_and_unlock(nonce_lock);
|
||||
|
Reference in New Issue
Block a user