diff --git a/repos/gems/recipes/pkg/sculpt/archives b/repos/gems/recipes/pkg/sculpt/archives
index 51f69b996f..482040abb1 100644
--- a/repos/gems/recipes/pkg/sculpt/archives
+++ b/repos/gems/recipes/pkg/sculpt/archives
@@ -45,3 +45,4 @@ _/src/zlib
_/src/menu_view
_/src/gpt_write
_/src/sculpt_manager
+_/src/fs_query
diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run
index 404903b142..e3e4fb6d31 100644
--- a/repos/gems/run/sculpt.run
+++ b/repos/gems/run/sculpt.run
@@ -110,6 +110,7 @@ install_config {
+
} [config_system_content] {
@@ -514,7 +515,7 @@ close $fd
#
-# Manual configuration of deploy runtime
+# Configuration of deploy runtime
#
# This configuration is not provided as a file at run/sculpt/ because some
# parts need to be filled in at run-script execution time, in particular the
@@ -532,200 +533,24 @@ append manual_deploy_config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
@@ -734,6 +559,51 @@ puts $fd $manual_deploy_config
close $fd
+#
+# Install launcher snippets
+#
+# The launcher snippets are wrapped into a tar archive to be loaded as boot
+# module. This procedure involves the following steps:
+#
+# The launcher snippets are copied from run/sculpt/launcher/ to
+# [run_dir]/genode/launcher. Each launcher is inspected regarding its 'pkg'
+# attribute. If its 'pkg' attribute contains a single identifier (rather than
+# a valid pkg path), the attribute value is replaced by a valid pkg path
+# referring to the current version of the pkg and the [depot_user]. The
+# filtered launchers are archived into 'launcher.tar' and removed from the
+# [run_dir].
+#
+
+set launchers [glob -tails -directory [genode_dir]/repos/gems/run/sculpt/launcher/ *]
+
+foreach file $launchers {
+
+ # skip backup files
+ if {[regexp {~$} $file dummy]} { continue }
+
+ set fd [open [genode_dir]/repos/gems/run/sculpt/launcher/$file r]
+ set content [read $fd]
+ close $fd
+
+ # filter 'pkg' attribute
+ set pattern {(\]+?pkg=")([^/]+)(")}
+ if {[regexp $pattern $content dummy head pkg tail]} {
+ set pkg_path [depot_user]/pkg/[current_pkg $pkg]
+ regsub $pattern $content "$head$pkg_path$tail" content
+ }
+
+ # write filtered launcher snippet
+ file mkdir [run_dir]/genode/launcher
+ set fd [open [run_dir]/genode/launcher/$file w]
+ puts $fd $content
+ close $fd
+}
+
+# wrap launcher snippets into tar archive and remove individual snippets
+exec tar cf [run_dir]/genode/launcher.tar -C [run_dir]/genode launcher
+exec rm -r [run_dir]/genode/launcher
+
+
#
# Create boot image
#
diff --git a/repos/gems/run/sculpt/launcher/2048 b/repos/gems/run/sculpt/launcher/2048
new file mode 100644
index 0000000000..4bae8f5559
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/2048
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/acpica b/repos/gems/run/sculpt/launcher/acpica
new file mode 100644
index 0000000000..0fb7ed3c5b
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/acpica
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/backdrop b/repos/gems/run/sculpt/launcher/backdrop
new file mode 100644
index 0000000000..ae0ad5ac89
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/backdrop
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/config_editor b/repos/gems/run/sculpt/launcher/config_editor
new file mode 100644
index 0000000000..0b88be5864
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/config_editor
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/download_debian b/repos/gems/run/sculpt/launcher/download_debian
new file mode 100644
index 0000000000..35533fe6ea
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/download_debian
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/fonts_fs b/repos/gems/run/sculpt/launcher/fonts_fs
new file mode 100644
index 0000000000..e9aa7bdca5
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/fonts_fs
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/gambatte b/repos/gems/run/sculpt/launcher/gambatte
new file mode 100644
index 0000000000..8508c9d33b
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/gambatte
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/nano3d b/repos/gems/run/sculpt/launcher/nano3d
new file mode 100644
index 0000000000..38d39fed9c
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/nano3d
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/noux-system b/repos/gems/run/sculpt/launcher/noux-system
new file mode 100644
index 0000000000..342a8f1534
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/noux-system
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/report_dump b/repos/gems/run/sculpt/launcher/report_dump
new file mode 100644
index 0000000000..6849520d7f
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/report_dump
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/seoul-vmm-browser b/repos/gems/run/sculpt/launcher/seoul-vmm-browser
new file mode 100644
index 0000000000..7a552e0e85
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/seoul-vmm-browser
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/shared_fs b/repos/gems/run/sculpt/launcher/shared_fs
new file mode 100644
index 0000000000..5f32c42641
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/shared_fs
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/top_view b/repos/gems/run/sculpt/launcher/top_view
new file mode 100644
index 0000000000..a60d7e3d35
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/top_view
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/usb_devices_rom b/repos/gems/run/sculpt/launcher/usb_devices_rom
new file mode 100644
index 0000000000..b432c3c03e
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/usb_devices_rom
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/vbox5-tc-browser b/repos/gems/run/sculpt/launcher/vbox5-tc-browser
new file mode 100644
index 0000000000..9bf6974ea6
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/vbox5-tc-browser
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/vm b/repos/gems/run/sculpt/launcher/vm
new file mode 100644
index 0000000000..5cd90f6156
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/vm
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/vm_fs b/repos/gems/run/sculpt/launcher/vm_fs
new file mode 100644
index 0000000000..4f77086ef0
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/vm_fs
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/repos/gems/run/sculpt/launcher/wm b/repos/gems/run/sculpt/launcher/wm
new file mode 100644
index 0000000000..a48fdf651e
--- /dev/null
+++ b/repos/gems/run/sculpt/launcher/wm
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/repos/gems/src/app/depot_deploy/child.h b/repos/gems/src/app/depot_deploy/child.h
index f03583e3de..c6b5e9a551 100644
--- a/repos/gems/src/app/depot_deploy/child.h
+++ b/repos/gems/src/app/depot_deploy/child.h
@@ -35,13 +35,15 @@ class Depot_deploy::Child : public List_model::Element
typedef String<80> Binary_name;
typedef String<80> Config_name;
typedef String<32> Depot_rom_server;
+ typedef String<100> Launcher_name;
private:
Allocator &_alloc;
- Reconstructible _start_xml; /* from config */
- Constructible _pkg_xml { }; /* from blueprint */
+ Reconstructible _start_xml; /* from config */
+ Constructible _launcher_xml { };
+ Constructible _pkg_xml { }; /* from blueprint */
/*
* State of the condition check for generating the start node of
@@ -55,11 +57,34 @@ class Depot_deploy::Child : public List_model::Element
Name const _name;
+ bool _defined_by_launcher() const
+ {
+ /*
+ * If the node lacks a 'pkg' attribute, we expect the
+ * policy to be defined by a launcher XML snippet.
+ */
+ return _start_xml.constructed() && !_start_xml->xml().has_attribute("pkg");
+ }
+
Archive::Path _config_pkg_path() const
{
+ if (_defined_by_launcher() && _launcher_xml.constructed())
+ return _launcher_xml->xml().attribute_value("pkg", Archive::Path());
+
return _start_xml->xml().attribute_value("pkg", Archive::Path());
}
+ Launcher_name _launcher_name() const
+ {
+ if (!_defined_by_launcher())
+ return Launcher_name();
+
+ if (_start_xml->xml().has_attribute("launcher"))
+ return _start_xml->xml().attribute_value("launcher", Launcher_name());
+
+ return _start_xml->xml().attribute_value("name", Launcher_name());
+ }
+
/*
* The pkg-archive path of the current blueprint query, which may
* deviate from pkg path given in the config, once the config is
@@ -67,8 +92,12 @@ class Depot_deploy::Child : public List_model::Element
*/
Archive::Path _blueprint_pkg_path = _config_pkg_path();
- Ram_quota _ram_quota { 0 };
- Cap_quota _cap_quota { 0 };
+ /*
+ * Quota definitions obtained from the blueprint
+ */
+ Number_of_bytes _pkg_ram_quota { 0 };
+ unsigned long _pkg_cap_quota { 0 };
+
Binary_name _binary_name { };
Config_name _config_name { };
@@ -131,20 +160,21 @@ class Depot_deploy::Child : public List_model::Element
if (!start_node_changed)
return;
- Archive::Path const pkg =
- start_node.attribute_value("pkg", Archive::Path());
-
- /* invalidate blueprint if 'pkg' attribute of start node changed */
- if (pkg != _config_pkg_path())
- _pkg_xml.destruct();
-
- _blueprint_pkg_path = pkg;
+ Archive::Path const old_pkg_path = _config_pkg_path();
/* import new start node */
_start_xml.construct(_alloc, start_node);
- /* reset error state, attempt to obtain the blueprint again */
- _pkg_incomplete = false;
+ Archive::Path const new_pkg_path = _config_pkg_path();
+
+ /* invalidate blueprint if 'pkg' path changed */
+ if (old_pkg_path != new_pkg_path) {
+ _blueprint_pkg_path = new_pkg_path;
+ _pkg_xml.destruct();
+
+ /* reset error state, attempt to obtain the blueprint again */
+ _pkg_incomplete = false;
+ }
}
void apply_blueprint(Xml_node pkg)
@@ -157,11 +187,8 @@ class Depot_deploy::Child : public List_model::Element
Xml_node const runtime = pkg.sub_node("runtime");
- Number_of_bytes const ram { runtime.attribute_value("ram", Number_of_bytes()) };
- _ram_quota = Ram_quota { _start_xml->xml().attribute_value("ram", ram) };
-
- unsigned long const caps = runtime.attribute_value("caps", 0UL);
- _cap_quota = Cap_quota { _start_xml->xml().attribute_value("caps", caps) };
+ _pkg_ram_quota = runtime.attribute_value("ram", Number_of_bytes());
+ _pkg_cap_quota = runtime.attribute_value("caps", 0UL);
_binary_name = runtime.attribute_value("binary", Binary_name());
_config_name = runtime.attribute_value("config", Config_name());
@@ -170,22 +197,57 @@ class Depot_deploy::Child : public List_model::Element
_pkg_xml.construct(_alloc, pkg);
}
- template
- void apply_condition(COND_FN const &fn)
+ void apply_launcher(Launcher_name const &name, Xml_node launcher)
{
- /* don't check the condition twice */
- if (_condition == SATISFIED)
+ if (!_defined_by_launcher())
return;
+ if (_launcher_name() != name)
+ return;
+
+ if (_launcher_xml.constructed()) {
+ bool const launcher_changed =
+ (launcher.size() != _launcher_xml->xml().size()) ||
+ (strcmp(launcher.addr(), _launcher_xml->xml().addr(),
+ launcher.size()) != 0);
+
+ if (!launcher_changed)
+ return;
+ }
+
+ _launcher_xml.construct(_alloc, launcher);
+
+ _blueprint_pkg_path = _config_pkg_path();
+ }
+
+ /*
+ * \return true if condition changed
+ */
+ template
+ bool apply_condition(COND_FN const &fn)
+ {
+ Condition const orig_condition = _condition;
+
+ Xml_node launcher_xml = _launcher_xml.constructed()
+ ? _launcher_xml->xml()
+ : Xml_node("");
+
if (_start_xml.constructed())
- _condition = fn(_start_xml->xml()) ? SATISFIED : UNSATISFIED;
+ _condition = fn(_start_xml->xml(), launcher_xml)
+ ? SATISFIED : UNSATISFIED;
+
+ return _condition != orig_condition;
}
template
void apply_if_unsatisfied(FN const &fn) const
{
+ Xml_node launcher_xml = _launcher_xml.constructed()
+ ? _launcher_xml->xml()
+ : Xml_node("");
+
if (_condition == UNSATISFIED && _start_xml.constructed())
- fn(_start_xml->xml());
+ fn(_start_xml->xml(), launcher_xml);
}
void mark_as_incomplete(Xml_node missing)
@@ -219,6 +281,9 @@ class Depot_deploy::Child : public List_model::Element
if (_configured() || _pkg_incomplete)
return;
+ if (_defined_by_launcher() && !_launcher_xml.constructed())
+ return;
+
xml.node("blueprint", [&] () {
xml.attribute("pkg", _blueprint_pkg_path); });
}
@@ -264,6 +329,9 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
if (!_configured() || _condition == UNSATISFIED)
return;
+ if (_defined_by_launcher() && !_launcher_xml.constructed())
+ return;
+
if (!_pkg_xml->xml().has_sub_node("runtime")) {
warning("blueprint for '", _name, "' lacks runtime information");
return;
@@ -272,7 +340,13 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
xml.node("start", [&] () {
xml.attribute("name", _name);
- xml.attribute("caps", _cap_quota.value);
+
+ unsigned long caps = _pkg_cap_quota;
+ if (_defined_by_launcher())
+ caps = _launcher_xml->xml().attribute_value("caps", caps);
+ caps = _start_xml->xml().attribute_value("caps", caps);
+
+ xml.attribute("caps", caps);
typedef String<64> Version;
Version const version = _start_xml->xml().attribute_value("version", Version());
@@ -281,22 +355,32 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
xml.node("binary", [&] () { xml.attribute("name", _binary_name); });
+ Number_of_bytes ram = _pkg_ram_quota;
+ if (_defined_by_launcher())
+ ram = _launcher_xml->xml().attribute_value("ram", ram);
+ ram = _start_xml->xml().attribute_value("ram", ram);
+
xml.node("resource", [&] () {
xml.attribute("name", "RAM");
- xml.attribute("quantum", String<32>(Number_of_bytes(_ram_quota.value)));
+ xml.attribute("quantum", String<32>(ram));
});
Xml_node const runtime = _pkg_xml->xml().sub_node("runtime");
/*
- * Insert inline '' node if provided by the start node or the
+ * Insert inline '' node if provided by the start node,
+ * the launcher definition (if a launcher is user), or the
* blueprint. The former is preferred over the latter.
*/
if (_start_xml->xml().has_sub_node("config")) {
_gen_copy_of_sub_node(xml, _start_xml->xml(), "config");
} else {
- if (runtime.has_sub_node("config"))
- _gen_copy_of_sub_node(xml, runtime, "config");
+ if (_defined_by_launcher() && _launcher_xml->xml().has_sub_node("config")) {
+ _gen_copy_of_sub_node(xml, _launcher_xml->xml(), "config");
+ } else {
+ if (runtime.has_sub_node("config"))
+ _gen_copy_of_sub_node(xml, runtime, "config");
+ }
}
/*
@@ -344,6 +428,14 @@ void Depot_deploy::Child::_gen_routes(Xml_generator &xml, Xml_node common,
xml.append(route.content_base(), route.content_size());
}
+ /*
+ * Add routes given in the launcher definition.
+ */
+ if (_launcher_xml.constructed() && _launcher_xml->xml().has_sub_node("route")) {
+ Xml_node const route = _launcher_xml->xml().sub_node("route");
+ xml.append(route.content_base(), route.content_size());
+ }
+
/**
* Return name of depot-ROM server used for obtaining the 'path'
*
diff --git a/repos/gems/src/app/depot_deploy/children.h b/repos/gems/src/app/depot_deploy/children.h
index 9ebe065b1c..7b76c4ec05 100644
--- a/repos/gems/src/app/depot_deploy/children.h
+++ b/repos/gems/src/app/depot_deploy/children.h
@@ -67,6 +67,12 @@ class Depot_deploy::Children
_children.update_from_xml(_model_update_policy, config);
}
+ void apply_launcher(Child::Launcher_name const &name, Xml_node launcher)
+ {
+ _children.for_each([&] (Child &child) {
+ child.apply_launcher(name, launcher); });
+ }
+
void apply_blueprint(Xml_node blueprint)
{
blueprint.for_each_sub_node("pkg", [&] (Xml_node pkg) {
@@ -78,11 +84,16 @@ class Depot_deploy::Children
child.mark_as_incomplete(missing); }); });
}
+ /*
+ * \return true if the condition of any child changed
+ */
template
- void apply_condition(COND_FN const &fn)
+ bool apply_condition(COND_FN const &fn)
{
+ bool any_condition_changed = false;
_children.for_each([&] (Child &child) {
- child.apply_condition(fn); });
+ any_condition_changed |= child.apply_condition(fn); });
+ return any_condition_changed;
}
/**
diff --git a/repos/gems/src/app/sculpt_manager/deploy.cc b/repos/gems/src/app/sculpt_manager/deploy.cc
index e960da45ec..28dbc231f6 100644
--- a/repos/gems/src/app/sculpt_manager/deploy.cc
+++ b/repos/gems/src/app/sculpt_manager/deploy.cc
@@ -17,33 +17,30 @@
bool Sculpt::Deploy::update_child_conditions()
{
- /* track whether any condition changed for the better */
- bool result = false;
+ /* return true if any condition changed */
+ return _children.apply_condition([&] (Xml_node start, Xml_node launcher) {
- _children.apply_condition([&] (Xml_node start) {
-
- /* the child cannot be started as long as any dependency is missing */
+ /* the child cannot run as long as any dependency is missing */
bool condition = true;
_for_each_missing_server(start, [&] (Start_name const &) {
condition = false; });
+ _for_each_missing_server(launcher, [&] (Start_name const &) {
+ condition = false; });
- result |= condition;
return condition;
});
- return result;
}
-void Sculpt::Deploy::_gen_missing_dependencies(Xml_generator &xml,
+void Sculpt::Deploy::_gen_missing_dependencies(Xml_generator &xml, Start_name const &name,
Xml_node start, int &count) const
{
- Start_name const child = start.attribute_value("name", Start_name());
_for_each_missing_server(start, [&] (Start_name const &server) {
gen_named_node(xml, "hbox", String<20>(count++), [&] () {
gen_named_node(xml, "float", "left", [&] () {
xml.attribute("west", "yes");
xml.node("label", [&] () {
- xml.attribute("text", String<64>(child, " requires ", server));
+ xml.attribute("text", String<64>(name, " requires ", server));
xml.attribute("font", "annotation/regular");
});
});
@@ -55,7 +52,7 @@ void Sculpt::Deploy::_gen_missing_dependencies(Xml_generator &xml,
void Sculpt::Deploy::gen_child_diagnostics(Xml_generator &xml) const
{
bool all_children_ok = true;
- _children.for_each_unsatisfied_child([&] (Xml_node) {
+ _children.for_each_unsatisfied_child([&] (Xml_node, Xml_node) {
all_children_ok = false; });
if (all_children_ok)
@@ -70,8 +67,13 @@ void Sculpt::Deploy::gen_child_diagnostics(Xml_generator &xml) const
xml.node("float", [&] () {
xml.node("vbox", [&] () {
- _children.for_each_unsatisfied_child([&] (Xml_node start) {
- _gen_missing_dependencies(xml, start, count); }); }); });
+ _children.for_each_unsatisfied_child([&] (Xml_node start, Xml_node launcher) {
+ Start_name const name = start.attribute_value("name", Start_name());
+ _gen_missing_dependencies(xml, name, start, count);
+ _gen_missing_dependencies(xml, name, launcher, count);
+ });
+ });
+ });
});
});
}
@@ -90,6 +92,31 @@ void Sculpt::Deploy::handle_deploy()
catch (...) {
error("spurious exception during deploy update (apply_config)"); }
+ /*
+ * Apply launchers
+ */
+ Xml_node const launcher_listing = _launcher_listing_rom.xml();
+ launcher_listing.for_each_sub_node("dir", [&] (Xml_node dir) {
+
+ typedef String<20> Path;
+ Path const path = dir.attribute_value("path", Path());
+
+ if (path != "/launcher")
+ return;
+
+ dir.for_each_sub_node("file", [&] (Xml_node file) {
+
+ if (file.attribute_value("xml", false) == false)
+ return;
+
+ typedef Depot_deploy::Child::Launcher_name Name;
+ Name const name = file.attribute_value("name", Name());
+
+ file.for_each_sub_node("launcher", [&] (Xml_node launcher) {
+ _children.apply_launcher(name, launcher); });
+ });
+ });
+
/* update query for blueprints of all unconfigured start nodes */
if (_arch.valid()) {
_depot_query_reporter.generate([&] (Xml_generator &xml) {
diff --git a/repos/gems/src/app/sculpt_manager/deploy.h b/repos/gems/src/app/sculpt_manager/deploy.h
index 728ca81919..ede29a0e7b 100644
--- a/repos/gems/src/app/sculpt_manager/deploy.h
+++ b/repos/gems/src/app/sculpt_manager/deploy.h
@@ -54,6 +54,8 @@ struct Sculpt::Deploy
Attached_rom_dataspace _manual_deploy_rom { _env, "config -> deploy" };
+ Attached_rom_dataspace _launcher_listing_rom { _env, "report -> /runtime/launcher_query/listing" };
+
Attached_rom_dataspace _blueprint_rom { _env, "report -> runtime/depot_query/blueprint" };
Expanding_reporter _depot_query_reporter { _env, "query", "depot_query"};
@@ -81,6 +83,7 @@ struct Sculpt::Deploy
void _handle_manual_deploy()
{
_manual_deploy_rom.update();
+ _launcher_listing_rom.update();
_query_version.value++;
handle_deploy();
}
@@ -125,7 +128,7 @@ struct Sculpt::Deploy
*/
bool update_child_conditions();
- void _gen_missing_dependencies(Xml_generator &, Xml_node, int &) const;
+ void _gen_missing_dependencies(Xml_generator &, Start_name const &, Xml_node, int &) const;
void gen_child_diagnostics(Xml_generator &xml) const;
@@ -134,6 +137,9 @@ struct Sculpt::Deploy
Signal_handler _manual_deploy_handler {
_env.ep(), *this, &Deploy::_handle_manual_deploy };
+ Signal_handler _launcher_listing_handler {
+ _env.ep(), *this, &Deploy::_handle_manual_deploy };
+
Signal_handler _blueprint_handler {
_env.ep(), *this, &Deploy::_handle_blueprint };
@@ -160,6 +166,7 @@ struct Sculpt::Deploy
_runtime_config_generator(runtime_config_generator)
{
_manual_deploy_rom.sigh(_manual_deploy_handler);
+ _launcher_listing_rom.sigh(_launcher_listing_handler);
_blueprint_rom.sigh(_blueprint_handler);
}
};
diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc
index 7405086a32..ceae0f711a 100644
--- a/repos/gems/src/app/sculpt_manager/main.cc
+++ b/repos/gems/src/app/sculpt_manager/main.cc
@@ -22,11 +22,11 @@
#include
/* local includes */
+#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -38,7 +38,6 @@ namespace Sculpt { struct Main; }
struct Sculpt::Main : Input_event_handler,
Dialog::Generator,
Runtime_config_generator,
- Runtime_info,
Storage::Target_user
{
Env &_env;
@@ -155,7 +154,7 @@ struct Sculpt::Main : Input_event_handler,
}
- Network _network { _env, _heap, *this, *this, *this, _pci_info };
+ Network _network { _env, _heap, *this, *this, _runtime_state, _pci_info };
/************
@@ -175,7 +174,7 @@ struct Sculpt::Main : Input_event_handler,
&& _network.ready()
&& _deploy.update_needed(); };
- Deploy _deploy { _env, _heap, *this, *this, *this };
+ Deploy _deploy { _env, _heap, _runtime_state, *this, *this };
@@ -242,19 +241,9 @@ struct Sculpt::Main : Input_event_handler,
});
}
- Attached_rom_dataspace _runtime_state { _env, "report -> runtime/state" };
+ Attached_rom_dataspace _runtime_state_rom { _env, "report -> runtime/state" };
- /**
- * Runtime_info interface
- */
- bool present_in_runtime(Start_name const &name) const override
- {
- bool present = false;
- _runtime_state.xml().for_each_sub_node("child", [&] (Xml_node child) {
- if (child.attribute_value("name", Start_name()) == name)
- present = true; });
- return present;
- }
+ Runtime_state _runtime_state { _heap };
Managed_config _runtime_config {
_env, "config", "runtime", *this, &Main::_handle_runtime };
@@ -372,7 +361,7 @@ struct Sculpt::Main : Input_event_handler,
Main(Env &env) : _env(env)
{
- _runtime_state.sigh(_runtime_state_handler);
+ _runtime_state_rom.sigh(_runtime_state_handler);
_nitpicker_displays.sigh(_nitpicker_displays_handler);
/*
@@ -631,9 +620,11 @@ void Sculpt::Main::_handle_update_state()
void Sculpt::Main::_handle_runtime_state()
{
- _runtime_state.update();
+ _runtime_state_rom.update();
- Xml_node state = _runtime_state.xml();
+ Xml_node state = _runtime_state_rom.xml();
+
+ _runtime_state.update_from_state_report(state);
bool reconfigure_runtime = false;
@@ -861,8 +852,12 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
xml.node("start", [&] () {
gen_update_start_content(xml); });
- if (_storage._sculpt_partition.valid() && !_prepare_in_progress())
+ if (_storage._sculpt_partition.valid() && !_prepare_in_progress()) {
+ xml.node("start", [&] () {
+ gen_launcher_query_start_content(xml); });
+
_deploy.gen_runtime_start_nodes(xml);
+ }
}
diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_state.h b/repos/gems/src/app/sculpt_manager/model/runtime_state.h
new file mode 100644
index 0000000000..34ee5c3c6f
--- /dev/null
+++ b/repos/gems/src/app/sculpt_manager/model/runtime_state.h
@@ -0,0 +1,87 @@
+/*
+ * \brief State of the components hosted in the runtime subsystem
+ * \author Norman Feske
+ * \date 2018-08-22
+ */
+
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef _MODEL__RUNTIME_STATE_H_
+#define _MODEL__RUNTIME_STATE_H_
+
+/* Genode includes */
+#include
+#include
+
+/* local includes */
+#include
+#include
+
+namespace Sculpt { class Runtime_state; }
+
+class Sculpt::Runtime_state : public Runtime_info
+{
+ private:
+
+ Allocator &_alloc;
+
+ struct Child : List_model::Element
+ {
+ Start_name const name;
+
+ Child(Start_name const &name) : name(name) { }
+ };
+
+ List_model _children { };
+
+ struct Update_policy : List_model::Update_policy
+ {
+ Allocator &_alloc;
+
+ Update_policy(Allocator &alloc) : _alloc(alloc) { }
+
+ void destroy_element(Child &elem) { destroy(_alloc, &elem); }
+
+ Child &create_element(Xml_node node)
+ {
+ return *new (_alloc)
+ Child(node.attribute_value("name", Start_name()));
+ }
+
+ void update_element(Child &, Xml_node) { }
+
+ static bool element_matches_xml_node(Child const &elem, Xml_node node)
+ {
+ return node.attribute_value("name", Start_name()) == elem.name;
+ }
+ };
+
+ public:
+
+ Runtime_state(Allocator &alloc) : _alloc(alloc) { }
+
+ void update_from_state_report(Xml_node state)
+ {
+ Update_policy policy(_alloc);
+ _children.update_from_xml(policy, state);
+ }
+
+ /**
+ * Runtime_info interface
+ */
+ bool present_in_runtime(Start_name const &name) const override
+ {
+ bool result = false;
+ _children.for_each([&] (Child const &child) {
+ if (!result && child.name == name)
+ result = true; });
+ return result;
+ }
+};
+
+#endif /* _MODEL__RUNTIME_STATE_H_ */
diff --git a/repos/gems/src/app/sculpt_manager/runtime.cc b/repos/gems/src/app/sculpt_manager/runtime.cc
index 229d178c3c..af0fcab8c2 100644
--- a/repos/gems/src/app/sculpt_manager/runtime.cc
+++ b/repos/gems/src/app/sculpt_manager/runtime.cc
@@ -16,6 +16,7 @@
#include
#include
+#include
#include
#include
#include
diff --git a/repos/gems/src/app/sculpt_manager/runtime.h b/repos/gems/src/app/sculpt_manager/runtime.h
index a82d238c85..d4fa174847 100644
--- a/repos/gems/src/app/sculpt_manager/runtime.h
+++ b/repos/gems/src/app/sculpt_manager/runtime.h
@@ -39,6 +39,7 @@ namespace Sculpt {
Path const &, Writeable);
void gen_depot_query_start_content(Xml_generator &);
+ void gen_launcher_query_start_content(Xml_generator &);
struct File_browser_version { unsigned value; };
void gen_file_browser(Xml_generator &, Storage_devices const &,
diff --git a/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc b/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc
new file mode 100644
index 0000000000..fbd66edd43
--- /dev/null
+++ b/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc
@@ -0,0 +1,48 @@
+/*
+ * \brief XML configuration for the fs-query tool for obtaining the launchers
+ * \author Norman Feske
+ * \date 2018-08-21
+ */
+
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include
+
+void Sculpt::gen_launcher_query_start_content(Xml_generator &xml)
+{
+ gen_common_start_content(xml, "launcher_query",
+ Cap_quota{200}, Ram_quota{2*1024*1024});
+
+ gen_named_node(xml, "binary", "fs_query");
+
+ xml.node("config", [&] () {
+ xml.attribute("query", "rom");
+ xml.node("vfs", [&] () {
+ xml.node("fs", [&] () {}); });
+
+ xml.node("query", [&] () {
+ xml.attribute("path", "/launcher");
+ xml.attribute("content", "yes");
+ });
+ });
+
+ xml.node("route", [&] () {
+ gen_parent_rom_route(xml, "fs_query");
+ gen_parent_rom_route(xml, "ld.lib.so");
+ gen_parent_rom_route(xml, "vfs.lib.so");
+
+ gen_parent_route (xml);
+ gen_parent_route (xml);
+ gen_parent_route (xml);
+ gen_parent_route (xml);
+
+ gen_service_node<::File_system::Session>(xml, [&] () {
+ xml.node("parent", [&] () {
+ xml.attribute("label", "config"); }); });
+ });
+}