Add initial integration of Ubuntu Advantage in subiquity
Introduce a new view, model and controllers pair to enable Ubuntu Advantage from Subiquity. For now, we expect the user to input an alphanumeric token and rely on cloud-init to enable the features associated with the subscription. This implementation comes with a number of limitations: * inability to validate the token before first-boot * inability to check what features are associated with the Ubuntu Advantage subscription, before first-boot * the user must input the token directly: there is no mechanism to deduce the token based on email address and password. The new screen is placed after the identity scree. The installation should already be running when the UA screen will be shown to the user. Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
parent
55b2d4cf86
commit
1c9c04d55d
|
@ -45,6 +45,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: false
|
||||
SnapList:
|
||||
|
|
|
@ -20,6 +20,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: false
|
||||
SnapList:
|
||||
|
|
|
@ -20,6 +20,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: true
|
||||
pwauth: false
|
||||
|
|
|
@ -64,6 +64,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: true
|
||||
pwauth: false
|
||||
|
|
|
@ -45,6 +45,8 @@ Filesystem:
|
|||
fstype: ext4
|
||||
mount: /
|
||||
- action: done
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
Identity:
|
||||
realname: Ubuntu
|
||||
username: ubuntu
|
||||
|
|
|
@ -25,6 +25,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: true
|
||||
pwauth: false
|
||||
|
|
|
@ -96,6 +96,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: false
|
||||
SnapList:
|
||||
|
|
|
@ -55,6 +55,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: false
|
||||
SnapList:
|
||||
|
|
|
@ -24,6 +24,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: true
|
||||
pwauth: false
|
||||
|
|
|
@ -28,6 +28,8 @@ Identity:
|
|||
hostname: ubuntu-server
|
||||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SSH:
|
||||
install_server: false
|
||||
SnapList:
|
||||
|
|
|
@ -22,6 +22,8 @@ Identity:
|
|||
# ubuntu
|
||||
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
|
||||
ssh-import-id: gh:mwhudson
|
||||
UbuntuAdvantage:
|
||||
token: "a1b2c3d4"
|
||||
SnapList:
|
||||
snaps:
|
||||
hello:
|
||||
|
|
|
@ -110,6 +110,7 @@ class SubiquityClient(TuiApplication):
|
|||
"Refresh",
|
||||
"Filesystem",
|
||||
"Identity",
|
||||
"UbuntuAdvantage",
|
||||
"SSH",
|
||||
"SnapList",
|
||||
"Progress",
|
||||
|
|
|
@ -26,6 +26,7 @@ from .serial import SerialController
|
|||
from .snaplist import SnapListController
|
||||
from .source import SourceController
|
||||
from .ssh import SSHController
|
||||
from .ubuntu_advantage import UbuntuAdvantageController
|
||||
from .welcome import WelcomeController
|
||||
from .zdev import ZdevController
|
||||
|
||||
|
@ -44,6 +45,7 @@ __all__ = [
|
|||
'SnapListController',
|
||||
'SourceController',
|
||||
'SSHController',
|
||||
'UbuntuAdvantageController',
|
||||
'WelcomeController',
|
||||
'ZdevController',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# 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/>.
|
||||
""" Module that defines the client-side controller class for Ubuntu Advantage.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from subiquity.client.controller import SubiquityTuiController
|
||||
from subiquity.common.types import UbuntuAdvantageInfo
|
||||
from subiquity.ui.views.ubuntu_advantage import UbuntuAdvantageView
|
||||
|
||||
log = logging.getLogger("subiquity.client.controllers.ubuntu_advantage")
|
||||
|
||||
|
||||
class UbuntuAdvantageController(SubiquityTuiController):
|
||||
""" Client-side controller for Ubuntu Advantage configuration. """
|
||||
|
||||
endpoint_name = "ubuntu_advantage"
|
||||
|
||||
async def make_ui(self) -> UbuntuAdvantageView:
|
||||
""" Generate the UI, based on the data provided by the model. """
|
||||
ubuntu_advantage_info = await self.endpoint.GET()
|
||||
return UbuntuAdvantageView(self, ubuntu_advantage_info.token)
|
||||
|
||||
def run_answers(self) -> None:
|
||||
if "token" in self.answers:
|
||||
self.done(self.answers["token"])
|
||||
|
||||
def cancel(self) -> None:
|
||||
self.app.prev_screen()
|
||||
|
||||
def done(self, token: str) -> None:
|
||||
log.debug("UbuntuAdvantageController.done token=%s", token)
|
||||
self.app.next_screen(
|
||||
self.endpoint.POST(UbuntuAdvantageInfo(token=token))
|
||||
)
|
|
@ -48,6 +48,7 @@ from subiquity.common.types import (
|
|||
StorageResponse,
|
||||
StorageResponseV2,
|
||||
TimeZoneInfo,
|
||||
UbuntuAdvantageInfo,
|
||||
WLANSupportInstallState,
|
||||
ZdevInfo,
|
||||
WSLConfigurationBase,
|
||||
|
@ -62,6 +63,7 @@ class API:
|
|||
locale = simple_endpoint(str)
|
||||
proxy = simple_endpoint(str)
|
||||
ssh = simple_endpoint(SSHData)
|
||||
ubuntu_advantage = simple_endpoint(UbuntuAdvantageInfo)
|
||||
updates = simple_endpoint(str)
|
||||
wslconfbase = simple_endpoint(WSLConfigurationBase)
|
||||
wslconfadvanced = simple_endpoint(WSLConfigurationAdvanced)
|
||||
|
|
|
@ -389,6 +389,11 @@ class TimeZoneInfo:
|
|||
from_geoip: bool
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class UbuntuAdvantageInfo:
|
||||
token: str
|
||||
|
||||
|
||||
class ShutdownMode(enum.Enum):
|
||||
REBOOT = enum.auto()
|
||||
POWEROFF = enum.auto()
|
||||
|
|
|
@ -41,6 +41,7 @@ from .snaplist import SnapListModel
|
|||
from .source import SourceModel
|
||||
from .ssh import SSHModel
|
||||
from .timezone import TimeZoneModel
|
||||
from .ubuntu_advantage import UbuntuAdvantageModel
|
||||
from .updates import UpdatesModel
|
||||
|
||||
|
||||
|
@ -143,6 +144,7 @@ class SubiquityModel:
|
|||
self.ssh = SSHModel()
|
||||
self.source = SourceModel()
|
||||
self.timezone = TimeZoneModel()
|
||||
self.ubuntu_advantage = UbuntuAdvantageModel()
|
||||
self.updates = UpdatesModel()
|
||||
self.userdata = {}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# 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/>.
|
||||
|
||||
import unittest
|
||||
|
||||
from subiquity.models.ubuntu_advantage import UbuntuAdvantageModel
|
||||
|
||||
|
||||
class TestUbuntuAdvantageModel(unittest.TestCase):
|
||||
def test_make_cloudconfig_(self):
|
||||
model = UbuntuAdvantageModel()
|
||||
|
||||
# Test with a token
|
||||
model.token = "0a1b2c3d4e5f6"
|
||||
expected = {
|
||||
"ubuntu_advantage": {
|
||||
"token": "0a1b2c3d4e5f6",
|
||||
}
|
||||
}
|
||||
self.assertEqual(model.make_cloudconfig(), expected)
|
||||
|
||||
# Test without token
|
||||
model.token = ""
|
||||
self.assertEqual(model.make_cloudconfig(), {})
|
||||
model.token = None
|
||||
self.assertEqual(model.make_cloudconfig(), {})
|
|
@ -0,0 +1,47 @@
|
|||
# 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/>.
|
||||
""" Module that defines the model for Ubuntu Advantage configuration. """
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger("subiquitycore.models.ubuntu_advantage")
|
||||
|
||||
|
||||
class UbuntuAdvantageModel:
|
||||
"""
|
||||
Model that represents the Ubuntu Advantage configuration.
|
||||
Currently, we rely only on cloud-init so we have no means to validate that
|
||||
the provided token is correct ; nor to retrieve information about the
|
||||
subscription.
|
||||
"""
|
||||
def __init__(self):
|
||||
""" Initialize the model. """
|
||||
self.token: str = ""
|
||||
|
||||
def make_cloudconfig(self) -> dict:
|
||||
"""
|
||||
Return a dictionary that will be included in cloud-init config.
|
||||
Having the token set to the empty-string disables the configuration.
|
||||
"""
|
||||
if not self.token:
|
||||
return {}
|
||||
# Both "ubuntu_advantage" and "ubuntu-advantage" keys are accepted, but
|
||||
# "ubuntu-advantage" is deprecated despite not being mentioned in the
|
||||
# documentation.
|
||||
return {
|
||||
"ubuntu_advantage": {
|
||||
"token": self.token,
|
||||
},
|
||||
}
|
|
@ -32,6 +32,7 @@ from .snaplist import SnapListController
|
|||
from .source import SourceController
|
||||
from .ssh import SSHController
|
||||
from .timezone import TimeZoneController
|
||||
from .ubuntu_advantage import UbuntuAdvantageController
|
||||
from .updates import UpdatesController
|
||||
from .userdata import UserdataController
|
||||
from .zdev import ZdevController
|
||||
|
@ -58,6 +59,7 @@ __all__ = [
|
|||
'SourceController',
|
||||
'SSHController',
|
||||
'TimeZoneController',
|
||||
'UbuntuAdvantageController',
|
||||
'UpdatesController',
|
||||
'UserdataController',
|
||||
'ZdevController',
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# 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/>.
|
||||
|
||||
import unittest
|
||||
|
||||
from subiquity.server.controllers.ubuntu_advantage import (
|
||||
UbuntuAdvantageController,
|
||||
)
|
||||
from subiquitycore.tests.mocks import make_app
|
||||
|
||||
|
||||
class TestUbuntuAdvantageController(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.controller = UbuntuAdvantageController(make_app())
|
||||
|
||||
def test_serialize(self):
|
||||
self.controller.model.token = "1a2b3C"
|
||||
self.assertEqual(self.controller.serialize(), "1a2b3C")
|
||||
|
||||
def test_deserialize(self):
|
||||
self.controller.deserialize("1A2B3C4D")
|
||||
self.assertEqual(self.controller.model.token, "1A2B3C4D")
|
|
@ -0,0 +1,53 @@
|
|||
# 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/>.
|
||||
""" Module defining the server-side controller class for Ubuntu Advantage. """
|
||||
|
||||
import logging
|
||||
|
||||
from subiquity.common.apidef import API
|
||||
from subiquity.common.types import UbuntuAdvantageInfo
|
||||
from subiquity.server.controller import SubiquityController
|
||||
|
||||
log = logging.getLogger("subiquity.server.controllers.ubuntu_advantage")
|
||||
|
||||
|
||||
class UbuntuAdvantageController(SubiquityController):
|
||||
""" Represent the server-side Ubuntu Advantage controller. """
|
||||
|
||||
endpoint = API.ubuntu_advantage
|
||||
|
||||
model_name = "ubuntu_advantage"
|
||||
|
||||
def serialize(self) -> str:
|
||||
""" Save the current state of the model so it can be loaded later.
|
||||
Currently this function is called automatically by .configured().
|
||||
"""
|
||||
return self.model.token
|
||||
|
||||
def deserialize(self, token: str) -> None:
|
||||
""" Loads the last-known state of the model. """
|
||||
self.model.token = token
|
||||
|
||||
async def GET(self) -> UbuntuAdvantageInfo:
|
||||
""" Handle a GET request coming from the client-side controller. """
|
||||
return UbuntuAdvantageInfo(token=self.model.token)
|
||||
|
||||
async def POST(self, data: UbuntuAdvantageInfo):
|
||||
""" Handle a POST request coming from the client-side controller and
|
||||
then call .configured().
|
||||
"""
|
||||
log.debug("Received POST: %s", data)
|
||||
self.model.token = data.token
|
||||
await self.configured()
|
|
@ -204,6 +204,7 @@ POSTINSTALL_MODEL_NAMES = ModelNames({
|
|||
"packages",
|
||||
"snaplist",
|
||||
"ssh",
|
||||
"ubuntu_advantage",
|
||||
"userdata",
|
||||
},
|
||||
desktop={"timezone"})
|
||||
|
@ -242,6 +243,7 @@ class SubiquityServer(Application):
|
|||
"Zdev",
|
||||
"Source",
|
||||
"Network",
|
||||
"UbuntuAdvantage",
|
||||
"Proxy",
|
||||
"Mirror",
|
||||
"Filesystem",
|
||||
|
|
|
@ -215,6 +215,10 @@ class TestFlow(TestAPI):
|
|||
}
|
||||
await inst.post('/ssh', ssh)
|
||||
await inst.post('/snaplist', [])
|
||||
ua_params = {
|
||||
"token": "a1b2c3d4e6f7g8h9I0K1",
|
||||
}
|
||||
await inst.post('/ubuntu_advantage', ua_params)
|
||||
for state in 'RUNNING', 'POST_WAIT', 'POST_RUNNING', 'UU_RUNNING':
|
||||
await inst.get('/meta/status', cur=state)
|
||||
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
# 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/>.
|
||||
""" Module that defines the view class for Ubuntu Advantage configuration. """
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from urwid import connect_signal
|
||||
|
||||
from subiquitycore.view import BaseView
|
||||
from subiquitycore.ui.form import (
|
||||
Form,
|
||||
simple_field,
|
||||
WantsToKnowFormField,
|
||||
)
|
||||
|
||||
from subiquitycore.ui.interactive import StringEditor
|
||||
|
||||
|
||||
log = logging.getLogger('subiquity.ui.views.ubuntu_advantage')
|
||||
|
||||
ua_help = _("If you want to enroll this system using your Ubuntu Advantage "
|
||||
"subscription, enter your Ubuntu Advantage token here. "
|
||||
"Otherwise, leave this blank.")
|
||||
|
||||
|
||||
class UATokenEditor(StringEditor, WantsToKnowFormField):
|
||||
""" Represent a text-box editor for the Ubuntu Advantage Token. """
|
||||
def __init__(self):
|
||||
""" Initialize the text-field editor for UA token. """
|
||||
self.valid_char_pat = r"[a-zA-Z0-9]"
|
||||
self.error_invalid_char = _("The only characters permitted in this "
|
||||
"field are alphanumeric characters.")
|
||||
super().__init__()
|
||||
|
||||
def valid_char(self, ch: str) -> bool:
|
||||
""" Tells whether the character passed is within the range of allowed
|
||||
characters
|
||||
"""
|
||||
if len(ch) == 1 and not re.match(self.valid_char_pat, ch):
|
||||
self.bff.in_error = True
|
||||
self.bff.show_extra(("info_error", self.error_invalid_char))
|
||||
return False
|
||||
return super().valid_char(ch)
|
||||
|
||||
|
||||
class UbuntuAdvantageForm(Form):
|
||||
"""
|
||||
Represents a form requesting Ubuntu Advantage information
|
||||
"""
|
||||
cancel_label = _("Back")
|
||||
|
||||
UATokenField = simple_field(UATokenEditor)
|
||||
|
||||
token = UATokenField(_("Ubuntu Advantage token:"), help=ua_help)
|
||||
|
||||
|
||||
class UbuntuAdvantageView(BaseView):
|
||||
""" Represent the view of the Ubuntu Advantage configuration. """
|
||||
|
||||
title = _("Enable Ubuntu Advantage")
|
||||
excerpt = _("Enter your Ubuntu Advantage token if you want to enroll "
|
||||
"this system.")
|
||||
|
||||
def __init__(self, controller, token: str):
|
||||
""" Initialize the view with the default value for the token. """
|
||||
self.controller = controller
|
||||
|
||||
self.form = UbuntuAdvantageForm(initial={"token": token})
|
||||
|
||||
def on_cancel(_: UbuntuAdvantageForm):
|
||||
self.cancel()
|
||||
|
||||
connect_signal(self.form, 'submit', self.done)
|
||||
connect_signal(self.form, 'cancel', on_cancel)
|
||||
|
||||
super().__init__(self.form.as_screen(excerpt=_(self.excerpt)))
|
||||
|
||||
def done(self, form: UbuntuAdvantageForm) -> None:
|
||||
""" Called when the user presses the Done button. """
|
||||
log.debug("User input: %r", form.as_data())
|
||||
|
||||
self.controller.done(form.token.value)
|
||||
|
||||
def cancel(self) -> None:
|
||||
""" Called when the user presses the Back button. """
|
||||
self.controller.cancel()
|
Loading…
Reference in New Issue