installation-scripting: rework step tracking

This commit is contained in:
Peter Eisenmann
2024-06-07 14:49:26 +02:00
parent 3654750d81
commit c00b7c1785

View File

@@ -25,78 +25,92 @@ class InstallationScripting():
* Configuration. Configures an OS according to user's choices.
'''
terminal = Vte.Terminal()
cancel = Gio.Cancellable()
lock = Lock()
current_step = Step.none
step_ready = Step.none
script_running = False
def __init__(self):
# setup terminal
self.terminal.set_input_enabled(False)
self.terminal.set_scroll_on_output(True)
self.terminal.set_hexpand(True)
self.terminal.set_vexpand(True)
self.terminal.connect('child-exited', self._on_child_exited)
self.terminal = self._setup_terminal()
self.cancel = Gio.Cancellable()
def _start_next_script(self):
if self.current_step is Step.configure:
global_state.installation_running = False
global_state.advance(None, allow_return=False)
self.lock = Lock()
self.ready_step = Step.none
self.running_step = Step.none
self.finished_step = Step.none
if self.current_step.value < self.step_ready.value and not self.script_running:
self.current_step = Step(self.current_step.value + 1)
print(f'Starting step "{self.current_step.name}"...')
def _setup_terminal(self):
terminal = Vte.Terminal()
terminal.set_input_enabled(False)
terminal.set_scroll_on_output(True)
terminal.set_hexpand(True)
terminal.set_vexpand(True)
terminal.connect('child-exited', self._on_child_exited)
return terminal
is_installing = self.current_step is Step.install or self.current_step is Step.configure
is_configuring = self.current_step is Step.configure
envs = global_state.create_envs(is_installing, is_configuring)
def _try_start_next_script(self):
if self.running_step != Step.none:
return
global_state.installation_running = is_installing
if self.finished_step.value >= self.ready_step.value:
return
# check config
if envs == None:
print(f'Not all config options set for "{self.current_step.name}". Please report this bug.')
print('############################')
print(global_state.config)
print('############################')
global_state.installation_failed()
return
next_step = Step(self.finished_step.value + 1)
print(f'Starting step "{next_step.name}"...')
# start script
file_name = f'/etc/os-installer/scripts/{self.current_step.name}.sh'
if os.path.exists(file_name):
self.script_running, _ = self.terminal.spawn_sync(
Vte.PtyFlags.DEFAULT, '/', ['sh', file_name],
envs, GLib.SpawnFlags.DEFAULT, None, None, self.cancel)
if not self.script_running:
print(f'Could not start {self.current_step.name} script! Ignoring.')
self._start_next_script()
with_install_env = next_step is Step.install or next_step is Step.configure
with_configure_env = next_step is Step.configure
envs = global_state.create_envs(with_install_env, with_configure_env)
# check config
if envs == None:
print(f'Not all config options set for "{next_step.name}". '
'Please report this bug.')
print('############################')
print(global_state.config)
print('############################')
global_state.installation_failed()
return
# start script
file_name = f'/etc/os-installer/scripts/{next_step.name}.sh'
if os.path.exists(file_name):
started_script, _ = self.terminal.spawn_sync(
Vte.PtyFlags.DEFAULT, '/', ['sh', file_name],
envs, GLib.SpawnFlags.DEFAULT, None, None, self.cancel)
if not started_script:
print(f'Could not start {self.finished_step.name} script! '
'Ignoring.')
self._try_start_next_script()
else:
print(f'No script for step {self.current_step.name} exists.')
self._start_next_script()
self.running_step = next_step
else:
print(f'No script for step {next_step.name} exists.')
self.finished_step = next_step
self._try_start_next_script()
### callbacks ###
def _on_child_exited(self, terminal, status):
with self.lock:
self.script_running = False
print(f'Finished step "{self.current_step.name}".')
self.finished_step = self.running_step
self.running_step = Step.none
if not status == 0 and not global_state.demo_mode:
print(f'Failure during step "{self.finished_step.name}"')
global_state.installation_failed()
return
print(f'Finished step "{self.finished_step.name}".')
if self.finished_step is Step.configure:
global_state.installation_running = False
global_state.advance(None, allow_return=False)
else:
self._start_next_script()
self._try_start_next_script()
### public methods ###
def set_ok_to_start_step(self, step: Step):
with self.lock:
if self.step_ready.value < step.value:
self.step_ready = step
self._start_next_script()
if self.ready_step.value < step.value:
self.ready_step = step
self._try_start_next_script()
installation_scripting = InstallationScripting()