Skip to content

Commit a78718d

Browse files
committed
contest: hw: mctrl: improve CLI SOL sanitization
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a20fc12 commit a78718d

1 file changed

Lines changed: 23 additions & 7 deletions

File tree

contest/hw/mc_cli.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,30 @@
66
import argparse
77
import json
88
import os
9+
import re
910
import sys
10-
import unicodedata
1111

1212
import requests
1313

1414
from lib.mc_client import MCClient, resolve_machines
1515

1616

17-
def _sanitize(text):
18-
"""Strip control characters except newline."""
17+
def _sanitize(text, keep_color=False):
18+
"""Strip ANSI escape sequences and control characters.
19+
20+
If keep_color is True, SGR sequences (color/formatting, ending
21+
with 'm') are preserved. All other escape sequences and control
22+
characters (except newline) are removed.
23+
"""
24+
if keep_color:
25+
# Strip non-SGR escape sequences (cursor movement, erase, etc.)
26+
text = re.sub(r'\x1b\[[0-9;]*[^0-9;m]', '', text)
27+
else:
28+
# Strip all ANSI escape sequences
29+
text = re.sub(r'\x1b\[[0-9;]*[a-zA-Z]', '', text)
30+
# Strip remaining control characters except newline
1931
return ''.join(c for c in text
20-
if c == '\n' or unicodedata.category(c)[0] != 'C')
32+
if c == '\n' or not (0 <= ord(c) < 32 or ord(c) == 127))
2133

2234

2335
def cmd_machines(args, mc):
@@ -77,14 +89,15 @@ def cmd_resolve(args, mc):
7789

7890
def cmd_sol(args, mc):
7991
"""Fetch SOL logs."""
92+
color = args.color
8093
if args.follow:
8194
# Fetch last 10 lines to start, then poll for new ones
8295
data = mc.get_sol_logs(args.machine_id, start_id=args.start_id,
8396
limit=10, sort='desc')
8497
lines = list(reversed(data.get('lines', [])))
8598
for entry in lines:
8699
ts = entry.get('ts', '')
87-
print(f"{ts} {_sanitize(entry['line'])}", end='')
100+
print(f"{ts} {_sanitize(entry['line'], keep_color=color)}", end='')
88101
last_id = data.get('last_id', 0)
89102

90103
import time
@@ -95,7 +108,8 @@ def cmd_sol(args, mc):
95108
limit=args.limit)
96109
for entry in data.get('lines', []):
97110
ts = entry.get('ts', '')
98-
print(f"{ts} {_sanitize(entry['line'])}", end='', flush=True)
111+
print(f"{ts} {_sanitize(entry['line'], keep_color=color)}",
112+
end='', flush=True)
99113
last_id = data.get('last_id', last_id)
100114
except KeyboardInterrupt:
101115
return 0
@@ -107,7 +121,7 @@ def cmd_sol(args, mc):
107121
return 0
108122
for entry in data.get('lines', []):
109123
ts = entry.get('ts', '')
110-
print(f"{ts} {_sanitize(entry['line'])}", end='')
124+
print(f"{ts} {_sanitize(entry['line'], keep_color=color)}", end='')
111125
last_id = data.get('last_id', 0)
112126
print(f"last_id={last_id}", file=sys.stderr)
113127
return 0
@@ -214,6 +228,8 @@ def main(argv=None):
214228
help='follow output like tail -f')
215229
p_sol.add_argument('--interval', type=float, default=2,
216230
help='poll interval in seconds for -f (default: 2)')
231+
p_sol.add_argument('--color', action='store_true',
232+
help='preserve ANSI color/formatting in output')
217233

218234
p_reserve = sub.add_parser('reserve', help='reserve machines')
219235
p_reserve.add_argument('--machine-ids', required=True,

0 commit comments

Comments
 (0)