system_setup: unify api names and simply WSLconfig class into function

This commit is contained in:
Patrick Wu 2021-10-04 18:55:25 +08:00
parent 5c0e64e78a
commit 1a7274dbba
12 changed files with 293 additions and 294 deletions

View File

@ -6,9 +6,9 @@ WSLIdentity:
# ubuntu # ubuntu
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1' password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
WSLConfigurationBase: WSLConfigurationBase:
custom_path: '/custom_mnt_path' automount_root: '/custom_mnt_path'
custom_mount_opt: 'metadata' automount_options: 'metadata'
gen_host: false network_generatehosts: false
gen_resolvconf: false network_generateresolvconf: false
Summary: Summary:
reboot: yes reboot: yes

View File

@ -356,21 +356,21 @@ class ShutdownMode(enum.Enum):
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
class WSLConfigurationBase: class WSLConfigurationBase:
custom_path: str = attr.ib(default='/mnt/') automount_root: str = attr.ib(default='/mnt/')
custom_mount_opt: str = '' automount_options: str = ''
gen_host: bool = attr.ib(default=True) network_generatehosts: bool = attr.ib(default=True)
gen_resolvconf: bool = attr.ib(default=True) network_generateresolvconf: bool = attr.ib(default=True)
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
class WSLConfigurationAdvanced: class WSLConfigurationAdvanced:
gui_theme: str = attr.ib(default='default') gui_theme: str = attr.ib(default='default')
gui_followwintheme: bool = attr.ib(default=True) gui_followwintheme: bool = attr.ib(default=True)
legacy_gui: bool = attr.ib(default=False) interop_guiintegration: bool = attr.ib(default=False)
legacy_audio: bool = attr.ib(default=False) interop_audiointegration: bool = attr.ib(default=False)
adv_ip_detect: bool = attr.ib(default=False) interop_advancedipdetection: bool = attr.ib(default=False)
wsl_motd_news: bool = attr.ib(default=True) motd_wslnewsenabled: bool = attr.ib(default=True)
automount: bool = attr.ib(default=True) automount_enabled: bool = attr.ib(default=True)
mountfstab: bool = attr.ib(default=True) automount_mountfstab: bool = attr.ib(default=True)
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)

View File

@ -33,21 +33,24 @@ class WSLConfigurationAdvancedController(SubiquityTuiController):
def run_answers(self): def run_answers(self):
if all(elem in self.answers for elem in if all(elem in self.answers for elem in
['interop_enabled', 'interop_appendwindowspath', ['interop_enabled', 'interop_appendwindowspath',
'gui_theme', 'gui_followwintheme', 'legacy_gui', 'gui_theme', 'gui_followwintheme', 'interop_guiintegration',
'legacy_audio', 'adv_ip_detect', 'interop_audiointegration', 'interop_advancedipdetection',
'wsl_motd_news', 'automount', 'mountfstab']): 'motd_wslnewsenabled', 'automount_enabled',
'automount_mountfstab']):
reconfiguration = WSLConfigurationAdvanced( reconfiguration = WSLConfigurationAdvanced(
interop_enabled=self.answers['interop_enabled'], interop_enabled=self.answers['interop_enabled'],
interop_appendwindowspath=self interop_appendwindowspath=self
.answers['interop_appendwindowspath'], .answers['interop_appendwindowspath'],
gui_theme=self.answers['gui_theme'], gui_theme=self.answers['gui_theme'],
gui_followwintheme=self.answers['gui_followwintheme'], gui_followwintheme=self.answers['gui_followwintheme'],
legacy_gui=self.answers['legacy_gui'], interop_guiintegration=self.answers['interop_guiintegration'],
legacy_audio=self.answers['legacy_audio'], interop_audiointegration=self
adv_ip_detect=self.answers['adv_ip_detect'], .answers['interop_audiointegration'],
wsl_motd_news=self.answers['wsl_motd_news'], interop_advancedipdetection=self
automount=self.answers['automount'], .answers['interop_advancedipdetection'],
mountfstab=self.answers['mountfstab'] motd_wslnewsenabled=self.answers['motd_wslnewsenabled'],
automount_enabled=self.answers['automount_enabled'],
automount_mountfstab=self.answers['automount_mountfstab']
) )
self.done(reconfiguration) self.done(reconfiguration)

View File

