diff --git a/docs/infrastructure/racks/rack01-elevation.svg b/docs/infrastructure/racks/rack01-elevation.svg index 67034a5..74a8a94 100644 --- a/docs/infrastructure/racks/rack01-elevation.svg +++ b/docs/infrastructure/racks/rack01-elevation.svg @@ -1,5 +1,5 @@ - - + + Rack rack01 front @@ -147,6 +147,56 @@ 46 47 48 +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 + + srv04 · server · staging · cluster: — · U5–U6 @@ -174,8 +224,8 @@ pdu02 · pdu · in-use · cluster: — · 0U right - -pdu02 + +pdu02 srv01 · server · staging · cluster: tappaas · shf01/front/slot 1 @@ -198,4 +248,23 @@ shf01 +Legend + +patch-panel + +pdu + +server + +shelf + +switch + +in-use + +staging + +broken + +spare diff --git a/docs/infrastructure/racks/rack01.md b/docs/infrastructure/racks/rack01.md index a6719f8..798beac 100644 --- a/docs/infrastructure/racks/rack01.md +++ b/docs/infrastructure/racks/rack01.md @@ -5,8 +5,8 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not ## Elevation
- - + + Rack rack01 front @@ -154,6 +154,56 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not 46 47 48 +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 + + srv04 · server · staging · cluster: — · U5–U6 @@ -181,8 +231,8 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not pdu02 · pdu · in-use · cluster: — · 0U right - -pdu02 + +pdu02 srv01 · server · staging · cluster: tappaas · shf01/front/slot 1 @@ -205,6 +255,25 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not shf01 +Legend + +patch-panel + +pdu + +server + +shelf + +switch + +in-use + +staging + +broken + +spare
diff --git a/scripts/gen_rack.py b/scripts/gen_rack.py index 3aecac0..d2a9e48 100644 --- a/scripts/gen_rack.py +++ b/scripts/gen_rack.py @@ -357,16 +357,18 @@ def render_svg(rack: str, items: list[dict]) -> str: PAD = 12 GAP = 50 TITLE_H = 28 + LEGEND_H = 56 items = _sorted_items(items) left_items = [i for i in items if i.get("rack_face") == "left"] right_items = [i for i in items if i.get("rack_face") == "right"] body_h = RACK_UNITS * U_H - height = PAD + TITLE_H + body_h + PAD + height = PAD + TITLE_H + body_h + PAD + LEGEND_H front_x = PAD + len(left_items) * RAIL_W + LABEL_W rear_x = front_x + COL_W + GAP - width = rear_x + COL_W + len(right_items) * RAIL_W + PAD + right_gutter_x = rear_x + COL_W + width = right_gutter_x + LABEL_W + len(right_items) * RAIL_W + PAD top = PAD + TITLE_H def u_y(u: int) -> int: @@ -405,6 +407,17 @@ def render_svg(rack: str, items: list[dict]) -> str: f'{u}' ) + for u in range(1, RACK_UNITS + 1): + y = u_y(u) + p.append( + f'{u}' + ) + for col_x in (front_x, rear_x): + p.append( + f'' + ) def draw_device(fm: dict, col_x: int) -> None: u = fm["rack_u"] @@ -457,7 +470,7 @@ def render_svg(rack: str, items: list[dict]) -> str: for idx, fm in enumerate(left_items): draw_rail(fm, PAD + idx * RAIL_W) for idx, fm in enumerate(right_items): - draw_rail(fm, rear_x + COL_W + idx * RAIL_W) + draw_rail(fm, right_gutter_x + LABEL_W + idx * RAIL_W) SHELF_STRIP_H = 6 shelves = [i for i in items if i.get("kind") == "shelf"] @@ -514,6 +527,33 @@ def render_svg(rack: str, items: list[dict]) -> str: for fm in sorted(shelves, key=lambda s: s.get("hostname", "")): draw_shelf(fm) + legend_y = top + body_h + PAD + 8 + p.append( + f'Legend' + ) + present_kinds = sorted({i.get("kind", "") for i in items if i.get("kind")}) + kx = front_x + ky = legend_y + 18 + for kind in present_kinds: + color = KIND_COLORS.get(kind, DEFAULT_COLOR) + p.append( + f'' + ) + p.append(f'{_esc(kind)}') + kx += 28 + 7 * len(kind) + sx = front_x + sy = ky + 18 + for label in ("in-use", "staging", "broken", "spare"): + stroke, sw, dash = _status_stroke(label) + dash_attr = f' stroke-dasharray="{dash}"' if dash else "" + p.append( + f'' + ) + p.append(f'{_esc(label)}') + sx += 28 + 7 * len(label) + p.append("") return "\n".join(p) + "\n" diff --git a/tests/test_gen_rack.py b/tests/test_gen_rack.py index d7e2d96..268ec87 100644 --- a/tests/test_gen_rack.py +++ b/tests/test_gen_rack.py @@ -674,3 +674,29 @@ def test_render_page_inlines_svg_with_download_link(): assert "Legend<" in svg + assert ">switch<" in svg + + +def test_svg_legend_omits_absent_kinds(): + items = [item(hostname="sw01", kind="switch", rack_u=10, u_height=1, + rack_face="front")] + svg = gen_rack.render_svg("rack01", items) + assert ">ups<" not in svg + + +def test_svg_u_numbers_in_both_gutters(): + svg = gen_rack.render_svg("rack01", []) + assert 'text-anchor="end"' in svg # left gutter + assert 'text-anchor="start"' in svg # right gutter + + +def test_svg_has_column_frames(): + svg = gen_rack.render_svg("rack01", []) + assert svg.count('fill="none"') >= 2 # one frame per column