diff --git a/autoinstall-schema.json b/autoinstall-schema.json index 05b21120..cb6c4976 100644 --- a/autoinstall-schema.json +++ b/autoinstall-schema.json @@ -420,6 +420,14 @@ "additionalProperties": false } }, + "codecs": { + "type": "object", + "properties": { + "install": { + "type": "boolean" + } + } + }, "drivers": { "type": "object", "properties": { diff --git a/documentation/autoinstall-reference.md b/documentation/autoinstall-reference.md index 28cd4823..015b8065 100644 --- a/documentation/autoinstall-reference.md +++ b/documentation/autoinstall-reference.md @@ -411,6 +411,23 @@ A list of SSH public keys to install in the initial user's account. **type:** boolean **default:** `true` if `authorized_keys` is empty, `false` otherwise + + +### codecs + +**type:** mapping, see below +**default:** see below +**can be interactive:** no + +Configure whether common restricted packages (including codecs) from [multiverse] should be installed. + +#### install + +**type:** boolean +**default:** `false` + +Whether to install the ubuntu-restricted-addons package. + ### drivers diff --git a/documentation/autoinstall-schema.md b/documentation/autoinstall-schema.md index 0b43f25f..6ba66742 100644 --- a/documentation/autoinstall-schema.md +++ b/documentation/autoinstall-schema.md @@ -442,6 +442,14 @@ The [JSON schema](https://json-schema.org/) for autoinstall data is as follows: "additionalProperties": false } }, + "codecs": { + "type": "object", + "properties": { + "install": { + "type": "boolean" + } + } + }, "drivers": { "type": "object", "properties": { diff --git a/subiquity/common/apidef.py b/subiquity/common/apidef.py index 0ce0808d..8523104b 100644 --- a/subiquity/common/apidef.py +++ b/subiquity/common/apidef.py @@ -44,6 +44,7 @@ from subiquity.common.types import ( ReformatDisk, RefreshStatus, ShutdownMode, + CodecsData, DriversResponse, DriversPayload, SnapInfo, @@ -316,6 +317,10 @@ class API: def POST(data: Payload[ModifyPartitionV2]) \ -> StorageResponseV2: ... + class codecs: + def GET() -> CodecsData: ... + def POST(data: Payload[CodecsData]) -> None: ... + class drivers: def GET(wait: bool = False) -> DriversResponse: ... def POST(data: Payload[DriversPayload]) -> None: ... diff --git a/subiquity/common/types.py b/subiquity/common/types.py index cdb5c14f..7d8c1d13 100644 --- a/subiquity/common/types.py +++ b/subiquity/common/types.py @@ -543,6 +543,11 @@ class DriversResponse: search_drivers: bool +@attr.s(auto_attribs=True) +class CodecsData: + install: bool + + @attr.s(auto_attribs=True) class DriversPayload: install: bool diff --git a/subiquity/models/codecs.py b/subiquity/models/codecs.py new file mode 100644 index 00000000..2f4f4b42 --- /dev/null +++ b/subiquity/models/codecs.py @@ -0,0 +1,29 @@ +# Copyright 2022 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 . + +import logging + +log = logging.getLogger('subiquity.models.codecs') + + +class CodecsModel: + do_install = False + + async def target_packages(self): + # NOTE currently, ubuntu-restricted-addons is an empty package that + # pulls relevant packages through Recommends: Ideally, we should make + # sure to run the APT command for this package with the + # --install-recommends option. + return ["ubuntu-restricted-addons"] if self.do_install else [] diff --git a/subiquity/models/subiquity.py b/subiquity/models/subiquity.py index 75e9ae9b..bd0dccb6 100644 --- a/subiquity/models/subiquity.py +++ b/subiquity/models/subiquity.py @@ -46,6 +46,7 @@ from subiquitycore.lsb_release import lsb_release from subiquity.common.resources import get_users_and_groups from subiquity.server.types import InstallerChannels +from .codecs import CodecsModel from .drivers import DriversModel from .filesystem import FilesystemModel from .identity import IdentityModel @@ -173,6 +174,7 @@ class SubiquityModel: self.target = root self.chroot_prefix = [] + self.codecs = CodecsModel() self.debconf_selections = DebconfSelectionsModel() self.drivers = DriversModel() self.filesystem = FilesystemModel() diff --git a/subiquity/server/controllers/__init__.py b/subiquity/server/controllers/__init__.py index a4038f6c..a609a4f1 100644 --- a/subiquity/server/controllers/__init__.py +++ b/subiquity/server/controllers/__init__.py @@ -14,6 +14,7 @@ # along with this program. If not, see . from .cmdlist import EarlyController, LateController, ErrorController +from .codecs import CodecsController from .debconf import DebconfController from .drivers import DriversController from .filesystem import FilesystemController @@ -39,6 +40,7 @@ from .userdata import UserdataController from .zdev import ZdevController __all__ = [ + 'CodecsController', 'DebconfController', 'DriversController', 'EarlyController', diff --git a/subiquity/server/controllers/codecs.py b/subiquity/server/controllers/codecs.py new file mode 100644 index 00000000..312b1078 --- /dev/null +++ b/subiquity/server/controllers/codecs.py @@ -0,0 +1,62 @@ +# Copyright 2022 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 . + +import logging + +from subiquity.common.apidef import API +from subiquity.common.types import CodecsData +from subiquity.server.controller import SubiquityController + +log = logging.getLogger('subiquity.server.controllers.codecs') + + +class CodecsController(SubiquityController): + + endpoint = API.codecs + + autoinstall_key = model_name = "codecs" + autoinstall_schema = { + 'type': 'object', + 'properties': { + 'install': { + 'type': 'boolean', + }, + }, + } + autoinstall_default = {"install": False} + + def serialize(self): + return self.model.do_install + + def deserialize(self, data): + if data is None: + return + self.model.do_install = data + + def make_autoinstall(self): + return { + "install": self.model.do_install, + } + + def load_autoinstall_data(self, data): + if data is not None and "install" in data: + self.model.do_install = data["install"] + + async def GET(self) -> CodecsData: + return CodecsData(install=self.model.do_install) + + async def POST(self, data: CodecsData) -> None: + self.model.do_install = data.install + await self.configured() diff --git a/subiquity/server/server.py b/subiquity/server/server.py index c544f800..2fb646b1 100644 --- a/subiquity/server/server.py +++ b/subiquity/server/server.py @@ -217,7 +217,7 @@ POSTINSTALL_MODEL_NAMES = ModelNames({ "ubuntu_pro", "userdata", }, - desktop={"timezone"}) + desktop={"timezone", "codecs"}) class SubiquityServer(Application): @@ -260,6 +260,7 @@ class SubiquityServer(Application): "Identity", "SSH", "SnapList", + "Codecs", "Drivers", "TimeZone", "Install",