@ -16,13 +16,14 @@ class WSLConfigurationBaseController(SubiquityTuiController):
def run_answers(self): def run_answers(self):
if all(elem in self.answers for elem in if all(elem in self.answers for elem in
['custom_path', 'custom_mount_opt', ['automount_root', 'automount_options',
'gen_host', 'gen_resolvconf']): 'network_generatehosts', 'network_generateresolvconf']):
configuration = WSLConfigurationBase( configuration = WSLConfigurationBase(
custom_path=self.answers['custom_path'], automount_root=self.answers['automount_root'],
custom_mount_opt=self.answers['custom_mount_opt'], automount_options=self.answers['automount_options'],
gen_host=self.answers['gen_host'], network_generatehosts=self.answers['network_generatehosts'],
gen_resolvconf=self.answers['gen_resolvconf']) network_generateresolvconf=self
.answers['network_generateresolvconf'])
self.done(configuration) self.done(configuration)
def done(self, configuration_data): def done(self, configuration_data):

View File

@ -17,25 +17,12 @@
# original code from ubuntuwslctl.core.loader # original code from ubuntuwslctl.core.loader
# Copyright (C) 2021 Canonical Ltd. # Copyright (C) 2021 Canonical Ltd.
import os
import logging import logging
from configparser import ConfigParser from configparser import ConfigParser
from os import path
log = logging.getLogger("system_setup.common.wsl_conf") log = logging.getLogger("system_setup.common.wsl_conf")
config_base_ref = {
"wsl": {
"automount": {
"root": "custom_path",
"options": "custom_mount_opt",
},
"network": {
"generatehosts": "gen_host",
"generateresolvconf": "gen_resolvconf",
},
}
}
config_base_default = { config_base_default = {
"wsl": { "wsl": {
"automount": { "automount": {
@ -49,33 +36,6 @@ config_base_default = {
} }
} }
config_adv_ref = {
"wsl": {
"automount": {
"enabled": "automount",
"mountfstab": "mountfstab",
},
"interop": {
"enabled": "interop_enabled",
"appendwindowspath": "interop_appendwindowspath",
}
},
"ubuntu": {
"GUI": {
"theme": "gui_theme",
"followwintheme": "gui_followwintheme",
},
"Interop": {
"guiintegration": "legacy_gui",
"audiointegration": "legacy_audio",
"advancedipdetection": "adv_ip_detect",
},
"Motd": {
"wslnewsenabled": "wsl_motd_news",
}
}
}
config_adv_default = { config_adv_default = {
"wsl": { "wsl": {
"automount": { "automount": {
@ -105,22 +65,38 @@ config_adv_default = {
def wsl_config_loader(data, pathname, config_ref, id): def wsl_config_loader(data, pathname, config_ref, id):
if path.exists(pathname): """
config = ConfigParser() Loads the configuration from the given file type,
config.read(pathname) section and reference config.
for conf_sec in config:
if conf_sec in config_ref[id]: :param data: dict, the data to load into
conf_sec_list = config[conf_sec] :param pathname: string, the path to the file to load
for conf_item in conf_sec_list: :param id: string, the name of the section to load
if conf_item in config_ref[id][conf_sec]: """
data[config_ref[id][conf_sec][conf_item]] = \ if not os.path.exists(pathname):
conf_sec_list[conf_item] return data
config = ConfigParser()
config.read(pathname)
for conf_sec in config:
if conf_sec in config_ref[id]:
conf_sec_list = config[conf_sec]
for conf_item in conf_sec_list:
if conf_item in config_ref[id][conf_sec]:
data[conf_sec.lower()
+ "_" + conf_item.lower()] = \
conf_sec_list[conf_item]
return data return data
def default_loader(is_advanced): def default_loader(is_advanced):
"""
This will load the default WSL config for the given type.
:param is_advanced: boolean, True if it is WSLConfigurationAdvanced,
else is WSLConfigurationBase
"""
data = {} data = {}
conf_ref = config_adv_ref if is_advanced else config_base_ref conf_ref = config_adv_default if is_advanced else config_base_default
data = wsl_config_loader(data, "/etc/wsl.conf", conf_ref, "wsl") data = wsl_config_loader(data, "/etc/wsl.conf", conf_ref, "wsl")
if is_advanced: if is_advanced:
data = \ data = \
@ -128,74 +104,67 @@ def default_loader(is_advanced):
return data return data
class WSLConfig: # TODO: remove dryrun and add root param once we write the option to .subiquity
def __init__(self, conf_file): def wsl_config_update(config_class, is_dry_run):
self.conf_file = conf_file """
This update the configuration file for the given class.zzd
self.config = ConfigParser() :param config_class: WSLConfigurationBase or WSLConfigurationAdvanced
self.config.BasicInterpolcation = None :param is_dry_run: boolean, True if it is a dry run
self.config.read(conf_file) """
if is_dry_run:
log.debug("mimicking setting config %s", config_class)
temp_conf_default = {}
temp_confname = config_class.__str__()
if temp_confname.startswith("WSLConfigurationBase"):
temp_conf_default = config_base_default
elif temp_confname.startswith("WSLConfigurationAdvanced"):
temp_conf_default = config_adv_default
else:
raise TypeError("Invalid type name.")
if is_dry_run:
return
def drop_if_exists(self, config_section, config_setting): # update the config file
if config_setting in self.config[config_section]: for config_type in temp_conf_default:
self.config.remove_option(config_section, config_setting) config_sections = temp_conf_default[config_type]
with open(self.conf_file, 'w') as configfile:
self.config.write(configfile)
def update(self, config_section, config_setting, config_value): config = ConfigParser()
self.config[config_section][config_setting] = config_value config.BasicInterpolcation = None
with open(self.conf_file, 'w') as configfile:
self.config.write(configfile)
if config_type == "wsl":
class WSLConfigHandler: conf_file = "/etc/wsl.conf"
elif config_type == "ubuntu":
def __init__(self, is_dry_run): conf_file = "/etc/ubuntu-wsl.conf"
self.is_dry_run = is_dry_run
self.ubuntu_conf = \
WSLConfig("/etc/ubuntu-wsl.conf")
self.wsl_conf = WSLConfig("/etc/wsl.conf")
def _select_config(self, type_input):
type_input = type_input.lower()
if type_input == "ubuntu":
return self.ubuntu_conf
elif type_input == "wsl":
return self.wsl_conf
else: else:
raise ValueError("Invalid config type '{}'.".format(type_input)) raise TypeError("Invalid type name " % config_type)
def update(self, config_class): config.read(conf_file)
if self.is_dry_run:
log.debug("mimicking setting config %s", for config_section in config_sections:
config_class) config_settings = config_sections[config_section]
temp_conf_ref = {} for config_setting in config_settings:
temp_conf_default = {} config_default_value = config_settings[config_setting]
test_confname = config_class.__str__() config_api_name = \
if test_confname.startswith("WSLConfigurationBase"): config_section.lower() + "_" + config_setting.lower()
temp_conf_ref = config_base_ref config_value = config_class.__dict__[config_api_name]
temp_conf_default = config_base_default # if the value for the setting is defualt value, drop it
elif test_confname.startswith("WSLConfigurationAdvanced"): if config_default_value == config_value:
temp_conf_ref = config_adv_ref if config_setting in config[config_section]:
temp_conf_default = config_adv_default config.remove_option(config_section, config_setting)
else: # drop the section if it become empty
raise TypeError("Invalid type name.") if config[config_section] == {}:
if self.is_dry_run: config.remove_section(config_section)
return else:
for config_type in temp_conf_ref: if config_section not in config:
config_sections = temp_conf_ref[config_type] config.add_section(config_section)
for config_section in config_sections: if isinstance(config_value, bool):
config_settings = config_sections[config_section] config_value = str(config_value).lower()
for config_setting in config_settings: config[config_section][config_setting] = config_value
config_realname = config_settings[config_setting]
config_value = config_class.__dict__[config_realname] with open(conf_file + ".new", 'w+') as configfile:
if temp_conf_default[config_type][config_section][ config.write(configfile)
config_setting] == config_value:
self._select_config(config_type). \ if os.isfile(conf_file):
drop_if_exists(config_section, os.rename(conf_file, conf_file + ".old")
config_setting) os.move(conf_file + ".new", conf_file)
else:
self._select_config(config_type). \
update(config_section,
config_setting,
config_value)

View File

@ -23,12 +23,12 @@ log = logging.getLogger('system_setup.models.wsl_configuration_advanced')
class WSLConfigurationAdvanced(object): class WSLConfigurationAdvanced(object):
gui_theme = attr.ib() gui_theme = attr.ib()
gui_followwintheme = attr.ib() gui_followwintheme = attr.ib()
legacy_gui = attr.ib() interop_guiintegration = attr.ib()
legacy_audio = attr.ib() interop_audiointegration = attr.ib()
adv_ip_detect = attr.ib() interop_advancedipdetection = attr.ib()
wsl_motd_news = attr.ib() motd_wslnewsenabled = attr.ib()
automount = attr.ib() automount_enabled = attr.ib()
mountfstab = attr.ib() automount_mountfstab = attr.ib()
interop_enabled = attr.ib() interop_enabled = attr.ib()
interop_appendwindowspath = attr.ib() interop_appendwindowspath = attr.ib()
@ -48,12 +48,12 @@ class WSLConfigurationAdvancedModel(object):
d['interop_appendwindowspath'] = result.interop_appendwindowspath d['interop_appendwindowspath'] = result.interop_appendwindowspath
d['gui_theme'] = result.gui_theme d['gui_theme'] = result.gui_theme
d['gui_followwintheme'] = result.gui_followwintheme d['gui_followwintheme'] = result.gui_followwintheme
d['legacy_gui'] = result.legacy_gui d['interop_guiintegration'] = result.interop_guiintegration
d['legacy_audio'] = result.legacy_audio d['interop_audiointegration'] = result.interop_audiointegration
d['adv_ip_detect'] = result.adv_ip_detect d['interop_advancedipdetection'] = result.interop_advancedipdetection
d['wsl_motd_news'] = result.wsl_motd_news d['motd_wslnewsenabled'] = result.motd_wslnewsenabled
d['automount'] = result.automount d['automount_enabled'] = result.automount_enabled
d['mountfstab'] = result.mountfstab d['automount_mountfstab'] = result.automount_mountfstab
self._wslconfadvanced = WSLConfigurationAdvanced(**d) self._wslconfadvanced = WSLConfigurationAdvanced(**d)
@property @property

View File

@ -21,10 +21,10 @@ log = logging.getLogger('system_setup.models.wsl_configuration_base')
@attr.s @attr.s
class WSLConfigurationBase(object): class WSLConfigurationBase(object):
custom_path = attr.ib() automount_root = attr.ib()
custom_mount_opt = attr.ib() automount_options = attr.ib()
gen_host = attr.ib() network_generatehosts = attr.ib()
gen_resolvconf = attr.ib() network_generateresolvconf = attr.ib()
class WSLConfigurationBaseModel(object): class WSLConfigurationBaseModel(object):
@ -37,10 +37,10 @@ class WSLConfigurationBaseModel(object):
def apply_settings(self, result): def apply_settings(self, result):
d = {} d = {}
d['custom_path'] = result.custom_path d['automount_root'] = result.automount_root
d['custom_mount_opt'] = result.custom_mount_opt d['automount_options'] = result.automount_options
d['gen_host'] = result.gen_host d['network_generatehosts'] = result.network_generatehosts
d['gen_resolvconf'] = result.gen_resolvconf d['network_generateresolvconf'] = result.network_generateresolvconf
self._wslconfbase = WSLConfigurationBase(**d) self._wslconfbase = WSLConfigurationBase(**d)
@property @property

View File

@ -20,7 +20,7 @@ from subiquity.common.types import ApplicationState
from subiquity.server.controller import SubiquityController from subiquity.server.controller import SubiquityController
from subiquitycore.context import with_context from subiquitycore.context import with_context
from subiquitycore.utils import run_command from subiquitycore.utils import run_command
from system_setup.common.wsl_conf import WSLConfigHandler from system_setup.common.wsl_conf import wsl_config_update
from system_setup.common.wsl_utils import get_userandgroups from system_setup.common.wsl_utils import get_userandgroups
log = logging.getLogger("system_setup.server.controllers.configure") log = logging.getLogger("system_setup.server.controllers.configure")
@ -68,7 +68,6 @@ class ConfigureController(SubiquityController):
dryrun = self.app.opts.dry_run dryrun = self.app.opts.dry_run
variant = self.app.variant variant = self.app.variant
config = WSLConfigHandler(dryrun)
if variant == "wsl_setup": if variant == "wsl_setup":
wsl_id = self.model.identity.user wsl_id = self.model.identity.user
if dryrun: if dryrun:
@ -93,9 +92,10 @@ class ConfigureController(SubiquityController):
raise Exception("Failed to assign groups to user %s" % raise Exception("Failed to assign groups to user %s" %
wsl_id.username) wsl_id.username)
else: else:
config.update(self.model.wslconfadvanced.wslconfadvanced) wsl_config_update(self.model.wslconfadvanced.wslconfadvanced,
dryrun)
config.update(self.model.wslconfbase.wslconfbase) wsl_config_update(self.model.wslconfbase.wslconfbase, dryrun)
self.app.update_state(ApplicationState.DONE) self.app.update_state(ApplicationState.DONE)
except Exception: except Exception:

View File

@ -40,12 +40,12 @@ class WSLConfigurationAdvancedController(SubiquityController):
'interop_appendwindowspath': {'type': 'boolean'}, 'interop_appendwindowspath': {'type': 'boolean'},
'gui_theme': {'type': 'string'}, 'gui_theme': {'type': 'string'},
'gui_followwintheme': {'type': 'boolean'}, 'gui_followwintheme': {'type': 'boolean'},
'legacy_gui': {'type': 'boolean'}, 'interop_guiintegration': {'type': 'boolean'},
'legacy_audio': {'type': 'boolean'}, 'interop_audiointegration': {'type': 'boolean'},
'adv_ip_detect': {'type': 'boolean'}, 'interop_advancedipdetection': {'type': 'boolean'},
'wsl_motd_news': {'type': 'boolean'}, 'motd_wslnewsenabled': {'type': 'boolean'},
'automount': {'type': 'boolean'}, 'automount_enabled': {'type': 'boolean'},
'mountfstab': {'type': 'boolean'} 'automount_mountfstab': {'type': 'boolean'}
}, },
'additionalProperties': False, 'additionalProperties': False,
} }
@ -65,12 +65,17 @@ class WSLConfigurationAdvancedController(SubiquityController):
data['interop_appendwindowspath']), data['interop_appendwindowspath']),
gui_theme=data['gui_theme'], gui_theme=data['gui_theme'],
gui_followwintheme=bool_converter(data['gui_followwintheme']), gui_followwintheme=bool_converter(data['gui_followwintheme']),
legacy_gui=bool_converter(data['legacy_gui']), interop_guiintegration=bool_converter(
legacy_audio=bool_converter(data['legacy_audio']), data['interop_guiintegration']),
adv_ip_detect=bool_converter(data['adv_ip_detect']), interop_audiointegration=bool_converter(
wsl_motd_news=bool_converter(data['wsl_motd_news']), data['interop_audiointegration']),
automount=bool_converter(data['automount']), interop_advancedipdetection=bool_converter(
mountfstab=bool_converter(data['mountfstab']), data['interop_advancedipdetection']),
motd_wslnewsenabled=bool_converter(
data['motd_wslnewsenabled']),
automount_enabled=bool_converter(data['automount_enabled']),
automount_mountfstab=bool_converter(
data['automount_mountfstab']),
) )
self.model.apply_settings(reconf_data) self.model.apply_settings(reconf_data)
@ -81,12 +86,13 @@ class WSLConfigurationAdvancedController(SubiquityController):
interop_appendwindowspath=data['interop_appendwindowspath'], interop_appendwindowspath=data['interop_appendwindowspath'],
gui_theme=data['gui_theme'], gui_theme=data['gui_theme'],
gui_followwintheme=data['gui_followwintheme'], gui_followwintheme=data['gui_followwintheme'],
legacy_gui=data['legacy_gui'], interop_guiintegration=data['interop_guiintegration'],
legacy_audio=data['legacy_audio'], interop_audiointegration=data['interop_audiointegration'],
adv_ip_detect=data['adv_ip_detect'], interop_advancedipdetection=data[
wsl_motd_news=data['wsl_motd_news'], 'interop_advancedipdetection'],
automount=data['automount'], motd_wslnewsenabled=data['motd_wslnewsenabled'],
mountfstab=data['mountfstab'] automount_enabled=data['automount_enabled'],
automount_mountfstab=data['automount_mountfstab']
) )
self.model.apply_settings(reconf_data) self.model.apply_settings(reconf_data)
@ -101,18 +107,26 @@ class WSLConfigurationAdvancedController(SubiquityController):
async def GET(self) -> WSLConfigurationAdvanced: async def GET(self) -> WSLConfigurationAdvanced:
data = WSLConfigurationAdvanced() data = WSLConfigurationAdvanced()
if self.model.wslconfadvanced is not None: if self.model.wslconfadvanced is not None:
data.interop_enabled = self.model.wslconfadvanced.interop_enabled data.interop_enabled = \
self.model.wslconfadvanced.interop_enabled
data.interop_appendwindowspath = \ data.interop_appendwindowspath = \
self.model.wslconfadvanced.interop_appendwindowspath self.model.wslconfadvanced.interop_appendwindowspath
data.gui_theme = self.model.wslconfadvanced.gui_theme data.gui_theme = \
self.model.wslconfadvanced.gui_theme
data.gui_followwintheme = \ data.gui_followwintheme = \
self.model.wslconfadvanced.gui_followwintheme self.model.wslconfadvanced.gui_followwintheme
data.legacy_gui = self.model.wslconfadvanced.legacy_gui data.interop_guiintegration = \
data.legacy_audio = self.model.wslconfadvanced.legacy_audio self.model.wslconfadvanced.interop_guiintegration
data.adv_ip_detect = self.model.wslconfadvanced.adv_ip_detect data.interop_audiointegration = \
data.wsl_motd_news = self.model.wslconfadvanced.wsl_motd_news self.model.wslconfadvanced.interop_audiointegration
data.automount = self.model.wslconfadvanced.automount data.interop_advancedipdetection = \
data.mountfstab = self.model.wslconfadvanced.mountfstab self.model.wslconfadvanced.interop_advancedipdetection
data.motd_wslnewsenabled = \
self.model.wslconfadvanced.motd_wslnewsenabled
data.automount_enabled = \
self.model.wslconfadvanced.automount_enabled
data.automount_mountfstab = \
self.model.wslconfadvanced.automount_mountfstab
return data return data
async def POST(self, data: WSLConfigurationAdvanced): async def POST(self, data: WSLConfigurationAdvanced):

