Skip to content

Commit ac93563

Browse files
daniel-nolandmvachharclaude
committed
feat(vlab): add vlab development scripts
Add scripts for running a local virtual lab (vlab) development environment. The vlab provides an isolated environment for testing dataplane images against a simulated Hedgehog fabric without requiring physical hardware. Components: - Dockerfile: development container based on Ubuntu with QEMU, docker, and OCI tooling (zot registry, oras, skopeo) - run.sh: orchestrates vlab lifecycle -- builds the container, generates TLS certificates for the local zot registry, and starts the environment - control.sh: provides SSH access into the running vlab VM for interactive debugging (defaults to launching k9s) - zot config: local OCI registry configuration with TLS for serving container images to the vlab VMs Co-Authored-By: Manish Vachharajani <manish@githedgehog.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cf96f1e commit ac93563

5 files changed

Lines changed: 237 additions & 0 deletions

File tree

scripts/vlab/Dockerfile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
ARG BASE_IMAGE=ubuntu:25.10
2+
FROM $BASE_IMAGE
3+
4+
SHELL ["/bin/bash", "-euo", "pipefail", "-c"]
5+
6+
RUN \
7+
apt update; \
8+
apt upgrade --yes; \
9+
:;
10+
11+
RUN \
12+
apt update; \
13+
apt upgrade --yes; \
14+
apt install --yes --no-install-recommends \
15+
ca-certificates \
16+
curl \
17+
docker.io \
18+
git \
19+
iproute2 \
20+
jq \
21+
less \
22+
neovim \
23+
openssh-client \
24+
openssl \
25+
qemu-kvm \
26+
qemu-utils `#for qemu-img` \
27+
socat \
28+
sudo \
29+
wget \
30+
yq \
31+
; \
32+
:;
33+
34+
RUN \
35+
mkdir /vlab; \
36+
:;
37+
38+
WORKDIR /vlab
39+
VOLUME ["/vlab"]
40+
41+
RUN \
42+
wget -O /usr/bin/zot 'https://github.com/project-zot/zot/releases/download/v2.1.15/zot-linux-amd64'; \
43+
chmod +x /usr/bin/zot; \
44+
chown root:root /usr/bin/zot; \
45+
:;
46+
47+
RUN \
48+
curl -fsSL 'https://i.hhdev.io/oras' | bash; \
49+
:;

scripts/vlab/control.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: Apache-2.0
3+
# Copyright Open Network Fabric Authors
4+
5+
if [ -z "$*" ]; then
6+
declare -r cmd="k9s --namespace fab --command pod"
7+
else
8+
declare -r cmd="$*"
9+
fi
10+
11+
docker exec -it vlab \
12+
ssh \
13+
-o StrictHostKeyChecking=no \
14+
-o UserKnownHostsFile=/dev/null \
15+
-t \
16+
-p 22000 \
17+
-i /vlab/vlab/sshkey \
18+
core@localhost "export PATH=\"/usr/bin:/bin:/opt/bin\"; $cmd"

scripts/vlab/root/etc/zot/cert.ini

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[req]
2+
default_bits = 4096
3+
prompt = no
4+
default_md = sha256
5+
distinguished_name = dn
6+
req_extensions = req_ext
7+
8+
[dn]
9+
C = US
10+
ST = CO
11+
L = Longmont
12+
O = Hedgehog
13+
OU = Dev
14+
CN = zot.loc
15+
16+
[req_ext]
17+
subjectAltName = IP:192.168.19.1
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"log": {
3+
"level": "debug"
4+
},
5+
"storage": {
6+
"rootDirectory": "/zot"
7+
},
8+
"http": {
9+
"address": "0.0.0.0",
10+
"port": "30000",
11+
"realm": "zot",
12+
"tls": {
13+
"cert": "/etc/zot/zot.crt",
14+
"key": "/etc/zot/zot.key"
15+
}
16+
},
17+
"extensions": {
18+
"sync": {
19+
"enable": true,
20+
"credentialsFile": "/etc/zot/creds.json",
21+
"registries": [
22+
{
23+
"urls": ["https://ghcr.io"],
24+
"onDemand": true,
25+
"tlsVerify": true,
26+
"content": [
27+
{
28+
"prefix": "/githedgehog/**",
29+
"destination": "/githedgehog",
30+
"stripPrefix": true
31+
}
32+
]
33+
}
34+
]
35+
}
36+
}
37+
}

