diff --git a/autoinstall-schema.json b/autoinstall-schema.json index cd950b54..98db501f 100644 --- a/autoinstall-schema.json +++ b/autoinstall-schema.json @@ -260,7 +260,7 @@ } ] }, - "ubuntu-advantage": { + "ubuntu-pro": { "type": "object", "properties": { "token": { @@ -272,6 +272,20 @@ } } }, + "ubuntu-advantage": { + "type": "object", + "properties": { + "token": { + "type": "string", + "minLength": 24, + "maxLength": 30, + "pattern": "^C[1-9A-HJ-NP-Za-km-z]+$", + "description": "A valid token starts with a C and is followed by 23 to 29 Base58 characters.\nSee https://pkg.go.dev/github.com/btcsuite/btcutil/base58#CheckEncode" + } + }, + "deprecated": true, + "description": "Compatibility only - use ubuntu-pro instead" + }, "proxy": { "type": [ "string", diff --git a/examples/answers-bond.yaml b/examples/answers-bond.yaml index 6eb24261..1f318154 100644 --- a/examples/answers-bond.yaml +++ b/examples/answers-bond.yaml @@ -45,7 +45,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: "" SSH: install_server: false diff --git a/examples/answers-guided-lvm.yaml b/examples/answers-guided-lvm.yaml index cbfc88a2..16621f3b 100644 --- a/examples/answers-guided-lvm.yaml +++ b/examples/answers-guided-lvm.yaml @@ -21,7 +21,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 SSH: install_server: false diff --git a/examples/answers-imsm.yaml b/examples/answers-imsm.yaml index 3bf409f0..b0fe5bb4 100644 --- a/examples/answers-imsm.yaml +++ b/examples/answers-imsm.yaml @@ -20,7 +20,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 SSH: install_server: true diff --git a/examples/answers-lvm-dmcrypt.yaml b/examples/answers-lvm-dmcrypt.yaml index d3983973..acd15a18 100644 --- a/examples/answers-lvm-dmcrypt.yaml +++ b/examples/answers-lvm-dmcrypt.yaml @@ -64,7 +64,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 SSH: install_server: true diff --git a/examples/answers-lvm.yaml b/examples/answers-lvm.yaml index 36675156..d4e07f64 100644 --- a/examples/answers-lvm.yaml +++ b/examples/answers-lvm.yaml @@ -45,7 +45,7 @@ Filesystem: fstype: ext4 mount: / - action: done -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 Identity: realname: Ubuntu diff --git a/examples/answers-preserve.yaml b/examples/answers-preserve.yaml index 82ff240f..ca699e2d 100644 --- a/examples/answers-preserve.yaml +++ b/examples/answers-preserve.yaml @@ -25,7 +25,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: "" SSH: install_server: true diff --git a/examples/answers-raid-lvm.yaml b/examples/answers-raid-lvm.yaml index 1e8eda17..8fae0824 100644 --- a/examples/answers-raid-lvm.yaml +++ b/examples/answers-raid-lvm.yaml @@ -96,7 +96,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 SSH: install_server: false diff --git a/examples/answers-raid.yaml b/examples/answers-raid.yaml index 56033fd3..012f85cd 100644 --- a/examples/answers-raid.yaml +++ b/examples/answers-raid.yaml @@ -55,7 +55,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 SSH: install_server: false diff --git a/examples/answers-serial.yaml b/examples/answers-serial.yaml index 98c4d5c5..808dd707 100644 --- a/examples/answers-serial.yaml +++ b/examples/answers-serial.yaml @@ -24,7 +24,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: "" SSH: install_server: true diff --git a/examples/answers-swap.yaml b/examples/answers-swap.yaml index 6a7f5816..361a8d9c 100644 --- a/examples/answers-swap.yaml +++ b/examples/answers-swap.yaml @@ -28,7 +28,7 @@ Identity: hostname: ubuntu-server # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' -UbuntuAdvantage: +UbuntuPro: token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 SSH: install_server: false diff --git a/examples/answers.yaml b/examples/answers.yaml index 2727f25f..d0b0d274 100644 --- a/examples/answers.yaml +++ b/examples/answers.yaml @@ -22,7 +22,7 @@ Identity: # ubuntu password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' ssh-import-id: gh:mwhudson -UbuntuAdvantage: +UbuntuPro: token: "" SnapList: snaps: diff --git a/examples/autoinstall.yaml b/examples/autoinstall.yaml index de7d4d20..9a71379b 100644 --- a/examples/autoinstall.yaml +++ b/examples/autoinstall.yaml @@ -48,7 +48,7 @@ snaps: channel: 3.2/stable updates: all timezone: Pacific/Guam -ubuntu-advantage: +ubuntu-pro: # Token that passes the basic format checking but is invalid (i.e. contains more than 16 bytes of random data) token: C1NWcZTHLteJXGVMM6YhvHDpGrhyy7 storage: diff --git a/subiquity/client/client.py b/subiquity/client/client.py index 512bb57f..2e2c6217 100644 --- a/subiquity/client/client.py +++ b/subiquity/client/client.py @@ -111,7 +111,7 @@ class SubiquityClient(TuiApplication): "Refresh", "Filesystem", "Identity", - "UbuntuAdvantage", + "UbuntuPro", "SSH", "SnapList", "Progress", diff --git a/subiquity/client/controllers/__init__.py b/subiquity/client/controllers/__init__.py index 4b1ed23a..3bf3f7e3 100644 --- a/subiquity/client/controllers/__init__.py +++ b/subiquity/client/controllers/__init__.py @@ -26,7 +26,7 @@ from .serial import SerialController from .snaplist import SnapListController from .source import SourceController from .ssh import SSHController -from .ubuntu_advantage import UbuntuAdvantageController +from .ubuntu_pro import UbuntuProController from .welcome import WelcomeController from .zdev import ZdevController @@ -45,7 +45,7 @@ __all__ = [ 'SnapListController', 'SourceController', 'SSHController', - 'UbuntuAdvantageController', + 'UbuntuProController', 'WelcomeController', 'ZdevController', ] diff --git a/subiquity/client/controllers/ubuntu_advantage.py b/subiquity/client/controllers/ubuntu_pro.py similarity index 75% rename from subiquity/client/controllers/ubuntu_advantage.py rename to subiquity/client/controllers/ubuntu_pro.py index f065e2d8..7332072a 100644 --- a/subiquity/client/controllers/ubuntu_advantage.py +++ b/subiquity/client/controllers/ubuntu_pro.py @@ -12,8 +12,7 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -""" Module that defines the client-side controller class for Ubuntu Advantage. -""" +""" Module that defines the client-side controller class for Ubuntu Pro. """ import asyncio import logging @@ -23,21 +22,21 @@ from subiquitycore.async_helpers import schedule_task from subiquity.client.controller import SubiquityTuiController from subiquity.common.types import ( - UbuntuAdvantageInfo, - UbuntuAdvantageCheckTokenStatus as TokenStatus, + UbuntuProInfo, + UbuntuProCheckTokenStatus as TokenStatus, ) -from subiquity.ui.views.ubuntu_advantage import UbuntuAdvantageView +from subiquity.ui.views.ubuntu_pro import UbuntuProView from subiquitycore.lsb_release import lsb_release from subiquitycore.tuicontroller import Skip -log = logging.getLogger("subiquity.client.controllers.ubuntu_advantage") +log = logging.getLogger("subiquity.client.controllers.ubuntu_pro") -class UbuntuAdvantageController(SubiquityTuiController): - """ Client-side controller for Ubuntu Advantage configuration. """ +class UbuntuProController(SubiquityTuiController): + """ Client-side controller for Ubuntu Pro configuration. """ - endpoint_name = "ubuntu_advantage" + endpoint_name = "ubuntu_pro" def __init__(self, app) -> None: """ Initializer for the client-side UA controller. """ @@ -45,7 +44,7 @@ class UbuntuAdvantageController(SubiquityTuiController): super().__init__(app) - async def make_ui(self) -> UbuntuAdvantageView: + async def make_ui(self) -> UbuntuProView: """ Generate the UI, based on the data provided by the model. """ dry_run: bool = self.app.opts.dry_run @@ -57,8 +56,8 @@ class UbuntuAdvantageController(SubiquityTuiController): await self.endpoint.skip.POST() raise Skip("Not running LTS version") - ubuntu_advantage_info = await self.endpoint.GET() - return UbuntuAdvantageView(self, ubuntu_advantage_info.token) + ubuntu_pro_info = await self.endpoint.GET() + return UbuntuProView(self, ubuntu_pro_info.token) def run_answers(self) -> None: if "token" in self.answers: @@ -69,16 +68,16 @@ class UbuntuAdvantageController(SubiquityTuiController): async def inner() -> None: answer = await self.endpoint.check_token.GET(token) if answer.status == TokenStatus.INVALID_TOKEN: - if isinstance(self.ui.body, UbuntuAdvantageView): + if isinstance(self.ui.body, UbuntuProView): self.ui.body.show_invalid_token() elif answer.status == TokenStatus.EXPIRED_TOKEN: - if isinstance(self.ui.body, UbuntuAdvantageView): + if isinstance(self.ui.body, UbuntuProView): self.ui.body.show_expired_token() elif answer.status == TokenStatus.UNKNOWN_ERROR: - if isinstance(self.ui.body, UbuntuAdvantageView): + if isinstance(self.ui.body, UbuntuProView): self.ui.body.show_unknown_error() else: - if isinstance(self.ui.body, UbuntuAdvantageView): + if isinstance(self.ui.body, UbuntuProView): self.ui.body.show_activable_services(answer.services) self._check_task = schedule_task(inner()) @@ -93,5 +92,5 @@ class UbuntuAdvantageController(SubiquityTuiController): def done(self, token: str) -> None: self.app.next_screen( - self.endpoint.POST(UbuntuAdvantageInfo(token=token)) + self.endpoint.POST(UbuntuProInfo(token=token)) ) diff --git a/subiquity/common/apidef.py b/subiquity/common/apidef.py index 0f783447..e0762741 100644 --- a/subiquity/common/apidef.py +++ b/subiquity/common/apidef.py @@ -50,8 +50,8 @@ from subiquity.common.types import ( StorageResponse, StorageResponseV2, TimeZoneInfo, - UbuntuAdvantageInfo, - UbuntuAdvantageCheckTokenAnswer, + UbuntuProInfo, + UbuntuProCheckTokenAnswer, WLANSupportInstallState, ZdevInfo, WSLConfigurationBase, @@ -321,16 +321,16 @@ class API: def GET() -> List[str]: ... def POST(data: Payload[List[str]]): ... - class ubuntu_advantage: - def GET() -> UbuntuAdvantageInfo: ... - def POST(data: Payload[UbuntuAdvantageInfo]) -> None: ... + class ubuntu_pro: + def GET() -> UbuntuProInfo: ... + def POST(data: Payload[UbuntuProInfo]) -> None: ... class skip: def POST() -> None: ... class check_token: def GET(token: Payload[str]) \ - -> UbuntuAdvantageCheckTokenAnswer: ... + -> UbuntuProCheckTokenAnswer: ... class LinkAction(enum.Enum): diff --git a/subiquity/common/types.py b/subiquity/common/types.py index 0de41c12..7d798cf5 100644 --- a/subiquity/common/types.py +++ b/subiquity/common/types.py @@ -414,11 +414,11 @@ class TimeZoneInfo: @attr.s(auto_attribs=True) -class UbuntuAdvantageInfo: +class UbuntuProInfo: token: str = attr.ib(repr=False) -class UbuntuAdvantageCheckTokenStatus(enum.Enum): +class UbuntuProCheckTokenStatus(enum.Enum): VALID_TOKEN = enum.auto() INVALID_TOKEN = enum.auto() EXPIRED_TOKEN = enum.auto() @@ -426,16 +426,16 @@ class UbuntuAdvantageCheckTokenStatus(enum.Enum): @attr.s(auto_attribs=True) -class UbuntuAdvantageService: +class UbuntuProService: name: str description: str @attr.s(auto_attribs=True) -class UbuntuAdvantageCheckTokenAnswer: - status: UbuntuAdvantageCheckTokenStatus +class UbuntuProCheckTokenAnswer: + status: UbuntuProCheckTokenStatus - services: Optional[List[UbuntuAdvantageService]] + services: Optional[List[UbuntuProService]] class ShutdownMode(enum.Enum): diff --git a/subiquity/models/subiquity.py b/subiquity/models/subiquity.py index 1302df9c..29fb94f2 100644 --- a/subiquity/models/subiquity.py +++ b/subiquity/models/subiquity.py @@ -43,7 +43,7 @@ from .snaplist import SnapListModel from .source import SourceModel from .ssh import SSHModel from .timezone import TimeZoneModel -from .ubuntu_advantage import UbuntuAdvantageModel +from .ubuntu_pro import UbuntuProModel from .updates import UpdatesModel @@ -147,7 +147,7 @@ class SubiquityModel: self.ssh = SSHModel() self.source = SourceModel() self.timezone = TimeZoneModel() - self.ubuntu_advantage = UbuntuAdvantageModel() + self.ubuntu_pro = UbuntuProModel() self.updates = UpdatesModel() self.userdata = {} diff --git a/subiquity/models/tests/test_ubuntu_advantage.py b/subiquity/models/tests/test_ubuntu_pro.py similarity index 88% rename from subiquity/models/tests/test_ubuntu_advantage.py rename to subiquity/models/tests/test_ubuntu_pro.py index c718164c..faed3bf6 100644 --- a/subiquity/models/tests/test_ubuntu_advantage.py +++ b/subiquity/models/tests/test_ubuntu_pro.py @@ -15,12 +15,12 @@ import unittest -from subiquity.models.ubuntu_advantage import UbuntuAdvantageModel +from subiquity.models.ubuntu_pro import UbuntuProModel -class TestUbuntuAdvantageModel(unittest.TestCase): +class TestUbuntuProModel(unittest.TestCase): def test_make_cloudconfig_(self): - model = UbuntuAdvantageModel() + model = UbuntuProModel() # Test with a token model.token = "0a1b2c3d4e5f6" diff --git a/subiquity/models/ubuntu_advantage.py b/subiquity/models/ubuntu_pro.py similarity index 87% rename from subiquity/models/ubuntu_advantage.py rename to subiquity/models/ubuntu_pro.py index 4fdbbf56..ddff3c49 100644 --- a/subiquity/models/ubuntu_advantage.py +++ b/subiquity/models/ubuntu_pro.py @@ -12,16 +12,16 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -""" Module that defines the model for Ubuntu Advantage configuration. """ +""" Module that defines the model for Ubuntu Pro configuration. """ import logging -log = logging.getLogger("subiquity.models.ubuntu_advantage") +log = logging.getLogger("subiquity.models.ubuntu_pro") -class UbuntuAdvantageModel: +class UbuntuProModel: """ - Model that represents the Ubuntu Advantage configuration. + Model that represents the Ubuntu Pro 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. diff --git a/subiquity/server/controllers/__init__.py b/subiquity/server/controllers/__init__.py index 323b920a..a4038f6c 100644 --- a/subiquity/server/controllers/__init__.py +++ b/subiquity/server/controllers/__init__.py @@ -33,7 +33,7 @@ from .snaplist import SnapListController from .source import SourceController from .ssh import SSHController from .timezone import TimeZoneController -from .ubuntu_advantage import UbuntuAdvantageController +from .ubuntu_pro import UbuntuProController from .updates import UpdatesController from .userdata import UserdataController from .zdev import ZdevController @@ -61,7 +61,7 @@ __all__ = [ 'SourceController', 'SSHController', 'TimeZoneController', - 'UbuntuAdvantageController', + 'UbuntuProController', 'UpdatesController', 'UserdataController', 'ZdevController', diff --git a/subiquity/server/controllers/tests/test_ubuntu_advantage.py b/subiquity/server/controllers/tests/test_ubuntu_pro.py similarity index 83% rename from subiquity/server/controllers/tests/test_ubuntu_advantage.py rename to subiquity/server/controllers/tests/test_ubuntu_pro.py index 19564144..fb03b894 100644 --- a/subiquity/server/controllers/tests/test_ubuntu_advantage.py +++ b/subiquity/server/controllers/tests/test_ubuntu_pro.py @@ -15,15 +15,15 @@ import unittest -from subiquity.server.controllers.ubuntu_advantage import ( - UbuntuAdvantageController, +from subiquity.server.controllers.ubuntu_pro import ( + UbuntuProController, ) from subiquitycore.tests.mocks import make_app -class TestUbuntuAdvantageController(unittest.TestCase): +class TestUbuntuProController(unittest.TestCase): def setUp(self): - self.controller = UbuntuAdvantageController(make_app()) + self.controller = UbuntuProController(make_app()) def test_serialize(self): self.controller.model.token = "1a2b3C" diff --git a/subiquity/server/controllers/ubuntu_advantage.py b/subiquity/server/controllers/ubuntu_pro.py similarity index 76% rename from subiquity/server/controllers/ubuntu_advantage.py rename to subiquity/server/controllers/ubuntu_pro.py index 54fe42b3..1d1ab98b 100644 --- a/subiquity/server/controllers/ubuntu_advantage.py +++ b/subiquity/server/controllers/ubuntu_pro.py @@ -19,13 +19,13 @@ import os from subiquity.common.apidef import API from subiquity.common.types import ( - UbuntuAdvantageInfo, - UbuntuAdvantageCheckTokenAnswer, - UbuntuAdvantageCheckTokenStatus, + UbuntuProInfo, + UbuntuProCheckTokenAnswer, + UbuntuProCheckTokenStatus, ) from subiquity.server.ubuntu_advantage import ( - InvalidUATokenError, - ExpiredUATokenError, + InvalidTokenError, + ExpiredTokenError, CheckSubscriptionError, UAInterface, UAInterfaceStrategy, @@ -34,20 +34,21 @@ from subiquity.server.ubuntu_advantage import ( ) from subiquity.server.controller import SubiquityController -log = logging.getLogger("subiquity.server.controllers.ubuntu_advantage") +log = logging.getLogger("subiquity.server.controllers.ubuntu_pro") TOKEN_DESC = """\ A valid token starts with a C and is followed by 23 to 29 Base58 characters. See https://pkg.go.dev/github.com/btcsuite/btcutil/base58#CheckEncode""" -class UbuntuAdvantageController(SubiquityController): - """ Represent the server-side Ubuntu Advantage controller. """ +class UbuntuProController(SubiquityController): + """ Represent the server-side Ubuntu Pro controller. """ - endpoint = API.ubuntu_advantage + endpoint = API.ubuntu_pro - model_name = "ubuntu_advantage" - autoinstall_key = "ubuntu-advantage" + model_name = "ubuntu_pro" + autoinstall_key = "ubuntu-pro" + autoinstall_key_alias = "ubuntu-advantage" autoinstall_schema = { "type": "object", "properties": { @@ -62,7 +63,7 @@ class UbuntuAdvantageController(SubiquityController): } def __init__(self, app) -> None: - """ Initializer for server-side UA controller. """ + """ Initializer for server-side Ubuntu Pro controller. """ strategy: UAInterfaceStrategy if app.opts.dry_run: strategy = MockedUAInterfaceStrategy(scale_factor=app.scale_factor) @@ -84,7 +85,7 @@ class UbuntuAdvantageController(SubiquityController): def make_autoinstall(self) -> dict: """ Return a dictionary that can be used as an autoinstall snippet for - Ubuntu Advantage. + Ubuntu Pro. """ if not self.model.token: return {} @@ -102,11 +103,11 @@ class UbuntuAdvantageController(SubiquityController): """ Loads the last-known state of the model. """ self.model.token = token - async def GET(self) -> UbuntuAdvantageInfo: + async def GET(self) -> UbuntuProInfo: """ Handle a GET request coming from the client-side controller. """ - return UbuntuAdvantageInfo(token=self.model.token) + return UbuntuProInfo(token=self.model.token) - async def POST(self, data: UbuntuAdvantageInfo) -> None: + async def POST(self, data: UbuntuProInfo) -> None: """ Handle a POST request coming from the client-side controller and then call .configured(). """ @@ -119,7 +120,7 @@ class UbuntuAdvantageController(SubiquityController): await self.configured() async def check_token_GET(self, token: str) \ - -> UbuntuAdvantageCheckTokenAnswer: + -> UbuntuProCheckTokenAnswer: """ Handle a GET request asking whether the contract token is valid or not. If it is valid, we provide the list of activable services associated with the subscription. @@ -128,14 +129,13 @@ class UbuntuAdvantageController(SubiquityController): try: services = await \ self.ua_interface.get_activable_services(token=token) - except InvalidUATokenError: - status = UbuntuAdvantageCheckTokenStatus.INVALID_TOKEN - except ExpiredUATokenError: - status = UbuntuAdvantageCheckTokenStatus.EXPIRED_TOKEN + except InvalidTokenError: + status = UbuntuProCheckTokenStatus.INVALID_TOKEN + except ExpiredTokenError: + status = UbuntuProCheckTokenStatus.EXPIRED_TOKEN except CheckSubscriptionError: - status = UbuntuAdvantageCheckTokenStatus.UNKNOWN_ERROR + status = UbuntuProCheckTokenStatus.UNKNOWN_ERROR else: - status = UbuntuAdvantageCheckTokenStatus.VALID_TOKEN + status = UbuntuProCheckTokenStatus.VALID_TOKEN - return UbuntuAdvantageCheckTokenAnswer(status=status, - services=services) + return UbuntuProCheckTokenAnswer(status=status, services=services) diff --git a/subiquity/server/server.py b/subiquity/server/server.py index d08746d2..cdc28433 100644 --- a/subiquity/server/server.py +++ b/subiquity/server/server.py @@ -207,7 +207,7 @@ POSTINSTALL_MODEL_NAMES = ModelNames({ "packages", "snaplist", "ssh", - "ubuntu_advantage", + "ubuntu_pro", "userdata", }, desktop={"timezone"}) @@ -246,7 +246,7 @@ class SubiquityServer(Application): "Zdev", "Source", "Network", - "UbuntuAdvantage", + "UbuntuPro", "Proxy", "Mirror", "Filesystem", diff --git a/subiquity/server/tests/test_ubuntu_advantage.py b/subiquity/server/tests/test_ubuntu_advantage.py index c479a390..32cd6b2f 100644 --- a/subiquity/server/tests/test_ubuntu_advantage.py +++ b/subiquity/server/tests/test_ubuntu_advantage.py @@ -17,10 +17,10 @@ from subprocess import CalledProcessError, CompletedProcess import unittest from unittest.mock import patch, AsyncMock -from subiquity.common.types import UbuntuAdvantageService +from subiquity.common.types import UbuntuProService from subiquity.server.ubuntu_advantage import ( - InvalidUATokenError, - ExpiredUATokenError, + InvalidTokenError, + ExpiredTokenError, CheckSubscriptionError, UAInterface, MockedUAInterfaceStrategy, @@ -36,7 +36,7 @@ class TestMockedUAInterfaceStrategy(unittest.TestCase): def test_query_info_invalid(self): # Tokens starting with "i" in dry-run mode cause the token to be # reported as invalid. - with self.assertRaises(InvalidUATokenError): + with self.assertRaises(InvalidTokenError): run_coro(self.strategy.query_info(token="invalidToken")) def test_query_info_failure(self): @@ -130,7 +130,7 @@ class TestUAInterface(unittest.TestCase): strategy = MockedUAInterfaceStrategy(scale_factor=1_000_000) interface = UAInterface(strategy) - with self.assertRaises(InvalidUATokenError): + with self.assertRaises(InvalidTokenError): run_coro(interface.get_activable_services(token="invalidToken")) # Tokens starting with "f" in dry-run mode simulate an "internal" # error. @@ -138,7 +138,7 @@ class TestUAInterface(unittest.TestCase): run_coro(interface.get_activable_services(token="failure")) # Tokens starting with "x" is dry-run mode simulate an expired token. - with self.assertRaises(ExpiredUATokenError): + with self.assertRaises(ExpiredTokenError): run_coro(interface.get_activable_services(token="xpiredToken")) # Other tokens are considered valid in dry-run mode. @@ -188,19 +188,19 @@ class TestUAInterface(unittest.TestCase): services = run_coro( interface.get_activable_services(token="XXX")) - self.assertIn(UbuntuAdvantageService( + self.assertIn(UbuntuProService( name="esm-infra", description="UA Infra: Extended Security Maintenance (ESM)", ), services) - self.assertIn(UbuntuAdvantageService( + self.assertIn(UbuntuProService( name="fips", description="NIST-certified core packages", ), services) - self.assertNotIn(UbuntuAdvantageService( + self.assertNotIn(UbuntuProService( name="esm-apps", description="UA Apps: Extended Security Maintenance (ESM)", ), services) - self.assertNotIn(UbuntuAdvantageService( + self.assertNotIn(UbuntuProService( name="cis", description="Center for Internet Security Audit Tools", ), services) diff --git a/subiquity/server/ubuntu_advantage.py b/subiquity/server/ubuntu_advantage.py index 8902f71e..eb973315 100644 --- a/subiquity/server/ubuntu_advantage.py +++ b/subiquity/server/ubuntu_advantage.py @@ -12,8 +12,8 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -""" This module defines utilities to interface with Ubuntu Advantage -subscriptions. """ +""" This module defines utilities to interface with the ubuntu-advantage-tools +helper. """ from abc import ABC, abstractmethod from datetime import datetime as dt @@ -23,14 +23,14 @@ from subprocess import CalledProcessError, CompletedProcess from typing import List, Sequence, Union import asyncio -from subiquity.common.types import UbuntuAdvantageService +from subiquity.common.types import UbuntuProService from subiquitycore import utils log = logging.getLogger("subiquity.server.ubuntu_advantage") -class InvalidUATokenError(Exception): +class InvalidTokenError(Exception): """ Exception to be raised when the supplied token is invalid. """ def __init__(self, token: str, message: str = "") -> None: self.token = token @@ -38,7 +38,7 @@ class InvalidUATokenError(Exception): super().__init__(message) -class ExpiredUATokenError(Exception): +class ExpiredTokenError(Exception): """ Exception to be raised when the supplied token has expired. """ def __init__(self, token: str, expires: str, message: str = "") -> None: self.token = token @@ -85,7 +85,7 @@ class MockedUAInterfaceStrategy(UAInterfaceStrategy): if token[0] == "x": path = "examples/uaclient-status-expired.json" elif token[0] == "i": - raise InvalidUATokenError(token) + raise InvalidTokenError(token) elif token[0] == "f": raise CheckSubscriptionError(token) else: @@ -149,7 +149,7 @@ class UAInterface: return await self.strategy.query_info(token) async def get_activable_services(self, token: str) \ - -> List[UbuntuAdvantageService]: + -> List[UbuntuProService]: """ Return a list of activable services (i.e. services that are entitled to the subscription and available on the current hardware). """ @@ -160,7 +160,7 @@ class UAInterface: # See https://bugs.python.org/issue35829 expiration = dt.fromisoformat(info["expires"].replace("Z", "+00:00")) if expiration.timestamp() <= dt.utcnow().timestamp(): - raise ExpiredUATokenError(token, expires=info["expires"]) + raise ExpiredTokenError(token, expires=info["expires"]) def is_activable_service(service: dict) -> bool: # - the available field for a service refers to its availability on @@ -170,13 +170,13 @@ class UAInterface: return service["available"] == "yes" \ and service["entitled"] == "yes" - def service_from_dict(service: dict) -> UbuntuAdvantageService: - return UbuntuAdvantageService( + def service_from_dict(service: dict) -> UbuntuProService: + return UbuntuProService( name=service["name"], description=service["description"], ) - activable_services: List[UbuntuAdvantageService] = [] + activable_services: List[UbuntuProService] = [] for service in info["services"]: if not is_activable_service(service): diff --git a/subiquity/tests/api/test_api.py b/subiquity/tests/api/test_api.py index 0993fb03..b80fc4b5 100755 --- a/subiquity/tests/api/test_api.py +++ b/subiquity/tests/api/test_api.py @@ -235,7 +235,7 @@ class TestFlow(TestAPI): ua_params = { "token": "a1b2c3d4e6f7g8h9I0K1", } - await inst.post('/ubuntu_advantage', ua_params) + await inst.post('/ubuntu_pro', ua_params) for state in 'RUNNING', 'POST_WAIT', 'POST_RUNNING', 'UU_RUNNING': await inst.get('/meta/status', cur=state) diff --git a/subiquity/ui/views/ubuntu_advantage.py b/subiquity/ui/views/ubuntu_pro.py similarity index 83% rename from subiquity/ui/views/ubuntu_advantage.py rename to subiquity/ui/views/ubuntu_pro.py index 323aac55..e9a66d0e 100644 --- a/subiquity/ui/views/ubuntu_advantage.py +++ b/subiquity/ui/views/ubuntu_pro.py @@ -12,7 +12,7 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -""" Module that defines the view class for Ubuntu Advantage configuration. """ +""" Module that defines the view class for Ubuntu Pro configuration. """ import logging import re @@ -25,7 +25,7 @@ from urwid import ( Widget, ) -from subiquity.common.types import UbuntuAdvantageService as UAService +from subiquity.common.types import UbuntuProService from subiquitycore.view import BaseView from subiquitycore.ui.buttons import ( back_btn, @@ -56,15 +56,15 @@ from subiquitycore.ui.utils import ( from subiquitycore.ui.interactive import StringEditor -log = logging.getLogger('subiquity.ui.views.ubuntu_advantage') +log = logging.getLogger('subiquity.ui.views.ubuntu_pro') -ua_help = _("If you want to enroll this system using your Ubuntu Advantage " - "subscription, enter your Ubuntu Advantage token here. " +ua_help = _("If you want to enroll this system using your Ubuntu Pro " + "subscription, enter your Ubuntu Pro token here. " "Otherwise, leave this blank.") class UATokenEditor(StringEditor, WantsToKnowFormField): - """ Represent a text-box editor for the Ubuntu Advantage Token. """ + """ Represent a text-box editor for the Ubuntu Pro Token. """ def __init__(self): """ Initialize the text-field editor for UA token. """ self.valid_char_pat = r"[a-zA-Z0-9]" @@ -83,26 +83,26 @@ class UATokenEditor(StringEditor, WantsToKnowFormField): return super().valid_char(ch) -class UbuntuAdvantageForm(Form): +class UbuntuProForm(Form): """ - Represents a form requesting Ubuntu Advantage information + Represents a form requesting Ubuntu Pro information """ cancel_label = _("Back") UATokenField = simple_field(UATokenEditor) - token = UATokenField(_("Ubuntu Advantage token:"), help=ua_help) + token = UATokenField(_("Ubuntu Pro token:"), help=ua_help) class CheckingUAToken(WidgetWrap): - """ Widget displaying a loading animation while checking ubuntu advantage + """ Widget displaying a loading animation while checking ubuntu pro subscription. """ def __init__(self, parent: BaseView): """ Initializes the loading animation widget. """ self.parent = parent spinner = Spinner(parent.controller.app.aio_loop, style="dots") spinner.start() - text = _("Checking Ubuntu Advantage subscription...") + text = _("Checking Ubuntu Pro subscription...") button = cancel_btn(label=_("Cancel"), on_press=self.cancel) self.width = len(text) + 4 super().__init__( @@ -119,20 +119,20 @@ class CheckingUAToken(WidgetWrap): self.parent.remove_overlay() -class UbuntuAdvantageView(BaseView): - """ Represent the view of the Ubuntu Advantage configuration. """ +class UbuntuProView(BaseView): + """ Represent the view of the Ubuntu Pro configuration. """ - title = _("Enable Ubuntu Advantage") - excerpt = _("Enter your Ubuntu Advantage token if you want to enroll " + title = _("Enable Ubuntu Pro") + excerpt = _("Enter your Ubuntu Pro 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}) + self.form = UbuntuProForm(initial={"token": token}) - def on_cancel(_: UbuntuAdvantageForm): + def on_cancel(_: UbuntuProForm): self.cancel() connect_signal(self.form, 'submit', self.done) @@ -140,7 +140,7 @@ class UbuntuAdvantageView(BaseView): super().__init__(self.form.as_screen(excerpt=_(self.excerpt))) - def done(self, form: UbuntuAdvantageForm) -> None: + def done(self, form: UbuntuProForm) -> None: """ If no token was supplied, move on to the next screen. If a token was provided, open the loading dialog and asynchronously check if the token is valid. """ @@ -165,7 +165,7 @@ class UbuntuAdvantageView(BaseView): self.show_stretchy_overlay( SomethingFailed(self, "Invalid token.", - "The Ubuntu Advantage token that you provided" + "The Ubuntu Pro token that you provided" " is invalid. Please make sure that you typed" " your token correctly.")) @@ -176,7 +176,7 @@ class UbuntuAdvantageView(BaseView): self.show_stretchy_overlay( SomethingFailed(self, "Token expired.", - "The Ubuntu Advantage token that you provided" + "The Ubuntu Pro token that you provided" " has expired. Please use a different token.")) def show_unknown_error(self) -> None: @@ -188,9 +188,10 @@ class UbuntuAdvantageView(BaseView): self.remove_overlay() self.show_stretchy_overlay(ContinueAnywayWidget(self)) - def show_activable_services(self, services: List[UAService]) -> None: + def show_activable_services(self, + services: List[UbuntuProService]) -> None: """ Display an overlay with the list of services that can be enabled - via Ubuntu Advantage subscription. After the user confirms, we will + via Ubuntu Pro subscription. After the user confirms, we will quit the current view and move on. """ self.remove_overlay() self.show_stretchy_overlay(ShowServicesWidget(self, services)) @@ -198,8 +199,8 @@ class UbuntuAdvantageView(BaseView): class ShowServicesWidget(Stretchy): """ Widget to show the activable services for UA subscription. """ - def __init__(self, parent: UbuntuAdvantageView, - services: List[UAService]) -> None: + def __init__(self, parent: UbuntuProView, + services: List[UbuntuProService]) -> None: """ Initializes the widget by including the list of services as a bullet-point list. """ self.parent = parent @@ -208,7 +209,7 @@ class ShowServicesWidget(Stretchy): title = _("Activable Services") header = _("List of services that are activable through your " - "Ubuntu Advantage subscription:") + "Ubuntu Pro subscription:") widgets: List[Widget] = [ Text(header), @@ -231,7 +232,7 @@ class ShowServicesWidget(Stretchy): class ContinueAnywayWidget(Stretchy): """ Widget that requests the user if he wants to go back or continue anyway. """ - def __init__(self, parent: UbuntuAdvantageView) -> None: + def __init__(self, parent: UbuntuProView) -> None: """ Initializes the widget by showing two buttons, one to go back and one to move forward anyway. """ self.parent = parent