2021-08-31 10:07:20 +00:00
|
|
|
# Copyright 2020 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
|
2021-09-28 12:48:30 +00:00
|
|
|
import os
|
2021-08-31 10:07:20 +00:00
|
|
|
|
|
|
|
from subiquity.common.errorreport import ErrorReportKind
|
2021-09-23 08:52:31 +00:00
|
|
|
from subiquity.common.types import ApplicationState
|
|
|
|
from subiquity.server.controller import SubiquityController
|
|
|
|
from subiquitycore.context import with_context
|
|
|
|
from subiquitycore.utils import run_command
|
2021-09-28 16:37:26 +00:00
|
|
|
from system_setup.common.wsl_conf import WSLConfigHandler
|
2021-08-31 10:07:20 +00:00
|
|
|
|
2021-09-27 12:36:25 +00:00
|
|
|
log = logging.getLogger("system_setup.server.controllers.configure")
|
2021-08-31 10:07:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ConfigureController(SubiquityController):
|
|
|
|
|
|
|
|
def __init__(self, app):
|
|
|
|
super().__init__(app)
|
2021-09-20 06:37:55 +00:00
|
|
|
self.app = app
|
2021-08-31 10:07:20 +00:00
|
|
|
self.model = app.base_model
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
self.install_task = self.app.aio_loop.create_task(self.configure())
|
|
|
|
|
|
|
|
@with_context(
|
|
|
|
description="final system configuration", level="INFO",
|
|
|
|
childlevel="DEBUG")
|
|
|
|
async def configure(self, *, context):
|
2021-09-01 08:48:44 +00:00
|
|
|
context.set('is-install-context', True)
|
2021-08-31 10:07:20 +00:00
|
|
|
try:
|
|
|
|
|
|
|
|
self.app.update_state(ApplicationState.WAITING)
|
|
|
|
|
2021-09-01 08:48:44 +00:00
|
|
|
await self.model.wait_install()
|
|
|
|
|
2021-08-31 10:07:20 +00:00
|
|
|
self.app.update_state(ApplicationState.NEEDS_CONFIRMATION)
|
|
|
|
|
|
|
|
self.app.update_state(ApplicationState.RUNNING)
|
|
|
|
|
2021-09-01 08:48:44 +00:00
|
|
|
await self.model.wait_postinstall()
|
|
|
|
|
2021-08-31 10:07:20 +00:00
|
|
|
self.app.update_state(ApplicationState.POST_WAIT)
|
|
|
|
|
|
|
|
# TODO WSL:
|
|
|
|
# 1. Use self.model to get all data to commit
|
2021-08-31 11:26:49 +00:00
|
|
|
# 2. Write directly (without wsl utilities) to wsl.conf and other
|
|
|
|
# fstab files
|
2021-08-31 13:56:08 +00:00
|
|
|
# 3. If not in reconfigure mode: create User, otherwise just write
|
|
|
|
# wsl.conf files.
|
2021-08-31 10:07:20 +00:00
|
|
|
# This must not use subprocesses.
|
|
|
|
# If dry-run: write in .subiquity
|
|
|
|
|
|
|
|
self.app.update_state(ApplicationState.POST_RUNNING)
|
|
|
|
|
2021-09-23 08:52:31 +00:00
|
|
|
dryrun = self.app.opts.dry_run
|
2021-09-14 08:16:06 +00:00
|
|
|
variant = self.app.variant
|
2021-09-23 08:52:31 +00:00
|
|
|
config = WSLConfigHandler(dryrun)
|
2021-09-28 12:48:30 +00:00
|
|
|
if variant == "wsl_setup":
|
2021-09-23 08:52:31 +00:00
|
|
|
wsl_identity = self.model.identity.user
|
|
|
|
if dryrun:
|
|
|
|
log.debug("mimicking creating user %s",
|
|
|
|
wsl_identity.username)
|
|
|
|
else:
|
|
|
|
run_command(["/usr/sbin/useradd", "-m", "-s", "/bin/bash",
|
|
|
|
"-p", wsl_identity.password,
|
|
|
|
wsl_identity.username])
|
|
|
|
run_command(["/usr/sbin/usermod", "-a",
|
|
|
|
"-c", wsl_identity.realname,
|
|
|
|
"-G", self.get_userandgroups(),
|
|
|
|
wsl_identity.username])
|
2021-09-28 12:48:30 +00:00
|
|
|
else:
|
2021-09-23 08:52:31 +00:00
|
|
|
wslconf_ad = self.model.wslconfadvanced.wslconfadvanced
|
|
|
|
config.update("WSL.automount.enabled",
|
|
|
|
wslconf_ad.automount)
|
|
|
|
config.update("WSL.automount.mountfstab",
|
|
|
|
wslconf_ad.mountfstab)
|
|
|
|
config.update("WSL.automount.root",
|
|
|
|
wslconf_ad.custom_path)
|
|
|
|
config.update("WSL.automount.options",
|
|
|
|
wslconf_ad.custom_mount_opt)
|
|
|
|
config.update("WSL.network.generatehosts",
|
|
|
|
wslconf_ad.gen_host)
|
|
|
|
config.update("WSL.network.generateresolvconf",
|
|
|
|
wslconf_ad.gen_resolvconf)
|
|
|
|
config.update("WSL.interop.enabled",
|
|
|
|
wslconf_ad.interop_enabled)
|
|
|
|
config.update(
|
|
|
|
"WSL.interop.appendwindowspath",
|
|
|
|
wslconf_ad.interop_appendwindowspath)
|
|
|
|
config.update("ubuntu.GUI.followwintheme",
|
|
|
|
wslconf_ad.gui_followwintheme)
|
|
|
|
config.update("ubuntu.GUI.theme",
|
|
|
|
wslconf_ad.gui_theme)
|
|
|
|
config.update("ubuntu.Interop.guiintergration",
|
|
|
|
wslconf_ad.legacy_gui)
|
|
|
|
config.update("ubuntu.Interop.audiointegration",
|
|
|
|
wslconf_ad.legacy_audio)
|
|
|
|
config.update("ubuntu.Interop.advancedipdetection",
|
|
|
|
wslconf_ad.adv_ip_detect)
|
|
|
|
config.update("ubuntu.Motd.wslnewsenabled",
|
|
|
|
wslconf_ad.wsl_motd_news)
|
|
|
|
|
|
|
|
wslconf_base = self.model.wslconfbase.wslconfbase
|
|
|
|
config.update("WSL.automount.root",
|
|
|
|
wslconf_base.custom_path)
|
|
|
|
config.update("WSL.automount.options",
|
|
|
|
wslconf_base.custom_mount_opt)
|
|
|
|
config.update("WSL.network.generatehosts",
|
|
|
|
wslconf_base.gen_host)
|
|
|
|
config.update("WSL.network.generateresolvconf",
|
|
|
|
wslconf_base.gen_resolvconf)
|
2021-09-28 12:48:30 +00:00
|
|
|
|
2021-08-31 10:07:20 +00:00
|
|
|
self.app.update_state(ApplicationState.DONE)
|
|
|
|
except Exception:
|
|
|
|
kw = {}
|
|
|
|
self.app.make_apport_report(
|
|
|
|
ErrorReportKind.INSTALL_FAIL, "configuration failed", **kw)
|
|
|
|
raise
|
|
|
|
|
2021-09-28 12:48:30 +00:00
|
|
|
def get_userandgroups(self):
|
|
|
|
usergroups_path = '/usr/share/subiquity/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
|
|
|
|
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)
|
|
|
|
return oneline_usergroups
|
|
|
|
|
2021-08-31 10:07:20 +00:00
|
|
|
def stop_uu(self):
|
|
|
|
# This is a no-op to allow Shutdown controller to depend on this one
|
2021-08-31 11:26:49 +00:00
|
|
|
pass
|