scripts/vlab/run.sh

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: Apache-2.0
3+
# Copyright Open Network Fabric Authors
4+
5+
set -euxo pipefail
6+
7+
# Config params
8+
9+
declare -ri RSA_BIT_LENGTH="${RSA_BIT_LENGTH:-4096}"
10+
declare -ri CERT_DAYS="${CERT_DAYS:-30}"
11+
12+
# end config
13+
14+
declare SOURCE_DIR
15+
SOURCE_DIR="$(dirname "${BASH_SOURCE}")"
16+
declare -r SOURCE_DIR
17+
18+
declare -r CERTS_DIR="${SOURCE_DIR}/root/etc/zot"
19+
20+
mkdir -p "${CERTS_DIR}"
21+
22+
pushd "${SOURCE_DIR}"
23+
24+
chmod go=rw "${SOURCE_DIR}/root//etc/zot/"{*.key,*.crt,*.csr}
25+
26+
openssl genrsa \
27+
-out "${CERTS_DIR}/ca.key" \
28+
"${RSA_BIT_LENGTH}"
29+
30+
chmod u=rw,go= "${CERTS_DIR}/ca.key"
31+
32+
openssl req \
33+
-x509 \
34+
-new \
35+
-nodes \
36+
-sha256 \
37+
-days "${CERT_DAYS}" \
38+
-key "${CERTS_DIR}/ca.key" \
39+
-subj "/CN=loc" \
40+
-out "${CERTS_DIR}/ca.crt"
41+
42+
openssl req \
43+
-new \
44+
-nodes \
45+
-sha256 \
46+
-newkey "rsa:${RSA_BIT_LENGTH}" \
47+
-keyout "${CERTS_DIR}/zot.key" \
48+
-out "${CERTS_DIR}/zot.csr" \
49+
-config "${CERTS_DIR}/cert.ini"
50+
51+
openssl x509 \
52+
-req \
53+
-in "${CERTS_DIR}/zot.csr" \
54+
-CA "${CERTS_DIR}/ca.crt" \
55+
-CAkey "${CERTS_DIR}/ca.key" \
56+
-CAcreateserial \
57+
-subj "/C=CN/ST=GD/L=SZ/O=githedgehog/CN=zot.loc" \
58+
-extfile <(printf "subjectAltName=DNS:zot,DNS:zot.loc,IP:192.168.19.1") \
59+
-out "${CERTS_DIR}/zot.crt" \
60+
-days "${CERT_DAYS}" \
61+
-sha256
62+
63+
64+
docker stop vlab || true
65+
docker network rm zot || true
66+
docker rm vlab || true
67+
68+
docker network create --attachable --driver bridge --ipv4 --ip-range 192.168.19.0/31 --subnet 192.168.19.0/31 zot
69+
70+
declare -r base="${1:-"ubuntu:25.10"}"
71+
72+
docker pull "${base}"
73+
74+
docker build \
75+
--build-arg BASE_IMAGE="${base}" \
76+
--tag vlab \
77+
"${SOURCE_DIR}"
78+
79+
docker run \
80+
--network zot \
81+
--privileged \
82+
--mount type=bind,source="${CERTS_DIR}",target=/etc/zot/,readonly \
83+
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
84+
--mount type=volume,source=vlab,target=/vlab \
85+
--mount type=volume,source=zot,target=/zot \
86+
--env DOCKER_HOST="unix:///var/run/docker.sock" \
87+
--volume ~/.docker:/root/.docker:ro \
88+
--name vlab \
89+
--add-host zot:192.168.19.1 \
90+
--add-host zot.loc:192.168.19.1 \
91+
--rm \
92+
--interactive \
93+
--tty \
94+
--detach \
95+
vlab \
96+
zot serve /etc/zot/config.json
97+
98+
### part 2 (in container)
99+
100+
docker exec vlab cp /etc/zot/ca.crt /usr/local/share/ca-certificates/
101+
docker exec vlab update-ca-certificates
102+
docker exec vlab /bin/bash -c "curl -fsSL 'https://i.hhdev.io/hhfab' | USE_SUDO=false INSTALL_DIR=. VERSION=master bash;"
103+
docker exec vlab /vlab/hhfab init --dev --registry-repo 192.168.19.1:30000 --gateway --import-host-upstream --force
104+
docker exec vlab mv fab.yaml fab.orig.yaml
105+
docker exec vlab bash -euxo pipefail -c "
106+
yq . fab.orig.yaml \
107+
| jq --slurp '
108+
. as \$input |
109+
\$input |
110+
([\$input[0] | setpath([\"spec\", \"config\", \"registry\", \"upstream\", \"noTLSVerify\"]; true)] + \$input[1:])
111+
' \
112+
| yq -y '.[]' \
113+
| tee fab.yaml
114+
"
115+
docker exec vlab /vlab/hhfab vlab gen
116+
docker exec vlab /vlab/hhfab vlab up -v --controls-restricted=false -m=manual --recreate

0 commit comments

Comments
 (0)