| #ifndef THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_ | |
| #define THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_ | |
| #include <systemd/sd-daemon.h> | |
| #include <chrono> // NOLINT | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <iostream> | |
| #include <thread> // NOLINT | |
| #include <utility> | |
| // NOLINTBEGIN | |
| #include "absl/base/log_severity.h" | |
| #include "absl/flags/declare.h" | |
| #include "absl/types/optional.h" | |
| #include "boost/asio/thread_pool.hpp" // NOLINT | |
| #include "g3/event_store.h" | |
| #include "subscription.h" | |
| #include "subscription_impl.h" | |
| #include "subscription_store_impl.h" | |
| #include "bmcweb_config.h" | |
| #include "app.hpp" | |
| #include "app_singleton.hpp" | |
| #ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER | |
| #include "absl/flags/flag.h" | |
| #include "exception_stack_tracer.hpp" | |
| #endif | |
| #include "logging.hpp" | |
| #include "cors_preflight.hpp" | |
| #include "persistent_data.hpp" | |
| #include "request_stats.hpp" | |
| #include "user_monitor.hpp" | |
| #include "webassets.hpp" | |
| #include "interface.hpp" | |
| #include "redfish.hpp" | |
| #include "health.hpp" | |
| #include "tlbmc/credentials/credential_manager.h" | |
| #include "tlbmc/credentials/credential_manager_impl.h" | |
| #include "tlbmc/hal/system_registry.h" | |
| #include "tlbmc/hal/system_registry_impl.h" | |
| #include "tlbmc/redfish/app.h" | |
| #include "managed_store.hpp" | |
| #include "managed_store_types.hpp" | |
| #include "subscription_backend_impl.hpp" | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| #include "absl/flags/flag.h" | |
| #include "absl/log/initialize.h" | |
| #include "absl/log/log.h" | |
| #include "server.h" | |
| // NOLINTEND | |
| // See absl/log/globals.h for detailed instructions | |
| ABSL_DECLARE_FLAG(int, stderrthreshold); | |
| ABSL_DECLARE_FLAG(int, minloglevel); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, httpport); | |
| ABSL_DECLARE_FLAG(int, mtls_grpc_port); | |
| ABSL_DECLARE_FLAG(int, insecure_grpc_port); | |
| // BMCWEB_ENABLE_STATEFUL_BMCWEB: | |
| ABSL_DECLARE_FLAG(absl::optional<bool>, stateful); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, stateful_pending_max); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tfixed_sec); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tgrace_sec); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tlru_sec); | |
| ABSL_DECLARE_FLAG(absl::optional<bool>, request_stats); | |
| ABSL_DECLARE_FLAG(absl::optional<bool>, timetrace); | |
| ABSL_DECLARE_FLAG(absl::optional<uint64_t>, timetrace_size_max); | |
| ABSL_DECLARE_FLAG(absl::optional<bool>, stateful_logs); | |
| ABSL_DECLARE_FLAG(bool, redfish_events); | |
| ABSL_DECLARE_FLAG(bool, testing_events); | |
| ABSL_DECLARE_FLAG(absl::optional<size_t>, redfish_event_store_size); | |
| ABSL_DECLARE_FLAG(absl::optional<bool>, rde_ratelimit); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, rde_errors_max); | |
| ABSL_DECLARE_FLAG(absl::optional<int>, rde_skips_max); | |
| ABSL_DECLARE_FLAG(bool, multi_thread_get); | |
| ABSL_DECLARE_FLAG(bool, enable_tlbmc); | |
| ABSL_DECLARE_FLAG(bool, enable_tlbmc_trace); | |
| ABSL_DECLARE_FLAG(bool, enable_tlbmc_thermal_control); | |
| ABSL_DECLARE_FLAG(bool, enable_fast_sanity); | |
| ABSL_DECLARE_FLAG(std::string, entity_config_location); | |
| ABSL_DECLARE_FLAG(std::string, server_cert_path); | |
| ABSL_DECLARE_FLAG(std::string, server_private_key_path); | |
| ABSL_DECLARE_FLAG(bool, enable_configure_core_count); | |
| ABSL_DECLARE_FLAG(bool, enable_configure_memory_capacity); | |
| ABSL_DECLARE_FLAG(bool, enable_redfish_configure_ifs); | |
| ABSL_DECLARE_FLAG(std::string, smbios_single_host_file_path); | |
| ABSL_DECLARE_FLAG(std::string, smbios_multihost_host_file_path_prefix); | |
| ABSL_DECLARE_FLAG(std::string, smbios_single_host_status_file_path); | |
| ABSL_DECLARE_FLAG(std::string, smbios_multihost_host_status_file_path_prefix); | |
| ABSL_DECLARE_FLAG(int, smbios_blob_timeout_sec); | |
| #endif // BMCWEB_ENABLE_GRPC | |
| #ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER | |
| // Guarded by the tracer macro, not BMCWEB_ENABLE_GRPC, so it matches its use in | |
| // run(). Without gRPC no flags are parsed, so it keeps its default there. | |
| ABSL_DECLARE_FLAG(bool, exception_stack_tracer); | |
| #endif // BMCWEB_ENABLE_EXCEPTION_STACK_TRACER | |
| #include <memory> | |
| #include <string> | |
| #include "boost/asio/io_context.hpp" // NOLINT | |
| #include "redfish_devpath_injector.hpp" | |
| #include "google/google_service_nvme.hpp" | |
| #include "google/google_service_root.hpp" | |
| #include "sdbusplus/asio/connection.hpp" | |
| // Default number of Redfish Events stored. | |
| constexpr size_t defaultRedfishEventStoreSize = 1000; | |
| inline void setupSocket(crow::App& app) { | |
| constexpr uint16_t defaultPort = 18080; | |
| int listenFd = sd_listen_fds(0); | |
| uint16_t portNumber = defaultPort; | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| portNumber = static_cast<uint16_t>( | |
| absl::GetFlag(FLAGS_httpport).value_or(defaultPort)); | |
| #endif | |
| BMCWEB_LOG_ALWAYS << "setupSocket: defaultPort: " << defaultPort | |
| << " portNumber: " << portNumber | |
| << " listenFd: " << listenFd; | |
| if (1 == listenFd) { | |
| BMCWEB_LOG_INFO << "attempting systemd socket activation"; | |
| if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1, 0) != | |
| 0) { | |
| BMCWEB_LOG_INFO << "Starting webserver on socket handle " | |
| << SD_LISTEN_FDS_START; | |
| app.socket(SD_LISTEN_FDS_START); | |
| } else { | |
| BMCWEB_LOG_ERROR << "bad incoming socket, starting webserver on port " | |
| << portNumber; | |
| app.port(portNumber); | |
| } | |
| } else { | |
| BMCWEB_LOG_INFO << "Starting webserver on port: " << portNumber; | |
| app.port(portNumber); | |
| } | |
| } | |
| inline std::shared_ptr<milotic_tlbmc::SystemRegistryImpl> | |
| createSystemRegistryImpl() { | |
| milotic_tlbmc::SystemRegistryImpl::Config config{}; | |
| #ifdef ENABLE_CONFIGURE_CORE_COUNT | |
| config.bios_config_config = | |
| std::make_unique<::platforms::gbmc::hal::BiosConfigConfig>(); | |
| #endif | |
| absl::StatusOr<std::shared_ptr<milotic_tlbmc::SystemRegistryImpl>> | |
| system_registry = milotic_tlbmc::SystemRegistryImpl::Create(config); | |
| if (!system_registry.ok()) { | |
| LOG(WARNING) << "Failed to create system registry: " | |
| << system_registry.status(); | |
| return nullptr; | |
| } | |
| return *system_registry; | |
| } | |
| inline std::shared_ptr<milotic_tlbmc::CredentialManager> | |
| createCredentialManagerImpl( | |
| const milotic::RedfishServiceConfig& config, | |
| const milotic_tlbmc::CredentialManagerImpl::CredentialManagerParams* | |
| custom_params = nullptr) { | |
| if (custom_params != nullptr) { | |
| absl::StatusOr<std::unique_ptr<milotic_tlbmc::CredentialManager>> | |
| credential_manager = | |
| milotic_tlbmc::CredentialManagerImpl::Create(*custom_params); | |
| if (!credential_manager.ok()) { | |
| LOG(WARNING) << "Failed to create credential manager: " | |
| << credential_manager.status(); | |
| return nullptr; | |
| } | |
| return *std::move(credential_manager); | |
| } | |
| milotic_tlbmc::CredentialManagerImpl::CredentialManagerParams params{ | |
| .private_key_path = config.private_key_path, | |
| .cert_path = config.own_cert_path, | |
| .owner_verification_cert_path = config.owner_verification_cert_path, | |
| .owner_verification_config_path = config.owner_verification_config_path, | |
| .bmc_ssh_trusted_user_ca_keys_path = | |
| config.bmc_ssh_trusted_user_ca_keys_path, | |
| .trust_bundle_path = config.trust_bundle_path, | |
| .trust_bundle_signature_path = config.trust_bundle_signature_path, | |
| .os_verification_cert_path = config.os_verification_cert_path, | |
| .os_verification_key_path = config.os_verification_key_path, | |
| .serial_console_trusted_user_ca_keys_path = | |
| config.serial_console_trusted_user_ca_keys_path, | |
| .serial_console_detatched_signature_path = | |
| config.serial_console_detatched_signature_path, | |
| .serial_console_access_level_dir = config.serial_console_access_level_dir, | |
| .syslog_client_conf_override_path = | |
| config.syslog_client_conf_override_path, | |
| .syslog_root_cert_path = config.syslog_root_cert_path, | |
| .owner_verification_rwfs_dir = config.owner_verification_rwfs_dir, | |
| .bmc_ssh_trusted_user_ca_keys_rwfs_path = | |
| config.bmc_ssh_trusted_user_ca_keys_rwfs_path, | |
| }; | |
| absl::StatusOr<std::unique_ptr<milotic_tlbmc::CredentialManager>> | |
| credential_manager = milotic_tlbmc::CredentialManagerImpl::Create(params); | |
| if (!credential_manager.ok()) { | |
| LOG(WARNING) << "Failed to create credential manager: " | |
| << credential_manager.status(); | |
| return nullptr; | |
| } | |
| return *std::move(credential_manager); | |
| } | |
| inline int run() { | |
| // First so even startup-path exceptions terminate with a throw-site stack. | |
| // Also the explicit reference that pulls the tracer TU (and its __cxa_throw | |
| // interposer) out of the bmcweblib archive despite --gc-sections. | |
| #ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER | |
| installExceptionStackTracer(absl::GetFlag(FLAGS_exception_stack_tracer)); | |
| #endif // BMCWEB_ENABLE_EXCEPTION_STACK_TRACER | |
| std::shared_ptr<milotic_tlbmc::CredentialManager> credential_manager = | |
| nullptr; | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| absl::InitializeLog(); | |
| std::shared_ptr<milotic_tlbmc::SystemRegistry> system_registry = | |
| createSystemRegistryImpl(); | |
| #ifdef ENABLE_CONFIGURE_CORE_COUNT | |
| absl::Status status = system_registry->SetInitialCoreCounts(); | |
| if (!status.ok()) { | |
| LOG(WARNING) << "Failed to set initial core counts: " << status; | |
| } | |
| #endif | |
| milotic::RedfishServiceConfig secure_service_config; | |
| secure_service_config.port = absl::GetFlag(FLAGS_mtls_grpc_port); | |
| secure_service_config.private_key_path = | |
| absl::GetFlag(FLAGS_server_private_key_path); | |
| secure_service_config.own_cert_path = absl::GetFlag(FLAGS_server_cert_path); | |
| secure_service_config.tlbmc_entity_config_location = | |
| absl::GetFlag(FLAGS_entity_config_location); | |
| secure_service_config.smbios_single_host_file_path = | |
| absl::GetFlag(FLAGS_smbios_single_host_file_path); | |
| secure_service_config.smbios_multihost_host_file_path_prefix = | |
| absl::GetFlag(FLAGS_smbios_multihost_host_file_path_prefix); | |
| secure_service_config.smbios_single_host_status_file_path = | |
| absl::GetFlag(FLAGS_smbios_single_host_status_file_path); | |
| secure_service_config.smbios_multihost_host_status_file_path_prefix = | |
| absl::GetFlag(FLAGS_smbios_multihost_host_status_file_path_prefix); | |
| secure_service_config.smbios_blob_timeout_sec = | |
| absl::GetFlag(FLAGS_smbios_blob_timeout_sec); | |
| secure_service_config.multi_thread_get = | |
| absl::GetFlag(FLAGS_multi_thread_get); | |
| secure_service_config.enable_tlbmc = absl::GetFlag(FLAGS_enable_tlbmc); | |
| secure_service_config.generate_testing_events = | |
| absl::GetFlag(FLAGS_testing_events); | |
| secure_service_config.enable_fast_sanity = | |
| absl::GetFlag(FLAGS_enable_fast_sanity); | |
| secure_service_config.enable_hft_test_sensor = true; | |
| secure_service_config.enable_tlbmc_trace = | |
| absl::GetFlag(FLAGS_enable_tlbmc_trace); | |
| secure_service_config.enable_tlbmc_thermal_control = | |
| absl::GetFlag(FLAGS_enable_tlbmc_thermal_control); | |
| secure_service_config.tlbmc_defer_router_registration_and_validation = true; | |
| secure_service_config.system_registry = system_registry; | |
| credential_manager = createCredentialManagerImpl(secure_service_config); | |
| secure_service_config.credential_manager = credential_manager; | |
| std::unique_ptr<milotic_tlbmc::RedfishApp> tlbmc_app = | |
| milotic::GrpcRedfishService::CreateTlbmcApp(secure_service_config); | |
| #ifdef ENABLE_LOAS3_VALIDATION | |
| secure_service_config.check_loas3_policy = true; | |
| LOG(WARNING) << "check_loas3_policy is enabled"; | |
| #endif | |
| auto crowLogLevel = crow::LogLevel::Debug; | |
| crow::Logger::setLogLevel(crowLogLevel); | |
| const auto minAbslLogLevel = | |
| static_cast<absl::LogSeverity>(absl::GetFlag(FLAGS_minloglevel)); | |
| BMCWEB_LOG_ALWAYS << "=> minAbslLogLevel: " | |
| << static_cast<int>(minAbslLogLevel); | |
| switch (minAbslLogLevel) { | |
| // unfortunately there is no: absl::LogSeverity::kInfo; so kInfo -> | |
| // Debug for now. | |
| case absl::LogSeverity::kInfo: | |
| crowLogLevel = crow::LogLevel::Debug; | |
| break; | |
| case absl::LogSeverity::kWarning: | |
| crowLogLevel = crow::LogLevel::Warning; | |
| break; | |
| case absl::LogSeverity::kError: | |
| crowLogLevel = crow::LogLevel::Error; | |
| break; | |
| case absl::LogSeverity::kFatal: | |
| crowLogLevel = crow::LogLevel::Critical; | |
| break; | |
| default: | |
| crowLogLevel = crow::LogLevel::Error; | |
| break; | |
| } | |
| BMCWEB_LOG_ALWAYS << "=> crowLogLevel: " << static_cast<int>(crowLogLevel); | |
| crow::Logger::setLogLevel(crowLogLevel); | |
| #else | |
| crow::Logger::setLogLevel(crow::LogLevel::Debug); | |
| #endif | |
| auto io = std::make_shared<boost::asio::io_context>(); | |
| bool allowSessionEmpty = false; | |
| #ifdef BMCWEB_INSECURE_DISABLE_AUTHX | |
| allowSessionEmpty = true; | |
| #endif | |
| std::unique_ptr<devpath_plugin::RedfishDevpathInjector> devpath_injector = | |
| nullptr; | |
| absl::StatusOr<std::unique_ptr<devpath_plugin::RedfishDevpathInjector>> | |
| injector = devpath_plugin::RedfishDevpathInjector::Create( | |
| "/usr/share/redfish_to_uhm_mappings/" | |
| "redfish_to_uhm_mappings.textproto"); | |
| if (injector.ok()) { | |
| devpath_injector = std::move(*injector); | |
| BMCWEB_LOG_ALWAYS << "RedfishDevpathInjector successfully initialized from " | |
| "/usr/share/redfish_to_uhm_mappings/" | |
| "redfish_to_uhm_mappings.textproto"; | |
| } else { | |
| BMCWEB_LOG_ERROR << "Failed to initialize RedfishDevpathInjector: " | |
| << injector.status().message(); | |
| } | |
| App app(allowSessionEmpty, io, tlbmc_app.get(), devpath_injector.get()); | |
| crow::globalBmcWebApp = &app; | |
| std::shared_ptr<sdbusplus::asio::connection> systemBusPtr = | |
| std::make_shared<sdbusplus::asio::connection>(*io); | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| BMCWEB_LOG_STATEFUL_ALWAYS << "=> stateful: " | |
| << absl::GetFlag(FLAGS_stateful).value_or(false); | |
| #endif | |
| managedStore::ManagedObjectStoreConfig config; | |
| // default to the compiler flag: | |
| #ifdef BMCWEB_ENABLE_STATEFUL_BMCWEB | |
| config.isEnabled = true; | |
| #else | |
| config.isEnabled = false; | |
| #endif | |
| // request stats config: | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| { | |
| const auto& persistentDataConfig = persistent_data::getConfig(); | |
| managedStore::RequestStatsStoreConfig requestStatsConfig; | |
| requestStatsConfig.enable = false; | |
| requestStatsConfig.enableRdeRateLimit = false; | |
| // command line first: | |
| if (absl::GetFlag(FLAGS_request_stats).has_value()) { | |
| requestStatsConfig.enable = | |
| absl::GetFlag(FLAGS_request_stats).value_or(false); | |
| } | |
| // enable rde rate limiter | |
| if (absl::GetFlag(FLAGS_rde_ratelimit).has_value()) { | |
| requestStatsConfig.enableRdeRateLimit = | |
| absl::GetFlag(FLAGS_rde_ratelimit).value_or(false); | |
| } | |
| if (absl::GetFlag(FLAGS_rde_errors_max).has_value()) { | |
| requestStatsConfig.rdeDbusErrorThreshold = | |
| absl::GetFlag(FLAGS_rde_errors_max).value_or(10); | |
| } | |
| if (absl::GetFlag(FLAGS_rde_skips_max).has_value()) { | |
| requestStatsConfig.rdeMaxSkips = | |
| absl::GetFlag(FLAGS_rde_skips_max).value_or(30); | |
| } else if (persistentDataConfig.isStatefulEnabled | |
| .has_value()) { // persistent config: | |
| requestStatsConfig.enable = | |
| persistentDataConfig.isRequestStatsEnabled.value(); | |
| } | |
| BMCWEB_LOG_STATEFUL_ALWAYS << "=> request_stats: " | |
| << requestStatsConfig.toJson(); | |
| managedStore::RequestStatsStore::initialize(requestStatsConfig); | |
| } | |
| #endif | |
| // stateful logs: | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| { | |
| const auto& persistentDataConfig = persistent_data::getConfig(); | |
| bool enable_stateful_logs = false; | |
| // command line first: | |
| if (absl::GetFlag(FLAGS_stateful_logs).has_value()) { | |
| enable_stateful_logs = absl::GetFlag(FLAGS_stateful_logs).value_or(false); | |
| } else if (persistentDataConfig.isStatefulLogsEnabled | |
| .has_value()) { // persistent config: | |
| enable_stateful_logs = persistentDataConfig.isStatefulLogsEnabled.value(); | |
| } | |
| BMCWEB_LOG_STATEFUL_ALWAYS << "=> stateful_logs flag: " | |
| << enable_stateful_logs; | |
| if (enable_stateful_logs) { | |
| crow::Logger::enableStatefulLogs(); | |
| } | |
| } | |
| #endif | |
| // stateful config: | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| // command line is always higher priority if set: | |
| if (absl::GetFlag(FLAGS_stateful).has_value()) { | |
| config.isEnabled = absl::GetFlag(FLAGS_stateful).value(); | |
| } else // NOLINT | |
| #endif | |
| { | |
| // read the persistent data config: | |
| const auto& persistentDataConfig = persistent_data::getConfig(); | |
| if (persistentDataConfig.isStatefulEnabled.has_value()) { | |
| config.isEnabled = persistentDataConfig.isStatefulEnabled.value(); | |
| } | |
| } | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| // other flags: | |
| if (absl::GetFlag(FLAGS_stateful_pending_max).has_value()) { | |
| config.pendingDbusResponsesMax = static_cast<uint64_t>( | |
| absl::GetFlag(FLAGS_stateful_pending_max).value()); | |
| } | |
| if (absl::GetFlag(FLAGS_stateful_tfixed_sec).has_value()) { | |
| config.tfixedThreshold = | |
| std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tfixed_sec).value()); | |
| } | |
| if (absl::GetFlag(FLAGS_stateful_tgrace_sec).has_value()) { | |
| config.tgraceThreshold = | |
| std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tgrace_sec).value()); | |
| } | |
| if (absl::GetFlag(FLAGS_stateful_tlru_sec).has_value()) { | |
| config.tLRUThreshold = | |
| std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tlru_sec).value()); | |
| } | |
| if (absl::GetFlag(FLAGS_timetrace).has_value()) { | |
| config.timetrace = absl::GetFlag(FLAGS_timetrace).value(); | |
| } | |
| if (absl::GetFlag(FLAGS_timetrace_size_max).has_value()) { | |
| config.timetrace_size_max = absl::GetFlag(FLAGS_timetrace_size_max).value(); | |
| } | |
| #endif | |
| BMCWEB_LOG_STATEFUL_ALWAYS << "=> ManagedObjectStoreConfig: " | |
| << config.toString(); | |
| #ifndef BMCWEB_ENABLE_STATEFUL_BMCWEB | |
| if (config.isEnabled) { | |
| BMCWEB_LOG_WARNING | |
| << "ManagedObjectStore can't be enabled without " | |
| << "BMCWEB_ENABLE_STATEFUL_BMCWEB; reverting to stateful=0"; | |
| config.isEnabled = false; | |
| } | |
| #endif // BMCWEB_ENABLE_STATEFUL_BMCWEB | |
| setupSocket(app); | |
| std::unique_ptr<ecclesia::SubscriptionService> subscriptionService = nullptr; | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| bool enableRedfishEvents = absl::GetFlag(FLAGS_redfish_events); | |
| size_t number_of_events_stored = defaultRedfishEventStoreSize; | |
| if (absl::GetFlag(FLAGS_redfish_event_store_size).has_value()) { | |
| number_of_events_stored = | |
| absl::GetFlag(FLAGS_redfish_event_store_size).value(); | |
| } | |
| using ::milotic::GrpcRedfishService; | |
| using ::milotic::RedfishServiceConfig; | |
| if (enableRedfishEvents) { | |
| BMCWEB_LOG_ALWAYS << "Redfish events enabled\n"; | |
| subscriptionService = CreateSubscriptionService( | |
| milotic::BmcWebBackend::Create(&app), | |
| ecclesia::CreateSubscriptionStore(), | |
| ecclesia::CreateEventStore(number_of_events_stored)); | |
| } | |
| #endif | |
| // ManagedStore should be initialized regardless of whether grpc is enabled | |
| auto io_worker_threads = std::make_shared<boost::asio::io_context>(); | |
| uint num_workers = std::thread::hardware_concurrency(); | |
| boost::asio::thread_pool worker_threads(num_workers); | |
| boost::asio::executor_work_guard<boost::asio::io_context::executor_type> | |
| work_guard_worker_threads( | |
| boost::asio::make_work_guard(*io_worker_threads)); | |
| boost::asio::executor_work_guard<boost::asio::io_context::executor_type> | |
| work_guard_main_thread(boost::asio::make_work_guard(*io)); | |
| for (uint i = 0; i < num_workers; ++i) { | |
| boost::asio::post(worker_threads, | |
| [io_worker_threads]() { io_worker_threads->run(); }); | |
| } | |
| managedStore::InitializeManagedStore(&config, io.get(), io_worker_threads, | |
| subscriptionService.get(), | |
| systemBusPtr.get(), system_registry); | |
| // Static assets need to be initialized before Authorization, because auth | |
| // needs to build the whitelist from the static routes | |
| #ifdef BMCWEB_ENABLE_STATIC_HOSTING | |
| crow::webassets::requestRoutes(app); | |
| #endif | |
| #ifdef BMCWEB_ENABLE_REDFISH | |
| redfish::RedfishService redfish(app); | |
| #endif | |
| #ifdef BMCWEB_ENABLE_DBUS_REST | |
| crow::image_upload::requestRoutes(app); | |
| crow::openbmc_mapper::requestRoutes(app); | |
| #endif | |
| #ifdef BMCWEB_ENABLE_GOOGLE_API | |
| crow::google_api::setupCredentialManager(credential_manager); | |
| crow::google_api::requestRoutes(app); | |
| crow::google_api::requestGoogleNVMeCollection(app); | |
| crow::google_api::requestGoogleNVMe(app); | |
| crow::google_api::requestGoogleNVMeController(app); | |
| crow::google_api::requestGoogleNVMeControllerCollection(app); | |
| crow::google_api::setupGoogleNVMeFdFetchIOContext(io); | |
| crow::google_api::requestGoogleNVMeControllerActionIdentify(app); | |
| crow::google_api::requestGoogleNVMeControllerActionLog(app); | |
| crow::google_api::requestGoogleNVMeControllerActionCustomNVMeIdentify(app); | |
| crow::google_api::requestGoogleNVMeControllerActionAdminNonData(app); | |
| crow::google_api::requestGoogleNVMeControllerActionLockdownInband(app); | |
| #endif | |
| if (bmcwebInsecureDisableXssPrevention != 0) { | |
| cors_preflight::requestRoutes(app); | |
| } | |
| #ifdef BMCWEB_ENABLE_GRPC | |
| #ifdef BMCWEB_ENABLE_INSECURE_GRPC | |
| std::cerr << "insecure grpc opened!\n"; | |
| RedfishServiceConfig insecure_config{ | |
| .port = absl::GetFlag(FLAGS_insecure_grpc_port), | |
| .self_signed_key_cert_path = "/var/volatile/self_signed_key_cert2.pem", | |
| .tlbmc_entity_config_location = | |
| absl::GetFlag(FLAGS_entity_config_location), | |
| .smbios_single_host_file_path = | |
| absl::GetFlag(FLAGS_smbios_single_host_file_path), | |
| .smbios_multihost_host_file_path_prefix = | |
| absl::GetFlag(FLAGS_smbios_multihost_host_file_path_prefix), | |
| .smbios_single_host_status_file_path = | |
| absl::GetFlag(FLAGS_smbios_single_host_status_file_path), | |
| .smbios_multihost_host_status_file_path_prefix = | |
| absl::GetFlag(FLAGS_smbios_multihost_host_status_file_path_prefix), | |
| .smbios_blob_timeout_sec = absl::GetFlag(FLAGS_smbios_blob_timeout_sec), | |
| .multi_thread_get = absl::GetFlag(FLAGS_multi_thread_get), | |
| .enable_tlbmc = absl::GetFlag(FLAGS_enable_tlbmc), | |
| .enable_insecure_server = true, | |
| .enable_fast_sanity = absl::GetFlag(FLAGS_enable_fast_sanity), | |
| .enable_tlbmc_thermal_control = | |
| absl::GetFlag(FLAGS_enable_tlbmc_thermal_control), | |
| .tlbmc_defer_router_registration_and_validation = true, | |
| .system_registry = system_registry, | |
| .credential_manager = credential_manager, | |
| }; | |
| GrpcRedfishService insecure_grpc_service( | |
| &app, tlbmc_app.get(), io, io_worker_threads, insecure_config, nullptr); | |
| #endif | |
| GrpcRedfishService grpc_service(&app, tlbmc_app.get(), io, io_worker_threads, | |
| secure_service_config, | |
| subscriptionService.get()); | |
| #endif | |
| // Register tlBMC append plugins before gBMCWeb plugins | |
| GrpcRedfishService::RegisterTlbmcRoutesAndValidate(tlbmc_app.get()); | |
| // These have to be registered after managedStore initialization | |
| #ifdef BMCWEB_ENABLE_SSL | |
| BMCWEB_LOG_INFO << "Start Hostname Monitor Service..."; | |
| crow::hostname_monitor::registerHostnameSignal(); | |
| #endif | |
| bmcweb::registerUserRemovedSignal(); | |
| #ifdef PLATFORM_PLUGINS_ENABLED | |
| redfish_plugin::loadPlatformPlugins(); | |
| #endif | |
| #ifdef GOOGLE_COMMON_PLUGINS_ENABLED | |
| redfish_plugin::loadGooglePlugins(); | |
| #endif | |
| #ifdef GOOGLE_PLUGINS_INTERNAL_ENABLED | |
| redfish_plugin::loadGooglePluginsInternal(); | |
| #endif | |
| #ifdef HEALTH_POPULATE | |
| redfish::HealthStatusCache::getInstance(); | |
| #ifndef UNIT_TEST_BUILD | |
| /* | |
| * This call subscribes to a live D-Bus signal from the HealthMonitor. | |
| * This directive excludes the live subscription call during the unit test | |
| * build, allowing the test to verify logic without attempting to create | |
| * a real signal match which does not exist in the test environment. | |
| */ | |
| managedStore::GetManagedObjectStore()->subscribeToEntityManagerChange( | |
| [](const std::string& objPath) { | |
| redfish::HealthStatusCache::getInstance().getHealthAttributes(objPath); | |
| }); | |
| #endif /* UNIT_TEST_BUILD */ | |
| #endif /* HEALTH_POPULATE */ | |
| app.validate(); | |
| sd_notify(0, "READY=1"); | |
| app.run(); | |
| // This will block forever, so skipping these in unit test builds | |
| #ifndef UNIT_TEST_BUILD | |
| io->run(); | |
| io_worker_threads->stop(); | |
| worker_threads.join(); | |
| #endif | |
| return 0; | |
| } | |
| #endif // THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_ |