View File

@ -36,10 +36,10 @@ class WSLConfigurationBaseController(SubiquityController):
autoinstall_schema = { autoinstall_schema = {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
'custom_path': {'type': 'string'}, 'automount_root': {'type': 'string'},
'custom_mount_opt': {'type': 'string'}, 'automount_options': {'type': 'string'},
'gen_host': {'type': 'boolean'}, 'network_generatehosts': {'type': 'boolean'},
'gen_resolvconf': {'type': 'boolean'}, 'network_generateresolvconf': {'type': 'boolean'},
}, },
'additionalProperties': False, 'additionalProperties': False,
} }
@ -54,20 +54,22 @@ class WSLConfigurationBaseController(SubiquityController):
def bool_converter(x): def bool_converter(x):
return x.lower() == 'true' return x.lower() == 'true'
conf_data = WSLConfigurationBase( conf_data = WSLConfigurationBase(
custom_path=data['custom_path'], automount_root=data['automount_root'],
custom_mount_opt=data['custom_mount_opt'], automount_options=data['automount_options'],
gen_host=bool_converter(data['gen_host']), network_generatehosts=bool_converter(
gen_resolvconf=bool_converter(data['gen_resolvconf']), data['network_generatehosts']),
network_generateresolvconf=bool_converter(
data['network_generateresolvconf']),
) )
self.model.apply_settings(conf_data) self.model.apply_settings(conf_data)
def load_autoinstall_data(self, data): def load_autoinstall_data(self, data):
if data is not None: if data is not None:
identity_data = WSLConfigurationBase( identity_data = WSLConfigurationBase(
custom_path=data['custom_path'], automount_root=data['automount_root'],
custom_mount_opt=data['custom_mount_opt'], automount_options=data['automount_options'],
gen_host=data['gen_host'], network_generatehosts=data['network_generatehosts'],
gen_resolvconf=data['gen_resolvconf'], network_generateresolvconf=data['network_generateresolvconf'],
) )
self.model.apply_settings(identity_data) self.model.apply_settings(identity_data)
@ -82,10 +84,12 @@ class WSLConfigurationBaseController(SubiquityController):
async def GET(self) -> WSLConfigurationBase: async def GET(self) -> WSLConfigurationBase:
data = WSLConfigurationBase() data = WSLConfigurationBase()
if self.model.wslconfbase is not None: if self.model.wslconfbase is not None:
data.custom_path = self.model.wslconfbase.custom_path data.automount_root = self.model.wslconfbase.automount_root
data.custom_mount_opt = self.model.wslconfbase.custom_mount_opt data.automount_options = self.model.wslconfbase.automount_options
data.gen_host = self.model.wslconfbase.gen_host data.network_generatehosts = \
data.gen_resolvconf = self.model.wslconfbase.gen_resolvconf self.model.wslconfbase.network_generatehosts
data.network_generateresolvconf = \
self.model.wslconfbase.network_generateresolvconf
return data return data
async def POST(self, data: WSLConfigurationBase): async def POST(self, data: WSLConfigurationBase):

