sculpt: track both manual and managed NIC target

By tracking the states for an interactive selected NIC target (managed)
and a manual-defined NIC target (config/nic_router) separately, the
sculpt manager becames able to present the user with the ability to
interactively disable and re-enable a manually-managed network
configuration.
This commit is contained in:
Norman Feske 2018-06-06 12:29:51 +02:00 committed by Christian Helmuth
parent ae55187a68
commit 9334f6c05d
5 changed files with 76 additions and 35 deletions

View File

@ -21,20 +21,55 @@ namespace Sculpt { struct Nic_target; }
struct Sculpt::Nic_target : Noncopyable
{
enum Type { OFF, LOCAL, WIRED, WIFI } type { OFF };
enum Policy { MANAGED, MANUAL } policy { MANAGED };
bool manual() const { return policy == MANUAL; }
bool managed() const { return policy == MANAGED; }
bool local() const { return type == LOCAL; }
bool wired() const { return type == WIRED; }
bool wifi() const { return type == WIFI; }
/*
* The 'UNDEFINED' state is used solely at the startup when neither a
* managed or manual policy is known. Once a manually managed 'nic_router'
* config is provided, it takes precedence over the 'UNDEFINED' managed
* state.
*/
enum Type { UNDEFINED, OFF, LOCAL, WIRED, WIFI };
bool nic_router_needed() const { return type != OFF; }
/**
* Interactive selection by the user, used when managed policy is in effect
*/
Type managed_type { UNDEFINED };
bool ready() const { return type == WIRED || type == WIFI; }
/**
* Selection by the manually-provided NIC-router configuration
*/
Type manual_type { UNDEFINED };
/**
* Return currently active NIC target type
*
* This method never returns 'UNDEFINED'.
*/
Type type() const
{
/*
* Enforce the user's interactive choice to disable networking
* even if the NIC target is manually managed.
*/
if (managed_type == OFF)
return OFF;
Type const result = manual() ? manual_type : managed_type;
return (result == UNDEFINED) ? OFF : result;
}
bool local() const { return type() == LOCAL; }
bool wired() const { return type() == WIRED; }
bool wifi() const { return type() == WIFI; }
bool nic_router_needed() const { return type() != OFF; }
bool ready() const { return type() == WIRED || type() == WIFI; }
};
#endif /* _MODEL__NIC_TARGET_H_ */

View File

