init rig
This commit is contained in:
47
rig/docs/graphs/01-install.dot
Normal file
47
rig/docs/graphs/01-install.dot
Normal file
@@ -0,0 +1,47 @@
|
||||
digraph rig_install {
|
||||
rankdir=LR
|
||||
bgcolor="#0a0e17"
|
||||
fontname="Helvetica"
|
||||
node [fontname="Helvetica" fontsize=11 style=filled color="#1e2a4a" fontcolor="#e8eaf0" shape=box]
|
||||
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
|
||||
|
||||
label="Installation — the only host prerequisite is Docker"
|
||||
labelloc=t
|
||||
fontsize=16
|
||||
fontcolor="#0066ff"
|
||||
|
||||
subgraph cluster_host {
|
||||
label="Your machine"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
docker [label="Docker\n(the one prerequisite)" fillcolor="#1a1a3a" fontcolor="#0066ff" shape=octagon]
|
||||
bin [label="~/.local/bin\nkind · kubectl · tilt\njq" fillcolor="#121829" shape=cylinder]
|
||||
}
|
||||
|
||||
subgraph cluster_wizard {
|
||||
label="Installer container (transient)"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
wizard [label="wizard\ncurl · jq · python · graphviz" fillcolor="#121829"]
|
||||
detect [label="detect host\nWSL · memory · inotify · docker" fillcolor="#121829"]
|
||||
fetch [label="fetch + verify\nSHA256, pinned versions" fillcolor="#121829"]
|
||||
}
|
||||
|
||||
upstream [label="upstream\nreleases / corporate mirror" fillcolor="#1a3a1a" fontcolor="#00c853" shape=octagon]
|
||||
report [label="report what it\nCANNOT do" fillcolor="#3a1a1a" fontcolor="#ffc107"]
|
||||
|
||||
docker -> wizard [label="docker run"]
|
||||
wizard -> detect
|
||||
detect -> fetch
|
||||
fetch -> upstream [label="pinned + checksummed" color="#00c853"]
|
||||
fetch -> bin [label="install"]
|
||||
detect -> report [style=dashed label="sudo / Windows-side steps" color="#ffc107"]
|
||||
|
||||
// The container is gone after this; nothing depends on it at run time.
|
||||
wizard -> gone [style=dotted label="exits"]
|
||||
gone [label="(container discarded)" fillcolor="#0a0e17" fontcolor="#4a5568" color="#1e2a4a" style="filled,dashed"]
|
||||
}
|
||||
128
rig/docs/graphs/01-install.svg
Normal file
128
rig/docs/graphs/01-install.svg
Normal file
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 14.1.2 (0)
|
||||
-->
|
||||
<!-- Title: rig_install Pages: 1 -->
|
||||
<svg width="1145pt" height="287pt"
|
||||
viewBox="0.00 0.00 1145.00 287.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 283.29)">
|
||||
<title>rig_install</title>
|
||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-283.29 1141.06,-283.29 1141.06,4 -4,4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="568.53" y="-260.09" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">Installation — the only host prerequisite is Docker</text>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_host</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="898.49,-8 898.49,-190 1123.82,-190 1123.82,-8 898.49,-8"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-170.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Your machine</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_wizard</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="8,-95 8,-175 745.5,-175 745.5,-95 8,-95"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="376.75" y="-155.8" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Installer container (transient)</text>
|
||||
</g>
|
||||
<!-- docker -->
|
||||
<g id="node1" class="node">
|
||||
<title>docker</title>
|
||||
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="1115.82,-31.9 1115.82,-54.1 1054.51,-69.79 967.8,-69.79 906.49,-54.1 906.49,-31.9 967.8,-16.21 1054.51,-16.21 1115.82,-31.9"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-46.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0066ff">Docker</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-32.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0066ff">(the one prerequisite)</text>
|
||||
</g>
|
||||
<!-- wizard -->
|
||||
<g id="node3" class="node">
|
||||
<title>wizard</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="181.25,-139 16,-139 16,-103 181.25,-103 181.25,-139"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="98.62" y="-124.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">wizard</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="98.62" y="-110.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">curl · jq · python · graphviz</text>
|
||||
</g>
|
||||
<!-- docker->wizard -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>docker->wizard</title>
|
||||
<path fill="none" stroke="#4a5568" d="M906.12,-45.7C757.47,-50.51 475.98,-63.12 238.25,-94 223.38,-95.93 207.7,-98.48 192.45,-101.24"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="192.13,-97.74 182.93,-103.01 193.4,-104.63 192.13,-97.74"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="506.62" y="-74.39" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">docker run</text>
|
||||
</g>
|
||||
<!-- bin -->
|
||||
<g id="node2" class="node">
|
||||
<title>bin</title>
|
||||
<path fill="#121829" stroke="#1e2a4a" d="M1069.03,-148.28C1069.03,-151.63 1043.09,-154.34 1011.15,-154.34 979.22,-154.34 953.28,-151.63 953.28,-148.28 953.28,-148.28 953.28,-93.72 953.28,-93.72 953.28,-90.37 979.22,-87.66 1011.15,-87.66 1043.09,-87.66 1069.03,-90.37 1069.03,-93.72 1069.03,-93.72 1069.03,-148.28 1069.03,-148.28"/>
|
||||
<path fill="none" stroke="#1e2a4a" d="M1069.03,-148.28C1069.03,-144.94 1043.09,-142.22 1011.15,-142.22 979.22,-142.22 953.28,-144.94 953.28,-148.28"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-130.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">~/.local/bin</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-117.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">kind · kubectl · tilt</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-103.8" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">jq</text>
|
||||
</g>
|
||||
<!-- detect -->
|
||||
<g id="node4" class="node">
|
||||
<title>detect</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="429,-139 238.25,-139 238.25,-103 429,-103 429,-139"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="333.62" y="-124.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">detect host</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="333.62" y="-110.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">WSL · memory · inotify · docker</text>
|
||||
</g>
|
||||
<!-- wizard->detect -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>wizard->detect</title>
|
||||
<path fill="none" stroke="#4a5568" d="M181.44,-121C195.97,-121 211.28,-121 226.37,-121"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="226.33,-124.5 236.33,-121 226.33,-117.5 226.33,-124.5"/>
|
||||
</g>
|
||||
<!-- gone -->
|
||||
<g id="node8" class="node">
|
||||
<title>gone</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="400.5,-47 266.75,-47 266.75,-11 400.5,-11 400.5,-47"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="333.62" y="-25.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#4a5568">(container discarded)</text>
|
||||
</g>
|
||||
<!-- wizard->gone -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>wizard->gone</title>
|
||||
<path fill="none" stroke="#4a5568" stroke-dasharray="1,5" d="M119.29,-102.62C138.26,-86 168.54,-62.29 199.25,-49.75 216.76,-42.6 236.49,-37.9 255.29,-34.81"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="255.67,-38.29 265.04,-33.35 254.64,-31.37 255.67,-38.29"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="209.75" y="-52.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">exits</text>
|
||||
</g>
|
||||
<!-- fetch -->
|
||||
<g id="node5" class="node">
|
||||
<title>fetch</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="737.5,-139 584.25,-139 584.25,-103 737.5,-103 737.5,-139"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="660.88" y="-124.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">fetch + verify</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="660.88" y="-110.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">SHA256, pinned versions</text>
|
||||
</g>
|
||||
<!-- detect->fetch -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>detect->fetch</title>
|
||||
<path fill="none" stroke="#4a5568" d="M429.14,-121C474.43,-121 528.32,-121 572.63,-121"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="572.46,-124.5 582.46,-121 572.46,-117.5 572.46,-124.5"/>
|
||||
</g>
|
||||
<!-- report -->
|
||||
<g id="node7" class="node">
|
||||
<title>report</title>
|
||||
<polygon fill="#3a1a1a" stroke="#1e2a4a" points="706.75,-219 615,-219 615,-183 706.75,-183 706.75,-219"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="660.88" y="-204.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">report what it</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="660.88" y="-190.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">CANNOT do</text>
|
||||
</g>
|
||||
<!-- detect->report -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>detect->report</title>
|
||||
<path fill="none" stroke="#ffc107" stroke-dasharray="5,2" d="M409.65,-139.45C468.85,-154.02 550.13,-174.01 603.78,-187.2"/>
|
||||
<polygon fill="#ffc107" stroke="#ffc107" points="602.77,-190.56 613.32,-189.55 604.45,-183.76 602.77,-190.56"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="506.62" y="-180.06" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">sudo / Windows-side steps</text>
|
||||
</g>
|
||||
<!-- fetch->bin -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>fetch->bin</title>
|
||||
<path fill="none" stroke="#4a5568" d="M737.88,-121C798.58,-121 882.9,-121 941.56,-121"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="941.43,-124.5 951.43,-121 941.43,-117.5 941.43,-124.5"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="811.38" y="-123.7" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">install</text>
|
||||
</g>
|
||||
<!-- upstream -->
|
||||
<g id="node6" class="node">
|
||||
<title>upstream</title>
|
||||
<polygon fill="#1a3a1a" stroke="#1e2a4a" points="1137.06,-213.9 1137.06,-236.1 1063.3,-251.79 959,-251.79 885.25,-236.1 885.25,-213.9 959,-198.21 1063.3,-198.21 1137.06,-213.9"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-228.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">upstream</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1011.15" y="-214.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">releases / corporate mirror</text>
|
||||
</g>
|
||||
<!-- fetch->upstream -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>fetch->upstream</title>
|
||||
<path fill="none" stroke="#00c853" d="M714.8,-139.5C759.85,-154.95 826.43,-177.11 885.25,-194 894.79,-196.74 904.78,-199.46 914.78,-202.09"/>
|
||||
<polygon fill="#00c853" stroke="#00c853" points="913.59,-205.4 924.15,-204.52 915.35,-198.62 913.59,-205.4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="811.38" y="-191.36" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">pinned + checksummed</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.0 KiB |
54
rig/docs/graphs/02-environment.dot
Normal file
54
rig/docs/graphs/02-environment.dot
Normal file
@@ -0,0 +1,54 @@
|
||||
digraph rig_environment {
|
||||
rankdir=TB
|
||||
bgcolor="#0a0e17"
|
||||
fontname="Helvetica"
|
||||
node [fontname="Helvetica" fontsize=11 style=filled color="#1e2a4a" fontcolor="#e8eaf0" shape=box]
|
||||
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
|
||||
|
||||
label="One environment per directory — copies never collide"
|
||||
labelloc=t
|
||||
fontsize=16
|
||||
fontcolor="#0066ff"
|
||||
|
||||
dirname [label="directory name\ne.g. acmebank/" fillcolor="#1f6feb" fontcolor="#ffffff" shape=octagon]
|
||||
|
||||
subgraph cluster_derived {
|
||||
label="Everything below is derived from it"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
cname [label="cluster name\nacmebank" fillcolor="#121829"]
|
||||
ctx [label="kubectl context\nkind-acmebank" fillcolor="#121829"]
|
||||
img [label="image tag\nacmebank-wizard" fillcolor="#121829"]
|
||||
ports [label="port block\n21300–21309" fillcolor="#121829"]
|
||||
reg [label="registry container\nacmebank-registry" fillcolor="#121829"]
|
||||
}
|
||||
|
||||
subgraph cluster_config {
|
||||
label="Configuration — weakest first, later wins"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
versions [label="versions.env\npinned toolchain" fillcolor="#121829"]
|
||||
profile [label="env.d/<profile>.env\nnodes · CNI · audit · addons" fillcolor="#121829"]
|
||||
localenv [label="ctrl/.env\nsecrets, overrides" fillcolor="#121829"]
|
||||
shell [label="the environment\nPROFILE=client make …" fillcolor="#1a3a1a" fontcolor="#00c853"]
|
||||
}
|
||||
|
||||
dirname -> cname
|
||||
dirname -> ctx
|
||||
dirname -> img
|
||||
dirname -> ports
|
||||
dirname -> reg
|
||||
|
||||
versions -> profile [label="overridden by"]
|
||||
profile -> localenv [label="overridden by"]
|
||||
localenv -> shell [label="overridden by" color="#00c853"]
|
||||
|
||||
cluster [label="kind cluster" fillcolor="#1a1a3a" fontcolor="#0066ff" shape=octagon]
|
||||
cname -> cluster
|
||||
ports -> cluster
|
||||
shell -> cluster [style=dashed]
|
||||
}
|
||||
169
rig/docs/graphs/02-environment.svg
Normal file
169
rig/docs/graphs/02-environment.svg
Normal file
@@ -0,0 +1,169 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 14.1.2 (0)
|
||||
-->
|
||||
<!-- Title: rig_environment Pages: 1 -->
|
||||
<svg width="971pt" height="481pt"
|
||||
viewBox="0.00 0.00 971.00 481.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 476.83)">
|
||||
<title>rig_environment</title>
|
||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-476.83 967,-476.83 967,4 -4,4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="481.5" y="-453.63" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#0066ff">One environment per directory — copies never collide</text>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_derived</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="8,-65 8,-144.5 605,-144.5 605,-65 8,-65"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="306.5" y="-125.3" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Everything below is derived from it</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_config</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="613,-65 613,-437.33 955,-437.33 955,-65 613,-65"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="784" y="-418.13" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Configuration — weakest first, later wins</text>
|
||||
</g>
|
||||
<!-- dirname -->
|
||||
<g id="node1" class="node">
|
||||
<title>dirname</title>
|
||||
<polygon fill="#1f6feb" stroke="#1e2a4a" points="375.11,-197.44 375.11,-219.63 329.94,-235.33 266.06,-235.33 220.89,-219.63 220.89,-197.44 266.06,-181.75 329.94,-181.75 375.11,-197.44"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="298" y="-211.59" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffffff">directory name</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="298" y="-198.09" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffffff">e.g. acmebank/</text>
|
||||
</g>
|
||||
<!-- cname -->
|
||||
<g id="node2" class="node">
|
||||
<title>cname</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="104,-109 16,-109 16,-73 104,-73 104,-109"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="60" y="-94.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">cluster name</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="60" y="-80.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">acmebank</text>
|
||||
</g>
|
||||
<!-- dirname->cname -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>dirname->cname</title>
|
||||
<path fill="none" stroke="#4a5568" d="M232.76,-193.05C195.81,-183.01 149.78,-167.28 113,-144.5 101.37,-137.29 90.31,-127.09 81.33,-117.6"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="84.04,-115.37 74.73,-110.3 78.85,-120.07 84.04,-115.37"/>
|
||||
</g>
|
||||
<!-- ctx -->
|
||||
<g id="node3" class="node">
|
||||
<title>ctx</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="223.75,-109 122.25,-109 122.25,-73 223.75,-73 223.75,-109"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="173" y="-94.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">kubectl context</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="173" y="-80.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">kind-acmebank</text>
|
||||
</g>
|
||||
<!-- dirname->ctx -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>dirname->ctx</title>
|
||||
<path fill="none" stroke="#4a5568" d="M269.64,-181.32C248.71,-161.98 220.42,-135.83 199.86,-116.83"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="202.4,-114.41 192.68,-110.19 197.65,-119.55 202.4,-114.41"/>
|
||||
</g>
|
||||
<!-- img -->
|
||||
<g id="node4" class="node">
|
||||
<title>img</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="354,-109 242,-109 242,-73 354,-73 354,-109"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="298" y="-94.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">image tag</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="298" y="-80.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">acmebank-wizard</text>
|
||||
</g>
|
||||
<!-- dirname->img -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>dirname->img</title>
|
||||
<path fill="none" stroke="#4a5568" d="M298,-181.32C298,-163.19 298,-139.07 298,-120.47"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="301.5,-120.67 298,-110.67 294.5,-120.67 301.5,-120.67"/>
|
||||
</g>
|
||||
<!-- ports -->
|
||||
<g id="node5" class="node">
|
||||
<title>ports</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="460.38,-109 371.62,-109 371.62,-73 460.38,-73 460.38,-109"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="416" y="-94.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">port block</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="416" y="-80.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">21300–21309</text>
|
||||
</g>
|
||||
<!-- dirname->ports -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>dirname->ports</title>
|
||||
<path fill="none" stroke="#4a5568" d="M324.94,-181.53C336.66,-170.19 350.54,-156.71 363,-144.5 372.11,-135.57 382.06,-125.74 390.85,-117.02"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="393.15,-119.67 397.79,-110.14 388.22,-114.7 393.15,-119.67"/>
|
||||
</g>
|
||||
<!-- reg -->
|
||||
<g id="node6" class="node">
|
||||
<title>reg</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="597.38,-109 478.62,-109 478.62,-73 597.38,-73 597.38,-109"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="538" y="-94.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">registry container</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="538" y="-80.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">acmebank-registry</text>
|
||||
</g>
|
||||
<!-- dirname->reg -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>dirname->reg</title>
|
||||
<path fill="none" stroke="#4a5568" d="M356.87,-190.63C390.74,-179.74 433.49,-163.98 469,-144.5 483.3,-136.65 497.86,-126.04 509.9,-116.41"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="511.88,-119.31 517.39,-110.26 507.44,-113.9 511.88,-119.31"/>
|
||||
</g>
|
||||
<!-- cluster -->
|
||||
<g id="node11" class="node">
|
||||
<title>cluster</title>
|
||||
<polygon fill="#1a1a3a" stroke="#1e2a4a" points="469.81,-10.54 469.81,-25.46 438.29,-36 393.71,-36 362.19,-25.46 362.19,-10.54 393.71,0 438.29,0 469.81,-10.54"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="416" y="-14.3" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#0066ff">kind cluster</text>
|
||||
</g>
|
||||
<!-- cname->cluster -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>cname->cluster</title>
|
||||
<path fill="none" stroke="#4a5568" d="M93.06,-72.62C99.54,-69.72 106.38,-67.02 113,-65 192.78,-40.7 288.45,-28.91 350.65,-23.42"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="350.69,-26.93 360.36,-22.6 350.1,-19.96 350.69,-26.93"/>
|
||||
</g>
|
||||
<!-- ports->cluster -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>ports->cluster</title>
|
||||
<path fill="none" stroke="#4a5568" d="M416,-72.81C416,-65.23 416,-56.1 416,-47.54"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="419.5,-47.54 416,-37.54 412.5,-47.54 419.5,-47.54"/>
|
||||
</g>
|
||||
<!-- versions -->
|
||||
<g id="node7" class="node">
|
||||
<title>versions</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="759.38,-401.83 652.62,-401.83 652.62,-365.83 759.38,-365.83 759.38,-401.83"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="706" y="-386.88" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">versions.env</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="706" y="-373.38" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">pinned toolchain</text>
|
||||
</g>
|
||||
<!-- profile -->
|
||||
<g id="node8" class="node">
|
||||
<title>profile</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="790.5,-318.58 621.5,-318.58 621.5,-282.58 790.5,-282.58 790.5,-318.58"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="706" y="-303.63" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">env.d/<profile>.env</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="706" y="-290.13" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">nodes · CNI · audit · addons</text>
|
||||
</g>
|
||||
<!-- versions->profile -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>versions->profile</title>
|
||||
<path fill="none" stroke="#4a5568" d="M706,-365.59C706,-355.32 706,-342.03 706,-330.21"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="709.5,-330.58 706,-320.58 702.5,-330.58 709.5,-330.58"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="737.5" y="-339.28" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">overridden by</text>
|
||||
</g>
|
||||
<!-- localenv -->
|
||||
<g id="node9" class="node">
|
||||
<title>localenv</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="761.88,-226.54 646.12,-226.54 646.12,-190.54 761.88,-190.54 761.88,-226.54"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="704" y="-211.59" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">ctrl/.env</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="704" y="-198.09" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">secrets, overrides</text>
|
||||
</g>
|
||||
<!-- profile->localenv -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>profile->localenv</title>
|
||||
<path fill="none" stroke="#4a5568" d="M705.61,-282.22C705.34,-269.76 704.96,-252.69 704.64,-238.23"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="708.14,-238.28 704.42,-228.36 701.14,-238.43 708.14,-238.28"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="736.68" y="-256.03" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">overridden by</text>
|
||||
</g>
|
||||
<!-- shell -->
|
||||
<g id="node10" class="node">
|
||||
<title>shell</title>
|
||||
<polygon fill="#1a3a1a" stroke="#1e2a4a" points="772.38,-109 623.62,-109 623.62,-73 772.38,-73 772.38,-109"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="698" y="-94.05" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">the environment</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="698" y="-80.55" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">PROFILE=client make …</text>
|
||||
</g>
|
||||
<!-- localenv->shell -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>localenv->shell</title>
|
||||
<path fill="none" stroke="#00c853" d="M703.11,-190.49C702.16,-172.16 700.63,-142.72 699.49,-120.79"/>
|
||||
<polygon fill="#00c853" stroke="#00c853" points="703,-120.81 698.99,-111.01 696.01,-121.18 703,-120.81"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="733.21" y="-155.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">overridden by</text>
|
||||
</g>
|
||||
<!-- shell->cluster -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>shell->cluster</title>
|
||||
<path fill="none" stroke="#4a5568" stroke-dasharray="5,2" d="M637.29,-72.6C627.83,-69.99 618.17,-67.38 609,-65 562.72,-52.99 509.89,-40.48 471.22,-31.54"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="472.2,-28.18 461.67,-29.35 470.63,-35 472.2,-28.18"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
56
rig/docs/graphs/03-architecture.dot
Normal file
56
rig/docs/graphs/03-architecture.dot
Normal file
@@ -0,0 +1,56 @@
|
||||
// TODO: PLACEHOLDER — replace with the real estate topology.
|
||||
//
|
||||
// This is where the extracted platform diagrams land. The shape below is
|
||||
// illustrative only: it shows how a mocked dependency, a real service and a
|
||||
// remote system are meant to sit together, not what the system actually is.
|
||||
//
|
||||
// The intended end state is that this file stops being hand-written and is
|
||||
// generated from the running cluster, so the diagram becomes a report of what
|
||||
// exists rather than a drawing of what was once intended.
|
||||
digraph estate {
|
||||
rankdir=LR
|
||||
bgcolor="#0a0e17"
|
||||
fontname="Helvetica"
|
||||
node [fontname="Helvetica" fontsize=11 style=filled color="#1e2a4a" fontcolor="#e8eaf0" shape=box]
|
||||
edge [fontname="Helvetica" fontsize=9 fontcolor="#8892a8" color="#4a5568"]
|
||||
|
||||
label="Estate topology — PLACEHOLDER"
|
||||
labelloc=t
|
||||
fontsize=16
|
||||
fontcolor="#ffc107"
|
||||
|
||||
subgraph cluster_new {
|
||||
label="New"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
api [label="service under work\n(real: built and hot-reloaded)" fillcolor="#1a3a1a" fontcolor="#00c853"]
|
||||
}
|
||||
|
||||
subgraph cluster_core {
|
||||
label="Core (mocked)"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
svc_a [label="upstream service\n(mock: canned responses)" fillcolor="#121829"]
|
||||
db [label="datastore\n(mock)" fillcolor="#121829" shape=cylinder]
|
||||
}
|
||||
|
||||
subgraph cluster_legacy {
|
||||
label="Legacy estate (mocked)"
|
||||
style=dashed
|
||||
color="#1e2a4a"
|
||||
fontcolor="#8892a8"
|
||||
|
||||
batch [label="batch drop\n(mock: writes files on a timer)" fillcolor="#121829"]
|
||||
}
|
||||
|
||||
remote [label="external system\n(remote: ExternalName,\nreachable only from a VDI)" fillcolor="#3a1a1a" fontcolor="#ffc107" shape=octagon]
|
||||
|
||||
api -> svc_a [label="HTTP"]
|
||||
api -> db [label="query"]
|
||||
api -> batch [label="file handoff" style=dashed]
|
||||
api -> remote [label="only when reachable" style=dashed color="#ffc107"]
|
||||
}
|
||||
94
rig/docs/graphs/03-architecture.svg
Normal file
94
rig/docs/graphs/03-architecture.svg
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 14.1.2 (0)
|
||||
-->
|
||||
<!-- Title: estate Pages: 1 -->
|
||||
<svg width="579pt" height="362pt"
|
||||
viewBox="0.00 0.00 579.00 362.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 357.62)">
|
||||
<title>estate</title>
|
||||
<polygon fill="#0a0e17" stroke="none" points="-4,4 -4,-357.62 575.41,-357.62 575.41,4 -4,4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="285.7" y="-334.42" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#ffc107">Estate topology — PLACEHOLDER</text>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_new</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="8,-130.12 8,-210.12 199,-210.12 199,-130.12 8,-130.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="103.5" y="-190.92" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">New</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_core</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="357.33,-172.12 357.33,-318.12 534.83,-318.12 534.83,-172.12 357.33,-172.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-298.92" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Core (mocked)</text>
|
||||
</g>
|
||||
<g id="clust3" class="cluster">
|
||||
<title>cluster_legacy</title>
|
||||
<polygon fill="#0a0e17" stroke="#1e2a4a" stroke-dasharray="5,2" points="341.83,-84.12 341.83,-164.12 551.33,-164.12 551.33,-84.12 341.83,-84.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.58" y="-144.92" font-family="Helvetica,sans-Serif" font-size="16.00" fill="#8892a8">Legacy estate (mocked)</text>
|
||||
</g>
|
||||
<!-- api -->
|
||||
<g id="node1" class="node">
|
||||
<title>api</title>
|
||||
<polygon fill="#1a3a1a" stroke="#1e2a4a" points="191,-174.12 16,-174.12 16,-138.12 191,-138.12 191,-174.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="103.5" y="-159.17" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">service under work</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="103.5" y="-145.67" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#00c853">(real: built and hot-reloaded)</text>
|
||||
</g>
|
||||
<!-- svc_a -->
|
||||
<g id="node2" class="node">
|
||||
<title>svc_a</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="526.83,-282.12 365.33,-282.12 365.33,-246.12 526.83,-246.12 526.83,-282.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-267.17" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">upstream service</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-253.67" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(mock: canned responses)</text>
|
||||
</g>
|
||||
<!-- api->svc_a -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>api->svc_a</title>
|
||||
<path fill="none" stroke="#4a5568" d="M149.07,-174.56C167.54,-182.07 189.23,-190.7 209,-198.12 258.25,-216.6 270.12,-222.85 320.75,-237.12 331.43,-240.13 342.71,-243 353.94,-245.67"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="353.12,-249.07 363.66,-247.92 354.71,-242.25 353.12,-249.07"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="255.88" y="-234.24" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">HTTP</text>
|
||||
</g>
|
||||
<!-- db -->
|
||||
<g id="node3" class="node">
|
||||
<title>db</title>
|
||||
<path fill="#121829" stroke="#1e2a4a" d="M480.7,-223.81C480.7,-226.22 465.18,-228.18 446.08,-228.18 426.97,-228.18 411.45,-226.22 411.45,-223.81 411.45,-223.81 411.45,-184.43 411.45,-184.43 411.45,-182.02 426.97,-180.06 446.08,-180.06 465.18,-180.06 480.7,-182.02 480.7,-184.43 480.7,-184.43 480.7,-223.81 480.7,-223.81"/>
|
||||
<path fill="none" stroke="#1e2a4a" d="M480.7,-223.81C480.7,-221.39 465.18,-219.43 446.08,-219.43 426.97,-219.43 411.45,-221.39 411.45,-223.81"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-207.17" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">datastore</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-193.67" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(mock)</text>
|
||||
</g>
|
||||
<!-- api->db -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>api->db</title>
|
||||
<path fill="none" stroke="#4a5568" d="M191.32,-168.36C257.83,-177.73 346.91,-190.28 399.91,-197.75"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="399.4,-201.22 409.79,-199.15 400.38,-194.29 399.4,-201.22"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="255.88" y="-185.69" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">query</text>
|
||||
</g>
|
||||
<!-- batch -->
|
||||
<g id="node4" class="node">
|
||||
<title>batch</title>
|
||||
<polygon fill="#121829" stroke="#1e2a4a" points="537.33,-128.12 354.83,-128.12 354.83,-92.12 537.33,-92.12 537.33,-128.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-113.17" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">batch drop</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-99.67" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#e8eaf0">(mock: writes files on a timer)</text>
|
||||
</g>
|
||||
<!-- api->batch -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>api->batch</title>
|
||||
<path fill="none" stroke="#4a5568" stroke-dasharray="5,2" d="M191.32,-144.39C237.67,-138.13 294.98,-130.39 343.4,-123.85"/>
|
||||
<polygon fill="#4a5568" stroke="#4a5568" points="343.61,-127.36 353.05,-122.55 342.67,-120.42 343.61,-127.36"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="255.88" y="-143.94" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">file handoff</text>
|
||||
</g>
|
||||
<!-- remote -->
|
||||
<g id="node5" class="node">
|
||||
<title>remote</title>
|
||||
<polygon fill="#3a1a1a" stroke="#1e2a4a" points="571.41,-21.74 571.41,-52.5 497.99,-74.24 394.17,-74.24 320.75,-52.5 320.75,-21.74 394.17,0 497.99,0 571.41,-21.74"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-46.92" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">external system</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-33.42" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">(remote: ExternalName,</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="446.08" y="-19.92" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#ffc107">reachable only from a VDI)</text>
|
||||
</g>
|
||||
<!-- api->remote -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>api->remote</title>
|
||||
<path fill="none" stroke="#ffc107" stroke-dasharray="5,2" d="M149.55,-137.68C167.9,-130.34 189.37,-121.97 209,-114.87 254.45,-98.43 305.32,-81.49 348.17,-67.64"/>
|
||||
<polygon fill="#ffc107" stroke="#ffc107" points="349,-71.05 357.44,-64.65 346.85,-64.39 349,-71.05"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="255.88" y="-117.57" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#8892a8">only when reachable</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.9 KiB |
588
rig/docs/index.html
Normal file
588
rig/docs/index.html
Normal file
@@ -0,0 +1,588 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>rig — local environment installer</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
background: #0a0e17;
|
||||
color: #e8eaf0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
line-height: 1.6;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
header {
|
||||
padding: 16px 24px;
|
||||
border-bottom: 1px solid #1e2a4a;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 3px;
|
||||
color: #0066ff;
|
||||
}
|
||||
|
||||
header .subtitle {
|
||||
font-size: 13px;
|
||||
color: #4a5568;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.layout { display: flex; flex: 1; min-height: 0; }
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 200px;
|
||||
flex-shrink: 0;
|
||||
background: #121829;
|
||||
border-right: 1px solid #1e2a4a;
|
||||
padding: 8px 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
nav a {
|
||||
padding: 10px 20px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: #8892a8;
|
||||
text-decoration: none;
|
||||
border-left: 2px solid transparent;
|
||||
transition: all 0.15s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
nav a:hover { color: #e8eaf0; background: #1a2340; }
|
||||
nav a.active { color: #0066ff; border-left-color: #0066ff; background: #0d1a33; }
|
||||
|
||||
main { flex: 1; overflow: auto; padding: 32px 48px; }
|
||||
|
||||
.section { display: none; animation: fadeIn 0.2s ease; }
|
||||
.section.active { display: block; }
|
||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||
|
||||
.section h2 {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #8892a8;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.section > p.lede {
|
||||
font-size: 13px;
|
||||
color: #4a5568;
|
||||
margin-bottom: 24px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.prose { max-width: 820px; }
|
||||
.prose p { font-size: 14px; color: #b4bccf; line-height: 1.7; margin-bottom: 14px; }
|
||||
.prose p b { color: #e8eaf0; }
|
||||
.prose ul { margin: 0 0 16px 20px; }
|
||||
.prose li { font-size: 14px; color: #b4bccf; margin-bottom: 6px; }
|
||||
|
||||
.prose h3 {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
color: #e8eaf0;
|
||||
margin: 32px 0 10px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.prose code, pre code {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: #7ab0ff;
|
||||
background: #121829;
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #121829;
|
||||
border: 1px solid #1e2a4a;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
pre code { background: none; padding: 0; }
|
||||
pre .c { color: #4a5568; }
|
||||
pre .k { color: #0066ff; }
|
||||
|
||||
.graph-container { margin: 16px 0; }
|
||||
.graph-container img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
background: #0a0e17;
|
||||
border: 1px solid #1e2a4a;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: 10px 24px;
|
||||
margin: 16px 0;
|
||||
max-width: 820px;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
color: #0066ff;
|
||||
font-size: 13px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
dd { font-size: 14px; color: #b4bccf; line-height: 1.6; }
|
||||
|
||||
table { border-collapse: collapse; margin: 16px 0; max-width: 820px; }
|
||||
th, td {
|
||||
text-align: left;
|
||||
padding: 7px 16px 7px 0;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #1e2a4a;
|
||||
color: #b4bccf;
|
||||
}
|
||||
th {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
color: #8892a8;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
td code { white-space: nowrap; }
|
||||
|
||||
.note {
|
||||
border-left: 2px solid #ffc107;
|
||||
background: #17130a;
|
||||
padding: 12px 16px;
|
||||
margin: 16px 0;
|
||||
max-width: 820px;
|
||||
}
|
||||
.note p { margin: 0; font-size: 13px; color: #b4bccf; }
|
||||
.note b { color: #ffc107; }
|
||||
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
background: transparent;
|
||||
border: 1px solid #1e2a4a;
|
||||
color: #8892a8;
|
||||
padding: 6px 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
line-height: 1;
|
||||
margin-left: auto;
|
||||
}
|
||||
.menu-toggle:hover { background: #1a2340; }
|
||||
|
||||
.nav-backdrop {
|
||||
display: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 10;
|
||||
}
|
||||
.layout.nav-open .nav-backdrop { display: block; }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
header { padding: 10px 12px; gap: 8px; }
|
||||
header h1 { font-size: 16px; letter-spacing: 1px; }
|
||||
header .subtitle { display: none; }
|
||||
.menu-toggle { display: inline-block; }
|
||||
.layout { position: relative; }
|
||||
nav {
|
||||
position: absolute; left: 0; top: 0; bottom: 0;
|
||||
width: 200px; z-index: 20;
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.2s ease;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.layout.nav-open nav { transform: translateX(0); }
|
||||
main { padding: 16px; }
|
||||
.section h2 { font-size: 13px; }
|
||||
.prose p, .prose li { font-size: 13px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>RIG</h1>
|
||||
<span class="subtitle">local environment installer</span>
|
||||
<button class="menu-toggle">☰</button>
|
||||
</header>
|
||||
|
||||
<div class="layout">
|
||||
<div class="nav-backdrop"></div>
|
||||
<nav>
|
||||
<a href="#start">Start here</a>
|
||||
<a href="#steps">The steps</a>
|
||||
<a href="#install">Installation</a>
|
||||
<a href="#environments">Environments</a>
|
||||
<a href="#profiles">Profiles</a>
|
||||
<a href="#registry">Registry</a>
|
||||
<a href="#architecture">Architecture</a>
|
||||
<a href="#troubleshooting">Troubleshooting</a>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
|
||||
<section class="section" id="start">
|
||||
<h2>Start here</h2>
|
||||
<p class="lede">A runnable local model of a large, regulated estate — legacy and new side by side.</p>
|
||||
<div class="prose">
|
||||
<p>rig builds a disposable Kubernetes environment on your machine so you can
|
||||
explore how a system fits together without needing access to any of it. Its
|
||||
job is <b>onboarding and exploration</b>, not a production replica.</p>
|
||||
|
||||
<p>Most services in it are deliberately <b>not real</b>. What has to be faithful
|
||||
is the topology — the names, the ports, the dependency order, who can reach whom,
|
||||
and how it fails. The workloads themselves are noise. This is what makes the
|
||||
whole estate fit on a laptop: a real 20-service platform will not fit even once
|
||||
on 14 GB, but mocks are about 30 MB each, so three faithful copies do.</p>
|
||||
|
||||
<h3>The only prerequisite</h3>
|
||||
<p><b>Docker.</b> No curl, no jq, no python, no apt repositories to configure.</p>
|
||||
<pre><code><span class="c"># then, in the environment directory:</span>
|
||||
make station <span class="c"># is this workstation ready? reports, never fixes</span>
|
||||
make deps <span class="c"># install the pinned toolchain</span>
|
||||
make cluster up <span class="c"># build the cluster for the active profile</span>
|
||||
</code></pre>
|
||||
<p>Read <code>make station</code> before <code>make deps</code>. It never changes
|
||||
anything — it prints what it found and, at the end, the steps it cannot perform
|
||||
for you.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="steps">
|
||||
<h2>The steps</h2>
|
||||
<p class="lede">Start to finish, in order, with what each one actually does.</p>
|
||||
<div class="prose">
|
||||
|
||||
<h3>1 · make station</h3>
|
||||
<p>Asks whether this workstation is ready. It <b>changes nothing</b> — it
|
||||
reports what it found and, at the end, the things only a human can do
|
||||
(anything needing <code>sudo</code>, or a Windows-side restart). Read it
|
||||
before installing anything; it is faster than discovering the same problems
|
||||
one failure at a time.</p>
|
||||
<pre><code>make station</code></pre>
|
||||
|
||||
<h3>2 · make setup</h3>
|
||||
<p>Does the preparation that can be automated: installs the pinned
|
||||
toolchain if it is missing, checks PATH, Docker, and this environment's
|
||||
ports. Every step is independently checked, so running it twice is safe and
|
||||
running it half-configured finishes the job.</p>
|
||||
<p>It <b>does not stop at the first failure</b>. A setup script that dies at
|
||||
step two hides that steps four and five would also have failed, and on an
|
||||
unfamiliar machine the complete list is the point. The tail of the output is
|
||||
a to-do list of only what is outstanding.</p>
|
||||
<pre><code>make setup <span class="c"># host + toolchain</span>
|
||||
make setup --share-docker <span class="c"># ...and offer this machine's Docker to other distros</span>
|
||||
</code></pre>
|
||||
|
||||
<h3>3 · make cluster up</h3>
|
||||
<p>Builds the cluster for the active profile. It prints what the profile
|
||||
locks in <i>before</i> spending the time, because the CNI and the audit
|
||||
policy are fixed at creation and cannot be changed afterwards.</p>
|
||||
<p>Re-running is safe and, more importantly, <b>convergent</b>: if a first
|
||||
attempt was interrupted before the CNI was installed, running it again
|
||||
finishes the job rather than reporting "already exists" and leaving every
|
||||
node permanently NotReady.</p>
|
||||
<pre><code>make cluster up <span class="c"># default profile</span>
|
||||
make cluster up PROFILE=client <span class="c"># three nodes, audit on, cached registry</span>
|
||||
make cluster reset <span class="c"># destroy and rebuild — the only way to change CNI or audit</span>
|
||||
</code></pre>
|
||||
|
||||
<h3>4 · make docs</h3>
|
||||
<p>Serves this page from a throwaway container. Works with no cluster and
|
||||
no toolchain, which is deliberate: these pages are the instructions for
|
||||
building everything else, so they cannot depend on it.</p>
|
||||
<pre><code>make docs</code></pre>
|
||||
|
||||
<h3>Checking on things</h3>
|
||||
<dl>
|
||||
<dt>make cluster list</dt><dd>Every cluster on the machine, its memory cost and its port block. The usual reason a new one will not start is an old one you forgot about; <code>make cluster free</code> frees them without deleting.</dd>
|
||||
<dt>make ports</dt><dd>This environment's port block, and whether each is derived or overridden.</dd>
|
||||
<dt>make registry</dt><dd>Which of the four registry modes is active, and where it points.</dd>
|
||||
<dt>make dockerhost</dt><dd>Which WSL distro owns Docker and what this one is using.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Running more than one</h3>
|
||||
<p>Copy the directory, rename it, and repeat from step 2. Cluster name,
|
||||
context, image tags and the port block all follow the directory name, so
|
||||
the second environment collides with nothing and neither one's teardown can
|
||||
reach the other.</p>
|
||||
<pre><code>cp -r rig ../platform-v2 && cd ../platform-v2
|
||||
make setup && make cluster up
|
||||
</code></pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="install">
|
||||
<h2>Installation</h2>
|
||||
<p class="lede">A container installs onto the host and then gets out of the way.</p>
|
||||
<div class="graph-container">
|
||||
<a href="viewer.html?src=graphs/01-install.svg"><img src="graphs/01-install.svg" alt="Installation flow"></a>
|
||||
</div>
|
||||
<div class="prose">
|
||||
<p>The installer is a container, not a shell script, for a specific reason: a
|
||||
stock slim Debian has no <code>curl</code>, no <code>wget</code>, no
|
||||
<code>jq</code>, no <code>python3</code> and <b>no CA bundle</b>. A shell
|
||||
installer could not make a verified HTTPS request, let alone check one. The
|
||||
container carries its own toolchain, so the host needs nothing but Docker.</p>
|
||||
|
||||
<p>The cluster never runs inside that container. Everything it installs —
|
||||
kind, kubectl, tilt, jq — runs natively afterwards, so nothing pays a
|
||||
container tax during daily work.</p>
|
||||
|
||||
<h3>Pinned and verified</h3>
|
||||
<p>Every tool is a single binary fetched at a pinned version and checked
|
||||
against a published SHA256. Node images are pinned <b>by digest</b>, so
|
||||
upgrading kind cannot silently move your Kubernetes version.</p>
|
||||
|
||||
<h3>Not every machine should get cluster tooling</h3>
|
||||
<p>A managed or corporate-issued machine — the kind that holds the access
|
||||
you cannot get anywhere else — is not somewhere to install development
|
||||
tools by default. So the toolchain comes in two tiers:</p>
|
||||
<table>
|
||||
<tr><th>tier</th><th>installs</th><th>for</th></tr>
|
||||
<tr><td><code>core</code></td><td>kubectl, jq</td><td>talk to a cluster someone else runs</td></tr>
|
||||
<tr><td><code>dev</code></td><td>+ kind, tilt</td><td>build clusters and hot-reload into them</td></tr>
|
||||
</table>
|
||||
<pre><code>make deps core <span class="c"># kubectl and jq only — nothing that creates a cluster</span>
|
||||
make deps <span class="c"># dev, the default</span>
|
||||
make setup core <span class="c"># same distinction, via setup</span>
|
||||
</code></pre>
|
||||
<p>Testing <i>in situ</i> on a managed machine is still possible — install
|
||||
the <code>dev</code> tier deliberately when you need it. The point is that
|
||||
it should be a decision rather than a side effect of running setup.</p>
|
||||
<p>The documentation itself needs neither tier: <code>make docs</code>
|
||||
wants only Docker.</p>
|
||||
|
||||
<h3>Air-gapped</h3>
|
||||
<pre><code>make wizard full <span class="c"># bakes every binary into the image</span>
|
||||
docker save …-wizard:full | gzip > rig.tgz
|
||||
<span class="c"># carry that one file in, then:</span>
|
||||
docker load < rig.tgz && make cluster up PROFILE=offline
|
||||
</code></pre>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="environments">
|
||||
<h2>Environments</h2>
|
||||
<p class="lede">One directory is one environment. Copy it, rename it, run it.</p>
|
||||
<div class="graph-container">
|
||||
<a href="viewer.html?src=graphs/02-environment.svg"><img src="graphs/02-environment.svg" alt="Environment derivation"></a>
|
||||
</div>
|
||||
<div class="prose">
|
||||
<p>Running several versions of a system at once means several clusters on one
|
||||
machine, not several machines. Everything that could collide is derived from
|
||||
the directory name:</p>
|
||||
<dl>
|
||||
<dt>cluster + context</dt><dd><code>acmebank/</code> builds <code>acmebank</code> on <code>kind-acmebank</code>.</dd>
|
||||
<dt>port block</dt><dd>Ten ports from a hash of the name, in the 20000+ range — clear of 80, 443, 3000, 5432, 8000 and 8080.</dd>
|
||||
<dt>registry + images</dt><dd>Named after the environment, so two copies never share one.</dd>
|
||||
</dl>
|
||||
<p>Two copies therefore never collide, and neither one's
|
||||
<code>make cluster down</code> can touch the other. <code>make ports</code>
|
||||
shows the block; <code>make ports persist</code> freezes it into
|
||||
<code>ctrl/.env</code> if you want it fixed rather than derived.</p>
|
||||
|
||||
<h3>Configuration layers</h3>
|
||||
<p>Weakest first, later wins: pinned versions → the profile →
|
||||
<code>ctrl/.env</code> → the environment. So
|
||||
<code>make cluster up PROFILE=client</code> always beats every file.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="profiles">
|
||||
<h2>Profiles</h2>
|
||||
<p class="lede">Cluster shape is declared, not baked in.</p>
|
||||
<div class="prose">
|
||||
<table>
|
||||
<tr><th>profile</th><th>nodes</th><th>audit</th><th>registry</th><th>for</th></tr>
|
||||
<tr><td><code>minimal</code></td><td>1</td><td>off</td><td>none</td><td>first boot; assumes nothing</td></tr>
|
||||
<tr><td><code>client</code></td><td>3</td><td>on</td><td>mirror</td><td>the regulated shape</td></tr>
|
||||
<tr><td><code>offline</code></td><td>1</td><td>on</td><td>local</td><td>air-gapped</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="note"><p><b>The audit policy cannot be changed later.</b> It is an
|
||||
apiserver flag, fixed when the cluster is created. <code>cluster up</code>
|
||||
prints what a profile locks in before spending the time, and
|
||||
<code>make cluster reset</code> is the way out.</p></div>
|
||||
|
||||
<h3>LoadBalancer services</h3>
|
||||
<p>Real manifests use <code>type: LoadBalancer</code>, because a real
|
||||
cluster has one. On a bare local cluster those Services sit at
|
||||
<code>EXTERNAL-IP <pending></code> forever, with no error anywhere —
|
||||
the deployment looks healthy and simply is not reachable.</p>
|
||||
<p>The <code>metallb</code> addon fixes that, so the same manifests work
|
||||
here as upstream and nothing has to be rewritten to NodePort. Its address
|
||||
pool is derived from the cluster's Docker network at install time rather
|
||||
than hardcoded, because Docker picks that subnet and it differs between
|
||||
machines.</p>
|
||||
<div class="note"><p><b>Where those addresses are reachable from.</b> The
|
||||
pool lives on the Docker bridge, so LoadBalancer IPs work from the Linux
|
||||
side — including from inside WSL. A browser on Windows has no route to
|
||||
them. Use the ingress host ports for anything you need to open in a
|
||||
browser.</p></div>
|
||||
|
||||
<h3>Networking</h3>
|
||||
<p>The cluster uses kind's built-in networking, which <b>does</b> enforce
|
||||
standard NetworkPolicy — verified against a no-policy control, not assumed.
|
||||
The widely repeated claim that it accepts policies and silently ignores
|
||||
them is out of date.</p>
|
||||
<p>A pluggable CNI was tried and removed: it only added
|
||||
GlobalNetworkPolicy, policy tiers and egress-CIDR rules, none of which are
|
||||
needed yet, in exchange for a slower boot and one more thing that has to be
|
||||
right at creation time. Worth revisiting only when a policy the built-in
|
||||
cannot express actually comes up.</p>
|
||||
|
||||
<h3>Memory</h3>
|
||||
<p>Every cluster is a running container tree whether you are using it or not.
|
||||
<code>make cluster list</code> shows what exists and what it costs;
|
||||
<code>make cluster free</code> stops the others without deleting them.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="registry">
|
||||
<h2>Registry</h2>
|
||||
<p class="lede">Local, cached, or straight to the corporate registry.</p>
|
||||
<div class="prose">
|
||||
<table>
|
||||
<tr><th>mode</th><th>what it does</th></tr>
|
||||
<tr><td><code>none</code></td><td>images are built straight into the node</td></tr>
|
||||
<tr><td><code>local</code></td><td>a registry container wired into the cluster</td></tr>
|
||||
<tr><td><code>mirror</code></td><td>that container as a <b>pull-through cache</b> of the corporate registry</td></tr>
|
||||
<tr><td><code>remote</code></td><td>no local container; pull direct with an imagePullSecret</td></tr>
|
||||
</table>
|
||||
<p><code>mirror</code> is what a locked-down network actually looks like:
|
||||
images originate from the corporate registry, you do not hammer it, and you
|
||||
keep working when the connection drops.</p>
|
||||
|
||||
<div class="note"><p><b>The corporate CA will bite you.</b> A corporate
|
||||
registry is usually behind an internal CA, and trust has to reach
|
||||
<b>three</b> places: the host Docker daemon, every cluster node's containerd
|
||||
(nodes do <i>not</i> inherit host trust), and any in-cluster client. Set
|
||||
<code>REGISTRY_CA_FILE</code> and <code>make station</code> reports which is
|
||||
still missing. The symptom otherwise is an opaque
|
||||
<code>x509: certificate signed by unknown authority</code>.</p></div>
|
||||
|
||||
<p>Reachability also depends on where you are: if the registry is only
|
||||
routable from a managed workspace, <code>mirror</code> and <code>remote</code>
|
||||
will not resolve from a laptop at all. That is what <code>local</code> and
|
||||
<code>offline</code> are for.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="architecture">
|
||||
<h2>Architecture</h2>
|
||||
<p class="lede">The estate being modelled.</p>
|
||||
<div class="note"><p><b>TODO — placeholder.</b> The diagram below is
|
||||
illustrative only: it shows how a mocked dependency, a service under active
|
||||
work, and an unreachable remote system sit together. It is not the real
|
||||
topology. Replace <code>docs/graphs/03-architecture.dot</code> with the
|
||||
extracted platform diagrams, then run <code>make docs graphs</code>.</p></div>
|
||||
<div class="graph-container">
|
||||
<a href="viewer.html?src=graphs/03-architecture.svg"><img src="graphs/03-architecture.svg" alt="Estate topology (placeholder)"></a>
|
||||
</div>
|
||||
<div class="prose">
|
||||
<p>Each component is one of three things, and switching between them should be
|
||||
a one-line change rather than a rewrite:</p>
|
||||
<dl>
|
||||
<dt>real</dt><dd>Built from source and hot-reloaded. The thing you are actually working on — usually exactly one.</dd>
|
||||
<dt>mock</dt><dd>A generic stub with canned responses. Everything you do not care about today.</dd>
|
||||
<dt>remote</dt><dd>No pod at all: a Service of type ExternalName pointing at the real system. In-cluster DNS resolves identically, so callers never change.</dd>
|
||||
</dl>
|
||||
<p>The intended end state is that this diagram is <b>generated from the
|
||||
running cluster</b> rather than drawn by hand — so it becomes a report of
|
||||
what exists instead of a picture of what was once intended.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="troubleshooting">
|
||||
<h2>Troubleshooting</h2>
|
||||
<p class="lede">The failures that are hard to diagnose from their symptoms.</p>
|
||||
<div class="prose">
|
||||
<h3>Tilt stops noticing file changes</h3>
|
||||
<p>Almost always <code>inotify</code> limits, and it fails <i>silently</i> —
|
||||
nothing errors, changes just stop being picked up. Defaults on WSL are far too
|
||||
low. <code>make station</code> reports it and prints the fix.</p>
|
||||
|
||||
<h3>Cluster creation dies halfway with a port error</h3>
|
||||
<p>Docker reports <code>failed to bind host port … address already in use</code>
|
||||
partway through creating the cluster. Run <code>make station</code> first — it
|
||||
checks every port in this environment's block before anything is built.</p>
|
||||
|
||||
<h3>Every node stays NotReady</h3>
|
||||
<p>Usually a cluster created with the default CNI disabled but the real CNI
|
||||
never installed — typically an interrupted first run. Just run
|
||||
<code>make cluster up</code> again: it converges rather than exiting early, and
|
||||
will finish the missing steps.</p>
|
||||
|
||||
<h3>x509: certificate signed by unknown authority</h3>
|
||||
<p>Corporate CA trust has not reached one of the three places it needs to be.
|
||||
See <a href="#registry">Registry</a>.</p>
|
||||
|
||||
<h3>kubectl says the context does not exist</h3>
|
||||
<p>The cluster can exist while its context does not — a reset or a switched
|
||||
<code>KUBECONFIG</code> loses it. <code>make cluster up</code> detects this and
|
||||
re-exports the context.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var layout = document.querySelector('.layout');
|
||||
var main = document.querySelector('main');
|
||||
|
||||
function syncActive() {
|
||||
var hash = location.hash.slice(1) || 'start';
|
||||
document.querySelectorAll('.section').forEach(function (s) { s.classList.remove('active'); });
|
||||
document.querySelectorAll('nav a').forEach(function (a) { a.classList.remove('active'); });
|
||||
var section = document.getElementById(hash);
|
||||
if (section) section.classList.add('active');
|
||||
var link = document.querySelector('nav a[href="#' + hash + '"]');
|
||||
if (link) link.classList.add('active');
|
||||
if (main) main.scrollTop = 0;
|
||||
layout.classList.remove('nav-open');
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', syncActive);
|
||||
window.addEventListener('DOMContentLoaded', syncActive);
|
||||
syncActive();
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
if (e.target.closest('.menu-toggle') || e.target.closest('.nav-backdrop')) {
|
||||
layout.classList.toggle('nav-open');
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
101
rig/docs/viewer.html
Normal file
101
rig/docs/viewer.html
Normal file
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Graph Viewer</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; }
|
||||
body {
|
||||
background: #0a0e17;
|
||||
overflow: hidden;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
#container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
cursor: grab;
|
||||
}
|
||||
#container.dragging { cursor: grabbing; }
|
||||
img {
|
||||
transform-origin: 0 0;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<img id="img" />
|
||||
</div>
|
||||
<script>
|
||||
var src = new URLSearchParams(location.search).get('src');
|
||||
var img = document.getElementById('img');
|
||||
var container = document.getElementById('container');
|
||||
|
||||
img.src = src;
|
||||
|
||||
var scale = 1;
|
||||
var x = 0, y = 0;
|
||||
var dragging = false;
|
||||
var startX, startY, startPanX, startPanY;
|
||||
|
||||
function apply() {
|
||||
img.style.transform = 'translate(' + x + 'px,' + y + 'px) scale(' + scale + ')';
|
||||
}
|
||||
|
||||
// Fit to screen on load
|
||||
img.onload = function() {
|
||||
var sw = window.innerWidth / img.naturalWidth;
|
||||
var sh = window.innerHeight / img.naturalHeight;
|
||||
scale = Math.min(sw, sh) * 0.95;
|
||||
x = (window.innerWidth - img.naturalWidth * scale) / 2;
|
||||
y = (window.innerHeight - img.naturalHeight * scale) / 2;
|
||||
apply();
|
||||
};
|
||||
|
||||
// Wheel zoom toward cursor
|
||||
container.addEventListener('wheel', function(e) {
|
||||
e.preventDefault();
|
||||
var factor = e.deltaY < 0 ? 1.12 : 0.89;
|
||||
var rect = container.getBoundingClientRect();
|
||||
var mx = e.clientX - rect.left;
|
||||
var my = e.clientY - rect.top;
|
||||
x = mx - (mx - x) * factor;
|
||||
y = my - (my - y) * factor;
|
||||
scale *= factor;
|
||||
apply();
|
||||
}, { passive: false });
|
||||
|
||||
// Pan
|
||||
container.addEventListener('mousedown', function(e) {
|
||||
if (e.button !== 0) return;
|
||||
dragging = true;
|
||||
startX = e.clientX;
|
||||
startY = e.clientY;
|
||||
startPanX = x;
|
||||
startPanY = y;
|
||||
container.classList.add('dragging');
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.addEventListener('mousemove', function(e) {
|
||||
if (!dragging) return;
|
||||
x = startPanX + (e.clientX - startX);
|
||||
y = startPanY + (e.clientY - startY);
|
||||
apply();
|
||||
});
|
||||
|
||||
window.addEventListener('mouseup', function() {
|
||||
dragging = false;
|
||||
container.classList.remove('dragging');
|
||||
});
|
||||
|
||||
// Double-click to reset
|
||||
container.addEventListener('dblclick', function() {
|
||||
img.onload();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user