added check version support to remote mounts
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
### Changes from v2.0.7-release
|
### Changes from v2.0.7-release
|
||||||
|
|
||||||
|
* Added check version support to remote mounts
|
||||||
* Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux
|
* Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux
|
||||||
* Fixed intermittent client hang on remote mount server disconnect
|
* Fixed intermittent client hang on remote mount server disconnect
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ private:
|
|||||||
|
|
||||||
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
||||||
|
|
||||||
[[nodiscard]] auto handshake(client &cli) const -> bool;
|
[[nodiscard]] auto handshake(client &cli, std::uint32_t &min_version) const
|
||||||
|
-> bool;
|
||||||
|
|
||||||
void put_client(std::shared_ptr<client> &cli);
|
void put_client(std::shared_ptr<client> &cli);
|
||||||
|
|
||||||
@@ -78,6 +79,9 @@ private:
|
|||||||
void resolve();
|
void resolve();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
[[nodiscard]] auto check_version(std::uint32_t client_version,
|
||||||
|
std::uint32_t &min_version) -> api_error;
|
||||||
|
|
||||||
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
|
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
|
||||||
-> packet::error_type;
|
-> packet::error_type;
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ create_rocksdb(const app_config &cfg, const std::string &name,
|
|||||||
[[nodiscard]] auto create_volume_label(provider_type prov) -> std::string;
|
[[nodiscard]] auto create_volume_label(provider_type prov) -> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD;
|
[[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_version_number(std::string_view version)
|
||||||
|
-> std::uint32_t;
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include "utils/collection.hpp"
|
#include "utils/collection.hpp"
|
||||||
#include "utils/common.hpp"
|
#include "utils/common.hpp"
|
||||||
#include "utils/error_utils.hpp"
|
#include "utils/error_utils.hpp"
|
||||||
#include "version.hpp"
|
|
||||||
|
|
||||||
using namespace repertory::comm;
|
using namespace repertory::comm;
|
||||||
|
|
||||||
@@ -58,7 +57,8 @@ void packet_client::close(client &cli) {
|
|||||||
|
|
||||||
boost::system::error_code err;
|
boost::system::error_code err;
|
||||||
[[maybe_unused]] auto res = cli.socket.close(err);
|
[[maybe_unused]] auto res = cli.socket.close(err);
|
||||||
} catch (...) {
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::raise_error(function_name, e, "connection handshake failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +76,39 @@ void packet_client::close_all() {
|
|||||||
unique_id_ = utils::create_uuid_string();
|
unique_id_ = utils::create_uuid_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto packet_client::check_version(std::uint32_t client_version,
|
||||||
|
std::uint32_t &min_version) -> api_error {
|
||||||
|
try {
|
||||||
|
min_version = 0U;
|
||||||
|
|
||||||
|
boost::asio::io_context ctx{};
|
||||||
|
auto resolve_results = tcp::resolver(ctx).resolve(
|
||||||
|
cfg_.host_name_or_ip, std::to_string(cfg_.api_port));
|
||||||
|
|
||||||
|
client cli(ctx);
|
||||||
|
connect_with_deadline(ctx, cli.socket, resolve_results,
|
||||||
|
std::chrono::milliseconds(cfg_.conn_timeout_ms));
|
||||||
|
|
||||||
|
cli.socket.set_option(boost::asio::ip::tcp::no_delay(true));
|
||||||
|
cli.socket.set_option(boost::asio::socket_base::linger(false, 0));
|
||||||
|
cli.socket.set_option(boost::asio::socket_base::keep_alive(true));
|
||||||
|
|
||||||
|
if (not handshake(cli, min_version)) {
|
||||||
|
return api_error::comm_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_version < min_version) {
|
||||||
|
return api_error::incompatible_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api_error::success;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::raise_error(function_name, e, "connection handshake failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return api_error::error;
|
||||||
|
}
|
||||||
|
|
||||||
void packet_client::connect(client &cli) {
|
void packet_client::connect(client &cli) {
|
||||||
try {
|
try {
|
||||||
resolve();
|
resolve();
|
||||||
@@ -87,7 +120,8 @@ void packet_client::connect(client &cli) {
|
|||||||
cli.socket.set_option(boost::asio::socket_base::linger(false, 0));
|
cli.socket.set_option(boost::asio::socket_base::linger(false, 0));
|
||||||
cli.socket.set_option(boost::asio::socket_base::keep_alive(true));
|
cli.socket.set_option(boost::asio::socket_base::keep_alive(true));
|
||||||
|
|
||||||
if (not handshake(cli)) {
|
std::uint32_t min_version{};
|
||||||
|
if (not handshake(cli, min_version)) {
|
||||||
close(cli);
|
close(cli);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,14 +165,18 @@ auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto packet_client::handshake(client &cli) const -> bool {
|
auto packet_client::handshake(client &cli, std::uint32_t &min_version) const
|
||||||
|
-> bool {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
min_version = 0U;
|
||||||
|
|
||||||
data_buffer buffer;
|
data_buffer buffer;
|
||||||
{
|
{
|
||||||
packet tmp;
|
packet tmp;
|
||||||
tmp.encode_top(utils::generate_random_string(packet_nonce_size));
|
tmp.encode(utils::get_version_number(REPERTORY_MIN_REMOTE_VERSION));
|
||||||
|
tmp.encode(utils::generate_random_string(packet_nonce_size));
|
||||||
tmp.to_buffer(buffer);
|
tmp.to_buffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +184,7 @@ auto packet_client::handshake(client &cli) const -> bool {
|
|||||||
boost::asio::buffer(buffer),
|
boost::asio::buffer(buffer),
|
||||||
std::chrono::milliseconds(cfg_.recv_timeout_ms));
|
std::chrono::milliseconds(cfg_.recv_timeout_ms));
|
||||||
packet response(buffer);
|
packet response(buffer);
|
||||||
|
response.decode(min_version);
|
||||||
response.encrypt(cfg_.encryption_token, false);
|
response.encrypt(cfg_.encryption_token, false);
|
||||||
response.to_buffer(buffer);
|
response.to_buffer(buffer);
|
||||||
|
|
||||||
@@ -154,7 +193,7 @@ auto packet_client::handshake(client &cli) const -> bool {
|
|||||||
std::chrono::milliseconds(cfg_.send_timeout_ms));
|
std::chrono::milliseconds(cfg_.send_timeout_ms));
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
repertory::utils::error::raise_error(function_name, e, "handlshake failed");
|
utils::error::raise_error(function_name, e, "handlshake failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -32,12 +32,12 @@
|
|||||||
#include "types/repertory.hpp"
|
#include "types/repertory.hpp"
|
||||||
#include "utils/error_utils.hpp"
|
#include "utils/error_utils.hpp"
|
||||||
#include "utils/timeout.hpp"
|
#include "utils/timeout.hpp"
|
||||||
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
using namespace repertory::comm;
|
using namespace repertory::comm;
|
||||||
using std::thread;
|
using std::thread;
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
|
|
||||||
packet_server::packet_server(std::uint16_t port, std::string token,
|
packet_server::packet_server(std::uint16_t port, std::string token,
|
||||||
std::uint8_t pool_size, closed_callback closed,
|
std::uint8_t pool_size, closed_callback closed,
|
||||||
message_handler_callback message_handler)
|
message_handler_callback message_handler)
|
||||||
@@ -91,7 +91,8 @@ auto packet_server::handshake(std::shared_ptr<connection> conn) const -> bool {
|
|||||||
|
|
||||||
data_buffer buffer;
|
data_buffer buffer;
|
||||||
packet request;
|
packet request;
|
||||||
request.encode_top(conn->nonce);
|
request.encode(utils::get_version_number(REPERTORY_MIN_REMOTE_VERSION));
|
||||||
|
request.encode(conn->nonce);
|
||||||
request.to_buffer(buffer);
|
request.to_buffer(buffer);
|
||||||
auto to_read{buffer.size() + utils::encryption::encryption_header_size};
|
auto to_read{buffer.size() + utils::encryption::encryption_header_size};
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "rocksdb/table.h"
|
|
||||||
|
|
||||||
#include "utils/utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
#include "app_config.hpp"
|
#include "app_config.hpp"
|
||||||
@@ -90,4 +88,13 @@ auto create_volume_label(provider_type prov) -> std::string {
|
|||||||
auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD {
|
auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD {
|
||||||
return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES)));
|
return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto get_repertory_version_number(std::string_view version) -> std::uint32_t {
|
||||||
|
auto parts = utils::string::split(version, '-', false);
|
||||||
|
parts = utils::string::split(parts.at(0U), '.', false);
|
||||||
|
|
||||||
|
return (utils::string::to_uint32(parts.at(0U)) << 24U) |
|
||||||
|
(utils::string::to_uint32(parts.at(1U)) << 16U) |
|
||||||
|
(utils::string::to_uint32(parts.at(2U)) << 8U);
|
||||||
|
}
|
||||||
} // namespace repertory::utils
|
} // namespace repertory::utils
|
||||||
|
|||||||
@@ -23,16 +23,40 @@
|
|||||||
#define REPERTORY_INCLUDE_CLI_CHECK_VERSION_HPP_
|
#define REPERTORY_INCLUDE_CLI_CHECK_VERSION_HPP_
|
||||||
|
|
||||||
#include "cli/common.hpp"
|
#include "cli/common.hpp"
|
||||||
|
#include "comm/packet/packet_client.hpp"
|
||||||
|
#include "utils/utils.hpp"
|
||||||
|
#include "version.cpp"
|
||||||
|
|
||||||
namespace repertory::cli::actions {
|
namespace repertory::cli::actions {
|
||||||
[[nodiscard]] inline auto check_version(std::vector<const char *> /* args */,
|
[[nodiscard]] inline auto
|
||||||
const std::string &data_directory,
|
check_version(const std::string &data_directory, provider_type prov,
|
||||||
provider_type prov,
|
const std::string &remote_host, std::uint16_t remote_port)
|
||||||
const std::string & /*unique_id*/,
|
-> exit_code {
|
||||||
std::string /*user*/,
|
if (prov == provider_type::remote) {
|
||||||
std::string /*password*/) -> exit_code {
|
app_config config(prov, data_directory);
|
||||||
|
auto remote_cfg = config.get_remote_config();
|
||||||
|
remote_cfg.host_name_or_ip = remote_host;
|
||||||
|
remote_cfg.api_port = remote_port;
|
||||||
|
config.set_remote_config(remote_cfg);
|
||||||
|
packet_client client(config.get_remote_config());
|
||||||
|
|
||||||
|
std::uint32_t min_version{};
|
||||||
|
auto client_version = utils::get_version_number(project_get_version());
|
||||||
|
auto ret = client.check_version(client_version, min_version);
|
||||||
|
if (ret == 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 ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (prov != provider_type::sia) {
|
if (prov != provider_type::sia) {
|
||||||
fmt::println("Success:\n\tNo specific version is required for {} providers",
|
fmt::println(
|
||||||
|
"0\nSuccess:\n\tNo specific version is required for {} providers",
|
||||||
app_config::get_provider_display_name(prov));
|
app_config::get_provider_display_name(prov));
|
||||||
return exit_code::success;
|
return exit_code::success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ auto main(int argc, char **argv) -> int {
|
|||||||
'_'),
|
'_'),
|
||||||
})
|
})
|
||||||
: utils::path::absolute(data_directory);
|
: utils::path::absolute(data_directory);
|
||||||
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << (e.what() == nullptr ? "Unable to parse port"
|
std::cerr << (e.what() == nullptr ? "Unable to parse port"
|
||||||
: e.what())
|
: e.what())
|
||||||
@@ -145,6 +146,11 @@ auto main(int argc, char **argv) -> int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (utils::cli::has_option(args,
|
||||||
|
utils::cli::options::check_version_option)) {
|
||||||
|
ret = static_cast<std::int32_t>(utils::cli::check_version(
|
||||||
|
data_directory, prov, remote_host, remote_port));
|
||||||
|
} else {
|
||||||
int mount_result{};
|
int mount_result{};
|
||||||
if (res == exit_code::success) {
|
if (res == exit_code::success) {
|
||||||
res = exit_code::option_not_found;
|
res = exit_code::option_not_found;
|
||||||
@@ -154,8 +160,8 @@ auto main(int argc, char **argv) -> int {
|
|||||||
idx++) {
|
idx++) {
|
||||||
try {
|
try {
|
||||||
res = cli::actions::perform_action(
|
res = cli::actions::perform_action(
|
||||||
utils::cli::options::option_list[idx], args, data_directory, prov,
|
utils::cli::options::option_list[idx], args, data_directory,
|
||||||
unique_id, user, password);
|
prov, unique_id, user, password);
|
||||||
} catch (const std::exception &ex) {
|
} catch (const std::exception &ex) {
|
||||||
res = exit_code::exception;
|
res = exit_code::exception;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -172,6 +178,7 @@ auto main(int argc, char **argv) -> int {
|
|||||||
ret = ((res == exit_code::mount_result) ? mount_result
|
ret = ((res == exit_code::mount_result) ? mount_result
|
||||||
: static_cast<std::int32_t>(res));
|
: static_cast<std::int32_t>(res));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
repertory::project_cleanup();
|
repertory::project_cleanup();
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
Reference in New Issue
Block a user