Skip to content

Commit 0362d13

Browse files
canercidamfkondejclaude[bot]
authored
Add unified BuilderNet mkosi recipe (#366)
(Fixing merge issues and avoiding commit loss) --------- Co-authored-by: fryd <fryderyk@flashbots.net> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
1 parent 4a78a84 commit 0362d13

36 files changed

+1887
-219
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.flashbots-images/
2+
.runtime/
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# BuilderNet VM Scripts
2+
3+
Temporary bash scripts for running BuilderNet VM alongside builder-playground.
4+
Feel free to translate them to Go and integrate into the CLI.
5+
6+
## Information:
7+
8+
Changes are made in two repos:
9+
- [flashbots-images](https://github.com/flashbots/flashbots-images/tree/fryd/mkosi-playground) on `fryd/mkosi-playground` branch,
10+
- [builder-playground](https://github.com/flashbots/builder-playground/tree/fryd/mkosi-playground) on `fryd/mkosi-playground` branch,
11+
12+
There are no plans of using [buildernet-playground](https://github.com/flashbots/buildernet-playground) repo.
13+
14+
## Start playground
15+
16+
Start playground with: `--bind-external` (expose ports to the VM) and `--contender` (create transactions)
17+
18+
```bash
19+
builder-playground \
20+
start buildernet \
21+
--bind-external \
22+
--output ".playground-home" \
23+
--contender \
24+
--detached fryd-vm-builder
25+
```
26+
27+
## First Time Setup
28+
29+
```bash
30+
./sync.sh # Clone / fetch flashbots-images repo
31+
./build.sh # Build VM image with mkosi
32+
./prepare.sh # Extract image + create data disk
33+
```
34+
35+
`sync.sh` clones/updates the `fryd/mkosi-playground` branch of flashbots-images.
36+
37+
## Run VM
38+
39+
```bash
40+
./start.sh # Start VM (background)
41+
./console.sh # Open console to the VM
42+
./ssh.sh # SSH into running VM (requires SSH key setup)
43+
./stop.sh # Stop VM
44+
```
45+
46+
## Builder Hub
47+
48+
```bash
49+
./builderhub-configure.sh # Register VM with builder-hub and update config for the VM
50+
./builderhub-get-config.sh # Get configuration for the VM
51+
```
52+
53+
## Operator API
54+
55+
Scripts to interact with the operator-api service running inside the VM.
56+
57+
> **Note:** Actions and File Uploads could potentially be used for various things, like injecting genesis config instead of BuilderHub - still exploring this functionality.
58+
59+
```bash
60+
./operator-api-health.sh # Check if operator-api is healthy
61+
./operator-api-logs.sh # Get event logs
62+
./operator-api-action.sh <action> # Execute an action
63+
```
64+
65+
Available actions:
66+
- `reboot` - Reboot the system
67+
- `rbuilder_restart` - Restart rbuilder-operator service
68+
- `rbuilder_stop` - Stop rbuilder-operator service
69+
- `fetch_config` - Fetch config from BuilderHub
70+
- `rbuilder_bidding_restart` - Restart rbuilder-bidding service
71+
- `ssh_stop` - Stop SSH service
72+
- `ssh_start` - Start SSH service
73+
- `haproxy_restart` - Restart HAProxy service
74+
75+
### File Uploads
76+
77+
Upload files to predefined paths. Only whitelisted names from `[file_uploads]` config are allowed:
78+
79+
```toml
80+
[file_uploads]
81+
rbuilder_blocklist = "/var/lib/persistent/rbuilder-operator/rbuilder.blocklist.json"
82+
```
83+
84+
```bash
85+
# Stores local blocklist.json content to the configured remote path
86+
curl -k --data-binary "@blocklist.json" https://localhost:13535/api/v1/file-upload/rbuilder_blocklist
87+
```
88+
89+
### Customization
90+
91+
To add more actions or file uploads, modify the config template:
92+
https://github.com/flashbots/flashbots-images/blob/fryd/mkosi-playground/mkosi.profiles/playground/mkosi.extra/usr/lib/mustache-templates/etc/operator-api/config.toml.mustache
93+
94+
## Maintenance
95+
96+
```bash
97+
./sync.sh # Update flashbots-images to latest
98+
./clean.sh # Clean build artifacts + runtime files
99+
```
100+
101+
## Ports
102+
103+
| Port | Service |
104+
|------|---------|
105+
| 2222 | SSH (maps to VM:40192) |
106+
| 13535 | Operator API (maps to VM:3535) |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
# Build the BuilderNet VM image
3+
set -eu -o pipefail
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
7+
FLASHBOTS_IMAGES_DIR="${SCRIPT_DIR}/.flashbots-images"
8+
9+
if [[ ! -d "${FLASHBOTS_IMAGES_DIR}" ]]; then
10+
echo "Error: flashbots-images not found. Run ./sync.sh first."
11+
exit 1
12+
fi
13+
14+
make -C "${FLASHBOTS_IMAGES_DIR}" build-playground
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
# Check builder-hub configuration
3+
set -eu -o pipefail
4+
5+
echo "Builder Configuration:"
6+
curl -s http://localhost:8888/api/l1-builder/v1/configuration | jq .
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env bash
2+
# Clean build artifacts and runtime files
3+
set -eu -o pipefail
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
7+
FLASHBOTS_IMAGES_DIR="${SCRIPT_DIR}/.flashbots-images"
8+
RUNTIME_DIR="${SCRIPT_DIR}/.runtime"
9+
PIDFILE="${RUNTIME_DIR}/qemu.pid"
10+
11+
# Check if VM is running
12+
if [[ -f "${PIDFILE}" ]] && kill -0 $(cat "${PIDFILE}") 2>/dev/null; then
13+
echo "Error: VM is still running. Run ./stop.sh first."
14+
exit 1
15+
fi
16+
17+
if [[ -d "${FLASHBOTS_IMAGES_DIR}" ]]; then
18+
make -C "${FLASHBOTS_IMAGES_DIR}" clean
19+
fi
20+
21+
rm -rf "${RUNTIME_DIR}"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
# Connect to the BuilderNet VM console (auto-login with devtools profile)
3+
set -eu -o pipefail
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
CONSOLE_SOCK="${SCRIPT_DIR}/.runtime/console.sock"
7+
8+
if [[ ! -S "${CONSOLE_SOCK}" ]]; then
9+
echo "Error: Console socket not found. Is the VM running?"
10+
echo "Run ./start.sh first."
11+
exit 1
12+
fi
13+
14+
echo "Connecting to VM console... (Ctrl+] to exit)"
15+
socat -,raw,echo=0,escape=0x1d UNIX-CONNECT:"${CONSOLE_SOCK}"
16+
17+
echo ""
18+
echo "Disconnected from VM console."
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
# Execute an operator-api action
3+
set -eu -o pipefail
4+
5+
OPERATOR_API_PORT=${OPERATOR_API_PORT:-13535}
6+
OPERATOR_API_HOST=${OPERATOR_API_HOST:-localhost}
7+
8+
ACTION=${1:-}
9+
10+
if [ -z "$ACTION" ]; then
11+
echo "Usage: $0 <action>"
12+
echo ""
13+
echo "Available actions:"
14+
echo " reboot - Reboot the system"
15+
echo " rbuilder_restart - Restart rbuilder-operator service"
16+
echo " rbuilder_stop - Stop rbuilder-operator service"
17+
echo " fetch_config - Fetch config from BuilderHub"
18+
echo " rbuilder_bidding_restart - Restart rbuilder-bidding service"
19+
echo " ssh_stop - Stop SSH service"
20+
echo " ssh_start - Start SSH service"
21+
echo " haproxy_restart - Restart HAProxy service"
22+
exit 1
23+
fi
24+
25+
curl -s -k "https://${OPERATOR_API_HOST}:${OPERATOR_API_PORT}/api/v1/actions/${ACTION}"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
# Check operator-api health
3+
set -eu -o pipefail
4+
5+
OPERATOR_API_PORT=${OPERATOR_API_PORT:-13535}
6+
OPERATOR_API_HOST=${OPERATOR_API_HOST:-localhost}
7+
8+
# /livez returns HTTP 200 with empty body on success
9+
HTTP_CODE=$(curl -s -k -o /dev/null -w "%{http_code}" "https://${OPERATOR_API_HOST}:${OPERATOR_API_PORT}/livez")
10+
11+
if [ "$HTTP_CODE" = "200" ]; then
12+
echo "OK"
13+
exit 0
14+
else
15+
echo "FAIL (HTTP $HTTP_CODE)"
16+
exit 1
17+
fi
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
# Get operator-api event logs
3+
set -eu -o pipefail
4+
5+
OPERATOR_API_PORT=${OPERATOR_API_PORT:-13535}
6+
OPERATOR_API_HOST=${OPERATOR_API_HOST:-localhost}
7+
8+
curl -s -k "https://${OPERATOR_API_HOST}:${OPERATOR_API_PORT}/logs"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env bash
2+
# Discover OVMF firmware files using QEMU firmware descriptors.
3+
# Usage:
4+
# source ovmf.sh
5+
# # Sets OVMF_CODE and OVMF_VARS variables
6+
set -eu -o pipefail
7+
8+
_discover_ovmf() {
9+
local search_dirs=(
10+
/usr/share/qemu/firmware
11+
/etc/qemu/firmware
12+
)
13+
14+
for dir in "${search_dirs[@]}"; do
15+
[[ -d "$dir" ]] || continue
16+
for f in "$dir"/*.json; do
17+
[[ -f "$f" ]] || continue
18+
# Match x86_64 UEFI, non-secure-boot, 4m variant
19+
if jq -e '
20+
(.targets[] | select(.architecture == "x86_64")) and
21+
(.["interface-types"] | index("uefi")) and
22+
((.features | index("secure-boot")) | not)
23+
' "$f" >/dev/null 2>&1; then
24+
OVMF_CODE=$(jq -r '.mapping.executable.filename' "$f")
25+
OVMF_VARS=$(jq -r '.mapping."nvram-template".filename' "$f")
26+
if [[ -f "$OVMF_CODE" && -f "$OVMF_VARS" ]]; then
27+
return 0
28+
fi
29+
fi
30+
done
31+
done
32+
33+
# Fallback: check common hardcoded paths
34+
local known_paths=(
35+
"/usr/share/OVMF/x64"
36+
"/usr/share/edk2/x64"
37+
"/usr/share/OVMF"
38+
"/usr/share/edk2/ovmf"
39+
"/usr/share/edk2-ovmf/x64"
40+
)
41+
for dir in "${known_paths[@]}"; do
42+
if [[ -f "$dir/OVMF_CODE.4m.fd" && -f "$dir/OVMF_VARS.4m.fd" ]]; then
43+
OVMF_CODE="$dir/OVMF_CODE.4m.fd"
44+
OVMF_VARS="$dir/OVMF_VARS.4m.fd"
45+
return 0
46+
fi
47+
done
48+
49+
echo "Error: Could not find OVMF firmware files." >&2
50+
echo "Install the edk2-ovmf package (or equivalent for your distro)." >&2
51+
return 1
52+
}
53+
54+
_discover_ovmf
55+
export OVMF_CODE OVMF_VARS
56+
echo "OVMF_CODE=${OVMF_CODE}"
57+
echo "OVMF_VARS=${OVMF_VARS}"

0 commit comments

Comments
 (0)