simple replacement for urwid signals wrapper as used in server
I think this removes all use of urwid from the server code.
This commit is contained in:
parent
ddf9baf19c
commit
dab04bcb3a
|
@ -57,8 +57,8 @@ subiquitycore/models/network.py
|
|||
subiquitycore/netplan.py
|
||||
subiquitycore/palette.py
|
||||
subiquitycore/prober.py
|
||||
subiquitycore/pubsub.py
|
||||
subiquitycore/screen.py
|
||||
subiquitycore/signals.py
|
||||
subiquitycore/snapd.py
|
||||
subiquitycore/ssh.py
|
||||
subiquitycore/testing/__init__.py
|
||||
|
@ -111,6 +111,7 @@ subiquity/models/tests/__init__.py
|
|||
subiquity/models/tests/test_filesystem.py
|
||||
subiquity/models/tests/test_mirror.py
|
||||
subiquity/models/tests/test_subiquity.py
|
||||
subiquity/models/updates.py
|
||||
subiquity/server/controller.py
|
||||
subiquity/server/controllers/cmdlist.py
|
||||
subiquity/server/controllers/debconf.py
|
||||
|
@ -130,6 +131,7 @@ subiquity/server/controllers/reporting.py
|
|||
subiquity/server/controllers/snaplist.py
|
||||
subiquity/server/controllers/ssh.py
|
||||
subiquity/server/controllers/tests/test_keyboard.py
|
||||
subiquity/server/controllers/updates.py
|
||||
subiquity/server/controllers/userdata.py
|
||||
subiquity/server/controllers/zdev.py
|
||||
subiquity/server/dryrun.py
|
||||
|
|
|
@ -55,15 +55,14 @@ class MirrorController(SubiquityController):
|
|||
},
|
||||
}
|
||||
model_name = "mirror"
|
||||
signals = [
|
||||
('snapd-network-change', 'snapd_network_changed'),
|
||||
]
|
||||
|
||||
def __init__(self, app):
|
||||
super().__init__(app)
|
||||
self.geoip_enabled = True
|
||||
self.check_state = CheckState.NOT_STARTED
|
||||
self.lookup_task = SingleInstanceTask(self.lookup)
|
||||
self.app.hub.subscribe(
|
||||
'snapd-network-change', self.snapd_network_changed)
|
||||
|
||||
def load_autoinstall_data(self, data):
|
||||
if data is None:
|
||||
|
|
|
@ -42,7 +42,7 @@ class ProxyController(SubiquityController):
|
|||
if self.model.proxy:
|
||||
os.environ['http_proxy'] = os.environ['https_proxy'] = \
|
||||
self.model.proxy
|
||||
self.signal.emit_signal('network-proxy-set')
|
||||
self.app.hub.broadcast('network-proxy-set')
|
||||
|
||||
@with_context()
|
||||
async def apply_autoinstall_config(self, context=None):
|
||||
|
@ -64,5 +64,5 @@ class ProxyController(SubiquityController):
|
|||
|
||||
async def POST(self, data: str):
|
||||
self.model.proxy = data
|
||||
self.signal.emit_signal('network-proxy-set')
|
||||
self.app.hub.broadcast('network-proxy-set')
|
||||
self.configured()
|
||||
|
|
|
@ -52,10 +52,6 @@ class RefreshController(SubiquityController):
|
|||
'additionalProperties': False,
|
||||
}
|
||||
|
||||
signals = [
|
||||
('snapd-network-change', 'snapd_network_changed'),
|
||||
]
|
||||
|
||||
def __init__(self, app):
|
||||
super().__init__(app)
|
||||
self.ai_data = {}
|
||||
|
@ -63,6 +59,8 @@ class RefreshController(SubiquityController):
|
|||
self.configure_task = None
|
||||
self.check_task = None
|
||||
self.status = RefreshStatus(availability=RefreshCheckState.UNKNOWN)
|
||||
self.app.hub.subscribe(
|
||||
'snapd-network-change', self.snapd_network_changed)
|
||||
|
||||
def load_autoinstall_data(self, data):
|
||||
if data is not None:
|
||||
|
|
|
@ -129,9 +129,6 @@ class SnapListController(SubiquityController):
|
|||
},
|
||||
}
|
||||
model_name = "snaplist"
|
||||
signals = [
|
||||
('snapd-network-change', 'snapd_network_changed'),
|
||||
]
|
||||
|
||||
def _make_loader(self):
|
||||
return SnapdSnapInfoLoader(
|
||||
|
@ -141,6 +138,8 @@ class SnapListController(SubiquityController):
|
|||
def __init__(self, app):
|
||||
super().__init__(app)
|
||||
self.loader = self._make_loader()
|
||||
self.app.hub.subscribe(
|
||||
'snapd-network-change', self.snapd_network_changed)
|
||||
|
||||
def load_autoinstall_data(self, ai_data):
|
||||
to_install = []
|
||||
|
|
|
@ -235,10 +235,10 @@ class SubiquityServer(Application):
|
|||
self.note_data_for_apport("SnapUpdated", str(self.updated))
|
||||
self.event_listeners = []
|
||||
self.autoinstall_config = None
|
||||
self.signal.connect_signals([
|
||||
('network-proxy-set', lambda: schedule_task(self._proxy_set())),
|
||||
('network-change', self._network_change),
|
||||
])
|
||||
self.hub.subscribe(
|
||||
'network-up', self._network_change)
|
||||
self.hub.subscribe(
|
||||
'network-proxy-set', lambda: schedule_task(self._proxy_set()))
|
||||
|
||||
def load_serialized_state(self):
|
||||
for controller in self.controllers.instances:
|
||||
|
@ -523,12 +523,12 @@ class SubiquityServer(Application):
|
|||
await self.apply_autoinstall_config()
|
||||
|
||||
def _network_change(self):
|
||||
self.signal.emit_signal('snapd-network-change')
|
||||
self.hub.broadcast('snapd-network-change')
|
||||
|
||||
async def _proxy_set(self):
|
||||
await run_in_thread(
|
||||
self.snapd.connection.configure_proxy, self.base_model.proxy)
|
||||
self.signal.emit_signal('snapd-network-change')
|
||||
self.hub.broadcast('snapd-network-change')
|
||||
|
||||
def restart(self):
|
||||
cmdline = ['snap', 'run', 'subiquity.subiquity-server']
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from subiquitycore.signals import Signal
|
||||
from subiquitycore.testing import view_helpers
|
||||
|
||||
from subiquity.client.controllers.identity import IdentityController
|
||||
|
@ -22,7 +21,6 @@ class IdentityViewTests(unittest.TestCase):
|
|||
|
||||
def make_view(self):
|
||||
controller = mock.create_autospec(spec=IdentityController)
|
||||
controller.signal = mock.create_autospec(spec=Signal)
|
||||
return IdentityView(controller, IdentityData())
|
||||
|
||||
def test_initial_focus(self):
|
||||
|
|
|
@ -22,25 +22,16 @@ log = logging.getLogger("subiquitycore.controller")
|
|||
class BaseController(ABC):
|
||||
"""Base class for controllers."""
|
||||
|
||||
signals = []
|
||||
model_name = None
|
||||
|
||||
def __init__(self, app):
|
||||
self.name = type(self).__name__[:-len("Controller")]
|
||||
self.signal = app.signal
|
||||
self.opts = app.opts
|
||||
self.app = app
|
||||
self.context = self.app.context.child(self.name, childlevel="DEBUG")
|
||||
if self.model_name is not None:
|
||||
self.model = getattr(self.app.base_model, self.model_name)
|
||||
|
||||
def register_signals(self):
|
||||
"""Defines signals associated with controller from model."""
|
||||
signals = []
|
||||
for sig, cb in self.signals:
|
||||
signals.append((sig, getattr(self, cb)))
|
||||
self.signal.connect_signals(signals)
|
||||
|
||||
def start(self):
|
||||
"""Called just before the main loop is started.
|
||||
|
||||
|
|
|
@ -470,7 +470,7 @@ class BaseNetworkController(BaseController):
|
|||
@abc.abstractmethod
|
||||
def update_default_routes(self, routes):
|
||||
if routes:
|
||||
self.signal.emit_signal('network-change')
|
||||
self.app.hub.broadcast('network-up')
|
||||
|
||||
@abc.abstractmethod
|
||||
def new_link(self, netdev):
|
||||
|
|
|
@ -22,7 +22,7 @@ from subiquitycore.context import (
|
|||
Context,
|
||||
)
|
||||
from subiquitycore.controllerset import ControllerSet
|
||||
from subiquitycore.signals import Signal
|
||||
from subiquitycore.pubsub import MessageHub
|
||||
|
||||
log = logging.getLogger('subiquitycore.core')
|
||||
|
||||
|
@ -69,7 +69,7 @@ class Application:
|
|||
self.scale_factor = float(
|
||||
os.environ.get('SUBIQUITY_REPLAY_TIMESCALE', "1"))
|
||||
self.updated = os.path.exists(self.state_path('updating'))
|
||||
self.signal = Signal()
|
||||
self.hub = MessageHub()
|
||||
self.aio_loop = asyncio.get_event_loop()
|
||||
self.aio_loop.set_exception_handler(self._exception_handler)
|
||||
self.controllers = ControllerSet(
|
||||
|
@ -84,13 +84,6 @@ class Application:
|
|||
else:
|
||||
loop.default_exception_handler(context)
|
||||
|
||||
def _connect_base_signals(self):
|
||||
"""Connect signals used in the core controller."""
|
||||
# Registers signals from each controller
|
||||
for controller in self.controllers.instances:
|
||||
controller.register_signals()
|
||||
log.debug("known signals: %s", self.signal.known_signals)
|
||||
|
||||
def state_path(self, *parts):
|
||||
return os.path.join(self.state_dir, *parts)
|
||||
|
||||
|
@ -124,7 +117,6 @@ class Application:
|
|||
|
||||
async def start(self):
|
||||
self.controllers.load_all()
|
||||
self._connect_base_signals()
|
||||
self.start_controllers()
|
||||
|
||||
def run(self):
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2021 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/>.
|
||||
|
||||
|
||||
class MessageHub:
|
||||
|
||||
def __init__(self):
|
||||
self.subscriptions = {}
|
||||
|
||||
def subscribe(self, channel, method, *args):
|
||||
self.subscriptions.setdefault(channel, []).append((method, args))
|
||||
|
||||
def broadcast(self, channel):
|
||||
for m, args in self.subscriptions.get(channel, []):
|
||||
m(*args)
|
|
@ -1,64 +0,0 @@
|
|||
# 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/>.
|
||||
|
||||
|
||||
""" Registers all known signal emitters
|
||||
"""
|
||||
import logging
|
||||
import types
|
||||
|
||||
import urwid
|
||||
|
||||
log = logging.getLogger('subiquity.signals')
|
||||
|
||||
|
||||
class SignalException(Exception):
|
||||
"Problem with a signal"
|
||||
|
||||
|
||||
class Signal:
|
||||
known_signals = []
|
||||
|
||||
def register_signals(self, signals):
|
||||
if type(signals) is list:
|
||||
self.known_signals.extend(signals)
|
||||
else:
|
||||
self.known_signals.append(signals)
|
||||
urwid.register_signal(Signal, self.known_signals)
|
||||
|
||||
def emit_signal(self, name, *args, **kwargs):
|
||||
urwid.emit_signal(self, name, *args, **kwargs)
|
||||
|
||||
def connect_signal(self, name, cb):
|
||||
if isinstance(cb, types.MethodType):
|
||||
scb = "{}.{}".format(
|
||||
cb.__self__.__class__.__name__, cb.__func__.__name__)
|
||||
else:
|
||||
scb = str(cb)
|
||||
log.debug("connect_signal: %s -> %s", name, scb)
|
||||
urwid.connect_signal(self, name, cb)
|
||||
|
||||
def connect_signals(self, signal_callback):
|
||||
""" Connects a batch of signals
|
||||
|
||||
:param list signal_callback: List of tuples eg. ('signame', self.cb)
|
||||
"""
|
||||
if not type(signal_callback) is list:
|
||||
raise SignalException(
|
||||
"Passed something other than a required list.")
|
||||
for sig, cb in signal_callback:
|
||||
if sig not in self.known_signals:
|
||||
self.register_signals(sig)
|
||||
self.connect_signal(sig, cb)
|
|
@ -98,9 +98,6 @@ class RepeatedController(BaseController):
|
|||
self.index = index
|
||||
self.context = orig.context
|
||||
|
||||
def register_signals(self):
|
||||
pass
|
||||
|
||||
def make_ui(self):
|
||||
return self.orig.make_ui(self.index)
|
||||
|
||||
|
|
Loading…
Reference in New Issue