10
10
#include < ydb/library/yaml_config/yaml_config.h>
11
11
#include < ydb/core/mind/tenant_pool.h>
12
12
#include < ydb/core/mon/mon.h>
13
+ #include < ydb/core/config/init/mock.h>
14
+ #include < ydb/core/base/counters.h>
13
15
14
16
#include < ydb/library/actors/core/actor_bootstrapped.h>
15
17
#include < ydb/library/actors/core/interconnect.h>
16
18
#include < ydb/library/actors/core/mon.h>
17
19
#include < ydb/library/actors/interconnect/interconnect.h>
18
20
#include < library/cpp/json/json_reader.h>
19
21
#include < library/cpp/json/json_writer.h>
22
+ #include < ydb/core/config/init/init.h>
20
23
21
24
#include < util/generic/bitmap.h>
22
25
#include < util/generic/ptr.h>
35
38
36
39
namespace NKikimr ::NConsole {
37
40
41
+ using namespace NConfig ;
42
+
38
43
const THashSet<ui32> DYNAMIC_KINDS ({
39
44
(ui32)NKikimrConsole::TConfigItem::ActorSystemConfigItem,
40
45
(ui32)NKikimrConsole::TConfigItem::BootstrapConfigItem,
@@ -161,6 +166,8 @@ class TConfigsDispatcher : public TActorBootstrapped<TConfigsDispatcher> {
161
166
162
167
TDynBitMap FilterKinds (const TDynBitMap& in);
163
168
169
+ void UpdateCandidateStartupConfig (TEvConsole::TEvConfigSubscriptionNotification::TPtr &ev);
170
+
164
171
void Handle (NMon::TEvHttpInfo::TPtr &ev);
165
172
void Handle (TEvInterconnect::TEvNodesInfo::TPtr &ev);
166
173
void Handle (TEvConsole::TEvConfigSubscriptionNotification::TPtr &ev);
@@ -232,7 +239,14 @@ class TConfigsDispatcher : public TActorBootstrapped<TConfigsDispatcher> {
232
239
const std::variant<std::monostate, TDenyList, TAllowList> ItemsServeRules;
233
240
const NKikimrConfig::TAppConfig BaseConfig;
234
241
NKikimrConfig::TAppConfig CurrentConfig;
242
+ NKikimrConfig::TAppConfig CandidateStartupConfig;
243
+ bool StartupConfigProcessError = false ;
244
+ bool StartupConfigProcessDiff = false ;
245
+ TString StartupConfigInfo;
246
+ ::NMonitoring::TDynamicCounters::TCounterPtr StartupConfigChanged;
235
247
const std::optional<TDebugInfo> DebugInfo;
248
+ std::shared_ptr<NConfig::TRecordedInitialConfiguratorDeps> RecordedInitialConfiguratorDeps;
249
+ std::vector<TString> Args;
236
250
ui64 NextRequestCookie;
237
251
TVector<TActorId> HttpRequests;
238
252
TActorId CommonSubscriptionClient;
@@ -257,7 +271,10 @@ TConfigsDispatcher::TConfigsDispatcher(const TConfigsDispatcherInitInfo& initInf
257
271
, ItemsServeRules(initInfo.ItemsServeRules)
258
272
, BaseConfig(initInfo.InitialConfig)
259
273
, CurrentConfig(initInfo.InitialConfig)
274
+ , CandidateStartupConfig(initInfo.InitialConfig)
260
275
, DebugInfo(initInfo.DebugInfo)
276
+ , RecordedInitialConfiguratorDeps(std::move(initInfo.RecordedInitialConfiguratorDeps))
277
+ , Args(initInfo.Args)
261
278
, NextRequestCookie(Now().GetValue())
262
279
{}
263
280
@@ -270,6 +287,10 @@ void TConfigsDispatcher::Bootstrap()
270
287
NMonitoring::TIndexMonPage *actorsMonPage = mon->RegisterIndexPage (" actors" , " Actors" );
271
288
mon->RegisterActorPage (actorsMonPage, " configs_dispatcher" , " Configs Dispatcher" , false , TlsActivationContext->ExecutorThread .ActorSystem , SelfId ());
272
289
}
290
+ TIntrusivePtr<NMonitoring::TDynamicCounters> rootCounters = AppData ()->Counters ;
291
+ TIntrusivePtr<NMonitoring::TDynamicCounters> authCounters = GetServiceCounters (rootCounters, " config" );
292
+ NMonitoring::TDynamicCounterPtr counters = authCounters->GetSubgroup (" subsystem" , " ConfigsDispatcher" );
293
+ StartupConfigChanged = counters->GetCounter (" StartupConfigChanged" , true );
273
294
274
295
auto commonClient = CreateConfigsSubscriber (
275
296
SelfId (),
@@ -536,6 +557,33 @@ void TConfigsDispatcher::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev)
536
557
str << " <br />" << Endl;
537
558
COLLAPSED_REF_CONTENT (" debug-info" , " Debug info" ) {
538
559
DIV_CLASS (" tab-left" ) {
560
+ COLLAPSED_REF_CONTENT (" args" , " Startup process args" ) {
561
+ PRE () {
562
+ for (auto & arg : Args) {
563
+ str << " \" " << arg << " \" " ;
564
+ }
565
+ }
566
+ }
567
+ str << " <br />" << Endl;
568
+ COLLAPSED_REF_CONTENT (" candidate-startup-config" , " Candidate startup config" ) {
569
+ str << " <div class=\" alert alert-primary tab-left\" role=\" alert\" >" << Endl;
570
+ if (StartupConfigProcessError) {
571
+ str << " <b>Error: </b>" << Endl;
572
+ PRE () {
573
+ str << StartupConfigInfo;
574
+ }
575
+ } else if (StartupConfigProcessDiff) {
576
+ str << " <b>Configs are different: </b>" << Endl;
577
+ PRE () {
578
+ str << StartupConfigInfo;
579
+ }
580
+ } else {
581
+ str << " <b>Configs are same.</b>" << Endl;
582
+ }
583
+ str << " </div>" << Endl;
584
+ NHttp::OutputConfigHTML (str, CandidateStartupConfig);
585
+ }
586
+ str << " <br />" << Endl;
539
587
COLLAPSED_REF_CONTENT (" effective-config-debug-info" , " Effective config debug info" ) {
540
588
NHttp::OutputConfigDebugInfoHTML (
541
589
str,
@@ -700,10 +748,112 @@ void TConfigsDispatcher::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev)
700
748
HttpRequests.clear ();
701
749
}
702
750
751
+ class TConfigurationResult
752
+ : public IConfigurationResult
753
+ {
754
+ public:
755
+ // TODO make ref
756
+ const NKikimrConfig::TAppConfig& GetConfig () const {
757
+ return Config;
758
+ }
759
+
760
+ bool HasYamlConfig () const {
761
+ return !YamlConfig.empty ();
762
+ }
763
+
764
+ const TString& GetYamlConfig () const {
765
+ return YamlConfig;
766
+ }
767
+
768
+ TMap<ui64, TString> GetVolatileYamlConfigs () const {
769
+ return VolatileYamlConfigs;
770
+ }
771
+
772
+ NKikimrConfig::TAppConfig Config;
773
+ TString YamlConfig;
774
+ TMap<ui64, TString> VolatileYamlConfigs;
775
+ };
776
+
777
+ void TConfigsDispatcher::UpdateCandidateStartupConfig (TEvConsole::TEvConfigSubscriptionNotification::TPtr &ev)
778
+ try {
779
+ if (!RecordedInitialConfiguratorDeps) {
780
+ CandidateStartupConfig = {};
781
+ StartupConfigProcessError = true ;
782
+ StartupConfigProcessDiff = false ;
783
+ StartupConfigInfo = " Startup params not recorded. Corresponding functionality won't work." ;
784
+ *StartupConfigChanged = 0 ;
785
+ return ;
786
+ }
787
+
788
+ auto &rec = ev->Get ()->Record ;
789
+
790
+ auto dcClient = std::make_unique<TDynConfigClientMock>();
791
+ auto configs = std::make_shared<TConfigurationResult>();
792
+ dcClient->SavedResult = configs;
793
+ configs->Config = rec.GetRawConsoleConfig ();
794
+ configs->YamlConfig = rec.GetYamlConfig ();
795
+ // TODO volatile
796
+ RecordedInitialConfiguratorDeps->DynConfigClient = std::move (dcClient);
797
+ auto deps = RecordedInitialConfiguratorDeps->GetDeps ();
798
+ NConfig::TInitialConfigurator initCfg (deps);
799
+
800
+ std::vector<const char *> argv;
801
+
802
+ for (const auto & arg : Args) {
803
+ argv.push_back (arg.data ());
804
+ }
805
+
806
+ NLastGetopt::TOpts opts;
807
+ initCfg.RegisterCliOptions (opts);
808
+ deps.ProtoConfigFileProvider .RegisterCliOptions (opts);
809
+
810
+ NLastGetopt::TOptsParseResult parseResult (&opts, argv.size (), argv.data ());
811
+
812
+ initCfg.ValidateOptions (opts, parseResult);
813
+ initCfg.Parse (parseResult.GetFreeArgs ());
814
+
815
+ NKikimrConfig::TAppConfig appConfig;
816
+ ui32 nodeId;
817
+ TKikimrScopeId scopeId;
818
+ TString tenantName;
819
+ TBasicKikimrServicesMask servicesMask;
820
+ TString clusterName;
821
+ NConfig::TConfigsDispatcherInitInfo configsDispatcherInitInfo;
822
+
823
+ initCfg.Apply (
824
+ appConfig,
825
+ nodeId,
826
+ scopeId,
827
+ tenantName,
828
+ servicesMask,
829
+ clusterName,
830
+ configsDispatcherInitInfo);
831
+
832
+ CandidateStartupConfig = appConfig;
833
+ StartupConfigProcessError = false ;
834
+ StartupConfigProcessDiff = false ;
835
+ StartupConfigInfo.clear ();
836
+ google::protobuf::util::MessageDifferencer md;
837
+ auto fieldComparator = google::protobuf::util::DefaultFieldComparator ();
838
+ md.set_field_comparator (&fieldComparator);
839
+ md.ReportDifferencesToString (&StartupConfigInfo);
840
+ StartupConfigProcessDiff = !md.Compare (BaseConfig, CandidateStartupConfig);
841
+ *StartupConfigChanged = StartupConfigProcessDiff ? 1 : 0 ;
842
+ }
843
+ catch (...) {
844
+ CandidateStartupConfig = {};
845
+ StartupConfigProcessError = true ;
846
+ StartupConfigProcessDiff = false ;
847
+ StartupConfigInfo = " Got exception while processing candidate config." ;
848
+ *StartupConfigChanged = 1 ;
849
+ }
850
+
703
851
void TConfigsDispatcher::Handle (TEvConsole::TEvConfigSubscriptionNotification::TPtr &ev)
704
852
{
705
853
auto &rec = ev->Get ()->Record ;
706
854
855
+ UpdateCandidateStartupConfig (ev);
856
+
707
857
CurrentConfig = rec.GetConfig ();
708
858
709
859
const auto & newYamlConfig = rec.GetYamlConfig ();
0 commit comments