View File

@ -42,55 +42,53 @@ class WSLConfigurationAdvancedForm(Form):
def __init__(self, initial): def __init__(self, initial):
super().__init__(initial=initial) super().__init__(initial=initial)
automount = BooleanField(_("Enable Auto-Mount"), automount_enabled = \
help=_("Whether the Auto-Mount freature is" BooleanField(_("Enable Auto-Mount"),
" enabled. This feature allows you " help=_("Whether the Auto-Mount freature is enabled. "
"to mount Windows drive in WSL")) "This feature allows you to mount Windows drive"
mountfstab = BooleanField(_("Mount `/etc/fstab`"), " in WSL."))
help=_("Whether `/etc/fstab` will be mounted." automount_mountfstab = \
" The configuration file `/etc/fstab` " BooleanField(_("Mount `/etc/fstab`"),
"contains the necessary information to" help=_("Whether `/etc/fstab` will be mounted. The "
" automate the process of mounting " "configuration file `/etc/fstab` contains "
"partitions. ")) "the necessary information to automate the"
interop_enabled = BooleanField(_("Enable Interop"), " process of mounting partitions. "))
help=_("Whether the interoperability is" interop_enabled = \
" enabled")) BooleanField(_("Enable Interop"),
interop_appendwindowspath = BooleanField(_("Append Windows Path"), help=_("Whether the interoperability is enabled"))
help=_("Whether Windows Path " interop_appendwindowspath = \
"will be append in the" BooleanField(_("Append Windows Path"),
" PATH environment " help=_("Whether Windows Path will be append in the"
"variable in WSL.")) " PATH environment variable in WSL."))
gui_theme = ChoiceField(_("GUI Theme"), gui_theme = \
help=_("This option changes the Ubuntu theme."), ChoiceField(_("GUI Theme"),
choices=["default", "light", "dark"]) help=_("This option changes the Ubuntu theme."),
gui_followwintheme = BooleanField(_("Follow Windows Theme"), choices=["default", "light", "dark"])
help=_("This option manages whether the" gui_followwintheme = \
" Ubuntu theme follows the " BooleanField(_("Follow Windows Theme"),
"Windows theme; that is, when " help=_("This option manages whether the Ubuntu theme"
"Windows uses dark theme, " " follows the Windows theme; that is, when "
"Ubuntu also uses dark theme." "Windows uses dark theme, Ubuntu also uses dark"
" Requires WSL interoperability" " theme. Requires WSL interoperability enabled. "))
" enabled. ")) interop_guiintegration = \
legacy_gui = BooleanField(_("Legacy GUI Integration"), BooleanField(_("Legacy GUI Integration"),
help=_("This option enables the Legacy GUI " help=_("This option enables the Legacy GUI Integration "
"Integration on Windows 10. Requires" "on Windows 10. Requires a Third-party X Server."))
" a Third-party X Server.")) interop_audiointegration = \
legacy_audio = BooleanField(_("Legacy Audio Integration"), BooleanField(_("Legacy Audio Integration"),
help=_("This option enables the Legacy " help=_("This option enables the Legacy Audio Integration "
"Audio Integration on Windows 10. " "on Windows 10. Requires PulseAudio for Windows "
"Requires PulseAudio for " "Installed."))
"Windows Installed.")) interop_advancedipdetection = \
adv_ip_detect = BooleanField(_("Advanced IP Detection"), BooleanField(_("Advanced IP Detection"),
help=_("This option enables advanced " help=_("This option enables advanced detection of IP by "
"detection of IP by Windows " "Windows IPv4 Address which is more reliable to "
"IPv4 Address which is more " "use with WSL2. Requires WSL interoperability "
"reliable to use with WSL2. " "enabled."))
"Requires WSL interoperability" motd_wslnewsenabled = \
" enabled.")) BooleanField(_("Enable WSL News"),
wsl_motd_news = BooleanField(_("Enable WSL News"), help=_("This option allows you to control your MOTD News."
help=_("This options allows you to control" " Toggling it on allows you to see the MOTD."))
" your MOTD News. Toggling it on "
"allows you to see the MOTD."))
class WSLConfigurationAdvancedView(BaseView): class WSLConfigurationAdvancedView(BaseView):
@ -107,12 +105,15 @@ class WSLConfigurationAdvancedView(BaseView):
configuration_data.interop_appendwindowspath, configuration_data.interop_appendwindowspath,
'gui_theme': configuration_data.gui_theme, 'gui_theme': configuration_data.gui_theme,
'gui_followwintheme': configuration_data.gui_followwintheme, 'gui_followwintheme': configuration_data.gui_followwintheme,
'legacy_gui': configuration_data.legacy_gui, 'interop_guiintegration': configuration_data
'legacy_audio': configuration_data.legacy_audio, .interop_guiintegration,
'adv_ip_detect': configuration_data.adv_ip_detect, 'interop_audiointegration': configuration_data
'wsl_motd_news': configuration_data.wsl_motd_news, .interop_audiointegration,
'automount': configuration_data.automount, 'interop_advancedipdetection': configuration_data
'mountfstab': configuration_data.mountfstab, .interop_advancedipdetection,
'motd_wslnewsenabled': configuration_data.motd_wslnewsenabled,
'automount_enabled': configuration_data.automount_enabled,
'automount_mountfstab': configuration_data.automount_mountfstab,
} }
self.form = WSLConfigurationAdvancedForm(initial=initial) self.form = WSLConfigurationAdvancedForm(initial=initial)
@ -133,10 +134,11 @@ class WSLConfigurationAdvancedView(BaseView):
.interop_appendwindowspath.value, .interop_appendwindowspath.value,
gui_theme=self.form.gui_theme.value, gui_theme=self.form.gui_theme.value,
gui_followwintheme=self.form.gui_followwintheme.value, gui_followwintheme=self.form.gui_followwintheme.value,
legacy_gui=self.form.legacy_gui.value, interop_guiintegration=self.form.interop_guiintegration.value,
legacy_audio=self.form.legacy_audio.value, interop_audiointegration=self.form.interop_audiointegration.value,
adv_ip_detect=self.form.adv_ip_detect.value, interop_advancedipdetection=self
wsl_motd_news=self.form.wsl_motd_news.value, .form.interop_advancedipdetection.value,
automount=self.form.automount.value, motd_wslnewsenabled=self.form.motd_wslnewsenabled.value,
mountfstab=self.form.mountfstab.value, automount_enabled=self.form.automount_enabled.value,
automount_mountfstab=self.form.automount_mountfstab.value,
)) ))

