Add manual ipv4 network configuration

Signed-off-by: Adam Stokes <adam.stokes@ubuntu.com>
This commit is contained in:
Adam Stokes 2015-10-08 18:10:54 -04:00
parent 4a878baa21
commit a82fb9e6a8
7 changed files with 243 additions and 20 deletions

View File

@ -16,7 +16,9 @@
from subiquity.controller import ControllerPolicy
from subiquity.models import NetworkModel
from subiquity.ui.views import (NetworkView,
NetworkSetDefaultRouteView)
NetworkSetDefaultRouteView,
NetworkConfigureInterfaceView,
NetworkConfigureIPv4InterfaceView)
from subiquity.ui.dummy import DummyView
from subiquity.curtin import curtin_write_network_actions
@ -42,9 +44,38 @@ class NetworkController(ControllerPolicy):
self.signal.emit_signal('filesystem:show')
def set_default_route(self):
self.model.prev_signal = ('Back to network view',
'network:show',
'network')
self.ui.set_header("Default route")
self.ui.set_body(NetworkSetDefaultRouteView(self.model,
self.signal))
def network_configure_interface(self, iface):
self.model.prev_signal = ('Back to network view',
'network:show',
'network')
self.ui.set_header("Network interface {}".format(iface))
self.ui.set_body(NetworkConfigureInterfaceView(self.model,
self.signal,
iface))
def network_configure_ipv4_interface(self, iface):
self.model.prev_signal = ('Back to configure interface menu',
'network:configure-interface-menu',
'network_configure_interface')
self.ui.set_header("Network interface {} manual IPv4 "
"configuration".format(iface))
self.ui.set_body(NetworkConfigureIPv4InterfaceView(self.model,
self.signal,
iface))
def network_configure_ipv6_interface(self, iface):
self.model.prev_signal = ('Back to configure interface menu',
'network:configure-interface-menu',
'network_configure_interface')
self.ui.set_body(DummyView(self.signal))
def bond_interfaces(self):
self.ui.set_body(DummyView(self.signal))

View File

