System-Setup: Add systemd experimental support to WSL

Grow a new API for enabling/disabling systemd experimental support. We
do this by chaining a specific command= in the boot section.
We preserve the user customized command= content when systemd
experimental support is not enabled.

Co-authored-by: Jean-Baptiste Lallement <jean-baptiste@ubuntu.com>
This commit is contained in:
Didier Roche 2022-03-16 12:20:33 +01:00
parent 303f78fb6d
commit d17cd6fc38
11 changed files with 66 additions and 3 deletions

View File

@ -99,6 +99,9 @@
}, },
"automount_mountfstab": { "automount_mountfstab": {
"type": "boolean" "type": "boolean"
},
"systemd_enabled": {
"type": "boolean"
} }
}, },
"additionalProperties": false "additionalProperties": false

View File

@ -8,5 +8,6 @@ WSLConfigurationAdvanced:
interop_appendwindowspath: false interop_appendwindowspath: false
automount_enabled: false automount_enabled: false
automount_mountfstab: false automount_mountfstab: false
systemd_enabled: true
Summary: Summary:
reboot: yes reboot: yes

View File

@ -19,4 +19,5 @@ wslconfadvanced:
interop_appendwindowspath: false interop_appendwindowspath: false
automount_enabled: false automount_enabled: false
automount_mountfstab: false automount_mountfstab: false
systemd_enabled: true
shutdown: 'poweroff' shutdown: 'poweroff'

View File

@ -458,3 +458,4 @@ class WSLConfigurationAdvanced:
automount_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)
systemd_enabled: bool = attr.ib(default=False)

View File

@ -32,7 +32,8 @@ 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',
'automount_enabled', 'automount_mountfstab']): 'automount_enabled', 'automount_mountfstab',
'systemd_enabled']):
reconfiguration = WSLConfigurationAdvanced(**self.answers) reconfiguration = WSLConfigurationAdvanced(**self.answers)
self.done(reconfiguration) self.done(reconfiguration)

View File

@ -24,6 +24,8 @@ from configparser import ConfigParser
log = logging.getLogger("system_setup.common.wsl_conf") log = logging.getLogger("system_setup.common.wsl_conf")
WSL_SYSTEMD_BOOT_COMMAND = "/usr/libexec/wsl-systemd"
config_base_default = { config_base_default = {
"wsl": { "wsl": {
"automount": { "automount": {
@ -46,6 +48,9 @@ config_adv_default = {
"interop": { "interop": {
"enabled": "true", "enabled": "true",
"appendwindowspath": "true" "appendwindowspath": "true"
},
"boot": {
"command": ""
} }
} }
} }
@ -74,9 +79,20 @@ def wsl_config_loader(data, config_ref, id):
conf_sec_list = config[conf_sec] conf_sec_list = config[conf_sec]
for conf_item in conf_sec_list: for conf_item in conf_sec_list:
if conf_item in config_ref[id][conf_sec]: if conf_item in config_ref[id][conf_sec]:
# Handle systemd experimental feature (string -> bool)
if (
conf_sec.lower() == "boot" and
conf_item.lower() == "command"):
v = conf_sec_list[conf_item]
data["systemd_enabled"] = "false"
if v == WSL_SYSTEMD_BOOT_COMMAND:
data["systemd_enabled"] = "true"
continue
data[conf_sec.lower() data[conf_sec.lower()
+ "_" + conf_item.lower()] = \ + "_" + conf_item.lower()] = \
conf_sec_list[conf_item] conf_sec_list[conf_item]
# This is the systemd value we converted
data.pop("boot_command", None)
return data return data
@ -128,9 +144,31 @@ def wsl_config_update(config_class, root_dir):
config_default_value = config_settings[config_setting] config_default_value = config_settings[config_setting]
config_api_name = \ config_api_name = \
config_section.lower() + "_" + config_setting.lower() config_section.lower() + "_" + config_setting.lower()
# on systemd, select correct API endpoint
systemd_experimental_section = False
if (config_section.lower() == "boot" and
config_setting.lower() == "command"):
systemd_experimental_section = True
config_api_name = "systemd_enabled"
config_value = config_class.__dict__[config_api_name] config_value = config_class.__dict__[config_api_name]
if isinstance(config_value, bool): if isinstance(config_value, bool):
config_value = str(config_value).lower() config_value = str(config_value).lower()
# map systemd bool -> boot command string and keep old value
# if it was not set to wsl-systemd (user customized)
if systemd_experimental_section:
v = ""
# Keep previous value set by user if the option is kept
# disabled and they set their own boot command.
if (config.has_option("boot", "command") and
config["boot"]["command"] != WSL_SYSTEMD_BOOT_COMMAND):
v = config["boot"]["command"]
if config_value == "true":
v = WSL_SYSTEMD_BOOT_COMMAND
config_value = v
# if the value for the setting is default value, drop it # if the value for the setting is default value, drop it
if config_default_value == config_value: if config_default_value == config_value:
if config_section in config: if config_section in config:

View File

@ -25,6 +25,7 @@ class WSLConfigurationAdvanced(object):
interop_appendwindowspath = attr.ib() interop_appendwindowspath = attr.ib()
automount_enabled = attr.ib() automount_enabled = attr.ib()
automount_mountfstab = attr.ib() automount_mountfstab = attr.ib()
systemd_enabled = attr.ib()
class WSLConfigurationAdvancedModel(object): class WSLConfigurationAdvancedModel(object):

View File

@ -39,7 +39,8 @@ class WSLConfigurationAdvancedController(SubiquityController):
'interop_enabled': {'type': 'boolean'}, 'interop_enabled': {'type': 'boolean'},
'interop_appendwindowspath': {'type': 'boolean'}, 'interop_appendwindowspath': {'type': 'boolean'},
'automount_enabled': {'type': 'boolean'}, 'automount_enabled': {'type': 'boolean'},
'automount_mountfstab': {'type': 'boolean'} 'automount_mountfstab': {'type': 'boolean'},
'systemd_enabled': {'type': 'boolean'}
}, },
'additionalProperties': False, 'additionalProperties': False,
} }
@ -80,6 +81,8 @@ class WSLConfigurationAdvancedController(SubiquityController):
self.model.wslconfadvanced.automount_enabled self.model.wslconfadvanced.automount_enabled
data.automount_mountfstab = \ data.automount_mountfstab = \
self.model.wslconfadvanced.automount_mountfstab self.model.wslconfadvanced.automount_mountfstab
data.systemd_enabled = \
self.model.wslconfadvanced.systemd_enabled
return data return data
async def POST(self, data: WSLConfigurationAdvanced): async def POST(self, data: WSLConfigurationAdvanced):

