blob: d431fdfe16fde12b2feb8aeee05c6d1233fbef11 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "peridot/lib/modular_config/modular_config.h"
#include <fcntl.h>
#include <src/lib/fxl/strings/substitute.h>
#include "peridot/lib/fidl/json_xdr.h"
#include "peridot/lib/modular_config/modular_config_constants.h"
#include "peridot/lib/modular_config/modular_config_xdr.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
namespace modular {
namespace {
std::string GetSectionAsString(const rapidjson::Document& doc, const std::string& section_name) {
auto config_json = doc.FindMember(section_name);
if (config_json == doc.MemberEnd()) {
// |section_name| was not found
return "{}";
}
return modular::JsonValueToString(config_json->value);
}
std::string StripLeadingSlash(std::string str) {
if (str.find("/") == 0)
return str.substr(1);
return str;
}
} // namespace
ModularConfigReader::ModularConfigReader(fbl::unique_fd dir_fd) {
FXL_CHECK(dir_fd.get() >= 0);
// 1. Figure out where the config file is.
std::string config_path = files::JoinPath(StripLeadingSlash(modular_config::kOverriddenConfigDir),
modular_config::kStartupConfigFilePath);
if (!files::IsFileAt(dir_fd.get(), config_path)) {
config_path = files::JoinPath(StripLeadingSlash(modular_config::kDefaultConfigDir),
modular_config::kStartupConfigFilePath);
}
// 2. Parse the JSON out of the config file.
json::JSONParser json_parser;
auto doc = json_parser.ParseFromFileAt(dir_fd.get(), config_path);
ParseConfig(std::move(json_parser), std::move(doc), config_path);
}
ModularConfigReader::ModularConfigReader(std::string config, std::string config_path) {
// Parse the JSON out of the config string.
json::JSONParser json_parser;
auto doc = json_parser.ParseFromString(config, config_path);
ParseConfig(std::move(json_parser), std::move(doc), config_path);
}
// static
ModularConfigReader ModularConfigReader::CreateFromNamespace() {
return ModularConfigReader(fbl::unique_fd(open("/", O_RDONLY)));
}
ModularConfigReader::~ModularConfigReader() {}
void ModularConfigReader::ParseConfig(json::JSONParser json_parser, rapidjson::Document doc,
std::string config_path) {
std::string basemgr_json;
std::string sessionmgr_json;
if (json_parser.HasError()) {
FXL_LOG(ERROR) << "Error while parsing " << config_path
<< " to string. Error: " << json_parser.error_str();
// Leave |basemgr_config_| and |sessionmgr_config_| empty-initialized.
basemgr_json = "{}";
sessionmgr_json = "{}";
} else {
// Parse the `basemgr` and `sessionmgr` sections out of the config.
basemgr_json = GetSectionAsString(doc, modular_config::kBasemgrConfigName);
sessionmgr_json = GetSectionAsString(doc, modular_config::kSessionmgrConfigName);
}
if (!XdrRead(basemgr_json, &basemgr_config_, XdrBasemgrConfig)) {
FXL_LOG(ERROR) << "Unable to parse 'basemgr' from " << config_path;
}
if (!XdrRead(sessionmgr_json, &sessionmgr_config_, XdrSessionmgrConfig)) {
FXL_LOG(ERROR) << "Unable to parse 'sessionmgr' from " << config_path;
}
}
fuchsia::modular::session::BasemgrConfig ModularConfigReader::GetBasemgrConfig() const {
fuchsia::modular::session::BasemgrConfig result;
basemgr_config_.Clone(&result);
return result;
}
fuchsia::modular::session::SessionmgrConfig ModularConfigReader::GetSessionmgrConfig() const {
fuchsia::modular::session::SessionmgrConfig result;
sessionmgr_config_.Clone(&result);
return result;
}
fuchsia::modular::session::SessionmgrConfig ModularConfigReader::GetDefaultSessionmgrConfig()
const {
fuchsia::modular::session::SessionmgrConfig sessionmgr_config;
XdrRead("{}", &sessionmgr_config, XdrSessionmgrConfig);
return sessionmgr_config;
}
// static
std::string ModularConfigReader::GetConfigAsString(
fuchsia::modular::session::BasemgrConfig* basemgr_config,
fuchsia::modular::session::SessionmgrConfig* sessionmgr_config) {
std::string basemgr_json;
std::string sessionmgr_json;
XdrWrite(&basemgr_json, basemgr_config, XdrBasemgrConfig);
XdrWrite(&sessionmgr_json, sessionmgr_config, XdrSessionmgrConfig);
return fxl::Substitute(R"({
"$0": $1,
"$2": $3
})",
modular_config::kBasemgrConfigName, basemgr_json,
modular_config::kSessionmgrConfigName, sessionmgr_json);
}
} // namespace modular