@ -59,16 +59,22 @@ class NetworkModel(ModelPolicy):
'network'),
('Network finish',
'network:finish',
'network_finish')
'network_finish'),
('Network configure interface',
'network:configure-interface-menu',
'network_configure_interface'),
('Network configure ipv4 interface',
'network:configure-ipv4-interface',
'network_configure_ipv4_interface')
]
additional_options = [
('Set default route',
'network:set-default-route',
'set_default_route'),
('Bond interfaces',
'network:bond-interfaces',
'bond_interfaces'),
# ('Bond interfaces',
# 'network:bond-interfaces',
# 'bond_interfaces'),
# ('Install network driver',
# 'network:install-network-driver',
# 'install_network_driver')

View File

@ -22,6 +22,8 @@ from .ceph import CephDiskView # NOQA
from .iscsi import IscsiDiskView # NOQA
from .network import NetworkView # NOQA
from .network_default_route import NetworkSetDefaultRouteView # NOQA
from .network_configure_interface import NetworkConfigureInterfaceView #NOQA
from .network_configure_ipv4_interface import NetworkConfigureIPv4InterfaceView #NOQA
from .installpath import InstallpathView # NOQA
from .installprogress import ProgressView # NOQA
from .welcome import WelcomeView # NOQA

View File

@ -24,7 +24,7 @@ from urwid import (ListBox, Pile, BoxAdapter,
Text, Columns)
import yaml
from subiquity.ui.lists import SimpleList
from subiquity.ui.buttons import cancel_btn, menu_btn
from subiquity.ui.buttons import cancel_btn, menu_btn, done_btn
from subiquity.ui.utils import Padding, Color
from subiquity.view import ViewPolicy
from subiquity.models.actions import RouteAction
@ -48,9 +48,12 @@ class NetworkView(ViewPolicy):
super().__init__(ListBox(self.body))
def _build_buttons(self):
cancel = cancel_btn(on_press=self.cancel)
done = done_btn(on_press=self.done)
buttons = [
Color.button(cancel_btn(on_press=self.cancel),
focus_map='button focus'),
Color.button(done, focus_map='button focus'),
Color.button(cancel, focus_map='button focus')
]
return Pile(buttons)
@ -145,6 +148,10 @@ class NetworkView(ViewPolicy):
def on_net_dev_press(self, result):
log.debug("Selected network dev: {}".format(result.label))
self.signal.emit_signal('network:configure-interface-menu',
result.label)
def done(self, result):
actions = [action.get() for _, action in
self.model.configured_interfaces.items()]
actions += self.model.get_default_route()

View File

@ -0,0 +1,65 @@
# Copyright 2015 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from urwid import Text, Pile, ListBox
from subiquity.view import ViewPolicy
from subiquity.ui.buttons import done_btn, confirm_btn
from subiquity.ui.utils import Color, Padding
import logging
log = logging.getLogger('subiquity.network.network_configure_interface')
class NetworkConfigureInterfaceView(ViewPolicy):
def __init__(self, model, signal, iface):
self.model = model
self.signal = signal
self.iface = iface
body = [
Padding.center_79(Text("Will use DHCP for IPv4:")),
Padding.center_79(self._build_gateway_info()),
Padding.center_79(self._build_manual_ipv4_button()),
Padding.line_break(""),
Padding.center_79(Text("Checking IPv6...")),
Padding.center_79(self._build_manual_ipv6_button()),
Padding.line_break(""),
Padding.center_20(self._build_buttons())
]
super().__init__(ListBox(body))
def _build_gateway_info(self):
return Pile([Text("<ip> offered by DHCP server <gateway ip>")])
def _build_manual_ipv4_button(self):
btn = confirm_btn(label="Switch to manual IPv4 configuration",
on_press=self.show_ipv4_configuration)
return Pile([Color.menu_button(btn, focus_map="menu_button focus")])
def _build_manual_ipv6_button(self):
return Pile([Text("Switch to manual IPv6 configuration")])
def _build_buttons(self):
done = done_btn(on_press=self.done)
buttons = [
Color.button(done, focus_map='button focus'),
]
return Pile(buttons)
def show_ipv4_configuration(self, btn):
self.signal.emit_signal('network:configure-ipv4-interface', self.iface)
def done(self, result):
self.signal.emit_signal('network:show')

View File

@ -0,0 +1,102 @@
# Copyright 2015 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from urwid import Text, Pile, ListBox, Columns
from subiquity.view import ViewPolicy
from subiquity.ui.buttons import done_btn, confirm_btn, cancel_btn
from subiquity.ui.utils import Color, Padding
from subiquity.ui.interactive import StringEditor
import logging
log = logging.getLogger('subiquity.network.network_configure_ipv4_interface')
class NetworkConfigureIPv4InterfaceView(ViewPolicy):
def __init__(self, model, signal, iface):
self.model = model
self.signal = signal
self.iface = iface
self.gateway_input = StringEditor(caption="")
self.address_input = StringEditor(caption="")
self.subnet_input = StringEditor(caption="")
body = [
Padding.center_79(self._build_iface_inputs()),
Padding.line_break(""),
Padding.center_79(self._build_set_as_default_gw_button()),
Padding.center_20(self._build_buttons())
]
super().__init__(ListBox(body))
def _build_iface_inputs(self):
col1 = [
Columns(
[
("weight", 0.2, Text("Subnet")),
("weight", 0.3,
Color.string_input(self.subnet_input,
focus_map="string_input focus")),
("weight", 0.5, Text("CIDR e.g. 192.168.9.0/24"))
], dividechars=2
),
Columns(
[
("weight", 0.2, Text("Address")),
("weight", 0.3,
Color.string_input(self.address_input,
focus_map="string_input focus")),
("weight", 0.5, Text(""))
], dividechars=2
),
Columns(
[
("weight", 0.2, Text("Gateway")),
("weight", 0.3,
Color.string_input(self.gateway_input,
focus_map="string_input focus")),
("weight", 0.5, Text(""))
], dividechars=2
)
]
return Pile(col1)
def _build_set_as_default_gw_button(self):
ifaces = self.model.get_interfaces()
if len(ifaces) > 1:
btn = confirm_btn(label="Set this as default gateway",
on_press=self.set_default_gateway)
else:
btn = Text("This will be your default gateway")
return Pile([btn])
def set_default_gateway(self):
if self.gateway_input.value:
self.model.default_gateway = self.gateway_input.value
def _build_buttons(self):
cancel = cancel_btn(on_press=self.cancel)
done = done_btn(on_press=self.done)
buttons = [
Color.button(done, focus_map='button focus'),
Color.button(cancel, focus_map='button focus')
]
return Pile(buttons)
def done(self, result):
self.signal.emit_signal('network:show')
def cancel(self, button):
self.model.default_gateway = None
self.signal.emit_signal('network:show')

View File

@ -29,23 +29,30 @@ class NetworkSetDefaultRouteView(ViewPolicy):
self.signal = signal
self.default_gateway_w = None
body = [
Padding.center_50(self._build_default_routes()),
Padding.center_79(Text("Please set the default gateway:")),
Padding.line_break(""),
Padding.center_79(self._build_default_routes()),
Padding.line_break(""),
Padding.center_20(self._build_buttons())
]
super().__init__(ListBox(body))
def _build_default_routes(self):
items = [
Text("Please set the default gateway:"),
Color.menu_button(done_btn(label="192.168.9.1 (em1, em2)",
on_press=self.done),
focus_map="menu_button focus"),
ifaces = self.model.get_interfaces()
items = []
for iface in ifaces:
items.append(Padding.center_50(
Color.menu_button(done_btn(
label="{ip} ({iface})".format(
ip="FIXME: needs default gateway",
iface=iface),
on_press=self.done),
focus_map="menu_button focus")))
items.append(Padding.center_50(
Color.menu_button(
done_btn(label="Specify the default route manually",
on_press=self.show_edit_default_route),
focus_map="menu_button focus")
]
focus_map="menu_button focus")))
self.pile = Pile(items)
return self.pile
@ -63,14 +70,17 @@ class NetworkSetDefaultRouteView(ViewPolicy):
log.debug("Re-rendering specify default route")
self.default_gateway_w = StringEditor(
caption="Default gateway will be ")
self.pile.contents[-1] = (Color.string_input(
self.default_gateway_w,
focus_map="string_input focus"), self.pile.options())
self.pile.contents[-1] = (Padding.center_50(
Color.string_input(
self.default_gateway_w,
focus_map="string_input focus")), self.pile.options())
# self.signal.emit_signal('refresh')
def done(self, result):
if self.default_gateway_w.value:
if self.default_gateway_w and self.default_gateway_w.value:
self.model.default_gateway = self.default_gateway_w.value
else:
self.model.default_gateway = result.label
self.signal.emit_signal('network:show')
def cancel(self, button):