system_setup: changes and fixes

1. rebase with main and update autoinstall-system-setup.yml
2. provide a more unified indent style
3. update get_userandgroups() to the dropped one
4. fix the problematic os action
5. simply asignments
6. assign default_loader a default value
7. provide a type-to-file dict in wsl_conf
8. provide stderr info when providing error in creating user
9. update schema and example files
This commit is contained in:
Patrick Wu 2021-10-05 09:38:10 +08:00
parent 1a7274dbba
commit c934268813
13 changed files with 128 additions and 174 deletions

View File

@ -70,16 +70,16 @@
"wslconfbase": {
"type": "object",
"properties": {
"custom_path": {
"automount_root": {
"type": "string"
},
"custom_mount_opt": {
"automount_options": {
"type": "string"
},
"gen_host": {
"network_generatehosts": {
"type": "boolean"
},
"gen_resolvconf": {
"network_generateresolvconf": {
"type": "boolean"
}
},
@ -100,22 +100,22 @@
"gui_followwintheme": {
"type": "boolean"
},
"legacy_gui": {
"interop_guiintegration": {
"type": "boolean"
},
"legacy_audio": {
"interop_audiointegration": {
"type": "boolean"
},
"adv_ip_detect": {
"interop_advancedipdetection": {
"type": "boolean"
},
"wsl_motd_news": {
"motd_wslnewsenabled": {
"type": "boolean"
},
"automount": {
"automount_enabled": {
"type": "boolean"
},
"mountfstab": {
"automount_mountfstab": {
"type": "boolean"
}
},

View File

@ -3,17 +3,15 @@ early-commands:
- echo a
- ["sleep", "1"]
- echo a
Welcome:
lang: en_US
locale: en_US
identity:
realname: Ubuntu
username: ubuntu
# ubuntu
password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
WSLConfigurationBase:
custom_path: '/custom_mnt_path'
custom_mount_opt: 'opt1 opt2 opt3'
gen_host: false
gen_resolvconf: false
Summary:
reboot: yes
wslconfbase:
automount_root: '/custom_mnt_path'
automount_options: 'metadata'
network_generatehosts: false
network_generateresolvconf: false
shutdown: 'reboot'

View File

@ -37,21 +37,8 @@ class WSLConfigurationAdvancedController(SubiquityTuiController):
'interop_audiointegration', 'interop_advancedipdetection',
'motd_wslnewsenabled', 'automount_enabled',
'automount_mountfstab']):
reconfiguration = WSLConfigurationAdvanced(
interop_enabled=self.answers['interop_enabled'],
interop_appendwindowspath=self
.answers['interop_appendwindowspath'],
gui_theme=self.answers['gui_theme'],
gui_followwintheme=self.answers['gui_followwintheme'],
interop_guiintegration=self.answers['interop_guiintegration'],
interop_audiointegration=self
.answers['interop_audiointegration'],
interop_advancedipdetection=self
.answers['interop_advancedipdetection'],
motd_wslnewsenabled=self.answers['motd_wslnewsenabled'],
automount_enabled=self.answers['automount_enabled'],
automount_mountfstab=self.answers['automount_mountfstab']
)
reconfiguration = WSLConfigurationAdvanced(**self.answers)
self.done(reconfiguration)
def done(self, reconf_data):

View File

@ -18,12 +18,7 @@ class WSLConfigurationBaseController(SubiquityTuiController):
if all(elem in self.answers for elem in
['automount_root', 'automount_options',
'network_generatehosts', 'network_generateresolvconf']):
configuration = WSLConfigurationBase(
automount_root=self.answers['automount_root'],
automount_options=self.answers['automount_options'],
network_generatehosts=self.answers['network_generatehosts'],
network_generateresolvconf=self
.answers['network_generateresolvconf'])
configuration = WSLConfigurationBase(**self.answers)
self.done(configuration)
def done(self, configuration_data):

View File

@ -63,8 +63,13 @@ config_adv_default = {
}
}
conf_type_to_file = {
"wsl": "/etc/wsl.conf",
"ubuntu": "/etc/ubuntu-wsl.conf"
}
def wsl_config_loader(data, pathname, config_ref, id):
def wsl_config_loader(data, config_ref, id):
"""
Loads the configuration from the given file type,
section and reference config.
@ -73,6 +78,7 @@ def wsl_config_loader(data, pathname, config_ref, id):
:param pathname: string, the path to the file to load
:param id: string, the name of the section to load
"""
pathname = conf_type_to_file[id]
if not os.path.exists(pathname):
return data
config = ConfigParser()
@ -88,7 +94,7 @@ def wsl_config_loader(data, pathname, config_ref, id):
return data
def default_loader(is_advanced):
def default_loader(is_advanced=False):
"""
This will load the default WSL config for the given type.
@ -97,10 +103,10 @@ def default_loader(is_advanced):
"""
data = {}
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, conf_ref, "wsl")
if is_advanced:
data = \
wsl_config_loader(data, "/etc/ubuntu-wsl.conf", conf_ref, "ubuntu")
wsl_config_loader(data, conf_ref, "ubuntu")
return data
@ -132,12 +138,7 @@ def wsl_config_update(config_class, is_dry_run):
config = ConfigParser()
config.BasicInterpolcation = None
if config_type == "wsl":
conf_file = "/etc/wsl.conf"
elif config_type == "ubuntu":
conf_file = "/etc/ubuntu-wsl.conf"
else:
raise TypeError("Invalid type name " % config_type)
conf_file = conf_type_to_file[config_type]
config.read(conf_file)
@ -165,6 +166,4 @@ def wsl_config_update(config_class, is_dry_run):
with open(conf_file + ".new", 'w+') as configfile:
config.write(configfile)
if os.isfile(conf_file):
os.rename(conf_file, conf_file + ".old")
os.move(conf_file + ".new", conf_file)
os.rename(conf_file + ".new", conf_file)

View File

@ -18,8 +18,6 @@ import os
import logging
import subprocess
from subiquity.common.resources import resource_path
log = logging.getLogger("subiquity.system_setup.common.wsl_utils")
@ -64,19 +62,28 @@ def get_windows_locale():
def get_userandgroups():
usergroups_path = resource_path('users-and-groups')
build_usergroups_path = \
os.path.realpath(__file__ + '/../../../users-and-groups')
if os.path.isfile(build_usergroups_path):
usergroups_path = build_usergroups_path
from subiquity.common.resources import resource_path
from subiquitycore.utils import run_command
user_groups = set()
if os.path.exists(usergroups_path):
with open(usergroups_path) as fp:
for line in fp:
line = line.strip()
if line.startswith('#') or not line:
continue
user_groups.add(line)
oneline_usergroups = ",".join(user_groups)
users_and_groups_path = resource_path('users-and-groups')
if os.path.exists(users_and_groups_path):
groups = open(users_and_groups_path).read().split()
else:
groups = ['admin']
groups.append('sudo')
command = ['getent', 'group']
cp = run_command(command, check=True)
target_groups = set()
for line in cp.stdout.splitlines():
target_groups.add(line.split(':')[0])
groups = [group for group in groups if group in target_groups]
oneline_usergroups = ",".join(groups)
return oneline_usergroups
def convert_if_bool(value):
if value.lower() in ('true', 'false'):
return value.lower() == 'true'
return value

View File

@ -41,19 +41,7 @@ class WSLConfigurationAdvancedModel(object):
self._wslconfadvanced = None
def apply_settings(self, result):
d = {}
# TODO: placholder settings; should be dynamically assgined using
# ubuntu-wsl-integration
d['interop_enabled'] = result.interop_enabled
d['interop_appendwindowspath'] = result.interop_appendwindowspath
d['gui_theme'] = result.gui_theme
d['gui_followwintheme'] = result.gui_followwintheme
d['interop_guiintegration'] = result.interop_guiintegration
d['interop_audiointegration'] = result.interop_audiointegration
d['interop_advancedipdetection'] = result.interop_advancedipdetection
d['motd_wslnewsenabled'] = result.motd_wslnewsenabled
d['automount_enabled'] = result.automount_enabled
d['automount_mountfstab'] = result.automount_mountfstab
d = result.__dict__
self._wslconfadvanced = WSLConfigurationAdvanced(**d)
@property

View File

@ -36,11 +36,7 @@ class WSLConfigurationBaseModel(object):
# TODO WSL: Load settings from system
def apply_settings(self, result):
d = {}
d['automount_root'] = result.automount_root
d['automount_options'] = result.automount_options
d['network_generatehosts'] = result.network_generatehosts
d['network_generateresolvconf'] = result.network_generateresolvconf
d = result.__dict__
self._wslconfbase = WSLConfigurationBase(**d)
@property

View File

@ -80,8 +80,9 @@ class ConfigureController(SubiquityController):
wsl_id.password,
wsl_id.username])
if create_user_act.returncode != 0:
raise Exception("Failed to create user %s"
% wsl_id.username)
raise Exception("Failed to create user %s: %s"
% (wsl_id.username,
create_user_act.stderr))
log.debug("created user %s", wsl_id.username)
assign_grp_act = \
run_command(["/usr/sbin/usermod", "-a",
@ -89,8 +90,10 @@ class ConfigureController(SubiquityController):
"-G", get_userandgroups(),
wsl_id.username])
if assign_grp_act.returncode != 0:
raise Exception("Failed to assign groups to user %s" %
wsl_id.username)
raise Exception(("Failed to assign group"
" to user %s: %s")
% (wsl_id.username,
assign_grp_act.stderr))
else:
wsl_config_update(self.model.wslconfadvanced.wslconfadvanced,
dryrun)

View File

@ -23,6 +23,7 @@ from subiquity.common.types import WSLConfigurationAdvanced
from subiquity.server.controller import SubiquityController
from system_setup.common.wsl_conf import default_loader
from system_setup.common.wsl_utils import convert_if_bool
log = logging.getLogger(
'system_setup.server.controllers.wsl_configuration_advanced')
@ -54,46 +55,17 @@ class WSLConfigurationAdvancedController(SubiquityController):
super().__init__(app)
# load the config file
data = default_loader(True)
data = default_loader(is_advanced=True)
if data:
def bool_converter(x):
return x.lower() == 'true'
reconf_data = WSLConfigurationAdvanced(
interop_enabled=bool_converter(data['interop_enabled']),
interop_appendwindowspath=bool_converter(
data['interop_appendwindowspath']),
gui_theme=data['gui_theme'],
gui_followwintheme=bool_converter(data['gui_followwintheme']),
interop_guiintegration=bool_converter(
data['interop_guiintegration']),
interop_audiointegration=bool_converter(
data['interop_audiointegration']),
interop_advancedipdetection=bool_converter(
data['interop_advancedipdetection']),
motd_wslnewsenabled=bool_converter(
data['motd_wslnewsenabled']),
automount_enabled=bool_converter(data['automount_enabled']),
automount_mountfstab=bool_converter(
data['automount_mountfstab']),
)
proc_data = \
{key: convert_if_bool(value) for (key, value) in data.items()}
reconf_data = WSLConfigurationAdvanced(**proc_data)
self.model.apply_settings(reconf_data)
def load_autoinstall_data(self, data):
if data is not None:
reconf_data = WSLConfigurationAdvanced(
interop_enabled=data['interop_enabled'],
interop_appendwindowspath=data['interop_appendwindowspath'],
gui_theme=data['gui_theme'],
gui_followwintheme=data['gui_followwintheme'],
interop_guiintegration=data['interop_guiintegration'],
interop_audiointegration=data['interop_audiointegration'],
interop_advancedipdetection=data[
'interop_advancedipdetection'],
motd_wslnewsenabled=data['motd_wslnewsenabled'],
automount_enabled=data['automount_enabled'],
automount_mountfstab=data['automount_mountfstab']
)
reconf_data = WSLConfigurationAdvanced(**data)
self.model.apply_settings(reconf_data)
@with_context()

View File

@ -23,6 +23,7 @@ from subiquity.common.types import WSLConfigurationBase
from subiquity.server.controller import SubiquityController
from system_setup.common.wsl_conf import default_loader
from system_setup.common.wsl_utils import convert_if_bool
log = logging.getLogger('system_setup.server' +
'.controllers.wsl_configuration_base')
@ -48,29 +49,17 @@ class WSLConfigurationBaseController(SubiquityController):
super().__init__(app)
# load the config file
data = default_loader(False)
data = default_loader()
if data:
def bool_converter(x):
return x.lower() == 'true'
conf_data = WSLConfigurationBase(
automount_root=data['automount_root'],
automount_options=data['automount_options'],
network_generatehosts=bool_converter(
data['network_generatehosts']),
network_generateresolvconf=bool_converter(
data['network_generateresolvconf']),
)
proc_data = \
{key: convert_if_bool(value) for (key, value) in data.items()}
conf_data = WSLConfigurationBase(**proc_data)
self.model.apply_settings(conf_data)
def load_autoinstall_data(self, data):
if data is not None:
identity_data = WSLConfigurationBase(
automount_root=data['automount_root'],
automount_options=data['automount_options'],
network_generatehosts=data['network_generatehosts'],
network_generateresolvconf=data['network_generateresolvconf'],
)
identity_data = WSLConfigurationBase(**data)
self.model.apply_settings(identity_data)
@with_context()

View File

@ -100,20 +100,26 @@ class WSLConfigurationAdvancedView(BaseView):
self.controller = controller
initial = {
'interop_enabled': configuration_data.interop_enabled,
'interop_enabled':
configuration_data.interop_enabled,
'interop_appendwindowspath':
configuration_data.interop_appendwindowspath,
'gui_theme': configuration_data.gui_theme,
'gui_followwintheme': configuration_data.gui_followwintheme,
'interop_guiintegration': configuration_data
.interop_guiintegration,
'interop_audiointegration': configuration_data
.interop_audiointegration,
'interop_advancedipdetection': configuration_data
.interop_advancedipdetection,
'motd_wslnewsenabled': configuration_data.motd_wslnewsenabled,
'automount_enabled': configuration_data.automount_enabled,
'automount_mountfstab': configuration_data.automount_mountfstab,
'gui_theme':
configuration_data.gui_theme,
'gui_followwintheme':
configuration_data.gui_followwintheme,
'interop_guiintegration':
configuration_data.interop_guiintegration,
'interop_audiointegration':
configuration_data.interop_audiointegration,
'interop_advancedipdetection':
configuration_data.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)
@ -129,16 +135,24 @@ class WSLConfigurationAdvancedView(BaseView):
def done(self, result):
self.controller.done(WSLConfigurationAdvanced(
interop_enabled=self.form.interop_enabled.value,
interop_enabled=self.form
.interop_enabled.value,
interop_appendwindowspath=self.form
.interop_appendwindowspath.value,
gui_theme=self.form.gui_theme.value,
gui_followwintheme=self.form.gui_followwintheme.value,
interop_guiintegration=self.form.interop_guiintegration.value,
interop_audiointegration=self.form.interop_audiointegration.value,
interop_advancedipdetection=self
.form.interop_advancedipdetection.value,
motd_wslnewsenabled=self.form.motd_wslnewsenabled.value,
automount_enabled=self.form.automount_enabled.value,
automount_mountfstab=self.form.automount_mountfstab.value,
gui_theme=self.form
.gui_theme.value,
gui_followwintheme=self.form
.gui_followwintheme.value,
interop_guiintegration=self.form
.interop_guiintegration.value,
interop_audiointegration=self.form
.interop_audiointegration.value,
interop_advancedipdetection=self.form
.interop_advancedipdetection.value,
motd_wslnewsenabled=self.form
.motd_wslnewsenabled.value,
automount_enabled=self.form
.automount_enabled.value,
automount_mountfstab=self.form
.automount_mountfstab.value,
))

View File

@ -103,11 +103,14 @@ class WSLConfigurationBaseView(BaseView):
self.controller = controller
initial = {
'automount_root': configuration_data.automount_root,
'automount_options': configuration_data.automount_options,
'network_generatehosts': configuration_data.network_generatehosts,
'network_generateresolvconf': configuration_data
.network_generateresolvconf,
'automount_root':
configuration_data.automount_root,
'automount_options':
configuration_data.automount_options,
'network_generatehosts':
configuration_data.network_generatehosts,
'network_generateresolvconf':
configuration_data.network_generateresolvconf,
}
self.form = WSLConfBaseForm(initial=initial)
@ -123,9 +126,12 @@ class WSLConfigurationBaseView(BaseView):
def done(self, result):
self.controller.done(WSLConfigurationBase(
automount_root=self.form.automount_root.value,
automount_options=self.form.automount_options.value,
network_generatehosts=self.form.network_generatehosts.value,
network_generateresolvconf=self
.form.network_generateresolvconf.value
automount_root=self.form
.automount_root.value,
automount_options=self.form
.automount_options.value,
network_generatehosts=self.form
.network_generatehosts.value,
network_generateresolvconf=self.form
.network_generateresolvconf.value
))