Adding WSLSetupOptions API endpoint

Intended to receive options that affect the setup process.
and won't be written to /etc/wsl.conf
Options relative to that conf file are handled by WslConfBase and
WslConfAdvanced.
Currently only the option for skip installing language packs is
available.
This commit is contained in:
Carlos Nihelton 2022-08-19 15:36:15 -03:00
parent f4efde9dba
commit 6dd157dac7
No known key found for this signature in database
GPG Key ID: 6FE346D245197E9A
7 changed files with 109 additions and 3 deletions

View File

@ -48,6 +48,15 @@
"locale": { "locale": {
"type": "string" "type": "string"
}, },
"wslsetupoptions": {
"type": "object",
"properties": {
"install_language_support_packages": {
"type": "boolean"
}
},
"additionalProperties": false
},
"identity": { "identity": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -1,5 +1,7 @@
Welcome: Welcome:
lang: en_US lang: en_US
WSLSetupOptions:
install_language_support_packages: true
WSLIdentity: WSLIdentity:
realname: Ubuntu realname: Ubuntu
username: ubuntu username: ubuntu

View File

@ -4,6 +4,8 @@ early-commands:
- ["sleep", "1"] - ["sleep", "1"]
- echo a - echo a
locale: en_US locale: en_US
wslsetupoptions:
install_language_support_packages: true
identity: identity:
realname: Ubuntu realname: Ubuntu
username: ubuntu username: ubuntu
@ -20,4 +22,4 @@ wslconfadvanced:
automount_enabled: false automount_enabled: false
automount_mountfstab: false automount_mountfstab: false
systemd_enabled: true systemd_enabled: true
shutdown: 'poweroff' shutdown: 'poweroff'

View File

@ -64,6 +64,7 @@ from subiquity.common.types import (
ZdevInfo, ZdevInfo,
WSLConfigurationBase, WSLConfigurationBase,
WSLConfigurationAdvanced, WSLConfigurationAdvanced,
WSLSetupOptions,
) )
@ -76,6 +77,7 @@ class API:
updates = simple_endpoint(str) updates = simple_endpoint(str)
wslconfbase = simple_endpoint(WSLConfigurationBase) wslconfbase = simple_endpoint(WSLConfigurationBase)
wslconfadvanced = simple_endpoint(WSLConfigurationAdvanced) wslconfadvanced = simple_endpoint(WSLConfigurationAdvanced)
wslsetupoptions = simple_endpoint(WSLSetupOptions)
class meta: class meta:
class status: class status:

View File

@ -614,3 +614,11 @@ class WSLConfigurationAdvanced:
interop_enabled: bool = attr.ib(default=True) interop_enabled: bool = attr.ib(default=True)
interop_appendwindowspath: bool = attr.ib(default=True) interop_appendwindowspath: bool = attr.ib(default=True)
systemd_enabled: bool = attr.ib(default=False) systemd_enabled: bool = attr.ib(default=False)
# Options that affect the setup experience itself, but won't reflect in the
# /etc/wsl.conf configuration file.
@attr.s(auto_attribs=True)
class WSLSetupOptions:
install_language_support_packages: bool = attr.ib(default=True)

View File

@ -151,6 +151,18 @@ class Server(Client):
pass pass
class SystemSetupServer(Server):
async def spawn(self, output_base, socket, machine_config,
bootloader='uefi', extra_args=None):
env = os.environ.copy()
env['SUBIQUITY_REPLAY_TIMESCALE'] = '100'
cmd = ['python3', '-m', 'system_setup.cmd.server',
'--dry-run', '--socket', socket]
if extra_args is not None:
cmd.extend(extra_args)
self.proc = await astart_command(cmd, env=env)
class TestAPI(SubiTestCase): class TestAPI(SubiTestCase):
class _MachineConfig(os.PathLike): class _MachineConfig(os.PathLike):
def __init__(self, outer, path): def __init__(self, outer, path):
@ -206,12 +218,12 @@ def tempdirs(*args, **kwargs):
@contextlib.asynccontextmanager @contextlib.asynccontextmanager
async def start_server(*args, **kwargs): async def start_server_factory(factory, *args, **kwargs):
with tempfile.TemporaryDirectory() as tempdir: with tempfile.TemporaryDirectory() as tempdir:
socket_path = f'{tempdir}/socket' socket_path = f'{tempdir}/socket'
conn = aiohttp.UnixConnector(path=socket_path) conn = aiohttp.UnixConnector(path=socket_path)
async with aiohttp.ClientSession(connector=conn) as session: async with aiohttp.ClientSession(connector=conn) as session:
server = Server(session) server = factory(session)
try: try:
await server.spawn(tempdir, socket_path, *args, **kwargs) await server.spawn(tempdir, socket_path, *args, **kwargs)
await poll_for_socket_exist(socket_path) await poll_for_socket_exist(socket_path)
@ -221,6 +233,18 @@ async def start_server(*args, **kwargs):
await server.close() await server.close()
@contextlib.asynccontextmanager
async def start_server(*args, **kwargs):
async with start_server_factory(Server, *args, **kwargs) as instance:
yield instance
@contextlib.asynccontextmanager
async def start_system_setup_server(*args, **kwargs):
async with start_server_factory(SystemSetupServer, *args, **kwargs) as srv:
yield srv
@contextlib.asynccontextmanager @contextlib.asynccontextmanager
async def connect_server(*args, **kwargs): async def connect_server(*args, **kwargs):
# This is not used by the tests directly, but can be convenient when # This is not used by the tests directly, but can be convenient when
@ -1356,3 +1380,18 @@ class TestUbuntuProContractSelection(TestAPI):
await inst.post('/ubuntu_pro/contract_selection/cancel') await inst.post('/ubuntu_pro/contract_selection/cancel')
with self.assertRaises(Exception): with self.assertRaises(Exception):
await inst.get('/ubuntu_pro/contract_selection/wait') await inst.get('/ubuntu_pro/contract_selection/wait')
class TestWSLSetupOptions(TestAPI):
async def test_wslsetupoptions(self):
async with start_system_setup_server('examples/simple.json') as inst:
await inst.post('/meta/client_variant', variant='wsl_setup')
payload = {'install_language_support_packages': False}
endpoint = '/wslsetupoptions'
resp = await inst.get(endpoint)
self.assertTrue(resp['install_language_support_packages'])
await inst.post(endpoint, payload)
resp = await inst.get(endpoint)
self.assertFalse(resp['install_language_support_packages'])

View File

@ -0,0 +1,44 @@
# 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 <http://www.gnu.org/licenses/>.
import logging
import attr
log = logging.getLogger('system_setup.models.wslsetupoptions')
@attr.s
class WSLSetupOptions(object):
install_language_support_packages = attr.ib()
class WSLSetupOptionsModel(object):
""" Model representing basic wsl configuration
"""
def __init__(self):
self._wslsetupoptions = None
def apply_settings(self, result):
d = result.__dict__
self._wslsetupoptions = WSLSetupOptions(**d)
@property
def wslsetupoptions(self):
return self._wslsetupoptions
def __repr__(self):
return "<WSL Setup Options: {}>".format(self.wslsetupoptions)