blob: 92fecd163e09aae9bca6ad811caea1b170404531 [file] [log] [blame]
#include "tlbmc/central_config/config.h"
#include <fstream>
#include <string>
#include <string_view>
#include "absl/base/no_destructor.h"
#include "absl/log/log.h"
#include "central_config.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/text_format.h"
namespace milotic_tlbmc {
namespace internal {
constexpr const char* kRofsConfigBundlePath =
"/etc/tlbmc/tlbmc_config_bundle.textproto";
using ::google::protobuf::TextFormat;
using ::google::protobuf::io::IstreamInputStream;
std::string GetPlatformName(const std::string& release_file_path) {
std::ifstream release_file(release_file_path);
if (!release_file.is_open()) {
LOG(WARNING) << "Failed to open release file at '" << release_file_path
<< "'. Using default platform name.";
return "";
}
std::string read_line;
std::string platform_name;
while (std::getline(release_file, read_line)) {
constexpr std::string_view kPlatformNamePrefix = "OPENBMC_TARGET_MACHINE=";
if (!read_line.starts_with(kPlatformNamePrefix)) {
continue;
}
platform_name = read_line.substr(kPlatformNamePrefix.size());
break;
}
// Remove the quotes if any.
if (platform_name.size() > 2 && platform_name.front() == '"' &&
platform_name.back() == '"') {
platform_name = platform_name.substr(1, platform_name.size() - 2);
}
return platform_name;
}
TlbmcConfig MergeConfig(const TlbmcConfig& general_config,
const TlbmcConfig& platform_config) {
TlbmcConfig merged_config = general_config;
merged_config.MergeFrom(platform_config);
return merged_config;
}
TlbmcConfig GetConfigFromPathOrFallbackToDefault(
const std::string& config_bundle_path,
const std::string& release_file_path) {
// Try to open the config bundle file from the given path. If it fails, try to
// open the rofs config bundle file. If both fail, return the default config.
std::ifstream config_file(config_bundle_path);
if (!config_file.is_open()) {
LOG(WARNING) << "Failed to open config bundle file at '"
<< config_bundle_path << "'. Using default config.";
config_file = std::ifstream(kRofsConfigBundlePath);
if (!config_file.is_open()) {
LOG(WARNING) << "Failed to open rofs config bundle file at '"
<< kRofsConfigBundlePath << "'. Using default config.";
return TlbmcConfig();
}
}
TlbmcConfigBundle config_bundle;
IstreamInputStream istream_source(&config_file);
if (!TextFormat::Parse(&istream_source, &config_bundle)) {
LOG(WARNING) << "Failed to parse config bundle from file: '"
<< config_bundle_path << "'. Using default config.";
return TlbmcConfig();
}
std::string platform_name = GetPlatformName(release_file_path);
if (auto it = config_bundle.platform_to_config().find(platform_name);
it != config_bundle.platform_to_config().end()) {
return MergeConfig(config_bundle.general_config(), it->second);
}
return config_bundle.general_config();
}
} // namespace internal
TlbmcConfig& InitializeTlbmcConfig(const std::string& config_bundle_path,
const std::string& release_file_path) {
static absl::NoDestructor<TlbmcConfig> static_config(
internal::GetConfigFromPathOrFallbackToDefault(config_bundle_path,
release_file_path));
return *static_config;
}
const TlbmcConfig& GetTlbmcConfig() { return InitializeTlbmcConfig("", ""); }
TlbmcConfig& GetMutableTlbmcConfigForTest() {
return InitializeTlbmcConfig("", "");
}
} // namespace milotic_tlbmc