Add manual ipv4 network configuration
Signed-off-by: Adam Stokes <adam.stokes@ubuntu.com>
This commit is contained in:
parent
4a878baa21
commit
a82fb9e6a8
|
@ -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))
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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')
|
|
@ -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')
|
|
@ -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)",
|
||||
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"),
|
||||
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.pile.contents[-1] = (Padding.center_50(
|
||||
Color.string_input(
|
||||
self.default_gateway_w,
|
||||
focus_map="string_input focus"), self.pile.options())
|
||||
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):
|
||||
|
|
Loading…
Reference in New Issue