View File

@ -4,6 +4,9 @@ mountfstab = false
options = metadata options = metadata
root = /custom_mnt_path root = /custom_mnt_path
[boot]
command = /usr/libexec/wsl-systemd
[interop] [interop]
appendwindowspath = false appendwindowspath = false
enabled = false enabled = false

View File

@ -4,6 +4,9 @@ mountfstab = false
options = metadata options = metadata
root = /custom_mnt_path root = /custom_mnt_path
[boot]
command = /usr/libexec/wsl-systemd
[interop] [interop]
appendwindowspath = false appendwindowspath = false
enabled = false enabled = false

View File

@ -59,6 +59,10 @@ class WSLConfigurationAdvancedForm(Form):
BooleanField(_("Append Windows Path"), BooleanField(_("Append Windows Path"),
help=_("Whether Windows Path will be append in the" help=_("Whether Windows Path will be append in the"
" PATH environment variable in WSL.")) " PATH environment variable in WSL."))
systemd_enabled = \
BooleanField(_("Enable Systemd"),
help=_("EXPERIMENTAL - Whether systemd should be"
" activated at boot time."))
class WSLConfigurationAdvancedView(BaseView): class WSLConfigurationAdvancedView(BaseView):
@ -78,6 +82,8 @@ class WSLConfigurationAdvancedView(BaseView):
configuration_data.automount_enabled, configuration_data.automount_enabled,
'automount_mountfstab': 'automount_mountfstab':
configuration_data.automount_mountfstab, configuration_data.automount_mountfstab,
'systemd_enabled':
configuration_data.systemd_enabled,
} }
self.form = WSLConfigurationAdvancedForm(initial=initial) self.form = WSLConfigurationAdvancedForm(initial=initial)
@ -101,4 +107,6 @@ class WSLConfigurationAdvancedView(BaseView):
.automount_enabled.value, .automount_enabled.value,
automount_mountfstab=self.form automount_mountfstab=self.form
.automount_mountfstab.value, .automount_mountfstab.value,
systemd_enabled=self.form
.systemd_enabled.value,
)) ))