@ -70,9 +70,9 @@ void Sculpt::Network::_generate_nic_router_config()
xml.node("default-policy", [&] () {
xml.attribute("domain", "default"); });
if (_nic_target.type != Nic_target::LOCAL) {
if (_nic_target.type() != Nic_target::LOCAL) {
gen_named_node(xml, "domain", "uplink", [&] () {
switch (_nic_target.type) {
switch (_nic_target.type()) {
case Nic_target::WIRED: xml.attribute("label", "wired"); break;
case Nic_target::WIFI: xml.attribute("label", "wifi"); break;
default: break;
@ -92,11 +92,11 @@ void Sculpt::Network::_generate_nic_router_config()
xml.node("dhcp-server", [&] () {
xml.attribute("ip_first", "10.0.1.2");
xml.attribute("ip_last", "10.0.1.200");
if (_nic_target.type != Nic_target::LOCAL) {
if (_nic_target.type() != Nic_target::LOCAL) {
xml.attribute("dns_server_from", "uplink"); }
});
if (_nic_target.type != Nic_target::LOCAL) {
if (_nic_target.type() != Nic_target::LOCAL) {
xml.node("tcp", [&] () {
xml.attribute("dst", "0.0.0.0/0");
xml.node("permit-any", [&] () {
@ -158,28 +158,34 @@ void Sculpt::Network::_handle_nic_router_state()
void Sculpt::Network::_handle_nic_router_config(Xml_node config)
{
Nic_target::Type target = _nic_target.managed_type;
_nic_target.policy = config.has_type("empty")
? Nic_target::MANAGED : Nic_target::MANUAL;
/* obtain uplink information from configuration */
Nic_target::Type target = Nic_target::LOCAL;
target = Nic_target::LOCAL;
if (_nic_target.manual()) {
if (!config.has_sub_node("domain"))
target = Nic_target::OFF;
/* obtain uplink information from configuration */
target = Nic_target::LOCAL;
config.for_each_sub_node("domain", [&] (Xml_node domain) {
if (!config.has_sub_node("domain"))
target = Nic_target::OFF;
/* skip non-uplink domains */
if (domain.attribute_value("name", String<16>()) != "uplink")
return;
config.for_each_sub_node("domain", [&] (Xml_node domain) {
if (domain.attribute_value("label", String<16>()) == "wired")
target = Nic_target::WIRED;
/* skip non-uplink domains */
if (domain.attribute_value("name", String<16>()) != "uplink")
return;
if (domain.attribute_value("label", String<16>()) == "wifi")
target = Nic_target::WIFI;
});
if (domain.attribute_value("label", String<16>()) == "wired")
target = Nic_target::WIRED;
if (domain.attribute_value("label", String<16>()) == "wifi")
target = Nic_target::WIFI;
});
_nic_target.manual_type = target;
}
nic_target(target);
_generate_nic_router_config();
@ -196,7 +202,7 @@ void Sculpt::Network::gen_runtime_start_nodes(Xml_generator &xml) const
if (_use_wifi_drv)
xml.node("start", [&] () { gen_wifi_drv_start_content(xml); });
if (_nic_target.type != Nic_target::OFF)
if (_nic_target.type() != Nic_target::OFF)
xml.node("start", [&] () {
gen_nic_router_start_content(xml); });
}

View File

@ -135,8 +135,8 @@ struct Sculpt::Network : Network_dialog::Action
if (type == Nic_target::WIFI) _use_wifi_drv = true;
if (type == Nic_target::WIRED) _use_nic_drv = true;
if (type != _nic_target.type) {
_nic_target.type = type;
if (type != _nic_target.managed_type) {
_nic_target.managed_type = type;
_generate_nic_router_config();
_runtime_config_generator.generate_runtime_config();
_dialog_generator.generate_dialog();

View File

@ -204,7 +204,7 @@ void Sculpt::Network_dialog::generate(Xml_generator &xml) const
_nic_item.gen_button_attr(xml, id);
if (_nic_target.type == type)
if (_nic_target.type() == type)
xml.attribute("selected", "yes");
xml.node("label", [&] () { xml.attribute("text", label); });
@ -217,18 +217,18 @@ void Sculpt::Network_dialog::generate(Xml_generator &xml) const
* Allow interactive selection only if NIC-router configuration
* is not manually maintained.
*/
if (_nic_target.managed() || _nic_target.local())
if (_nic_target.managed() || _nic_target.manual_type == Nic_target::LOCAL)
gen_nic_button("local", Nic_target::LOCAL, "Local");
if (_nic_target.managed() || _nic_target.wired())
if (_nic_target.managed() || _nic_target.manual_type == Nic_target::WIRED)
gen_nic_button("wired", Nic_target::WIRED, "Wired");
if (_nic_target.managed() || _nic_target.wifi())
if (_nic_target.managed() || _nic_target.manual_type == Nic_target::WIFI)
if (_pci_info.wifi_present)
gen_nic_button("wifi", Nic_target::WIFI, "Wifi");
});
if (_nic_target.type == Nic_target::WIFI || _nic_target.type == Nic_target::WIRED) {
if (_nic_target.wifi() || _nic_target.wired()) {
gen_named_node(xml, "frame", "nic_info", [&] () {
xml.node("vbox", [&] () {
@ -238,7 +238,7 @@ void Sculpt::Network_dialog::generate(Xml_generator &xml) const
* the complete list of access points with the option
* to select one.
*/
if (_nic_target.type == Nic_target::WIFI) {
if (_nic_target.wifi()) {
if (_wifi_connection.connected())
_gen_connected_ap(xml);
else

View File

@ -47,7 +47,7 @@ struct Sculpt::Network_dialog : Dialog
Hoverable_item _nic_info { };
Hoverable_item _connect_item { }; /* confirm WPA passphrase */
bool ap_list_hovered() const { return _nic_target.type == Nic_target::WIFI
bool ap_list_hovered() const { return _nic_target.wifi()
&& _nic_info.hovered("nic_info"); }
/*