Merge pull request #123052 from xoe-labs/da-test-vm-innteractive-log-switch

nixos/testing: add interactive serial stdout logs switch and dim them

Changed files
+28 -7
nixos
+27 -6
nixos/lib/test-driver/test-driver.py
···
from queue import Queue, Empty
from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List, Iterable
from xml.sax.saxutils import XMLGenerator
import queue
import io
import _thread
···
self.xml.startDocument()
self.xml.startElement("logfile", attrs={})
def close(self) -> None:
self.xml.endElement("logfile")
self.xml.endDocument()
···
self.drain_log_queue()
self.log_line(message, attributes)
-
def enqueue(self, message: Dict[str, str]) -> None:
-
self.queue.put(message)
def drain_log_queue(self) -> None:
try:
while True:
item = self.queue.get_nowait()
-
attributes = {"machine": item["machine"], "type": "serial"}
-
self.log_line(self.sanitise(item["msg"]), attributes)
except Empty:
pass
···
def log(self, msg: str) -> None:
self.logger.log(msg, {"machine": self.name})
def nested(self, msg: str, attrs: Dict[str, str] = {}) -> _GeneratorContextManager:
my_attrs = {"machine": self.name}
my_attrs.update(attrs)
···
# Ignore undecodable bytes that may occur in boot menus
line = _line.decode(errors="ignore").replace("\r", "").rstrip()
self.last_lines.put(line)
-
eprint("{} # {}".format(self.name, line))
-
self.logger.enqueue({"msg": line, "machine": self.name})
_thread.start_new_thread(process_serial_output, ())
···
for machine in machines:
if machine.is_up():
machine.execute("sync")
@contextmanager
···
from queue import Queue, Empty
from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List, Iterable
from xml.sax.saxutils import XMLGenerator
+
from colorama import Style
import queue
import io
import _thread
···
self.xml.startDocument()
self.xml.startElement("logfile", attrs={})
+
self._print_serial_logs = True
+
def close(self) -> None:
self.xml.endElement("logfile")
self.xml.endDocument()
···
self.drain_log_queue()
self.log_line(message, attributes)
+
def log_serial(self, message: str, machine: str) -> None:
+
self.enqueue({"msg": message, "machine": machine, "type": "serial"})
+
if self._print_serial_logs:
+
eprint(Style.DIM + "{} # {}".format(machine, message) + Style.RESET_ALL)
+
+
def enqueue(self, item: Dict[str, str]) -> None:
+
self.queue.put(item)
def drain_log_queue(self) -> None:
try:
while True:
item = self.queue.get_nowait()
+
msg = self.sanitise(item["msg"])
+
del item["msg"]
+
self.log_line(msg, item)
except Empty:
pass
···
def log(self, msg: str) -> None:
self.logger.log(msg, {"machine": self.name})
+
def log_serial(self, msg: str) -> None:
+
self.logger.log_serial(msg, self.name)
+
def nested(self, msg: str, attrs: Dict[str, str] = {}) -> _GeneratorContextManager:
my_attrs = {"machine": self.name}
my_attrs.update(attrs)
···
# Ignore undecodable bytes that may occur in boot menus
line = _line.decode(errors="ignore").replace("\r", "").rstrip()
self.last_lines.put(line)
+
self.log_serial(line)
_thread.start_new_thread(process_serial_output, ())
···
for machine in machines:
if machine.is_up():
machine.execute("sync")
+
+
+
def serial_stdout_on() -> None:
+
global log
+
log._print_serial_logs = True
+
+
+
def serial_stdout_off() -> None:
+
global log
+
log._print_serial_logs = False
@contextmanager
+1 -1
nixos/lib/testing-python.nix
···
name = "nixos-test-driver";
nativeBuildInputs = [ makeWrapper ];
-
buildInputs = [ (python3.withPackages (p: [ p.ptpython ])) ];
checkInputs = with python3Packages; [ pylint black mypy ];
dontUnpack = true;
···
name = "nixos-test-driver";
nativeBuildInputs = [ makeWrapper ];
+
buildInputs = [ (python3.withPackages (p: [ p.ptpython p.colorama ])) ];
checkInputs = with python3Packages; [ pylint black mypy ];
dontUnpack = true;