split "Reboot" controller out of InstallProgress controller
this means late commands run before copying logs to the target and waiting for the user to click restart
This commit is contained in:
parent
88165ce5fd
commit
dd1969f89b
|
@ -24,6 +24,7 @@ from .package import PackageController
|
|||
from .proxy import ProxyController
|
||||
from .mirror import MirrorController
|
||||
from .network import NetworkController
|
||||
from .reboot import RebootController
|
||||
from .refresh import RefreshController
|
||||
from ..controller import RepeatedController
|
||||
from .reporting import ReportingController
|
||||
|
@ -46,6 +47,7 @@ __all__ = [
|
|||
'MirrorController',
|
||||
'NetworkController',
|
||||
'RefreshController',
|
||||
'RebootController',
|
||||
'RepeatedController',
|
||||
'ReportingController',
|
||||
'SnapListController',
|
||||
|
|
|
@ -18,10 +18,8 @@ import contextlib
|
|||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import traceback
|
||||
|
@ -43,7 +41,6 @@ from subiquitycore.context import Status
|
|||
from subiquitycore.utils import (
|
||||
arun_command,
|
||||
astart_command,
|
||||
run_command,
|
||||
)
|
||||
|
||||
from subiquity.controller import SubiquityController
|
||||
|
@ -322,18 +319,13 @@ class InstallProgressController(SubiquityController):
|
|||
await self.run_unattended_upgrades(context)
|
||||
self.progress_view.update_done()
|
||||
|
||||
await self.copy_logs_to_target(context)
|
||||
except Exception:
|
||||
self.curtin_error()
|
||||
if not self.interactive():
|
||||
raise
|
||||
|
||||
async def move_on(self):
|
||||
await asyncio.wait(
|
||||
{self.reboot_clicked.wait(), self.install_task})
|
||||
self.app.reboot_on_exit = True
|
||||
if not self.opts.dry_run and platform.machine() == 's390x':
|
||||
run_command(["chreipl", "/target/boot"])
|
||||
await self.install_task
|
||||
self.app.next_screen()
|
||||
|
||||
async def drain_curtin_events(self, context):
|
||||
|
@ -442,25 +434,6 @@ class InstallProgressController(SubiquityController):
|
|||
'--stop-only',
|
||||
]), check=True)
|
||||
|
||||
@install_step("copying logs to installed system")
|
||||
async def copy_logs_to_target(self, context):
|
||||
if self.opts.dry_run and 'copy-logs-fail' in self.app.debug_flags:
|
||||
raise PermissionError()
|
||||
target_logs = self.tpath('var/log/installer')
|
||||
if self.opts.dry_run:
|
||||
os.makedirs(target_logs, exist_ok=True)
|
||||
else:
|
||||
await arun_command(
|
||||
['cp', '-aT', '/var/log/installer', target_logs])
|
||||
journal_txt = os.path.join(target_logs, 'installer-journal.txt')
|
||||
try:
|
||||
with open(journal_txt, 'w') as output:
|
||||
await arun_command(
|
||||
['journalctl', '-b'],
|
||||
stdout=output, stderr=subprocess.STDOUT)
|
||||
except Exception:
|
||||
log.exception("saving journal failed")
|
||||
|
||||
async def _click_reboot(self):
|
||||
if self.unattended_upgrades_ctx is not None:
|
||||
await self.stop_unattended_upgrades()
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# 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
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
from subiquitycore.async_helpers import schedule_task
|
||||
from subiquitycore.utils import arun_command, run_command
|
||||
|
||||
from subiquity.controller import SubiquityController
|
||||
|
||||
log = logging.getLogger("subiquity.controllers.restart")
|
||||
|
||||
|
||||
class RebootController(SubiquityController):
|
||||
|
||||
def __init__(self, app):
|
||||
super().__init__(app)
|
||||
self.context.set('hidden', True)
|
||||
|
||||
def interactive(self):
|
||||
return self.app.interactive()
|
||||
|
||||
async def copy_logs_to_target(self):
|
||||
with self.context.child("copy_logs_to_target"):
|
||||
if self.opts.dry_run and 'copy-logs-fail' in self.app.debug_flags:
|
||||
raise PermissionError()
|
||||
target_logs = os.path.join(
|
||||
self.app.base_model.target, 'var/log/installer')
|
||||
if self.opts.dry_run:
|
||||
os.makedirs(target_logs, exist_ok=True)
|
||||
else:
|
||||
await arun_command(
|
||||
['cp', '-aT', '/var/log/installer', target_logs])
|
||||
journal_txt = os.path.join(target_logs, 'installer-journal.txt')
|
||||
try:
|
||||
with open(journal_txt, 'w') as output:
|
||||
await arun_command(
|
||||
['journalctl', '-b'],
|
||||
stdout=output, stderr=subprocess.STDOUT)
|
||||
except Exception:
|
||||
log.exception("saving journal failed")
|
||||
|
||||
def reboot(self):
|
||||
if self.opts.dry_run:
|
||||
self.app.exit()
|
||||
else:
|
||||
if platform.machine() == 's390x':
|
||||
run_command(["chreipl", "/target/boot"])
|
||||
run_command(["/sbin/reboot"])
|
||||
|
||||
async def apply_autoinstall_config(self):
|
||||
await self.copy_logs_to_target()
|
||||
self.reboot()
|
||||
|
||||
async def _run(self):
|
||||
await self.copy_logs_to_target()
|
||||
await self.app.controllers.InstallProgress.reboot_clicked.wait()
|
||||
self.reboot()
|
||||
|
||||
def start_ui(self):
|
||||
schedule_task(self._run())
|
||||
|
||||
def cancel(self):
|
||||
pass
|
|
@ -35,7 +35,6 @@ from subiquitycore.async_helpers import (
|
|||
)
|
||||
from subiquitycore.controller import Skip
|
||||
from subiquitycore.core import Application
|
||||
from subiquitycore.utils import run_command
|
||||
|
||||
from subiquity.controllers.error import (
|
||||
ErrorReportKind,
|
||||
|
@ -116,6 +115,7 @@ class Subiquity(Application):
|
|||
"SnapList",
|
||||
"InstallProgress",
|
||||
"Late",
|
||||
"Reboot",
|
||||
]
|
||||
|
||||
def __init__(self, opts, block_log_dir):
|
||||
|
@ -151,13 +151,6 @@ class Subiquity(Application):
|
|||
self.note_data_for_apport("UsingAnswers", str(bool(self.answers)))
|
||||
|
||||
self.install_confirmed = False
|
||||
self.reboot_on_exit = False
|
||||
|
||||
def exit(self):
|
||||
if self.reboot_on_exit and not self.opts.dry_run:
|
||||
run_command(["/sbin/reboot"])
|
||||
else:
|
||||
super().exit()
|
||||
|
||||
def restart(self, remove_last_screen=True):
|
||||
if remove_last_screen:
|
||||
|
@ -259,6 +252,8 @@ class Subiquity(Application):
|
|||
InstallProgress = getattr(self.controllers, "InstallProgress", None)
|
||||
if InstallProgress is None:
|
||||
return False
|
||||
if context.get('hidden', False):
|
||||
return False
|
||||
controller = context.get('controller')
|
||||
if controller is None or controller.interactive():
|
||||
return False
|
||||
|
|
Loading…
Reference in New Issue