View File

@ -41,24 +41,28 @@ class WSLConfBaseForm(Form):
def __init__(self, initial): def __init__(self, initial):
super().__init__(initial=initial) super().__init__(initial=initial)
custom_path = MountField(_("Mount Location"), automount_root = MountField(_("Mount Location"),
help=_("Location for the automount")) help=_("Location for the automount"))
custom_mount_opt = StringField(_("Mount Option"), automount_options = StringField(_("Mount Option"),
help=_("Mount option passed " help=_("Mount option passed "
"for the automount")) "for the automount"))
gen_host = BooleanField(_("Enable Host Generation"), help=_( network_generatehosts = \
"Selecting enables /etc/host re-generation at every start")) BooleanField(_("Enable Host Generation"),
gen_resolvconf = BooleanField(_("Enable resolv.conf Generation"), help=_( help=_("Selecting enables /etc/host re-generation at"
"Selecting enables /etc/resolv.conf re-generation at every start")) " every start"))
network_generateresolvconf = \
BooleanField(_("Enable resolv.conf Generation"),
help=_("Selecting enables /etc/resolv.conf re-generation"
" at every start"))
def validate_custom_path(self): def validate_automount_root(self):
p = self.custom_path.value p = self.automount_root.value
if p != "" and (re.fullmatch(r"(/[^/ ]*)+/?", p) is None): if p != "" and (re.fullmatch(r"(/[^/ ]*)+/?", p) is None):
return _("Mount location must be a absolute UNIX path" return _("Mount location must be a absolute UNIX path"
" without space.") " without space.")
def validate_custom_mount_opt(self): def validate_automount_options(self):
o = self.custom_mount_opt.value o = self.automount_options.value
# filesystem independent mount option # filesystem independent mount option
fsimo = [r"async", r"(no)?atime", r"(no)?auto", fsimo = [r"async", r"(no)?atime", r"(no)?auto",
r"(fs|def|root)?context=\w+", r"(no)?dev", r"(no)?diratime", r"(fs|def|root)?context=\w+", r"(no)?dev", r"(no)?diratime",
@ -99,10 +103,11 @@ class WSLConfigurationBaseView(BaseView):
self.controller = controller self.controller = controller
initial = { initial = {
'custom_path': configuration_data.custom_path, 'automount_root': configuration_data.automount_root,
'custom_mount_opt': configuration_data.custom_mount_opt, 'automount_options': configuration_data.automount_options,
'gen_host': configuration_data.gen_host, 'network_generatehosts': configuration_data.network_generatehosts,
'gen_resolvconf': configuration_data.gen_resolvconf, 'network_generateresolvconf': configuration_data
.network_generateresolvconf,
} }
self.form = WSLConfBaseForm(initial=initial) self.form = WSLConfBaseForm(initial=initial)
@ -118,8 +123,9 @@ class WSLConfigurationBaseView(BaseView):
def done(self, result): def done(self, result):
self.controller.done(WSLConfigurationBase( self.controller.done(WSLConfigurationBase(
custom_path=self.form.custom_path.value, automount_root=self.form.automount_root.value,
custom_mount_opt=self.form.custom_mount_opt.value, automount_options=self.form.automount_options.value,
gen_host=self.form.gen_host.value, network_generatehosts=self.form.network_generatehosts.value,
gen_resolvconf=self.form.gen_resolvconf.value network_generateresolvconf=self
.form.network_generateresolvconf.value
)) ))