Merge pull request #1029 from mwhudson/reboot-flexibility

add more flexibility for shutdown time
This commit is contained in:
Michael Hudson-Doyle 2021-08-22 22:00:56 +12:00 committed by GitHub
commit 1c06aba1ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 85 additions and 29 deletions

View File

@ -721,6 +721,13 @@
"type": "string"
}
}
},
"shutdown": {
"type": "string",
"enum": [
"reboot",
"poweroff"
]
}
},
"required": [

View File

@ -42,6 +42,7 @@ subiquity/common/filesystem/tests/test_actions.py
subiquity/common/filesystem/tests/test_labels.py
subiquity/common/filesystem/tests/test_manipulator.py
subiquity/common/__init__.py
subiquity/common/resources.py
subiquity/common/serialize.py
subiquity/common/tests/__init__.py
subiquity/common/tests/test_serialization.py
@ -72,8 +73,11 @@ subiquitycore/ssh.py
subiquitycore/testing/__init__.py
subiquitycore/testing/view_helpers.py
subiquitycore/tests/__init__.py
subiquitycore/tests/mocks.py
subiquitycore/tests/test_netplan.py
subiquitycore/tests/test_pubsub.py
subiquitycore/tests/test_view.py
subiquitycore/tests/util.py
subiquitycore/tuicontroller.py
subiquitycore/tui.py
subiquitycore/ui/actionmenu.py
@ -120,6 +124,7 @@ subiquity/models/tests/__init__.py
subiquity/models/tests/test_filesystem.py
subiquity/models/tests/test_mirror.py
subiquity/models/tests/test_subiquity.py
subiquity/models/timezone.py
subiquity/models/updates.py
subiquity/server/controller.py
subiquity/server/controllers/cmdlist.py
@ -135,21 +140,26 @@ subiquity/server/controllers/mirror.py
subiquity/server/controllers/network.py
subiquity/server/controllers/package.py
subiquity/server/controllers/proxy.py
subiquity/server/controllers/reboot.py
subiquity/server/controllers/refresh.py
subiquity/server/controllers/reporting.py
subiquity/server/controllers/shutdown.py
subiquity/server/controllers/snaplist.py
subiquity/server/controllers/ssh.py
subiquity/server/controllers/tests/test_keyboard.py
subiquity/server/controllers/timezone.py
subiquity/server/controllers/updates.py
subiquity/server/controllers/userdata.py
subiquity/server/controllers/zdev.py
subiquity/server/dryrun.py
subiquity/server/errors.py
subiquity/server/geoip.py
subiquity/server/__init__.py
subiquity/server/server.py
subiquity/server/tests/__init__.py
subiquity/server/tests/test_geoip.py
subiquity/tests/fakes.py
subiquity/tests/__init__.py
subiquity/tests/test_timezonecontroller.py
subiquity/ui/frame.py
subiquity/ui/__init__.py
subiquity/ui/mount.py

View File

@ -252,7 +252,7 @@ class SubiquityClient(TuiApplication):
elif event['SUBIQUITY_EVENT_TYPE'] == 'finish':
print('finish: ' + event["MESSAGE"])
context_name = event.get('SUBIQUITY_CONTEXT_NAME', '')
if context_name == 'subiquity/Reboot/reboot':
if context_name == 'subiquity/Shutdown/shutdown':
self.exit()
async def connect(self):

View File

@ -21,7 +21,10 @@ import aiohttp
from subiquitycore.context import with_context
from subiquity.client.controller import SubiquityTuiController
from subiquity.common.types import ApplicationState
from subiquity.common.types import (
ApplicationState,
ShutdownMode,
)
from subiquity.ui.views.installprogress import (
InstallRunning,
ProgressView,
@ -65,7 +68,7 @@ class ProgressController(SubiquityTuiController):
async def send_reboot_and_wait(self):
try:
await self.app.client.reboot.POST()
await self.app.client.shutdown.POST(mode=ShutdownMode.REBOOT)
except aiohttp.ClientError:
pass
self.app.exit()

View File

@ -37,6 +37,7 @@ from subiquity.common.types import (
IdentityData,
NetworkStatus,
RefreshStatus,
ShutdownMode,
SnapInfo,
SnapListResponse,
SnapSelection,
@ -235,8 +236,8 @@ class API:
def GET() -> TimeZoneInfo: ...
def POST(tz: str): ...
class reboot:
def POST(): ...
class shutdown:
def POST(mode: ShutdownMode, immediate: bool = False): ...
class LinkAction(enum.Enum):

View File

@ -330,3 +330,8 @@ class SnapListResponse:
class TimeZoneInfo:
timezone: str
from_geoip: bool
class ShutdownMode(enum.Enum):
REBOOT = enum.auto()
POWEROFF = enum.auto()

View File

@ -25,9 +25,9 @@ from .mirror import MirrorController
from .network import NetworkController
from .package import PackageController
from .proxy import ProxyController
from .reboot import RebootController
from .refresh import RefreshController
from .reporting import ReportingController
from .shutdown import ShutdownController
from .snaplist import SnapListController
from .ssh import SSHController
from .timezone import TimeZoneController
@ -50,9 +50,9 @@ __all__ = [
'NetworkController',
'PackageController',
'ProxyController',
'RebootController',
'RefreshController',
'ReportingController',
'ShutdownController',
'SnapListController',
'SSHController',
'TimeZoneController',

View File

@ -23,42 +23,68 @@ from subiquitycore.context import with_context
from subiquitycore.utils import arun_command, run_command
from subiquity.common.apidef import API
from subiquity.common.types import ShutdownMode
from subiquity.server.controller import SubiquityController
from subiquity.server.controllers.install import ApplicationState
log = logging.getLogger("subiquity.controllers.restart")
class RebootController(SubiquityController):
class ShutdownController(SubiquityController):
endpoint = API.reboot
endpoint = API.shutdown
autoinstall_key = 'shutdown'
autoinstall_schema = {
'type': 'string',
'enum': ['reboot', 'poweroff']
}
def __init__(self, app):
super().__init__(app)
self.user_reboot_event = asyncio.Event()
self.rebooting_event = asyncio.Event()
# user_shutdown_event is set when the user requests the shutdown.
# server_reboot_event is set when the server is ready for shutdown
# shuttingdown_event is set when the shutdown has begun (so don't
# depend on anything actually happening after it is set, it's all a bag
# of races from that point!)
self.user_shutdown_event = asyncio.Event()
self.server_reboot_event = asyncio.Event()
self.shuttingdown_event = asyncio.Event()
self.mode = ShutdownMode.REBOOT
async def POST(self):
def load_autoinstall_data(self, data):
if data == 'reboot':
self.mode = ShutdownMode.REBOOT
elif data == 'poweroff':
self.mode = ShutdownMode.POWEROFF
async def POST(self, mode: ShutdownMode, immediate: bool = False):
self.mode = mode
self.app.controllers.Install.stop_uu()
self.user_reboot_event.set()
await self.rebooting_event.wait()
self.user_shutdown_event.set()
if immediate:
self.server_reboot_event.set()
await self.shuttingdown_event.wait()
def interactive(self):
return self.app.interactive
def start(self):
self.app.aio_loop.create_task(self._wait_install())
self.app.aio_loop.create_task(self._run())
async def _run(self):
Install = self.app.controllers.Install
await Install.install_task
async def _wait_install(self):
await self.app.controllers.Install.install_task
await self.app.controllers.Late.run_event.wait()
await self.copy_logs_to_target()
self.server_reboot_event.set()
async def _run(self):
await self.server_reboot_event.wait()
if self.app.interactive:
await self.user_reboot_event.wait()
self.reboot()
await self.user_shutdown_event.wait()
self.shutdown()
elif self.app.state == ApplicationState.DONE:
self.reboot()
self.shutdown()
@with_context()
async def copy_logs_to_target(self, context):
@ -80,12 +106,16 @@ class RebootController(SubiquityController):
except Exception:
log.exception("saving journal failed")
@with_context()
def reboot(self, context):
self.rebooting_event.set()
@with_context(description='mode={self.mode.name}')
def shutdown(self, context):
self.shuttingdown_event.set()
if self.opts.dry_run:
self.app.exit()
else:
if platform.machine() == 's390x':
run_command(["chreipl", "/target/boot"])
run_command(["/sbin/reboot"])
if self.app.state == ApplicationState.DONE:
if platform.machine() == 's390x':
run_command(["chreipl", "/target/boot"])
if self.mode == ShutdownMode.REBOOT:
run_command(["/sbin/reboot"])
elif self.mode == ShutdownMode.POWEROFF:
run_command(["/sbin/poweroff"])

View File

@ -222,7 +222,7 @@ class SubiquityServer(Application):
"Install",
"Updates",
"Late",
"Reboot",
"Shutdown",
]
def make_model(self):

View File

@ -131,7 +131,7 @@ def with_context(name=None, description="", **context_kw):
context = self.context
kw['context'] = context.child(
name=name.format(**kw),
description=description.format(**kw),
description=description.format(self=self, **kw),
**context_kw)
return kw