installation-scripting: rework step tracking
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user