mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-06 17:31:46 +00:00
parent
c9f2847420
commit
5dc8e330b6
@ -108,8 +108,43 @@ struct Sculpt::Deploy
|
|||||||
*/
|
*/
|
||||||
deploy.for_each_sub_node("start", [&] (Xml_node node) {
|
deploy.for_each_sub_node("start", [&] (Xml_node node) {
|
||||||
Start_name const name = node.attribute_value("name", Start_name());
|
Start_name const name = node.attribute_value("name", Start_name());
|
||||||
if (!_runtime_info.abandoned_by_user(name))
|
if (_runtime_info.abandoned_by_user(name))
|
||||||
append_xml_node(node);
|
return;
|
||||||
|
|
||||||
|
xml.node("start", [&] () {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy attributes
|
||||||
|
*/
|
||||||
|
|
||||||
|
xml.attribute("name", name);
|
||||||
|
|
||||||
|
/* override version with restarted version, after restart */
|
||||||
|
using Version = Child_state::Version;
|
||||||
|
Version version = _runtime_info.restarted_version(name);
|
||||||
|
if (version.value == 0)
|
||||||
|
version = Version { node.attribute_value("version", 0U) };
|
||||||
|
|
||||||
|
if (version.value > 0)
|
||||||
|
xml.attribute("version", version.value);
|
||||||
|
|
||||||
|
auto copy_attribute = [&] (auto attr)
|
||||||
|
{
|
||||||
|
if (node.has_attribute(attr)) {
|
||||||
|
using Value = String<128>;
|
||||||
|
xml.attribute(attr, node.attribute_value(attr, Value()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
copy_attribute("caps");
|
||||||
|
copy_attribute("ram");
|
||||||
|
copy_attribute("cpu");
|
||||||
|
copy_attribute("pkg");
|
||||||
|
|
||||||
|
/* copy start-node content */
|
||||||
|
node.with_raw_content([&] (char const *start, size_t length) {
|
||||||
|
xml.append(start, length); });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -24,13 +24,16 @@ void Graph::_gen_selected_node_content(Xml_generator &xml, Start_name const &nam
|
|||||||
|
|
||||||
if (removable) {
|
if (removable) {
|
||||||
gen_named_node(xml, "frame", "operations", [&] () {
|
gen_named_node(xml, "frame", "operations", [&] () {
|
||||||
xml.node("vbox", [&] () {
|
xml.node("hbox", [&] () {
|
||||||
gen_named_node(xml, "button", "remove", [&] () {
|
gen_named_node(xml, "button", "remove", [&] () {
|
||||||
_remove_item.gen_button_attr(xml, "remove");
|
_action_item.gen_button_attr(xml, "remove");
|
||||||
xml.node("label", [&] () {
|
xml.node("label", [&] () {
|
||||||
xml.attribute("text", "Remove");
|
xml.attribute("text", "Remove"); }); });
|
||||||
});
|
|
||||||
});
|
gen_named_node(xml, "button", "restart", [&] () {
|
||||||
|
_action_item.gen_button_attr(xml, "restart");
|
||||||
|
xml.node("label", [&] () {
|
||||||
|
xml.attribute("text", "Restart"); }); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -276,8 +279,8 @@ Dialog::Hover_result Graph::hover(Xml_node hover)
|
|||||||
_ram_fs_dialog.match_sub_dialog(hover, "depgraph", "frame", "vbox", "frame", "vbox"),
|
_ram_fs_dialog.match_sub_dialog(hover, "depgraph", "frame", "vbox", "frame", "vbox"),
|
||||||
_node_button_item.match(hover, "depgraph", "frame", "vbox", "button", "name"),
|
_node_button_item.match(hover, "depgraph", "frame", "vbox", "button", "name"),
|
||||||
_add_button_item .match(hover, "depgraph", "button", "name"),
|
_add_button_item .match(hover, "depgraph", "button", "name"),
|
||||||
_remove_item .match(hover, "depgraph", "frame", "vbox",
|
_action_item .match(hover, "depgraph", "frame", "vbox",
|
||||||
"frame", "vbox", "button", "name"));
|
"frame", "hbox", "button", "name"));
|
||||||
|
|
||||||
if (_add_button_item.hovered("global+")) {
|
if (_add_button_item.hovered("global+")) {
|
||||||
|
|
||||||
@ -335,11 +338,11 @@ void Graph::click(Action &action)
|
|||||||
|
|
||||||
_runtime_state.toggle_selection(_node_button_item._hovered,
|
_runtime_state.toggle_selection(_node_button_item._hovered,
|
||||||
_runtime_config);
|
_runtime_config);
|
||||||
_remove_item.reset();
|
_action_item.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_remove_item.hovered("remove"))
|
if (_action_item.hovered("remove") || _action_item.hovered("restart"))
|
||||||
_remove_item.propose_activation_on_click();
|
_action_item.propose_activation_on_click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -352,11 +355,11 @@ void Graph::clack(Action &action, Ram_fs_dialog::Action &ram_fs_action)
|
|||||||
if (_storage_dialog->clack(action) == Clack_result::CONSUMED)
|
if (_storage_dialog->clack(action) == Clack_result::CONSUMED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_remove_item.hovered("remove")) {
|
if (_action_item.hovered("remove")) {
|
||||||
|
|
||||||
_remove_item.confirm_activation_on_clack();
|
_action_item.confirm_activation_on_clack();
|
||||||
|
|
||||||
if (_remove_item.activated("remove")) {
|
if (_action_item.activated("remove")) {
|
||||||
action.remove_deployed_component(_runtime_state.selected());
|
action.remove_deployed_component(_runtime_state.selected());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -366,8 +369,16 @@ void Graph::clack(Action &action, Ram_fs_dialog::Action &ram_fs_action)
|
|||||||
_runtime_state.toggle_selection(_runtime_state.selected(),
|
_runtime_state.toggle_selection(_runtime_state.selected(),
|
||||||
_runtime_config);
|
_runtime_config);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
_remove_item.reset();
|
|
||||||
}
|
if (_action_item.hovered("restart")) {
|
||||||
|
|
||||||
|
_action_item.confirm_activation_on_clack();
|
||||||
|
|
||||||
|
if (_action_item.activated("restart"))
|
||||||
|
action.restart_deployed_component(_runtime_state.selected());
|
||||||
|
}
|
||||||
|
|
||||||
|
_action_item.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ struct Sculpt::Graph : Dialog
|
|||||||
|
|
||||||
Hoverable_item _node_button_item { };
|
Hoverable_item _node_button_item { };
|
||||||
Hoverable_item _add_button_item { };
|
Hoverable_item _add_button_item { };
|
||||||
Activatable_item _remove_item { };
|
Activatable_item _action_item { };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defined when '+' button is hovered
|
* Defined when '+' button is hovered
|
||||||
@ -106,6 +106,7 @@ struct Sculpt::Graph : Dialog
|
|||||||
struct Action : Storage_dialog::Action
|
struct Action : Storage_dialog::Action
|
||||||
{
|
{
|
||||||
virtual void remove_deployed_component(Start_name const &) = 0;
|
virtual void remove_deployed_component(Start_name const &) = 0;
|
||||||
|
virtual void restart_deployed_component(Start_name const &) = 0;
|
||||||
virtual void toggle_launcher_selector(Rect) = 0;
|
virtual void toggle_launcher_selector(Rect) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -642,6 +642,17 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
_deploy.update_managed_deploy_config(_manual_deploy_rom.xml());
|
_deploy.update_managed_deploy_config(_manual_deploy_rom.xml());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Graph::Action interface
|
||||||
|
*/
|
||||||
|
void restart_deployed_component(Start_name const &name) override
|
||||||
|
{
|
||||||
|
_runtime_state.restart(name);
|
||||||
|
|
||||||
|
/* update config/managed/deploy with the component 'name' removed */
|
||||||
|
_deploy.update_managed_deploy_config(_manual_deploy_rom.xml());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Graph::Action interface
|
* Graph::Action interface
|
||||||
*/
|
*/
|
||||||
|
@ -25,6 +25,10 @@ namespace Sculpt { struct Child_state; }
|
|||||||
|
|
||||||
struct Sculpt::Child_state : Noncopyable
|
struct Sculpt::Child_state : Noncopyable
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Version { unsigned value; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Registry<Child_state>::Element _element;
|
Registry<Child_state>::Element _element;
|
||||||
@ -37,7 +41,7 @@ struct Sculpt::Child_state : Noncopyable
|
|||||||
Ram_quota _ram_quota = _initial_ram_quota;
|
Ram_quota _ram_quota = _initial_ram_quota;
|
||||||
Cap_quota _cap_quota = _initial_cap_quota;
|
Cap_quota _cap_quota = _initial_cap_quota;
|
||||||
|
|
||||||
struct Version { unsigned value; } _version { 0 };
|
Version _version { 0 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
using Version = Child_state::Version;
|
||||||
|
|
||||||
struct Info
|
struct Info
|
||||||
{
|
{
|
||||||
bool selected;
|
bool selected;
|
||||||
@ -45,6 +47,8 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
|
|
||||||
unsigned long assigned_caps;
|
unsigned long assigned_caps;
|
||||||
unsigned long avail_caps;
|
unsigned long avail_caps;
|
||||||
|
|
||||||
|
Version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -60,8 +64,11 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
Info info { .selected = false,
|
Info info { .selected = false,
|
||||||
.tcb = false,
|
.tcb = false,
|
||||||
.tcb_updated = false,
|
.tcb_updated = false,
|
||||||
.assigned_ram = 0, .avail_ram = 0,
|
.assigned_ram = 0,
|
||||||
.assigned_caps = 0, .avail_caps = 0 };
|
.avail_ram = 0,
|
||||||
|
.assigned_caps = 0,
|
||||||
|
.avail_caps = 0,
|
||||||
|
.version = { 0 }};
|
||||||
|
|
||||||
bool abandoned_by_user = false;
|
bool abandoned_by_user = false;
|
||||||
|
|
||||||
@ -79,11 +86,27 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
struct Abandoned_child : Interface
|
struct Abandoned_child : Interface
|
||||||
{
|
{
|
||||||
Start_name const name;
|
Start_name const name;
|
||||||
|
|
||||||
Abandoned_child(Start_name const &name) : name(name) { };
|
Abandoned_child(Start_name const &name) : name(name) { };
|
||||||
};
|
};
|
||||||
|
|
||||||
Registry<Registered<Abandoned_child> > _abandoned_children { };
|
Registry<Registered<Abandoned_child> > _abandoned_children { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child that was interactively restarted
|
||||||
|
*/
|
||||||
|
struct Restarted_child : Interface
|
||||||
|
{
|
||||||
|
Start_name const name;
|
||||||
|
|
||||||
|
Version version;
|
||||||
|
|
||||||
|
Restarted_child(Start_name const &name, Version const &version)
|
||||||
|
: name(name), version(version) { };
|
||||||
|
};
|
||||||
|
|
||||||
|
Registry<Registered<Restarted_child> > _restarted_children { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Child that was interactively launched
|
* Child that was interactively launched
|
||||||
*/
|
*/
|
||||||
@ -115,13 +138,18 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
construction.construct(alloc, pkg_path, info, space);
|
construction.construct(alloc, pkg_path, info, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_deploy_start_node(Xml_generator &xml) const
|
void gen_deploy_start_node(Xml_generator &xml, Runtime_state const &state) const
|
||||||
{
|
{
|
||||||
if (!launched)
|
if (!launched)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gen_named_node(xml, "start", name, [&] () {
|
gen_named_node(xml, "start", name, [&] () {
|
||||||
|
|
||||||
|
Version const version = state.restarted_version(name);
|
||||||
|
|
||||||
|
if (version.value > 0)
|
||||||
|
xml.attribute("version", version.value);
|
||||||
|
|
||||||
/* interactively constructed */
|
/* interactively constructed */
|
||||||
if (construction.constructed()) {
|
if (construction.constructed()) {
|
||||||
xml.attribute("pkg", construction->path);
|
xml.attribute("pkg", construction->path);
|
||||||
@ -187,6 +215,8 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
caps.attribute_value("quota", 0UL));
|
caps.attribute_value("quota", 0UL));
|
||||||
child.info.avail_caps = caps.attribute_value("avail", 0UL);
|
child.info.avail_caps = caps.attribute_value("avail", 0UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
child.info.version.value = node.attribute_value("version", 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool element_matches_xml_node(Child const &elem, Xml_node node)
|
static bool element_matches_xml_node(Child const &elem, Xml_node node)
|
||||||
@ -240,9 +270,28 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
bool abandoned_by_user(Start_name const &name) const override
|
bool abandoned_by_user(Start_name const &name) const override
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
_abandoned_children.for_each([&] (Abandoned_child const &child) {
|
_abandoned_children.for_each([&] (Abandoned_child const &child) {
|
||||||
if (!result && child.name == name)
|
if (!result && child.name == name)
|
||||||
result = true; });
|
result = true; });
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return version of restarted child
|
||||||
|
*
|
||||||
|
* If the returned value is version 0, the child has not been
|
||||||
|
* restarted.
|
||||||
|
*/
|
||||||
|
Version restarted_version(Start_name const &name) const override
|
||||||
|
{
|
||||||
|
Version result { 0 };
|
||||||
|
|
||||||
|
_restarted_children.for_each([&] (Restarted_child const &child) {
|
||||||
|
if (!result.value && child.name == name)
|
||||||
|
result = child.version; });
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +301,7 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
void gen_launched_deploy_start_nodes(Xml_generator &xml) const override
|
void gen_launched_deploy_start_nodes(Xml_generator &xml) const override
|
||||||
{
|
{
|
||||||
_launched_children.for_each([&] (Launched_child const &child) {
|
_launched_children.for_each([&] (Launched_child const &child) {
|
||||||
child.gen_deploy_start_node(xml); });
|
child.gen_deploy_start_node(xml, *this); });
|
||||||
}
|
}
|
||||||
|
|
||||||
Info info(Start_name const &name) const
|
Info info(Start_name const &name) const
|
||||||
@ -363,6 +412,30 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
new (_alloc) Registered<Abandoned_child>(_abandoned_children, name);
|
new (_alloc) Registered<Abandoned_child>(_abandoned_children, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void restart(Start_name const &name)
|
||||||
|
{
|
||||||
|
/* determin current version from most recent state report */
|
||||||
|
Version current_version { 0 };
|
||||||
|
_children.for_each([&] (Child const &child) {
|
||||||
|
if (child.name == name)
|
||||||
|
current_version = child.info.version; });
|
||||||
|
|
||||||
|
Version const next_version { current_version.value + 1 };
|
||||||
|
|
||||||
|
bool already_restarted = false;
|
||||||
|
|
||||||
|
_restarted_children.for_each([&] (Restarted_child &child) {
|
||||||
|
if (child.name == name) {
|
||||||
|
already_restarted = true;
|
||||||
|
child.version = next_version;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!already_restarted)
|
||||||
|
new (_alloc)
|
||||||
|
Registered<Restarted_child>(_restarted_children, name, next_version);
|
||||||
|
}
|
||||||
|
|
||||||
void launch(Start_name const &name, Path const &launcher)
|
void launch(Start_name const &name, Path const &launcher)
|
||||||
{
|
{
|
||||||
new (_alloc) Registered<Launched_child>(_launched_children, name, launcher);
|
new (_alloc) Registered<Launched_child>(_launched_children, name, launcher);
|
||||||
@ -431,6 +504,9 @@ class Sculpt::Runtime_state : public Runtime_info
|
|||||||
|
|
||||||
_launched_children.for_each([&] (Launched_child &child) {
|
_launched_children.for_each([&] (Launched_child &child) {
|
||||||
destroy(_alloc, &child); });
|
destroy(_alloc, &child); });
|
||||||
|
|
||||||
|
_restarted_children.for_each([&] (Restarted_child &child) {
|
||||||
|
destroy(_alloc, &child); });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <model/storage_devices.h>
|
#include <model/storage_devices.h>
|
||||||
#include <model/storage_target.h>
|
#include <model/storage_target.h>
|
||||||
#include <model/nic_target.h>
|
#include <model/nic_target.h>
|
||||||
|
#include <model/child_state.h>
|
||||||
|
|
||||||
namespace Sculpt {
|
namespace Sculpt {
|
||||||
|
|
||||||
@ -29,6 +30,8 @@ namespace Sculpt {
|
|||||||
|
|
||||||
struct Runtime_info : Interface
|
struct Runtime_info : Interface
|
||||||
{
|
{
|
||||||
|
using Version = Child_state::Version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if specified child is present in the runtime subsystem
|
* Return true if specified child is present in the runtime subsystem
|
||||||
*/
|
*/
|
||||||
@ -36,6 +39,8 @@ namespace Sculpt {
|
|||||||
|
|
||||||
virtual bool abandoned_by_user(Start_name const &) const = 0;
|
virtual bool abandoned_by_user(Start_name const &) const = 0;
|
||||||
|
|
||||||
|
virtual Version restarted_version(Start_name const &) const = 0;
|
||||||
|
|
||||||
virtual void gen_launched_deploy_start_nodes(Xml_generator &) const = 0;
|
virtual void gen_launched_deploy_start_nodes(Xml_generator &) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ struct Sculpt::Activatable_item : Hoverable_item
|
|||||||
if (!_selected.valid() || !_activated.valid())
|
if (!_selected.valid() || !_activated.valid())
|
||||||
Hoverable_item::gen_button_attr(xml, id);
|
Hoverable_item::gen_button_attr(xml, id);
|
||||||
|
|
||||||
if (_selected.valid() && _selected == _hovered)
|
if (_selected.valid() && _selected == _hovered && _selected == id)
|
||||||
xml.attribute("selected", "yes");
|
xml.attribute("selected", "yes");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user