1616#include " cloud_storage_clients/client_pool.h"
1717#include " cluster/cloud_metadata/offsets_upload_router.h"
1818#include " cluster/cloud_metadata/offsets_uploader.h"
19+ #include " cluster/cluster_discovery.h"
1920#include " cluster/config_manager.h"
2021#include " cluster/controller.h"
2122#include " cluster/node_isolation_watcher.h"
@@ -338,7 +339,11 @@ int application::run(int ac, char** av) {
338339 // Cluster config validation uses OpenSSL (e.g. TLS cipher
339340 // checks), so crypto must be initialized first.
340341 wire_up_and_start_crypto_services ();
342+ wire_up_pre_bootstrap_services ();
341343 hydrate_cluster_config (node_cfg_yaml);
344+ wire_up_and_start_rpc_service ();
345+ establish_cluster_view (app_signal);
346+ log_cluster_config ();
342347 init_crashtracker (app_signal);
343348 initialize ();
344349 check_environment ();
@@ -387,9 +392,20 @@ void application::initialize(
387392 std::optional<YAML::Node> schema_reg_client_cfg,
388393 std::optional<YAML::Node> audit_log_client_cfg) {
389394 ss::smp::invoke_on_all ([] {
390- // initialize memory groups now that our configuration is loaded
395+ // re-initialize memory groups now that our configuration is loaded
396+ memory_groups_holder ().reset ();
391397 memory_groups ();
392398 }).get ();
399+
400+ // With memory groups re-initialized, we can now set a proper memory
401+ // capacity in the _rpc server (which was constructed before a consistent
402+ // cluster view was established).
403+ _rpc
404+ .invoke_on_all ([](rpc::rpc_server& r) {
405+ r.set_memory_capacity (memory_groups ().rpc_total_memory ());
406+ })
407+ .get ();
408+
393409 construct_service (
394410 _memory_sampling, std::ref (_log), ss::sharded_parameter ([]() {
395411 return config::shard_local_cfg ().sampled_memory_profile .bind ();
@@ -460,21 +476,6 @@ void application::initialize(
460476 " data directory" , config::node ().data_directory ().path );
461477 syschecks::pidfile_create (config::node ().pidfile_path ());
462478 }
463- smp_groups::config smp_groups_cfg{
464- .raft_group_max_non_local_requests
465- = config::shard_local_cfg ().raft_smp_max_non_local_requests ().value_or (
466- smp_groups::default_raft_non_local_requests (
467- config::shard_local_cfg ().topic_partitions_per_shard ())),
468- .proxy_group_max_non_local_requests
469- = config::shard_local_cfg ().pp_sr_smp_max_non_local_requests ().value_or (
470- smp_groups::default_max_nonlocal_requests)};
471-
472- smp_service_groups.create_groups (smp_groups_cfg).get ();
473- _deferred.emplace_back (
474- [this ] { smp_service_groups.destroy_groups ().get (); });
475-
476- // Ensure the scheduling groups singleton is initialized early
477- std::ignore = scheduling_groups::instance ();
478479
479480 construct_service (_scheduling_groups_probe).get ();
480481 _scheduling_groups_probe
@@ -514,6 +515,18 @@ void application::initialize(
514515}
515516
516517void application::setup_metrics () {
518+ // Two systems that were created in the pre-bootstrapping process that may
519+ // now need their metrics enabled.
520+ feature_table.invoke_on_all (&features::feature_table::setup_metrics).get ();
521+ _rpc
522+ .invoke_on_all ([](rpc::rpc_server& r) {
523+ r.setup_metrics (
524+ /* disable_metrics=*/ config::shard_local_cfg ().disable_metrics (),
525+ /* disable_public_metrics=*/ config::shard_local_cfg ()
526+ .disable_public_metrics ());
527+ })
528+ .get ();
529+ _rpc.invoke_on_all (&rpc::rpc_server::setup_metrics).get ();
517530 setup_internal_metrics ();
518531 setup_public_metrics ();
519532}
@@ -724,31 +737,78 @@ YAML::Node application::hydrate_node_config(const po::variables_map& cfg) {
724737 return config;
725738}
726739
727- void application::hydrate_cluster_config (const YAML::Node& config) {
728- auto config_printer = [this ](std::string_view service, const auto & cfg) {
729- std::vector<ss::sstring> items;
730- cfg.for_each ([&items, &service](const auto & item) {
731- items.push_back (
732- ssx::sformat (" {}.{}\t - {}" , service, item, item.desc ()));
733- });
734- std::sort (items.begin (), items.end ());
735- for (const auto & item : items) {
736- vlog (_log.info , " {}" , item);
737- }
738- };
740+ // Forward declarations of helper functions defined in application_config.cc
741+ std::optional<storage::file_sanitize_config> read_file_sanitizer_config ();
742+
743+ storage::kvstore_config kvstore_config_from_global_config (
744+ std::optional<storage::file_sanitize_config> sanitizer_config);
745+
746+ storage::log_config manager_config_from_global_config (
747+ scheduling_groups& sgs,
748+ std::optional<storage::file_sanitize_config> sanitizer_config);
749+
750+ void application::wire_up_pre_bootstrap_services () {
751+ // Ensure the scheduling groups singleton is initialized early
752+ std::ignore = scheduling_groups::instance ();
753+
754+ // Construct the feature table
755+ syschecks::systemd_message (" Creating feature table" ).get ();
756+ construct_service (feature_table).get ();
757+
758+ // Construct local storage
759+ const auto sanitizer_config = read_file_sanitizer_config ();
760+ syschecks::systemd_message (" Creating storage" ).get ();
761+ construct_service (
762+ storage,
763+ [c = sanitizer_config]() mutable {
764+ return kvstore_config_from_global_config (std::move (c));
765+ },
766+ [c = sanitizer_config]() mutable {
767+ auto log_cfg = manager_config_from_global_config (
768+ scheduling_groups::instance (), std::move (c));
769+ log_cfg.reclaim_opts .background_reclaimer_sg
770+ = scheduling_groups::instance ().cache_background_reclaim_sg ();
771+ return log_cfg;
772+ },
773+ std::ref (feature_table))
774+ .get ();
775+
776+ // Construct smp groups using potentially stale cluster config.
777+ auto & cfg = config::shard_local_cfg_unsafe ();
778+ smp_groups::config smp_groups_cfg{
779+ .raft_group_max_non_local_requests
780+ = cfg.raft_smp_max_non_local_requests ().value_or (
781+ smp_groups::default_raft_non_local_requests (
782+ cfg.topic_partitions_per_shard ())),
783+ .proxy_group_max_non_local_requests
784+ = cfg.pp_sr_smp_max_non_local_requests ().value_or (
785+ smp_groups::default_max_nonlocal_requests)};
786+
787+ smp_service_groups.create_groups (smp_groups_cfg).get ();
788+ _deferred.emplace_back (
789+ [this ] { smp_service_groups.destroy_groups ().get (); });
790+ }
791+
792+ void application::establish_cluster_view (::stop_signal& app_signal) {
793+ bootstrap_from_kvstore ().get ();
739794
795+ // Begin the cluster discovery manager so we can confirm our initial node
796+ // ID. A valid node ID is required before we can initialize the rest of our
797+ // subsystems. The local node and cluster UUIDs would have been set in
798+ // bootstrap_from_kvstore().
799+ _cluster_discovery = std::make_unique<cluster::cluster_discovery>(
800+ storage.local ().node_uuid (),
801+ storage.local ().get_cluster_uuid (),
802+ app_signal.abort_source ());
803+
804+ bootstrap_controller_view ().get ();
805+ }
806+
807+ void application::hydrate_cluster_config (const YAML::Node& config) {
740808 // This includes loading from local bootstrap file or legacy
741809 // config file on first-start or upgrade cases.
742810 _config_preload = cluster::config_manager::preload (config).get ();
743811
744- vlog (_log.info , " Cluster configuration properties:" );
745- vlog (_log.info , " (use `rpk cluster config edit` to change)" );
746- config_printer (" redpanda" , config::shard_local_cfg ());
747-
748- vlog (_log.info , " Node configuration properties:" );
749- vlog (_log.info , " (use `rpk redpanda config set <cfg> <value>` to change)" );
750- config_printer (" redpanda" , config::node ());
751-
752812 if (config[" pandaproxy" ]) {
753813 _proxy_config.emplace (config[" pandaproxy" ]);
754814 for (const auto & e : _proxy_config->errors ()) {
@@ -768,8 +828,6 @@ void application::hydrate_cluster_config(const YAML::Node& config) {
768828 set_local_kafka_client_config (_proxy_client_config, config::node ());
769829 }
770830 set_pp_kafka_client_defaults (*_proxy_config, *_proxy_client_config);
771- config_printer (" pandaproxy" , *_proxy_config);
772- config_printer (" pandaproxy_client" , *_proxy_client_config);
773831 }
774832 if (config[" schema_registry" ]) {
775833 _schema_reg_config.emplace (config[" schema_registry" ]);
@@ -780,8 +838,6 @@ void application::hydrate_cluster_config(const YAML::Node& config) {
780838 _schema_reg_client_config, config::node ());
781839 }
782840 set_sr_kafka_client_defaults (*_schema_reg_client_config);
783- config_printer (" schema_registry" , *_schema_reg_config);
784- config_printer (" schema_registry_client" , *_schema_reg_client_config);
785841 }
786842 // / Auditing will be toggled via cluster config settings, internal audit
787843 // / client options can be configured via local config properties
@@ -791,7 +847,44 @@ void application::hydrate_cluster_config(const YAML::Node& config) {
791847 set_local_kafka_client_config (_audit_log_client_config, config::node ());
792848 }
793849 set_auditing_kafka_client_defaults (*_audit_log_client_config);
794- config_printer (" audit_log_client" , *_audit_log_client_config);
850+ }
851+
852+ void application::log_cluster_config () {
853+ auto config_printer = [this ](std::string_view service, const auto & cfg) {
854+ std::vector<ss::sstring> items;
855+ cfg.for_each ([&items, &service](const auto & item) {
856+ items.push_back (
857+ ssx::sformat (" {}.{}\t - {}" , service, item, item.desc ()));
858+ });
859+ std::sort (items.begin (), items.end ());
860+ for (const auto & item : items) {
861+ vlog (_log.info , " {}" , item);
862+ }
863+ };
864+
865+ vlog (_log.info , " Cluster configuration properties:" );
866+ vlog (_log.info , " (use `rpk cluster config edit` to change)" );
867+ config_printer (" redpanda" , config::shard_local_cfg ());
868+
869+ vlog (_log.info , " Node configuration properties:" );
870+ vlog (_log.info , " (use `rpk redpanda config set <cfg> <value>` to change)" );
871+ config_printer (" redpanda" , config::node ());
872+
873+ if (_proxy_config) {
874+ config_printer (" pandaproxy" , *_proxy_config);
875+ }
876+ if (_proxy_client_config) {
877+ config_printer (" pandaproxy_client" , *_proxy_client_config);
878+ }
879+ if (_schema_reg_config) {
880+ config_printer (" schema_registry" , *_schema_reg_config);
881+ }
882+ if (_schema_reg_client_config) {
883+ config_printer (" schema_registry_client" , *_schema_reg_client_config);
884+ }
885+ if (_audit_log_client_config) {
886+ config_printer (" audit_log_client" , *_audit_log_client_config);
887+ }
795888}
796889
797890void application::check_environment () {
0 commit comments