-
Notifications
You must be signed in to change notification settings - Fork 56
/
microvm-tiles.py
executable file
·100 lines (76 loc) · 3.45 KB
/
microvm-tiles.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""
A demo script for visualising on-host microVM network activity.
Will read bytes recieved by the host on microVM tun/tap devices, as per
`/proc/net/dev` file, and then use that data to color a cell on the terminal.
The terminal screen is refreshed periodically. The brigher a cell is colored,
the more bytes the host recieved from that microVM. The brightness range is
scaled based on the maximum amount of bytes a microvm has sent in that refresh
cycle.
"""
#!/usr/bin/python3
import curses
import re
import time
MAX_MICROVMS = 4096
COLOR_BLACK = 101
MICROVM_TAP_REGEX = r'fc-(\d+)-tap'
def render_microvms(stdscr):
# Put key-grabbing in no-wait mode.
stdscr.nodelay(True)
# Clear screen
stdscr.clear()
# Create a gradient "color palette" with 100 color pairs, from dark grey to
# Amazon orange. Color pair 0 is reserved in curses, we'll start from 1.
for shade in range (1, 101):
curses.init_color(shade, 200 + shade * 8, 200 + int(shade * 4.8), 208)
curses.init_pair(shade, shade, shade)
# Black for background.
curses.init_color(COLOR_BLACK, 0, 0, 0)
curses.init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK)
# Seed value for the last iteration's microVM network interface activty.
last_rx = [0] * MAX_MICROVMS
delta_rx = [0] * MAX_MICROVMS
# Blinky loop of infinite microVM activity rendering
# TODO: End loop on any key press (Ctrl+C required now).
last_iface_idx = 0
while True:
# Reads the latest received bytes on the microVMs' tun/tap interfaces
# and computes the delta against the last iteration, as well as the
# highest delta in this iteration.
with open('/proc/net/dev') as net_iface_list:
# The first two lines of `/proc/net/dev` are headers.
next(net_iface_list)
next(net_iface_list)
max_rx = 0
for iface_line in net_iface_list:
# Only operate microVM tun/tap lines, and extract their index
# (they show up in an arbitrary order in the file).
scan_for_microvm_tap = re.match(MICROVM_TAP_REGEX, iface_line)
if not scan_for_microvm_tap:
continue
iface_idx = int(scan_for_microvm_tap.group(1))
current_rx = int(iface_line.split()[1])
delta_rx[iface_idx] = current_rx - last_rx[iface_idx]
last_rx[iface_idx] = current_rx
if delta_rx[iface_idx] > max_rx:
max_rx = delta_rx[iface_idx]
if last_iface_idx < iface_idx:
last_iface_idx = iface_idx
# "Render" all microVMs. Their brightness is proportional to
# delta_rx_bytes/max_rx_bytes
for i in range(0, curses.LINES - 1):
for j in range(0, curses.COLS):
slot_idx = i * curses.COLS + j
# If there's no microVM there yet, use black
if slot_idx > last_iface_idx:
microvm_color = COLOR_BLACK
else:
# Inactive microvms get a grey color.
microvm_color = 1
if max_rx > 0:
microvm_color += int(99 * delta_rx[slot_idx] / max_rx)
stdscr.addstr(i, j, ' ', curses.color_pair(microvm_color))
stdscr.refresh()
time.sleep(0.25)
# Run the curses "rendering" loop in the terminal, and clean up after.
curses.wrapper(render_microvms)