move snaplist controller to new world
This commit is contained in:
parent
4ab676d984
commit
4367f8f97c
|
@ -10,6 +10,7 @@ subiquity/client/controllers/network.py
|
|||
subiquity/client/controllers/progress.py
|
||||
subiquity/client/controllers/proxy.py
|
||||
subiquity/client/controllers/refresh.py
|
||||
subiquity/client/controllers/snaplist.py
|
||||
subiquity/client/controllers/ssh.py
|
||||
subiquity/client/controllers/welcome.py
|
||||
subiquity/client/controllers/zdev.py
|
||||
|
@ -42,7 +43,6 @@ subiquity/common/types.py
|
|||
subiquity/controller.py
|
||||
subiquity/controllers/__init__.py
|
||||
subiquity/controllers/reboot.py
|
||||
subiquity/controllers/snaplist.py
|
||||
subiquitycore/async_helpers.py
|
||||
subiquitycore/contextlib38.py
|
||||
subiquitycore/context.py
|
||||
|
@ -131,6 +131,7 @@ subiquity/server/controllers/package.py
|
|||
subiquity/server/controllers/proxy.py
|
||||
subiquity/server/controllers/refresh.py
|
||||
subiquity/server/controllers/reporting.py
|
||||
subiquity/server/controllers/snaplist.py
|
||||
subiquity/server/controllers/ssh.py
|
||||
subiquity/server/controllers/userdata.py
|
||||
subiquity/server/controllers/zdev.py
|
||||
|
|
|
@ -101,6 +101,7 @@ class SubiquityClient(TuiApplication):
|
|||
"Filesystem",
|
||||
"Identity",
|
||||
"SSH",
|
||||
"SnapList",
|
||||
"Progress",
|
||||
]
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ from .network import NetworkController
|
|||
from .progress import ProgressController
|
||||
from .proxy import ProxyController
|
||||
from .refresh import RefreshController
|
||||
from .snaplist import SnapListController
|
||||
from .ssh import SSHController
|
||||
from .welcome import WelcomeController
|
||||
from .zdev import ZdevController
|
||||
|
@ -36,6 +37,7 @@ __all__ = [
|
|||
'ProxyController',
|
||||
'RefreshController',
|
||||
'RepeatedController',
|
||||
'SnapListController',
|
||||
'SSHController',
|
||||
'WelcomeController',
|
||||
'ZdevController',
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
# Copyright 2018 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/>.
|
||||
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
from subiquitycore.tuicontroller import (
|
||||
Skip,
|
||||
)
|
||||
|
||||
from subiquity.client.controller import (
|
||||
SubiquityTuiController,
|
||||
)
|
||||
from subiquity.common.types import (
|
||||
SnapCheckState,
|
||||
SnapSelection,
|
||||
)
|
||||
from subiquity.ui.views.snaplist import SnapListView
|
||||
|
||||
log = logging.getLogger('subiquity.client.controllers.snaplist')
|
||||
|
||||
|
||||
class SnapListController(SubiquityTuiController):
|
||||
|
||||
endpoint_name = 'snaplist'
|
||||
|
||||
async def make_ui(self):
|
||||
data = await self.endpoint.GET()
|
||||
if data.status == SnapCheckState.FAILED:
|
||||
# If loading snaps failed or the network is disabled, skip the
|
||||
# screen.
|
||||
raise Skip()
|
||||
return SnapListView(self, data)
|
||||
|
||||
def run_answers(self):
|
||||
if 'snaps' in self.answers:
|
||||
selections = []
|
||||
for snap_name, selection in self.answers['snaps'].items():
|
||||
selections.append(SnapSelection(name=snap_name, **selection))
|
||||
self.done(selections)
|
||||
|
||||
def done(self, selections: List[SnapSelection]):
|
||||
log.debug(
|
||||
"SnapListController.done next_screen snaps_to_install=%s",
|
||||
selections)
|
||||
self.app.next_screen(self.endpoint.POST(selections))
|
||||
|
||||
def cancel(self, sender=None):
|
||||
self.app.prev_screen()
|
||||
|
||||
async def get_list_wait(self):
|
||||
return await self.endpoint.GET(wait=True)
|
||||
|
||||
async def get_snap_info(self, snap):
|
||||
if not snap.channels:
|
||||
data = await self.endpoint.snap_info.GET(snap_name=snap.name)
|
||||
snap.channels = data.channels
|
|
@ -32,6 +32,9 @@ from subiquity.common.types import (
|
|||
InstallState,
|
||||
InstallStatus,
|
||||
RefreshStatus,
|
||||
SnapInfo,
|
||||
SnapListResponse,
|
||||
SnapSelection,
|
||||
SSHData,
|
||||
StorageResponse,
|
||||
ZdevInfo,
|
||||
|
@ -172,6 +175,13 @@ class API:
|
|||
class reset:
|
||||
def POST() -> StorageResponse: ...
|
||||
|
||||
class snaplist:
|
||||
def GET(wait: bool = False) -> SnapListResponse: ...
|
||||
def POST(data: Payload[List[SnapSelection]]): ...
|
||||
|
||||
class snap_info:
|
||||
def GET(snap_name: str) -> SnapInfo: ...
|
||||
|
||||
class install:
|
||||
class status:
|
||||
def GET(cur: Optional[InstallState] = None) -> InstallStatus: ...
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .reboot import RebootController
|
||||
from .snaplist import SnapListController
|
||||
|
||||
__all__ = [
|
||||
'RebootController',
|
||||
'SnapListController',
|
||||
]
|
||||
|
|
|
@ -26,6 +26,7 @@ from .package import PackageController
|
|||
from .proxy import ProxyController
|
||||
from .refresh import RefreshController
|
||||
from .reporting import ReportingController
|
||||
from .snaplist import SnapListController
|
||||
from .ssh import SSHController
|
||||
from .userdata import UserdataController
|
||||
from .zdev import ZdevController
|
||||
|
@ -46,6 +47,7 @@ __all__ = [
|
|||
'ProxyController',
|
||||
'RefreshController',
|
||||
'ReportingController',
|
||||
'SnapListController',
|
||||
'SSHController',
|
||||
'UserdataController',
|
||||
'ZdevController',
|
||||
|
|
|
@ -16,28 +16,28 @@
|
|||
import logging
|
||||
from typing import List
|
||||
|
||||
import attr
|
||||
|
||||
import requests.exceptions
|
||||
|
||||
from subiquitycore.async_helpers import (
|
||||
schedule_task,
|
||||
)
|
||||
from subiquitycore.context import with_context
|
||||
from subiquitycore.tuicontroller import (
|
||||
Skip,
|
||||
)
|
||||
|
||||
from subiquity.controller import (
|
||||
SubiquityTuiController,
|
||||
)
|
||||
|
||||
from subiquity.common.apidef import API
|
||||
from subiquity.common.types import (
|
||||
SnapListResponse,
|
||||
SnapCheckState,
|
||||
SnapInfo,
|
||||
SnapListResponse,
|
||||
SnapSelection,
|
||||
)
|
||||
from subiquity.ui.views.snaplist import SnapListView
|
||||
from subiquity.server.controller import (
|
||||
SubiquityController,
|
||||
)
|
||||
|
||||
log = logging.getLogger('subiquity.controllers.snaplist')
|
||||
|
||||
log = logging.getLogger('subiquity.server.controllers.snaplist')
|
||||
|
||||
|
||||
class SnapdSnapInfoLoader:
|
||||
|
@ -52,7 +52,7 @@ class SnapdSnapInfoLoader:
|
|||
self.failed = False
|
||||
|
||||
self.snapd = snapd
|
||||
self.pending_info_snaps = []
|
||||
self.pending_snaps = []
|
||||
self.tasks = {} # {snap:task}
|
||||
|
||||
def start(self):
|
||||
|
@ -109,7 +109,9 @@ class SnapdSnapInfoLoader:
|
|||
return self.tasks[snap]
|
||||
|
||||
|
||||
class SnapListController(SubiquityTuiController):
|
||||
class SnapListController(SubiquityController):
|
||||
|
||||
endpoint = API.snaplist
|
||||
|
||||
autoinstall_key = "snaps"
|
||||
autoinstall_default = []
|
||||
|
@ -141,11 +143,12 @@ class SnapListController(SubiquityTuiController):
|
|||
self.loader = self._make_loader()
|
||||
|
||||
def load_autoinstall_data(self, ai_data):
|
||||
to_install = {}
|
||||
to_install = []
|
||||
for snap in ai_data:
|
||||
to_install[snap['name']] = SnapSelection(
|
||||
to_install.append(SnapSelection(
|
||||
name=snap['name'],
|
||||
channel=snap.get('channel', 'stable'),
|
||||
is_classic=snap.get('classic', False))
|
||||
is_classic=snap.get('classic', False)))
|
||||
self.model.set_installed_list(to_install)
|
||||
|
||||
def snapd_network_changed(self):
|
||||
|
@ -160,24 +163,12 @@ class SnapListController(SubiquityTuiController):
|
|||
self.loader = self._make_loader()
|
||||
self.loader.start()
|
||||
|
||||
async def make_ui(self):
|
||||
data = await self.get_snap_list(wait=False)
|
||||
if data.status == SnapCheckState.FAILED:
|
||||
# If loading snaps failed or the network is disabled, skip the
|
||||
# screen.
|
||||
self.configured()
|
||||
raise Skip()
|
||||
return SnapListView(self, data)
|
||||
def make_autoinstall(self):
|
||||
return [attr.asdict(sel) for sel in self.model.selections]
|
||||
|
||||
def run_answers(self):
|
||||
if 'snaps' in self.answers:
|
||||
selections = []
|
||||
for snap_name, selection in self.answers['snaps'].items():
|
||||
selections.append(SnapSelection(name=snap_name, **selection))
|
||||
self.done(selections)
|
||||
|
||||
async def get_snap_list(self, *, wait: bool) -> SnapListResponse:
|
||||
async def GET(self, wait: bool = False) -> SnapListResponse:
|
||||
if self.loader.failed or not self.app.base_model.network.has_network:
|
||||
self.configured()
|
||||
return SnapListResponse(status=SnapCheckState.FAILED)
|
||||
if not self.loader.snap_list_fetched and not wait:
|
||||
return SnapListResponse(status=SnapCheckState.LOADING)
|
||||
|
@ -187,19 +178,11 @@ class SnapListController(SubiquityTuiController):
|
|||
snaps=self.model.get_snap_list(),
|
||||
selections=self.model.selections)
|
||||
|
||||
def get_snap_info_task(self, snap):
|
||||
return self.loader.get_snap_info_task(snap)
|
||||
|
||||
def done(self, selections: List[SnapSelection]):
|
||||
log.debug(
|
||||
"SnapListController.done next_screen snaps_to_install=%s",
|
||||
selections)
|
||||
self.model.set_installed_list(selections)
|
||||
async def POST(self, data: List[SnapSelection]):
|
||||
self.model.set_installed_list(data)
|
||||
self.configured()
|
||||
self.app.next_screen()
|
||||
|
||||
def cancel(self, sender=None):
|
||||
self.app.prev_screen()
|
||||
|
||||
def make_autoinstall(self):
|
||||
return self.model.selections
|
||||
async def snap_info_GET(self, snap_name: str) -> SnapInfo:
|
||||
snap = self.model._snap_for_name(snap_name)
|
||||
await self.loader.get_snap_info_task(snap)
|
||||
return snap
|
|
@ -128,6 +128,7 @@ class SubiquityServer(Application):
|
|||
"Filesystem",
|
||||
"Identity",
|
||||
"SSH",
|
||||
"SnapList",
|
||||
"Install",
|
||||
"Late",
|
||||
]
|
||||
|
|
|
@ -297,7 +297,7 @@ class SnapCheckBox(CheckBox):
|
|||
app = self.parent.controller.app
|
||||
await app.wait_with_text_dialog(
|
||||
asyncio.shield(
|
||||
self.parent.controller.get_snap_info_task(self.snap)),
|
||||
self.parent.controller.get_snap_info(self.snap)),
|
||||
_("Fetching info for {snap}").format(snap=self.snap.name),
|
||||
can_cancel=True)
|
||||
if len(self.snap.channels) == 0: # or other indication of failure
|
||||
|
@ -357,7 +357,7 @@ class SnapListView(BaseView):
|
|||
# If we show the loading screen at all, we want to show it for
|
||||
# at least a second to avoid flickering at the user.
|
||||
min_wait = self.controller.app.aio_loop.create_task(asyncio.sleep(1))
|
||||
data = await self.controller.get_snap_list(wait=True)
|
||||
data = await self.controller.get_list_wait()
|
||||
await min_wait
|
||||
spinner.stop()
|
||||
if data.status == SnapCheckState.FAILED:
|
||||
|
|
Loading…
Reference in New Issue