Compare commits
1 Commits
cf901b11b0
...
v2.0.5-rc
Author | SHA1 | Date | |
---|---|---|---|
62555e6125 |
@@ -4,9 +4,6 @@
|
||||
|
||||
### Issues
|
||||
|
||||
* ~~\#12 [Unit Test] Complete all providers unit tests~~
|
||||
* ~~\#21 [Unit Test] Complete WinFSP unit tests~~
|
||||
* ~~\#22 [Unit Test] Complete FUSE unit tests~~
|
||||
* \#39 Create management portal in Flutter
|
||||
|
||||
### Changes from v2.0.4-rc
|
||||
@@ -14,6 +11,7 @@
|
||||
* Continue documentation updates
|
||||
* Fixed `-status` command erasing active mount information
|
||||
* Fixed overlapping HTTP REST API port's
|
||||
* Refactored/fixed instance locking
|
||||
* Removed passwords and secret key values from API calls
|
||||
* Renamed setting `ApiAuth` to `ApiPassword`
|
||||
* Require `--name,-na` option for encryption provider
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace repertory {
|
||||
[[nodiscard]] auto create_lock_id(provider_type prov,
|
||||
std::string_view unique_id);
|
||||
std::string_view unique_id)->std::string;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
@@ -30,7 +30,7 @@ class i_provider;
|
||||
|
||||
class lock_data final {
|
||||
public:
|
||||
explicit lock_data(const provider_type &prov, std::string unique_id);
|
||||
lock_data(provider_type prov, std::string_view unique_id);
|
||||
|
||||
lock_data(const lock_data &) = delete;
|
||||
lock_data(lock_data &&) = delete;
|
||||
@@ -42,19 +42,21 @@ public:
|
||||
|
||||
private:
|
||||
std::string mutex_id_;
|
||||
int lock_fd_;
|
||||
|
||||
private:
|
||||
int handle_{};
|
||||
int lock_status_{EWOULDBLOCK};
|
||||
|
||||
private:
|
||||
[[nodiscard]] static auto get_state_directory() -> std::string;
|
||||
|
||||
[[nodiscard]] static auto get_lock_data_file() -> std::string;
|
||||
[[nodiscard]] auto get_lock_data_file() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_lock_file() -> std::string;
|
||||
[[nodiscard]] auto get_lock_file() const -> std::string;
|
||||
|
||||
private:
|
||||
[[nodiscard]] static auto wait_for_lock(int fd,
|
||||
std::uint8_t retry_count = 30u)
|
||||
[[nodiscard]] static auto wait_for_lock(int handle,
|
||||
std::uint8_t retry_count = 30U)
|
||||
-> int;
|
||||
|
||||
public:
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "app_config.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/types/filesystem_item_added.hpp"
|
||||
#include "providers/i_provider.hpp"
|
||||
@@ -36,14 +35,14 @@
|
||||
#include "utils/unix.hpp"
|
||||
|
||||
namespace repertory {
|
||||
lock_data::lock_data(const provider_type &prov, std::string unique_id)
|
||||
lock_data::lock_data(provider_type prov, std::string_view unique_id)
|
||||
: mutex_id_(create_lock_id(prov, unique_id)) {
|
||||
lock_fd_ = 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(); }
|
||||
|
||||
auto lock_data::get_lock_data_file() -> std::string {
|
||||
auto lock_data::get_lock_data_file() const -> std::string {
|
||||
auto dir = get_state_directory();
|
||||
if (not utils::file::directory(dir).create_directory()) {
|
||||
throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
|
||||
@@ -56,7 +55,7 @@ auto lock_data::get_lock_data_file() -> std::string {
|
||||
});
|
||||
}
|
||||
|
||||
auto lock_data::get_lock_file() -> std::string {
|
||||
auto lock_data::get_lock_file() const -> std::string {
|
||||
auto dir = get_state_directory();
|
||||
if (not utils::file::directory(dir).create_directory()) {
|
||||
throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
|
||||
@@ -70,19 +69,31 @@ auto lock_data::get_lock_file() -> std::string {
|
||||
}
|
||||
|
||||
auto lock_data::get_mount_state(json &mount_state) -> bool {
|
||||
auto fd =
|
||||
open(get_lock_data_file().c_str(), O_CREAT | O_RDWR, S_IWUSR | S_IRUSR);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
auto handle = open(get_lock_data_file().c_str(), O_RDWR, S_IWUSR | S_IRUSR);
|
||||
if (handle == -1) {
|
||||
mount_state = {
|
||||
{"Active", false},
|
||||
{"Location", ""},
|
||||
{"PID", -1},
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ret{false};
|
||||
if (wait_for_lock(fd) == 0) {
|
||||
if (wait_for_lock(handle) == 0) {
|
||||
ret = utils::file::read_json_file(get_lock_data_file(), mount_state);
|
||||
flock(fd, LOCK_UN);
|
||||
if (ret && mount_state.empty()) {
|
||||
mount_state = {
|
||||
{"Active", false},
|
||||
{"Location", ""},
|
||||
{"PID", -1},
|
||||
};
|
||||
}
|
||||
flock(handle, LOCK_UN);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
close(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -90,18 +101,18 @@ 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
|
||||
#else // !defined(__APPLE__)
|
||||
return utils::path::absolute("~/.local/" + std::string{REPERTORY_DATA_NAME} +
|
||||
"/state");
|
||||
#endif
|
||||
#endif // defined(__APPLE__)
|
||||
}
|
||||
|
||||
auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
|
||||
if (lock_fd_ == -1) {
|
||||
if (handle_ == -1) {
|
||||
return lock_result::failure;
|
||||
}
|
||||
|
||||
lock_status_ = wait_for_lock(lock_fd_, retry_count);
|
||||
lock_status_ = wait_for_lock(handle_, retry_count);
|
||||
switch (lock_status_) {
|
||||
case 0:
|
||||
return lock_result::success;
|
||||
@@ -113,20 +124,20 @@ auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
|
||||
}
|
||||
|
||||
void lock_data::release() {
|
||||
if (lock_fd_ == -1) {
|
||||
if (handle_ == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lock_status_ == 0) {
|
||||
utils::file::file{get_lock_file()}.delete();
|
||||
flock(lock_fd_, LOCK_UN);
|
||||
[[maybe_unused]] auto success{utils::file::file{get_lock_file()}.remove()};
|
||||
flock(handle_, LOCK_UN);
|
||||
}
|
||||
|
||||
close(lock_fd_);
|
||||
lock_fd_ = -1;
|
||||
close(handle_);
|
||||
handle_ = -1;
|
||||
}
|
||||
|
||||
auto lock_data::set_mount_state(bool active, const std::string &mount_location,
|
||||
auto lock_data::set_mount_state(bool active, std::string_view mount_location,
|
||||
int pid) -> bool {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
@@ -150,7 +161,7 @@ auto lock_data::set_mount_state(bool active, const std::string &mount_location,
|
||||
((mount_state.find("Location") == mount_state.end()) ||
|
||||
(mount_state["Location"].get<std::string>() != mount_location)))) {
|
||||
if (mount_location.empty() && not active) {
|
||||
ret = utils::file::file{get_lock_data_file()}.delete();
|
||||
ret = utils::file::file{get_lock_data_file()}.remove();
|
||||
} else {
|
||||
ret = utils::file::write_json_file(
|
||||
get_lock_data_file(),
|
||||
@@ -171,13 +182,13 @@ auto lock_data::set_mount_state(bool active, const std::string &mount_location,
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto lock_data::wait_for_lock(int fd, std::uint8_t retry_count) -> int {
|
||||
auto lock_data::wait_for_lock(int handle, std::uint8_t retry_count) -> int {
|
||||
static constexpr const std::uint32_t max_sleep{100U};
|
||||
|
||||
auto lock_status{EWOULDBLOCK};
|
||||
auto remain{static_cast<std::uint32_t>(retry_count * max_sleep)};
|
||||
while ((remain > 0) && (lock_status == EWOULDBLOCK)) {
|
||||
lock_status = flock(fd, LOCK_EX | LOCK_NB);
|
||||
lock_status = flock(handle, LOCK_EX | LOCK_NB);
|
||||
if (lock_status == -1) {
|
||||
lock_status = errno;
|
||||
if (lock_status == EWOULDBLOCK) {
|
||||
@@ -232,7 +243,7 @@ auto provider_meta_handler(i_provider &provider, bool directory,
|
||||
file.changed_date, file.creation_date, directory, getgid(), file.key,
|
||||
directory ? S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR
|
||||
: S_IFREG | S_IRUSR | S_IWUSR,
|
||||
file.modified_date, 0u, 0u, file.file_size, file.source_path, getuid(),
|
||||
file.modified_date, 0U, 0U, file.file_size, file.source_path, getuid(),
|
||||
file.modified_date);
|
||||
auto res = provider.set_item_meta(file.api_path, meta);
|
||||
if (res == api_error::success) {
|
||||
|
@@ -29,9 +29,7 @@
|
||||
#include "events/types/service_stop_end.hpp"
|
||||
#include "events/types/unmount_requested.hpp"
|
||||
#include "rpc/common.hpp"
|
||||
#include "utils/base64.hpp"
|
||||
#include "utils/error_utils.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace repertory {
|
||||
server::server(app_config &config) : config_(config) {}
|
||||
@@ -144,13 +142,17 @@ void server::start() {
|
||||
initialize(*server_);
|
||||
|
||||
server_thread_ = std::make_unique<std::thread>([this]() {
|
||||
#ifdef _WIN32
|
||||
server_->set_socket_options([](auto &&sock) {
|
||||
int enable = 1;
|
||||
#if defined(_WIN32)
|
||||
int enable{1};
|
||||
setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
|
||||
reinterpret_cast<const char *>(&enable), sizeof(enable));
|
||||
#else // !defined(_WIN32)
|
||||
linger opt{1, 0};
|
||||
setsockopt(sock, SOL_SOCKET, SO_LINGER,
|
||||
reinterpret_cast<const char *>(&opt), sizeof(opt));
|
||||
#endif // defined(_WIN32)
|
||||
});
|
||||
#endif // _WIN32
|
||||
|
||||
server_->listen("127.0.0.1", config_.get_api_port());
|
||||
});
|
||||
|
@@ -24,7 +24,7 @@
|
||||
#include "app_config.hpp"
|
||||
|
||||
namespace repertory {
|
||||
auto create_lock_id(provider_type prov, std::string_view unique_id) {
|
||||
auto create_lock_id(provider_type prov, std::string_view unique_id)->std::string {
|
||||
return fmt::format("{}_{}_{}", REPERTORY_DATA_NAME,
|
||||
app_config::get_provider_name(prov), unique_id);
|
||||
}
|
||||
|
@@ -109,13 +109,17 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server)
|
||||
server_(server) {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
#ifdef _WIN32
|
||||
server_->set_socket_options([](auto &&sock) {
|
||||
int enable = 1;
|
||||
#if defined(_WIN32)
|
||||
int enable{1};
|
||||
setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
|
||||
reinterpret_cast<const char *>(&enable), sizeof(enable));
|
||||
#else // !defined(_WIN32)
|
||||
linger opt{1, 0};
|
||||
setsockopt(sock, SOL_SOCKET, SO_LINGER,
|
||||
reinterpret_cast<const char *>(&opt), sizeof(opt));
|
||||
#endif // defined(_WIN32)
|
||||
});
|
||||
#endif // _WIN32
|
||||
|
||||
server_->set_pre_routing_handler(
|
||||
[this](const httplib::Request &req,
|
||||
|
@@ -25,8 +25,8 @@
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace repertory::utils {
|
||||
auto compare_version_strings(std::string version1,
|
||||
std::string version2) -> std::int32_t {
|
||||
auto compare_version_strings(std::string version1, std::string version2)
|
||||
-> std::int32_t {
|
||||
|
||||
if (utils::string::contains(version1, "-")) {
|
||||
version1 = utils::string::split(version1, '-', true)[0U];
|
||||
@@ -157,7 +157,7 @@ auto get_next_available_port(std::uint16_t first_port,
|
||||
++check_port;
|
||||
continue;
|
||||
}
|
||||
|
||||
acceptor.set_option(boost::asio::ip::tcp::acceptor::linger(true, 0));
|
||||
acceptor.bind({tcp::v4(), static_cast<std::uint16_t>(check_port)},
|
||||
error_code);
|
||||
if (error_code) {
|
||||
|
Reference in New Issue
Block a user