Экран установки системы: после остановки экрана установщика 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:
@@ -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: подробности и командная строка
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user