diff --git a/ydb/core/config/init/init.cpp b/ydb/core/config/init/init.cpp index 18da922dbbc2..4724d83696cf 100644 --- a/ydb/core/config/init/init.cpp +++ b/ydb/core/config/init/init.cpp @@ -1,6 +1,7 @@ #include "init_impl.h" #include "mock.h" #include +#include namespace NKikimr::NConfig { @@ -202,22 +203,7 @@ class TDefaultNodeBrokerClient const TString& nodeRegistrationToken, const IEnv& env) { - TCommandConfig::TServerEndpoint endpoint = TCommandConfig::ParseServerAddress(addr); - NYdb::TDriverConfig config; - if (endpoint.EnableSsl.Defined() && endpoint.EnableSsl.GetRef()) { - if (grpcSettings.PathToGrpcCaFile) { - config.UseSecureConnection(env.ReadFromFile(grpcSettings.PathToGrpcCaFile, "CA certificates").c_str()); - } - if (grpcSettings.PathToGrpcCertFile && grpcSettings.PathToGrpcPrivateKeyFile) { - auto certificate = env.ReadFromFile(grpcSettings.PathToGrpcCertFile, "Client certificates"); - auto privateKey = env.ReadFromFile(grpcSettings.PathToGrpcPrivateKeyFile, "Client certificates key"); - config.UseClientCertificate(certificate.c_str(), privateKey.c_str()); - } - } - if (nodeRegistrationToken) { - config.SetAuthToken(nodeRegistrationToken); - } - config.SetEndpoint(endpoint.Address); + NYdb::TDriverConfig config = CreateDriverConfig(grpcSettings, addr, env, nodeRegistrationToken); auto connection = NYdb::TDriver(config); auto client = NYdb::NDiscovery::TDiscoveryClient(connection); @@ -339,6 +325,73 @@ class TDynConfigResultWrapper } }; +namespace { + +struct RetryResult { + bool Success; + int TotalAttempts; + int Rounds; +}; + +template +RetryResult RetryWithJitter( + const TVector& addrs, + const IEnv& env, + TAttemptFn attempt) +{ + const int maxRounds = 10; + const TDuration baseRoundDelay = TDuration::MilliSeconds(500); + const TDuration maxIntraAddrDelay = TDuration::Minutes(3); + const TDuration maxDelay = TDuration::Minutes(5); + const TDuration baseAddressDelay = TDuration::MilliSeconds(250); + + auto sleepWithJitteredExponentialDelay = [&env](TDuration baseDelay, TDuration maxDelay, int exponent) { + ui64 multiplier = 1ULL << exponent; + TDuration delay = baseDelay * multiplier; + delay = Min(delay, maxDelay); + + ui64 maxMs = delay.MilliSeconds(); + ui64 jitteredMs = RandomNumber(maxMs + 1); + TDuration jitteredDelay = TDuration::MilliSeconds(jitteredMs); + + env.Sleep(jitteredDelay); + }; + + int round = 0; + int totalAttempts = 0; + bool success = false; + + while (!success && round < maxRounds) { + int addressIndex = 0; + for (const auto& addr : addrs) { + success = attempt(addr); + ++totalAttempts; + + if (success) { + break; + } + + // Exponential delay between individual addresses - delay grows with each address in the round + if (addrs.size() > 1) { + sleepWithJitteredExponentialDelay(baseAddressDelay, maxIntraAddrDelay, Max(addressIndex, round)); + } + + ++addressIndex; + } + + if (!success) { + ++round; + + if (round < maxRounds) { + sleepWithJitteredExponentialDelay(baseRoundDelay, maxDelay, round - 1); + } + } + } + return {success, totalAttempts, round}; +} + +} // namespace + class TDefaultDynConfigClient : public IDynConfigClient { @@ -390,36 +443,128 @@ class TDefaultDynConfigClient IInitLogger& logger) const override { std::shared_ptr res; - bool success = false; TString error; SetRandomSeed(TInstant::Now().MicroSeconds()); - int minAttempts = 10; - int attempts = 0; - while (!success && attempts < minAttempts) { - for (auto addr : addrs) { - success = TryToLoadConfigForDynamicNodeFromCMS(grpcSettings, addr, settings, env, logger, res, error); - ++attempts; - if (success) { - break; - } - } - // Randomized backoff - if (!success) { - env.Sleep(TDuration::MilliSeconds(500 + RandomNumber(1000))); - } else { - break; + + auto attempt = [&](const TString& addr) { + logger.Out() << "Trying to get dynamic config from " << addr << Endl; + bool success = TryToLoadConfigForDynamicNodeFromCMS(grpcSettings, addr, settings, env, logger, res, error); + if (success) { + logger.Out() << "Success. Got dynamic config from " << addr << Endl; } - } + return success; + }; - if (!success) { - logger.Err() << "WARNING: couldn't load config from CMS: " << error << Endl; + const auto result = RetryWithJitter(addrs, env, attempt); + + if (!result.Success) { + logger.Err() << "WARNING: couldn't load config from Console after " + << result.TotalAttempts << " attempts across " << result.Rounds + << " rounds: " << error << Endl; } return res; } }; +class TConfigResultWrapper + : public IStorageConfigResult +{ +public: + TConfigResultWrapper(const NYdb::NConfig::TFetchConfigResult& result) { + TString clusterConfig; + TString storageConfig; + for (const auto& entry : result.GetConfigs()) { + std::visit([&](auto&& arg) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + MainYamlConfig = entry.Config; + } else if constexpr (std::is_same_v) { + StorageYamlConfig = entry.Config; + } + }, entry.Identity); + } + } + + const TString& GetMainYamlConfig() const override { + return MainYamlConfig; + } + + const TString& GetStorageYamlConfig() const override { + return StorageYamlConfig; + } + +private: + TString MainYamlConfig; + TString StorageYamlConfig; +}; + +class TDefaultConfigClient + : public IConfigClient +{ +private: + static NYdb::NConfig::TFetchConfigResult TryToFetchConfig( + const TGrpcSslSettings& grpcSettings, + const TString& addrs, + const IEnv& env) + { + + NYdb::TDriverConfig config = CreateDriverConfig(grpcSettings, addrs, env); + + auto connection = NYdb::TDriver(config); + + auto client = NYdb::NConfig::TConfigClient(connection); + NYdb::NConfig::TFetchConfigResult result = client.FetchAllConfigs().GetValueSync(); + connection.Stop(true); + return result; + } + + static NYdb::NConfig::TFetchConfigResult FetchConfigImpl( + const TGrpcSslSettings& grpcSettings, + const TVector& addrs, + const IEnv& env, + IInitLogger& logger) + { + std::optional result; + SetRandomSeed(TInstant::Now().MicroSeconds()); + + auto attempt = [&](const TString& addr) { + logger.Out() << "Trying to fetch config from " << addr << Endl; + result = TryToFetchConfig(grpcSettings, addr, env); + if (result->IsSuccess()) { + logger.Out() << "Success. Fetched config from " << addr << Endl; + return true; + } + logger.Err() << "Fetch config error: " << static_cast(*result) << Endl; + return false; + }; + + const auto retryResult = RetryWithJitter(addrs, env, attempt); + + if (!retryResult.Success) { + logger.Err() << "WARNING: couldn't fetch config from Console after " + << retryResult.TotalAttempts << " attempts across " << retryResult.Rounds + << " rounds. Last error: " << static_cast(*result) << Endl; + } + return *result; + } + +public: + std::shared_ptr FetchConfig( + const TGrpcSslSettings& grpcSettings, + const TVector& addrs, + const IEnv& env, + IInitLogger& logger) const override + { + auto result = FetchConfigImpl(grpcSettings, addrs, env, logger); + if (!result.IsSuccess()) { + return nullptr; + } + return std::make_shared(std::move(result)); + } +}; + class TDefaultInitLogger : public IInitLogger { @@ -461,6 +606,10 @@ std::unique_ptr MakeDefaultDynConfigClient() { return std::make_unique(); } +std::unique_ptr MakeDefaultConfigClient() { + return std::make_unique(); +} + std::unique_ptr MakeDefaultInitLogger() { return std::make_unique(); } @@ -770,6 +919,27 @@ NKikimrConfig::TAppConfig GetActualDynConfig( return regularConfig; } +NYdb::TDriverConfig CreateDriverConfig(const TGrpcSslSettings& grpcSettings, const TString& addr, const IEnv& env, const std::optional& authToken) { + TCommandConfig::TServerEndpoint endpoint = TCommandConfig::ParseServerAddress(addr); + NYdb::TDriverConfig config; + if (endpoint.EnableSsl.Defined() && endpoint.EnableSsl.GetRef()) { + if (grpcSettings.PathToGrpcCaFile) { + config.UseSecureConnection(env.ReadFromFile(grpcSettings.PathToGrpcCaFile, "CA certificates").c_str()); + } + if (grpcSettings.PathToGrpcCertFile && grpcSettings.PathToGrpcPrivateKeyFile) { + auto certificate = env.ReadFromFile(grpcSettings.PathToGrpcCertFile, "Client certificates"); + auto privateKey = env.ReadFromFile(grpcSettings.PathToGrpcPrivateKeyFile, "Client certificates key"); + config.UseClientCertificate(certificate.c_str(), privateKey.c_str()); + } + } + if (authToken) { + config.SetAuthToken(authToken.value()); + } + config.SetEndpoint(endpoint.Address); + + return config; +} + std::unique_ptr MakeDefaultInitialConfigurator(TInitialConfiguratorDependencies deps) { return std::make_unique(deps); } @@ -781,6 +951,7 @@ class TInitialConfiguratorDepsRecorder TProtoConfigFileProviderRecorder ProtoConfigFileProvider; TNodeBrokerClientRecorder NodeBrokerClient; TDynConfigClientRecorder DynConfigClient; + TConfigClientRecorder ConfigClient; TEnvRecorder Env; public: TInitialConfiguratorDepsRecorder(TInitialConfiguratorDependencies deps) @@ -788,6 +959,7 @@ class TInitialConfiguratorDepsRecorder , ProtoConfigFileProvider(deps.ProtoConfigFileProvider) , NodeBrokerClient(deps.NodeBrokerClient) , DynConfigClient(deps.DynConfigClient) + , ConfigClient(deps.ConfigClient) , Env(deps.Env) {} @@ -799,6 +971,7 @@ class TInitialConfiguratorDepsRecorder .MemLogInit = Impls.MemLogInit, .NodeBrokerClient = NodeBrokerClient, .DynConfigClient = DynConfigClient, + .ConfigClient = ConfigClient, .Env = Env, .Logger = Impls.Logger, }; @@ -812,6 +985,7 @@ class TInitialConfiguratorDepsRecorder .MemLogInit = MakeNoopMemLogInitializer(), .NodeBrokerClient = std::make_unique(NodeBrokerClient.GetMock()), .DynConfigClient = std::make_unique(DynConfigClient.GetMock()), + .ConfigClient = std::make_unique(ConfigClient.GetMock()), .Env = std::make_unique(Env.GetMock()), .Logger = MakeNoopInitLogger(), }; diff --git a/ydb/core/config/init/init.h b/ydb/core/config/init/init.h index b1c00ceab0db..415b5d73ee57 100644 --- a/ydb/core/config/init/init.h +++ b/ydb/core/config/init/init.h @@ -177,6 +177,25 @@ class IDynConfigClient { // === +class IStorageConfigResult { +public: + virtual ~IStorageConfigResult() {} + virtual const TString& GetMainYamlConfig() const = 0; + virtual const TString& GetStorageYamlConfig() const = 0; +}; + +class IConfigClient { +public: + virtual ~IConfigClient() {} + virtual std::shared_ptr FetchConfig( + const TGrpcSslSettings& grpcSettings, + const TVector& addrs, + const IEnv& env, + IInitLogger& logger) const = 0; +}; + +// === + struct TInitialConfiguratorDependencies { NConfig::IErrorCollector& ErrorCollector; NConfig::IProtoConfigFileProvider& ProtoConfigFileProvider; @@ -184,6 +203,7 @@ struct TInitialConfiguratorDependencies { NConfig::IMemLogInitializer& MemLogInit; NConfig::INodeBrokerClient& NodeBrokerClient; NConfig::IDynConfigClient& DynConfigClient; + NConfig::IConfigClient& ConfigClient; NConfig::IEnv& Env; NConfig::IInitLogger& Logger; }; @@ -197,6 +217,7 @@ struct TRecordedInitialConfiguratorDeps { *MemLogInit, *NodeBrokerClient, *DynConfigClient, + *ConfigClient, *Env, *Logger }; @@ -208,6 +229,7 @@ struct TRecordedInitialConfiguratorDeps { std::unique_ptr MemLogInit; std::unique_ptr NodeBrokerClient; std::unique_ptr DynConfigClient; + std::unique_ptr ConfigClient; std::unique_ptr Env; std::unique_ptr Logger; }; @@ -260,11 +282,13 @@ std::unique_ptr MakeDefaultErrorCollector(); std::unique_ptr MakeDefaultMemLogInitializer(); std::unique_ptr MakeDefaultNodeBrokerClient(); std::unique_ptr MakeDefaultDynConfigClient(); +std::unique_ptr MakeDefaultConfigClient(); std::unique_ptr MakeDefaultInitLogger(); std::unique_ptr MakeNoopMemLogInitializer(); std::unique_ptr MakeNoopNodeBrokerClient(); std::unique_ptr MakeNoopDynConfigClient(); +std::unique_ptr MakeNoopConfigClient(); std::unique_ptr MakeNoopInitLogger(); void AddProtoConfigOptions(IProtoConfigFileProvider& out); diff --git a/ydb/core/config/init/init_impl.h b/ydb/core/config/init/init_impl.h index 4d99c6ae600f..db83ba2d7f43 100644 --- a/ydb/core/config/init/init_impl.h +++ b/ydb/core/config/init/init_impl.h @@ -4,10 +4,12 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -338,6 +340,8 @@ struct TCommonAppOptions { bool TcpEnabled = false; bool SuppressVersionCheck = false; EWorkload Workload = EWorkload::Hybrid; + TString SeedNodesFile; + TVector SeedNodes; void RegisterCliOptions(NLastGetopt::TOpts& opts) { opts.AddLongOption("cluster-name", "which cluster this node belongs to") @@ -435,6 +439,9 @@ struct TCommonAppOptions { opts.AddLongOption("workload", Sprintf("Workload to be served by this node, allowed values are %s", GetEnumAllNames().data())) .RequiredArgument("NAME").StoreResult(&Workload); + + opts.AddLongOption("seed-nodes", "Path to seed nodes configuration file") + .RequiredArgument("PATH").StoreResult(&SeedNodesFile); } void ApplyFields(NKikimrConfig::TAppConfig& appConfig, IEnv& env, IConfigUpdateTracer& ConfigUpdateTracer) const { @@ -874,8 +881,9 @@ struct TCommonAppOptions { }; void FillClusterEndpoints(const NKikimrConfig::TAppConfig& appConfig, TVector &addrs) const { - if (!NodeBrokerAddresses.empty()) { - for (auto addr: NodeBrokerAddresses) { + const TVector& seedAddresses = NodeBrokerAddresses.empty() ? SeedNodes : NodeBrokerAddresses; + if (!seedAddresses.empty()) { + for (auto addr: seedAddresses) { addrs.push_back(addr); } } else { @@ -1019,6 +1027,8 @@ NKikimrConfig::TAppConfig GetActualDynConfig( const NKikimrConfig::TAppConfig& regularConfig, IConfigUpdateTracer& ConfigUpdateTracer); +NYdb::TDriverConfig CreateDriverConfig(const TGrpcSslSettings& settings, const TString& addrs, const IEnv& env, const std::optional& authToken = std::nullopt); + // ===== struct TAppInitDebugInfo { @@ -1086,6 +1096,19 @@ class TInitialConfiguratorImpl } } + if (CommonAppOptions.SeedNodesFile) { + ParseSeedNodes(CommonAppOptions); + } + + if (CommonAppOptions.IsStaticNode()) { + if (yamlConfigFile.empty() && CommonAppOptions.SeedNodesFile) { + InitConfigFromSeedNodes(yamlConfigFile, storageYamlConfigFile); + } + if (!CommonAppOptions.ConfigDirPath.empty() && yamlConfigFile.empty()) { + ythrow yexception() << "YAML config is not provided for static node"; + } + } + LoadMainYamlConfig(refs, yamlConfigFile, storageYamlConfigFile, loadedFromStore, AppConfig, csk); OptionMerge("auth-token-file", TCfg::TAuthConfigFieldTag{}); @@ -1411,6 +1434,103 @@ class TInitialConfiguratorImpl debugInfo.OldDynConfig.CopyFrom(InitDebug.OldConfig); debugInfo.NewDynConfig.CopyFrom(InitDebug.YamlConfig); } + + void ParseSeedNodes(TCommonAppOptions& cf) { + if (auto path = fs::path(cf.SeedNodesFile.c_str()); fs::is_regular_file(path)) { + try { + TFileInput file(cf.SeedNodesFile); + TString fileContent = file.ReadAll(); + auto doc = NFyaml::TDocument::Parse(fileContent); + if (doc.Root().Type() == NFyaml::ENodeType::Sequence) { + for (const auto& item : doc.Root().Sequence()) { + if (item.Type() == NFyaml::ENodeType::Scalar) { + cf.SeedNodes.push_back(item.Scalar()); + } else { + ythrow yexception() << "Invalid format in seed nodes file: expected a list of strings, but found non-scalar item at " << item.Path(); + } + } + } else { + ythrow yexception() << "Invalid format in seed nodes file: expected a list of strings at root"; + } + } catch (const std::exception& e) { + ythrow yexception() << "Failed to read or parse seed nodes file: " << e.what(); + } + } else { + ythrow yexception() << "Seed nodes file not found: " << cf.SeedNodesFile; + } + } + + void InitConfigFromSeedNodes(TString& yamlConfigFile, TString& storageYamlConfigFile) { + if (AppConfig.GetConfigDirPath().empty()) { + ythrow yexception() << "Seed nodes file provided, but config dir path is not set"; + } + + if (CommonAppOptions.SeedNodes.empty()) { + ythrow yexception() << "No seed nodes provided"; + } + + auto result = ConfigClient.FetchConfig(CommonAppOptions.GrpcSslSettings, CommonAppOptions.SeedNodes, Env, Logger); + if (!result) { + Logger.Out() << "Failed to fetch config from seed nodes" << Endl; + return; + } + + const TString& clusterConfig = result->GetMainYamlConfig(); + const TString& storageConfig = result->GetStorageYamlConfig(); + const TString configDirPath = AppConfig.GetConfigDirPath(); + + auto saveConfig = [&](const TString& config, const TString& configName) { + try { + TString tempPath = TStringBuilder() << AppConfig.GetConfigDirPath() << "/temp_" << configName; + TString configPath = TStringBuilder() << AppConfig.GetConfigDirPath() << "/" << configName; + { + TFileOutput tempFile(tempPath); + tempFile << config; + tempFile.Flush(); + + if (Chmod(tempPath.c_str(), S_IRUSR | S_IRGRP | S_IROTH) != 0) { + return false; + } + } + + return NFs::Rename(tempPath, configPath); + } catch (const std::exception& e) { + return false; + } + }; + + bool clusterSaved = !clusterConfig.empty() && saveConfig(clusterConfig, CONFIG_NAME); + bool storageSaved = !storageConfig.empty() && saveConfig(storageConfig, STORAGE_CONFIG_NAME); + + if (clusterSaved) { + yamlConfigFile = configDirPath + "/" + CONFIG_NAME; + } + if (storageSaved) { + storageYamlConfigFile = configDirPath + "/" + STORAGE_CONFIG_NAME; + } + + if (clusterSaved && storageSaved) { + Logger.Out() << "Initialized main and storage configs in " << configDirPath << "/" + << CONFIG_NAME << " and " << STORAGE_CONFIG_NAME << Endl; + } else if (clusterSaved) { + Logger.Out() << "Initialized config in " << configDirPath << "/" << CONFIG_NAME << Endl; + } else if (!clusterConfig.empty() || !storageConfig.empty()) { + TStringBuilder errorMsg; + errorMsg << "Failed to save configs: "; + if (!clusterConfig.empty() && !clusterSaved) { + errorMsg << "main config"; + } + if (!storageConfig.empty() && !storageSaved) { + if (!clusterConfig.empty() && !clusterSaved) { + errorMsg << ", "; + } + errorMsg << "storage config"; + } + ythrow yexception() << errorMsg; + } else { + Logger.Out() << "No configs received from seed nodes" << Endl; + } + } }; std::unique_ptr MakeDefaultInitialConfigurator( @@ -1420,6 +1540,7 @@ std::unique_ptr MakeDefaultInitialConfigurator( NConfig::IMemLogInitializer& memLogInit, NConfig::INodeBrokerClient& nodeBrokerClient, NConfig::IDynConfigClient& dynConfigClient, + NConfig::IConfigClient& configClient, NConfig::IEnv& env); } // namespace NKikimr::NConfig diff --git a/ydb/core/config/init/init_noop.cpp b/ydb/core/config/init/init_noop.cpp index 87198f5b3166..3978c85b44a1 100644 --- a/ydb/core/config/init/init_noop.cpp +++ b/ydb/core/config/init/init_noop.cpp @@ -62,6 +62,20 @@ class TNoopMemLogInitializer void Init(const NKikimrConfig::TMemoryLogConfig&) const override {} }; +class TNoopConfigClient + : public IConfigClient +{ +public: + std::shared_ptr FetchConfig( + const TGrpcSslSettings&, + const TVector&, + const IEnv&, + IInitLogger&) const override + { + return nullptr; + } +}; + std::unique_ptr MakeNoopMemLogInitializer() { return std::make_unique(); } @@ -74,6 +88,10 @@ std::unique_ptr MakeNoopDynConfigClient() { return std::make_unique(); } +std::unique_ptr MakeNoopConfigClient() { + return std::make_unique(); +} + std::unique_ptr MakeNoopInitLogger() { return std::make_unique(); } diff --git a/ydb/core/config/init/mock.h b/ydb/core/config/init/mock.h index 568aeaaab49b..94498a04c753 100644 --- a/ydb/core/config/init/mock.h +++ b/ydb/core/config/init/mock.h @@ -234,4 +234,46 @@ class TProtoConfigFileProviderRecorder } }; +class TConfigClientMock + : public IConfigClient +{ +public: + std::shared_ptr FetchConfig( + const TGrpcSslSettings& grpcSettings, + const TVector& addrs, + const IEnv& env, + IInitLogger& logger) const override + { + Y_UNUSED(grpcSettings, addrs, env, logger); + return SavedResult; + } + + std::shared_ptr SavedResult; +}; + +class TConfigClientRecorder + : public IConfigClient +{ + IConfigClient& Impl; + mutable TConfigClientMock Mock; +public: + TConfigClientRecorder(IConfigClient& impl) + : Impl(impl) + {} + + std::shared_ptr FetchConfig( + const TGrpcSslSettings& grpcSettings, + const TVector& addrs, + const IEnv& env, + IInitLogger& logger) const override + { + Mock.SavedResult = Impl.FetchConfig(grpcSettings, addrs, env, logger); + return Mock.SavedResult; + } + + TConfigClientMock GetMock() const { + return Mock; + } +}; + } // namespace NKikimr::NConfig diff --git a/ydb/core/config/init/ya.make b/ydb/core/config/init/ya.make index 58af302fc54f..140182bf2f1a 100644 --- a/ydb/core/config/init/ya.make +++ b/ydb/core/config/init/ya.make @@ -17,6 +17,7 @@ PEERDIR( yql/essentials/minikql yql/essentials/public/udf ydb/public/lib/deprecated/kicli + ydb/public/sdk/cpp/src/client/config ydb/public/sdk/cpp/src/client/discovery ydb/public/sdk/cpp/src/client/driver ) diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp index ef0534f45752..1efbbd548b4d 100644 --- a/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp @@ -11,6 +11,7 @@ TClientCommandServer::TClientCommandServer(std::shared_ptr fac , MemLogInit(NConfig::MakeDefaultMemLogInitializer()) , NodeBrokerClient(NConfig::MakeDefaultNodeBrokerClient()) , DynConfigClient(NConfig::MakeDefaultDynConfigClient()) + , ConfigClient(NConfig::MakeDefaultConfigClient()) , Env(NConfig::MakeDefaultEnv()) , Logger(NConfig::MakeDefaultInitLogger()) , DepsRecorder(NConfig::MakeDefaultInitialConfiguratorDepsRecorder({ @@ -20,6 +21,7 @@ TClientCommandServer::TClientCommandServer(std::shared_ptr fac *MemLogInit, *NodeBrokerClient, *DynConfigClient, + *ConfigClient, *Env, *Logger })) diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_server.h b/ydb/core/driver_lib/cli_utils/cli_cmds_server.h index d0b95d2874a4..d2df756a7474 100644 --- a/ydb/core/driver_lib/cli_utils/cli_cmds_server.h +++ b/ydb/core/driver_lib/cli_utils/cli_cmds_server.h @@ -27,6 +27,7 @@ class TClientCommandServer : public TClientCommand { std::unique_ptr MemLogInit; std::unique_ptr NodeBrokerClient; std::unique_ptr DynConfigClient; + std::unique_ptr ConfigClient; std::unique_ptr Env; std::unique_ptr Logger; diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp index 07cb216a4652..b50d206a53d8 100644 --- a/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp +++ b/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp @@ -12,6 +12,7 @@ NKikimrConfig::TAppConfig TransformConfig(const std::vector& args) { auto memLogInit = NConfig::MakeNoopMemLogInitializer(); auto nodeBrokerClient = NConfig::MakeNoopNodeBrokerClient(); auto dynConfigClient = NConfig::MakeNoopDynConfigClient(); + auto configClient = NConfig::MakeNoopConfigClient(); auto env = NConfig::MakeDefaultEnv(); auto logger = NConfig::MakeNoopInitLogger(); @@ -22,6 +23,7 @@ NKikimrConfig::TAppConfig TransformConfig(const std::vector& args) { *memLogInit, *nodeBrokerClient, *dynConfigClient, + *configClient, *env, *logger, }; diff --git a/ydb/tests/functional/ydb_cli/test_ydb_backup.py b/ydb/tests/functional/ydb_cli/test_ydb_backup.py index 704f6aedfc19..71e36a4fab26 100644 --- a/ydb/tests/functional/ydb_cli/test_ydb_backup.py +++ b/ydb/tests/functional/ydb_cli/test_ydb_backup.py @@ -1319,7 +1319,7 @@ def setup_class(cls): storage_pool_units_count={ 'hdd': 1 }, - timeout_seconds=100, + timeout_seconds=240, token=cls.cluster.config.default_clusteradmin ) @@ -1527,7 +1527,7 @@ def restore(cls, command, input, additional_args=[], token=""): "--endpoint", f"grpc://localhost:{cls.restore_cluster.nodes[1].grpc_port}", ] + command - + ["--input", backup_files_dir, "-w", "60s"] + + ["--input", backup_files_dir, "-w", "240s"] + additional_args, env={"YDB_TOKEN": token} ) diff --git a/ydb/tests/library/harness/kikimr_cluster_interface.py b/ydb/tests/library/harness/kikimr_cluster_interface.py index a71c99126293..7efdbb639557 100644 --- a/ydb/tests/library/harness/kikimr_cluster_interface.py +++ b/ydb/tests/library/harness/kikimr_cluster_interface.py @@ -140,7 +140,7 @@ def __wait_tenant_up( self, database_name, expected_computational_units=None, - timeout_seconds=120, + timeout_seconds=240, token=None ): def predicate():