diff --git a/deploy/iso/bj-install-progress b/deploy/iso/bj-install-progress index e272166..70a14e8 100644 --- a/deploy/iso/bj-install-progress +++ b/deploy/iso/bj-install-progress @@ -231,6 +231,46 @@ def demo(path, html_out): LIVE = "BJ_PROGRESS_STATE" not in os.environ # настоящая установка (не проверка) +TTY = "/dev/tty1" + + +class Console: + """Вывод на первую консоль. Экран установщика Ubuntu при остановке «вешает» консоль (vhangup): открытый + до этого вывод отвечает EIO (так упал первый вариант экрана) — тогда консоль открывается заново.""" + + def __init__(self): + self.f = None + + def _open(self): + if not LIVE: + return sys.stdout + return open(TTY, "w", encoding="utf-8", errors="replace") + + def write(self, s): + for _ in range(5): + try: + if self.f is None: + self.f = self._open() + self.f.write(s) + self.f.flush() + return + except OSError: + if self.f is not None and self.f is not sys.stdout: + try: + self.f.close() + except OSError: + pass + self.f = None + time.sleep(0.3) + + def size(self): + try: + return os.get_terminal_size(self.f.fileno()) if self.f is not None else os.get_terminal_size(sys.stdout.fileno()) + except OSError: + return os.terminal_size((100, 37)) + + +OUT = Console() PSF = "/snap/subiquity/current/subiquity.psf" # шрифт консоли установщика: кириллица и рамки @@ -244,7 +284,7 @@ def hold_console(state, font_set): subprocess.call(["systemctl", "stop", "--no-block", CLIENT_UNIT], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) sys.stderr.write("bj-install-progress: экран установщика Ubuntu остановлен\n") if not font_set and os.path.exists(PSF): - font_set = subprocess.call(["setfont", PSF], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 + font_set = subprocess.call(["setfont", "-C", TTY, PSF], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 return font_set @@ -263,7 +303,7 @@ def main(): def run(): sys.stderr.write("bj-install-progress: экран установки запущен\n") font_set = hold_console(read_state(), False) - sys.stdout.write("\033[?25l") # без мигающего курсора + OUT.write("\033[?25l") # без мигающего курсора p = Progress() j = subprocess.Popen(["journalctl", "-b", "-o", "json", "-f", "-n", "all", "-q", "SUBIQUITY_EVENT_TYPE=start", "SUBIQUITY_EVENT_TYPE=finish", "SUBIQUITY_EVENT_TYPE=error"], @@ -287,17 +327,16 @@ def run(): font_set = hold_console(p.state, font_set) if p.state == "NEEDS_CONFIRMATION": # установщик ждёт подтверждения — это делает его экран j.terminate() - sys.stdout.write("\033[?25h\033[H\033[2J") + OUT.write("\033[?25h\033[H\033[2J") return 3 - cols, rows = shutil.get_terminal_size((100, 37)) - sys.stdout.write(to_ansi(frame(p, cols, rows))) - sys.stdout.flush() + cols, rows = OUT.size() + OUT.write(to_ansi(frame(p, cols, rows))) if p.error: if not error_at: error_at = time.time() elif time.time() - error_at > 6: j.terminate() - sys.stdout.write("\033[?25h\033[H\033[2J") + OUT.write("\033[?25h\033[H\033[2J") return 2 # обёртка запустит экран установщика Ubuntu: подробности и командная строка