genode/repos/gems/src/app/depot_deploy/main.cc

118 lines
3.0 KiB
C++

/*
* \brief Tool for turning a subsystem blueprint into an init configuration
* \author Norman Feske
* \date 2017-07-07
*/
/*
* Copyright (C) 2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <util/retry.h>
#include <util/reconstructible.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <base/heap.h>
#include <os/reporter.h>
/* local includes */
#include "children.h"
namespace Depot_deploy { struct Main; }
struct Depot_deploy::Main
{
Env &_env;
Attached_rom_dataspace _config { _env, "config" };
Attached_rom_dataspace _blueprint { _env, "blueprint" };
Expanding_reporter _query_reporter { _env, "query" , "query"};
Expanding_reporter _init_config_reporter { _env, "config", "init.config"};
Constructible<Expanding_reporter> _state_reporter { };
Heap _heap { _env.ram(), _env.rm() };
Children _children { _heap };
Signal_handler<Main> _config_handler {
_env.ep(), *this, &Main::_handle_config };
typedef String<128> Name;
void _handle_config()
{
_config.update();
_blueprint.update();
bool const report_state =
_config.xml().has_sub_node("report") &&
_config.xml().sub_node("report").attribute_value("state", false);
_state_reporter.conditional(report_state, _env, "state", "state");
if (_state_reporter.constructed())
_state_reporter->generate([&] (Xml_generator xml) {
xml.attribute("running", true); });
Xml_node const config = _config.xml();
_children.apply_config(config);
_children.apply_blueprint(_blueprint.xml());
/* determine CPU architecture of deployment */
typedef String<16> Arch;
Arch const arch = config.attribute_value("arch", Arch());
if (!arch.valid())
warning("config lacks 'arch' attribute");
/* generate init config containing all configured start nodes */
_init_config_reporter.generate([&] (Xml_generator &xml) {
Xml_node static_config = config.sub_node("static");
static_config.with_raw_content([&] (char const *start, size_t length) {
xml.append(start, length); });
Child::Depot_rom_server const parent { };
_children.gen_start_nodes(xml, config.sub_node("common_routes"),
parent, parent);
});
/* update query for blueprints of all unconfigured start nodes */
if (arch.valid()) {
_query_reporter.generate([&] (Xml_generator &xml) {
xml.attribute("arch", arch);
_children.gen_queries(xml);
});
}
if ((_children.count() > 0UL)
&& !_children.any_incomplete()
&& !_children.any_blueprint_needed()
&& _state_reporter.constructed()) {
_state_reporter->generate([&] (Xml_generator xml) {
xml.attribute("running", false);
xml.attribute("count", _children.count());
});
}
}
Main(Env &env) : _env(env)
{
_config .sigh(_config_handler);
_blueprint.sigh(_config_handler);
_handle_config();
}
};
void Component::construct(Genode::Env &env) { static Depot_deploy::Main main(env); }