Экран установки системы: после остановки экрана установщика Ubuntu консоль «вешается» (vhangup) и запись в прежний вывод даёт EIO — экран падал на первом кадре (журнал установки .28); теперь консоль открывается заново, шрифт ставится явно на tty1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-10-05 21:16:24 +03:00
parent 2ca1c8c19c
commit b17ad6d8aa
+46 -7
View File
@@ -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: подробности и командная строка