prevent overlapping api ports
This commit is contained in:
parent
e3d036fcb8
commit
630c3463d8
@ -43,8 +43,7 @@ public:
|
||||
[[nodiscard]] static auto default_remote_api_port(const provider_type &prov)
|
||||
-> std::uint16_t;
|
||||
|
||||
[[nodiscard]] static auto default_rpc_port(const provider_type &prov)
|
||||
-> std::uint16_t;
|
||||
[[nodiscard]] static auto default_rpc_port() -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] static auto get_provider_display_name(const provider_type &prov)
|
||||
-> std::string;
|
||||
|
@ -67,7 +67,7 @@ app_config::app_config(const provider_type &prov,
|
||||
std::string_view data_directory)
|
||||
: prov_(prov),
|
||||
api_password_(utils::generate_random_string(default_api_password_size)),
|
||||
api_port_(default_rpc_port(prov)),
|
||||
api_port_(default_rpc_port()),
|
||||
api_user_(std::string{REPERTORY}),
|
||||
config_changed_(false),
|
||||
download_timeout_secs_(default_download_timeout_secs),
|
||||
@ -743,17 +743,7 @@ auto app_config::default_remote_api_port(const provider_type &prov)
|
||||
return PROVIDER_REMOTE_PORTS.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
|
||||
auto app_config::default_rpc_port(const provider_type &prov) -> std::uint16_t {
|
||||
static const std::array<std::uint16_t,
|
||||
static_cast<std::size_t>(provider_type::unknown)>
|
||||
PROVIDER_RPC_PORTS = {
|
||||
10000U,
|
||||
10010U,
|
||||
10100U,
|
||||
10002U,
|
||||
};
|
||||
return PROVIDER_RPC_PORTS.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
auto app_config::default_rpc_port() -> std::uint16_t { return 10000U; }
|
||||
|
||||
auto app_config::get_api_password() const -> std::string {
|
||||
return api_password_;
|
||||
|
@ -29,8 +29,6 @@
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
#include "utils/com_init_wrapper.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "drives/winfsp/remotewinfsp/remote_client.hpp"
|
||||
@ -62,125 +60,112 @@ mount(std::vector<const char *> args, std::string data_directory,
|
||||
lock_data lock(prov, unique_id);
|
||||
const auto res = lock.grab_lock();
|
||||
if (res == lock_result::locked) {
|
||||
ret = exit_code::mount_active;
|
||||
std::cerr << app_config::get_provider_display_name(prov)
|
||||
<< " mount is already active" << std::endl;
|
||||
} else if (res == lock_result::success) {
|
||||
const auto generate_config = utils::cli::has_option(
|
||||
args, utils::cli::options::generate_config_option);
|
||||
if (generate_config) {
|
||||
app_config config(prov, data_directory);
|
||||
if (prov == provider_type::remote) {
|
||||
auto cfg = config.get_remote_config();
|
||||
cfg.host_name_or_ip = remote_host;
|
||||
cfg.api_port = remote_port;
|
||||
config.set_remote_config(cfg);
|
||||
} else if (prov == provider_type::sia &&
|
||||
config.get_sia_config().bucket.empty()) {
|
||||
[[maybe_unused]] auto bucket =
|
||||
config.set_value_by_name("SiaConfig.Bucket", unique_id);
|
||||
}
|
||||
return exit_code::mount_active;
|
||||
}
|
||||
|
||||
std::cout << "Generated " << app_config::get_provider_display_name(prov)
|
||||
<< " Configuration" << std::endl;
|
||||
std::cout << config.get_config_file_path() << std::endl;
|
||||
ret = utils::file::file(config.get_config_file_path()).exists()
|
||||
? exit_code::success
|
||||
: exit_code::file_creation_failed;
|
||||
} else {
|
||||
#if defined(_WIN32)
|
||||
if (utils::cli::has_option(args, utils::cli::options::hidden_option)) {
|
||||
::ShowWindow(::GetConsoleWindow(), SW_HIDE);
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
auto drive_args =
|
||||
utils::cli::parse_drive_options(args, prov, data_directory);
|
||||
app_config config(prov, data_directory);
|
||||
#if defined(_WIN32)
|
||||
if (config.get_enable_mount_manager() &&
|
||||
not utils::is_process_elevated()) {
|
||||
utils::com_init_wrapper cw;
|
||||
if (not lock.set_mount_state(true, "elevating", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
lock.release();
|
||||
|
||||
mount_result = utils::run_process_elevated(args);
|
||||
lock_data lock2(prov, unique_id);
|
||||
if (lock2.grab_lock() == lock_result::success) {
|
||||
if (not lock2.set_mount_state(false, "", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
lock2.release();
|
||||
}
|
||||
|
||||
return exit_code::mount_result;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
std::cout << "Initializing "
|
||||
<< app_config::get_provider_display_name(prov)
|
||||
<< (unique_id.empty() ? ""
|
||||
: (prov == provider_type::remote)
|
||||
? " [" + remote_host + ':' +
|
||||
std::to_string(remote_port) + ']'
|
||||
: " [" + unique_id + ']')
|
||||
<< " Drive" << std::endl;
|
||||
if (prov == provider_type::remote) {
|
||||
std::uint16_t port{0U};
|
||||
if (utils::get_next_available_port(config.get_api_port(), port)) {
|
||||
auto cfg = config.get_remote_config();
|
||||
cfg.host_name_or_ip = remote_host;
|
||||
cfg.api_port = remote_port;
|
||||
config.set_remote_config(cfg);
|
||||
config.set_api_port(port);
|
||||
|
||||
try {
|
||||
remote_drive drive(
|
||||
config,
|
||||
[&config]() -> std::unique_ptr<remote_instance> {
|
||||
return std::unique_ptr<remote_instance>(
|
||||
new remote_client(config));
|
||||
},
|
||||
lock);
|
||||
if (not lock.set_mount_state(true, "", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
mount_result = drive.mount(drive_args);
|
||||
ret = exit_code::mount_result;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "FATAL: " << e.what() << std::endl;
|
||||
ret = exit_code::startup_exception;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "FATAL: Unable to get available port" << std::endl;
|
||||
ret = exit_code::startup_exception;
|
||||
}
|
||||
} else {
|
||||
if (prov == provider_type::sia &&
|
||||
config.get_sia_config().bucket.empty()) {
|
||||
[[maybe_unused]] auto bucket =
|
||||
config.set_value_by_name("SiaConfig.Bucket", unique_id);
|
||||
}
|
||||
|
||||
try {
|
||||
auto provider = create_provider(prov, config);
|
||||
repertory_drive drive(config, lock, *provider);
|
||||
if (not lock.set_mount_state(true, "", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
mount_result = drive.mount(drive_args);
|
||||
ret = exit_code::mount_result;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "FATAL: " << e.what() << std::endl;
|
||||
ret = exit_code::startup_exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (res != lock_result::success) {
|
||||
ret = exit_code::lock_failed;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#if defined(_WIN32)
|
||||
if (utils::cli::has_option(args, utils::cli::options::hidden_option)) {
|
||||
::ShowWindow(::GetConsoleWindow(), SW_HIDE);
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
auto drive_args = utils::cli::parse_drive_options(args, prov, data_directory);
|
||||
app_config config(prov, data_directory);
|
||||
{
|
||||
std::uint16_t port{};
|
||||
if (not utils::get_next_available_port(config.get_api_port(), port)) {
|
||||
std::cerr << "FATAL: Unable to get available port" << std::endl;
|
||||
return exit_code::startup_exception;
|
||||
}
|
||||
|
||||
config.set_api_port(port);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (config.get_enable_mount_manager() && not utils::is_process_elevated()) {
|
||||
utils::com_init_wrapper wrapper;
|
||||
if (not lock.set_mount_state(true, "elevating", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
lock.release();
|
||||
|
||||
mount_result = utils::run_process_elevated(args);
|
||||
lock_data prov_lock(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;
|
||||
}
|
||||
prov_lock.release();
|
||||
}
|
||||
|
||||
return exit_code::mount_result;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
std::cout << "Initializing " << app_config::get_provider_display_name(prov)
|
||||
<< (unique_id.empty() ? ""
|
||||
: (prov == provider_type::remote)
|
||||
? " [" + remote_host + ':' + std::to_string(remote_port) +
|
||||
']'
|
||||
: " [" + unique_id + ']')
|
||||
<< " Drive" << std::endl;
|
||||
if (prov == provider_type::remote) {
|
||||
std::uint16_t port{};
|
||||
if (not utils::get_next_available_port(config.get_remote_config().api_port,
|
||||
port)) {
|
||||
std::cerr << "FATAL: Unable to get available port" << std::endl;
|
||||
return exit_code::startup_exception;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
try {
|
||||
remote_drive drive(
|
||||
config,
|
||||
[&config]() -> std::unique_ptr<remote_instance> {
|
||||
return std::unique_ptr<remote_instance>(new remote_client(config));
|
||||
},
|
||||
lock);
|
||||
if (not lock.set_mount_state(true, "", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
|
||||
mount_result = drive.mount(drive_args);
|
||||
return exit_code::mount_result;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "FATAL: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return exit_code::startup_exception;
|
||||
}
|
||||
|
||||
if (prov == provider_type::sia && config.get_sia_config().bucket.empty()) {
|
||||
[[maybe_unused]] auto bucket =
|
||||
config.set_value_by_name("SiaConfig.Bucket", unique_id);
|
||||
}
|
||||
|
||||
try {
|
||||
auto provider = create_provider(prov, config);
|
||||
repertory_drive drive(config, lock, *provider);
|
||||
if (not lock.set_mount_state(true, "", -1)) {
|
||||
std::cerr << "failed to set mount state" << std::endl;
|
||||
}
|
||||
mount_result = drive.mount(drive_args);
|
||||
return exit_code::mount_result;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "FATAL: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return exit_code::startup_exception;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
|
@ -505,6 +505,9 @@ void handlers::handle_post_mount(const httplib::Request &req,
|
||||
return;
|
||||
}
|
||||
|
||||
static std::mutex mount_mtx;
|
||||
mutex_lock lock(mount_mtx);
|
||||
|
||||
launch_process(prov, name, {location}, true);
|
||||
config_->set_mount_location(prov, name, location);
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ std::atomic<std::uint64_t> app_config_test::idx{0U};
|
||||
|
||||
static void defaults_tests(const json &json_data, provider_type prov) {
|
||||
json json_defaults = {
|
||||
{JSON_API_PORT, app_config::default_rpc_port(prov)},
|
||||
{JSON_API_PORT, app_config::default_rpc_port()},
|
||||
{JSON_API_USER, std::string{REPERTORY}},
|
||||
{JSON_DOWNLOAD_TIMEOUT_SECS, default_download_timeout_secs},
|
||||
{JSON_DATABASE_TYPE, database_type::rocksdb},
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -111,10 +112,19 @@ class MountList with ChangeNotifier {
|
||||
Future<bool> add(
|
||||
String type,
|
||||
String name,
|
||||
Map<String, dynamic> mountConfig,
|
||||
Map<String, dynamic> settings,
|
||||
) async {
|
||||
var ret = false;
|
||||
|
||||
var apiPort = settings['ApiPort'] ?? 10000;
|
||||
for (var mount in _mountList) {
|
||||
var port = mount.mountConfig.settings['ApiPort'] as int?;
|
||||
if (port != null) {
|
||||
apiPort = max(apiPort, port + 1);
|
||||
}
|
||||
}
|
||||
settings["ApiPort"] = apiPort;
|
||||
|
||||
displayError() {
|
||||
if (constants.navigatorKey.currentContext == null) {
|
||||
return;
|
||||
@ -129,7 +139,7 @@ class MountList with ChangeNotifier {
|
||||
try {
|
||||
final auth = await _auth.createAuth();
|
||||
final map = await convertAllToString(
|
||||
jsonDecode(jsonEncode(mountConfig)),
|
||||
jsonDecode(jsonEncode(settings)),
|
||||
_auth.key,
|
||||
);
|
||||
final response = await http.post(
|
||||
|
Loading…
x
Reference in New Issue
Block a user