index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
author | Anton Hvornum <anton@hvornum.se> | 2021-05-01 12:12:10 +0200 |
---|---|---|
committer | Anton Hvornum <anton@hvornum.se> | 2021-05-01 12:12:10 +0200 |
commit | ea0d0a88174dbf7d8cad7d957ab3fd2ca00e02a4 (patch) | |
tree | 5ba03b7e2ecc37b72cb83f3a8908ab747028f695 /archinstall/lib/general.py | |
parent | a7c0142099066791d48240815c47c07772f9e025 (diff) | |
parent | b58bec202ab47259d5a3855032aca70fa8f36b91 (diff) |
-rw-r--r-- | archinstall/lib/general.py | 84 |
diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 6e3b66f1..eb0c5d14 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -1,10 +1,10 @@ import os, json, hashlib, shlex, sys -import time, pty +import time, pty, logging from datetime import datetime, date from subprocess import Popen, STDOUT, PIPE, check_output from select import epoll, EPOLLIN, EPOLLHUP from .exceptions import * -from .output import log, LOG_LEVELS +from .output import log def gen_uid(entropy_length=256): return hashlib.sha512(os.urandom(entropy_length)).hexdigest() @@ -76,7 +76,7 @@ class sys_command():#Thread): """ Stolen from archinstall_gui """ - def __init__(self, cmd, callback=None, start_callback=None, environment_vars={}, *args, **kwargs): + def __init__(self, cmd, callback=None, start_callback=None, peak_output=False, environment_vars={}, *args, **kwargs): kwargs.setdefault("worker_id", gen_uid()) kwargs.setdefault("emulate", False) kwargs.setdefault("suppress_errors", False) @@ -84,15 +84,24 @@ class sys_command():#Thread): self.log = kwargs.get('log', log) if kwargs['emulate']: - self.log(f"Starting command '{cmd}' in emulation mode.", level=LOG_LEVELS.Debug) + self.log(f"Starting command '{cmd}' in emulation mode.", level=logging.DEBUG) + + if type(cmd) is list: + # if we get a list of arguments + self.raw_cmd = shlex.join(cmd) + self.cmd = cmd + else: + # else consider it a single shell string + # this should only be used if really necessary + self.raw_cmd = cmd + try: + self.cmd = shlex.split(cmd) + except Exception as e: + raise ValueError(f'Incorrect string to split: {cmd}\n{e}') - self.raw_cmd = cmd - try: - self.cmd = shlex.split(cmd) - except Exception as e: - raise ValueError(f'Incorrect string to split: {cmd}\n{e}') self.args = args self.kwargs = kwargs + self.peak_output = peak_output self.environment_vars = environment_vars self.kwargs.setdefault("worker", None) @@ -151,6 +160,38 @@ class sys_command():#Thread): 'exit_code': self.exit_code } + def peak(self, output :str): + if type(output) == bytes: + try: + output = output.decode('UTF-8') + except UnicodeDecodeError: + return None + + output = output.strip('\r\n ') + if len(output) <= 0: + return None + + if self.peak_output: + from .user_interaction import get_terminal_width + + # Move back to the beginning of the terminal + sys.stdout.flush() + sys.stdout.write("\033[%dG" % 0) + sys.stdout.flush() + + # Clear the line + sys.stdout.write(" " * get_terminal_width()) + sys.stdout.flush() + + # Move back to the beginning again + sys.stdout.flush() + sys.stdout.write("\033[%dG" % 0) + sys.stdout.flush() + + # And print the new output we're peaking on: + sys.stdout.write(output) + sys.stdout.flush() + def run(self): self.status = 'running' old_dir = os.getcwd() @@ -163,7 +204,7 @@ class sys_command():#Thread): os.execve(self.cmd[0], self.cmd, {**os.environ, **self.environment_vars}) except FileNotFoundError: self.status = 'done' - self.log(f"{self.cmd[0]} does not exist.", level=LOG_LEVELS.Debug) + self.log(f"{self.cmd[0]} does not exist.", level=logging.DEBUG) self.exit_code = 1 return False @@ -173,8 +214,8 @@ class sys_command():#Thread): poller.register(child_fd, EPOLLIN | EPOLLHUP) if 'events' in self.kwargs and 'debug' in self.kwargs: - self.log(f'[D] Using triggers for command: {self.cmd}', level=LOG_LEVELS.Debug) - self.log(json.dumps(self.kwargs['events']), level=LOG_LEVELS.Debug) + self.log(f'[D] Using triggers for command: {self.cmd}', level=logging.DEBUG) + self.log(json.dumps(self.kwargs['events']), level=logging.DEBUG) alive = True last_trigger_pos = 0 @@ -182,13 +223,14 @@ class sys_command():#Thread): for fileno, event in poller.poll(0.1): try: output = os.read(child_fd, 8192) + self.peak(output) self.trace_log += output except OSError: alive = False break if 'debug' in self.kwargs and self.kwargs['debug'] and len(output): - self.log(self.cmd, 'gave:', output.decode('UTF-8'), level=LOG_LEVELS.Debug) + self.log(self.cmd, 'gave:', output.decode('UTF-8'), level=logging.DEBUG) if 'on_output' in self.kwargs: self.kwargs['on_output'](self.kwargs['worker'], output) @@ -209,8 +251,8 @@ class sys_command():#Thread): trigger_pos = self.trace_log[last_trigger_pos:].lower().find(trigger.lower()) if 'debug' in self.kwargs and self.kwargs['debug']: - self.log(f"Writing to subprocess {self.cmd[0]}: {self.kwargs['events'][trigger].decode('UTF-8')}", level=LOG_LEVELS.Debug) - self.log(f"Writing to subprocess {self.cmd[0]}: {self.kwargs['events'][trigger].decode('UTF-8')}", level=LOG_LEVELS.Debug) + self.log(f"Writing to subprocess {self.cmd[0]}: {self.kwargs['events'][trigger].decode('UTF-8')}", level=logging.DEBUG) + self.log(f"Writing to subprocess {self.cmd[0]}: {self.kwargs['events'][trigger].decode('UTF-8')}", level=logging.DEBUG) last_trigger_pos = trigger_pos os.write(child_fd, self.kwargs['events'][trigger]) @@ -224,18 +266,18 @@ class sys_command():#Thread): ## Adding a exit trigger: if len(self.kwargs['events']) == 0: if 'debug' in self.kwargs and self.kwargs['debug']: - self.log(f"Waiting for last command {self.cmd[0]} to finish.", level=LOG_LEVELS.Debug) + self.log(f"Waiting for last command {self.cmd[0]} to finish.", level=logging.DEBUG) if bytes(f']$'.lower(), 'UTF-8') in self.trace_log[0-len(f']$')-5:].lower(): if 'debug' in self.kwargs and self.kwargs['debug']: - self.log(f"{self.cmd[0]} has finished.", level=LOG_LEVELS.Debug) + self.log(f"{self.cmd[0]} has finished.", level=logging.DEBUG) alive = False break self.status = 'done' if 'debug' in self.kwargs and self.kwargs['debug']: - self.log(f"{self.cmd[0]} waiting for exit code.", level=LOG_LEVELS.Debug) + self.log(f"{self.cmd[0]} waiting for exit code.", level=logging.DEBUG) if not self.kwargs['emulate']: try: @@ -249,14 +291,14 @@ class sys_command():#Thread): self.exit_code = 0 if 'debug' in self.kwargs and self.kwargs['debug']: - self.log(f"{self.cmd[0]} got exit code: {self.exit_code}", level=LOG_LEVELS.Debug) + self.log(f"{self.cmd[0]} got exit code: {self.exit_code}", level=logging.DEBUG) if 'ignore_errors' in self.kwargs: self.exit_code = 0 if self.exit_code != 0 and not self.kwargs['suppress_errors']: - #self.log(self.trace_log.decode('UTF-8'), level=LOG_LEVELS.Debug) - #self.log(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.", level=LOG_LEVELS.Error) + #self.log(self.trace_log.decode('UTF-8'), level=logging.DEBUG) + #self.log(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.", level=logging.ERROR) raise SysCallError(message=f"{self.trace_log.decode('UTF-8')}\n'{self.raw_cmd}' did not exit gracefully (trace log above), exit code: {self.exit_code}", exit_code=self.exit_code) self.ended = time.time() |