import time from pathlib import Path from p1st.exec_print_capture import execute_print_capture from p1st.unix_sock_input import wait_for_message def repeat_until_successful(command: list[str], socket_file: Path, retries: int = 0, retry_delay_seconds: float = 5) -> str: """ Executes the given `command` and returns its stdout. If the command has failed, it is executed at most `retires` times again, until successful. Between each retry we wait for `retry_delay_seconds`. If no more retries are left, a UNIX socket is created at `socket_file` and we wait for user input. """ while True: returncode: int stdout: str returncode, stdout, _stderr = execute_print_capture(command) # If no error occurred, return stdout of subprocess. if returncode == 0: return stdout # Else, an error has occurred. print(f'\n' f'Error while executing:\n' f'\t{command}\n' f'\tFor details, see above output.') # If retry attempts are left, # wait `retry_delay_seconds` and then execute the command again. if retries > 0: print(f'\tRetrying the failed command in {retry_delay_seconds} seconds.' f'\n') time.sleep(retry_delay_seconds) retries -= 1 continue # Else, no more retry attempts are left. # Print message and wait for user input. print(f'Info:\n' f'\tPlease fix the above error first. Then continue here:\n' f'\tsudo pacman -S --needed openbsd-netcat\n' f'\techo "OK" | nc -U "{socket_file.absolute()}"') wait_for_message(socket_file, [b'OK\n']) print()