import socket from pathlib import Path from exec_print_capture import execute_print_capture def rsync_inform(rsync_cmd: list[str], inform_cmd: list[str], user_input_file: Path): """ First, this method transfers files to a remote pc. Then, it informs the remote pc. If some error occurs during the above steps, it waits for user input (via a UNIX-socket) and repeats the failed step. :param rsync_cmd: :param inform_cmd: :param user_input_file: :return: """ # - rsync to remote pc # - catch error # - wait until user input, then repeat while True: returncode, _out, _err = execute_print_capture(rsync_cmd) if returncode == 0: break else: print(f'Error while executing: {rsync_cmd}\n' f'See above output.') _wait_for_user(user_input_file) # - inform remote pc about complete rsync # - catch error # - wait until user input, then repeat while True: returncode, _out, _err = execute_print_capture(inform_cmd) if returncode == 0: break else: print(f'Error while executing: {rsync_cmd}\n' f'See above output.') _wait_for_user(user_input_file) def _wait_for_user(socket_file: Path): # INSPIRATION: https://pymotw.com/3/socket/uds.html print(f'Waiting for user to write "OK\\n" to unix socket {socket_file} ...\n' f'Hint:\n' f'\tFirst, fix the error reported above, then continue here:\n' f'\tsudo pacman -S --needed openbsd-netcat\n' f'\techo "OK" | nc -U "{socket_file.absolute()}"') sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.bind(str(socket_file)) sock.listen(1) while True: connection, client_address = sock.accept() try: b: bytes = connection.recv(32) if b == b'OK\n': print('Received "OK" from user.') break else: print(f'Received unknown message: {b}') except Exception as e: print(f'Error while reading message: {e}') finally: connection.close() sock.close() socket_file.unlink(missing_ok=False)