-
Notifications
You must be signed in to change notification settings - Fork 13
Add playground mkosi profile #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk/buildernet
Are you sure you want to change the base?
Changes from 11 commits
ed4e512
5bd5fd9
6c3a8fb
2021eaa
068d964
1744dec
9c39293
349b321
4d31db3
01724dc
2c4cfb9
feba364
4cab0fc
6717967
07eec4a
deb6186
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,9 @@ mkosi.tools.manifest | |
| .claudesync/ | ||
| .claudeignore | ||
| tmp/ | ||
| logs/ | ||
|
|
||
| !/**/.gitkeep | ||
| .vscode/ | ||
|
|
||
| .venv/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # Makefile for flashbots-images | ||
| # Build VM images using mkosi | ||
| # | ||
| # Also: | ||
| # - manages a Python virtual environment with a pinned version of mkosi. | ||
|
|
||
| .DEFAULT_GOAL := help | ||
|
|
||
| VERSION := $(shell git describe --tags --always --dirty="-dev" 2>/dev/null || echo "dev") | ||
| SHELL := /bin/bash | ||
| .SHELLFLAGS := -eu -o pipefail -c | ||
|
|
||
| # mkosi version | ||
| MKOSI_COMMIT := a425313c5811d2ed840630dbfc45c6bc296bfd48 | ||
|
|
||
| # Virtual environment paths | ||
| VENV := .venv | ||
| VENV_BIN := $(VENV)/bin | ||
| VENV_MARKER := $(VENV)/.installed-$(MKOSI_COMMIT) | ||
| MKOSI := $(VENV_BIN)/mkosi | ||
|
|
||
| # Build logs | ||
| LOGS_DIR := logs | ||
| TIMESTAMP := $(shell date +%Y%m%d-%H%M%S) | ||
|
|
||
| ##@ Help | ||
|
|
||
| # Awk script from https://github.com/paradigmxyz/reth/blob/main/Makefile | ||
| .PHONY: help | ||
| help: ## Display this help. | ||
| @awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) | ||
|
|
||
| .PHONY: v | ||
| v: ## Show the version | ||
| @echo "Version: $(VERSION)" | ||
|
|
||
| ##@ Build | ||
|
|
||
| .PHONY: build | ||
| build: $(VENV_MARKER) ## Build VM image | ||
| @mkdir -p $(LOGS_DIR) | ||
| $(MKOSI) --force -I buildernet.conf 2>&1 | tee $(LOGS_DIR)/build-$(TIMESTAMP).log | ||
|
|
||
| .PHONY: build-playground | ||
| build-playground: $(VENV_MARKER) ## Build VM image for playground | ||
| @mkdir -p $(LOGS_DIR) | ||
| $(MKOSI) --force -I buildernet.conf --profile="devtools,playground" 2>&1 | tee $(LOGS_DIR)/build-playground-$(TIMESTAMP).log | ||
|
|
||
| ##@ Setup | ||
|
|
||
| # Create venv only if it doesn't exist | ||
| $(VENV_BIN)/activate: | ||
| @echo "Creating Python virtual environment at $(VENV)..." | ||
| python3 -m venv $(VENV) | ||
|
|
||
| # Install/update dependencies when mkosi version changed | ||
| $(VENV_MARKER): $(VENV_BIN)/activate | ||
| @echo "Installing mkosi (commit: $(MKOSI_COMMIT))..." | ||
| @rm -f $(VENV)/.installed-* | ||
| $(VENV_BIN)/pip install -q --upgrade pip | ||
| $(VENV_BIN)/pip install -q git+https://github.com/systemd/mkosi.git@$(MKOSI_COMMIT) | ||
| @touch $@ | ||
| @echo "Installed: $$($(MKOSI) --version)" | ||
|
|
||
| .PHONY: setup | ||
| setup: $(VENV_MARKER) ## Setup build environment (venv + mkosi) | ||
| @echo "Environment ready. mkosi: $$($(MKOSI) --version)" | ||
|
|
||
| ##@ Utilities | ||
|
|
||
| .PHONY: clean | ||
| clean: ## Remove build artifacts (keeps venv) | ||
| git clean -fdX mkosi.output mkosi.builddir | ||
| rm -rf $(LOGS_DIR) | ||
|
|
||
| .PHONY: clean-all | ||
| clean-all: clean ## Remove all artifacts including venv | ||
| rm -rf $(VENV) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,4 +21,3 @@ rm -rf ${OUTPUTDIR}/esp | |
|
|
||
| cd ${OUTPUTDIR} | ||
| qemu-img convert -f raw -O qcow2 ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.qcow2 | ||
| rm -f ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am using
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted and switched to qcow2. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| [Match] | ||
| Profiles=playground | ||
|
|
||
| [Include] | ||
| Include=../../mkosi.profiles/playground |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| [Content] | ||
| # Playground profile - disables services that require external dependencies | ||
| # Use with devtools profile for full debugging capabilities: | ||
| # mkosi --profile=playground,devtools | ||
|
|
||
| Packages=login | ||
|
|
||
| # BuilderHub URL override for playground | ||
| # 10.0.2.2 is the QEMU user networking default gateway that maps to host | ||
| # 8888 is the port of the builder-hub-proxy service | ||
| Environment=BUILDERNET_BUILDERHUB_URL=http://10.0.2.2:8888 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Playground profile - disables services requiring external dependencies | ||
| # | ||
| # Services can be enabled at runtime with: | ||
| # systemctl enable --now <service>.service | ||
|
|
||
| # Downloads Reth state snapshot from S3 | ||
| disable reth-sync.service | ||
|
|
||
| # Ships logs to CloudWatch, metrics to Prometheus | ||
| disable vector.service | ||
|
|
||
| # ACME services | ||
| # - Issues TLS certs via Let's Encrypt | ||
| disable acme-le.service | ||
| # - Renews Let's Encrypt TLS certs | ||
| disable acme-le-renewal.service | ||
| # - Metrics exporter | ||
| disable acme-le-textfile-collector.service | ||
|
|
||
| # REST API for node operator management | ||
| # Note: keep it enabled, and explore if playground cli can take advantage of it | ||
| # disable operator-api.service | ||
|
|
||
| # Fetches rbuilder-bidding from private GitHub | ||
| # (static unit - no [Install] section, cannot be disabled via preset) | ||
| # disable rbuilder-bidding-downloader.service | ||
|
|
||
| # Rebalances ETH across builder wallets | ||
| disable rbuilder-rebalancer.service | ||
|
|
||
| # Watches external source, reloads rbuilder config | ||
| disable config-watchdog.service |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| [Service] | ||
| Environment= | ||
| ExecStart= | ||
| ExecStart=/usr/bin/persistent-setup --device-lun 10 --key-file /etc/disk-encryption-key | ||
| TimeoutStartSec=120 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| [Unit] | ||
| Description=Fetch configuration files from playground | ||
| Wants=network-online.target render-config.service | ||
| After=network.target network-online.target render-config.service persistent-setup.service | ||
| Before=reth.service lighthouse.service | ||
| ConditionPathIsDirectory=!/var/lib/persistent/playground | ||
|
|
||
| [Service] | ||
| Type=oneshot | ||
| User=root | ||
| StateDirectory=persistent/playground | ||
| ExecStart=/usr/local/bin/playground-config-fetch | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| [Service] | ||
|
||
| ExecStart= | ||
| ExecStart=-/sbin/agetty --autologin bnet --noclear %I $TERM | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| [general] | ||
| listen_addr = "0.0.0.0:3535" | ||
| pipe_file = "/run/operator-api/journal.fifo" | ||
| pprof = false | ||
| log_json = true | ||
| log_debug = false | ||
|
|
||
| # HTTP Basic Auth: the salt, and where to persistently store the hashed secret | ||
| basic_auth_secret_path = "/var/lib/persistent/operator-api/basic-auth-hash" | ||
| basic_auth_secret_salt = "bb36ef0b6643" | ||
|
|
||
| # HTTP server timeouts | ||
| # http_read_timeout_ms = 2500 | ||
| # http_write_timeout_ms = 2500 | ||
|
|
||
| # TLS configuration | ||
| tls_enabled = true | ||
| tls_create_if_missing = true | ||
| tls_cert_path = "/var/lib/persistent/operator-api/cert.pem" | ||
| tls_key_path = "/var/lib/persistent/operator-api/key.pem" | ||
|
|
||
| # Make sure to update buildernet/mkosi.extra/etc/sudoers.d/operator-api | ||
| # when adding a new action | ||
| [actions] | ||
| reboot = "sudo systemctl --no-pager --no-ask-password reboot" | ||
| rbuilder_restart = "sudo systemctl --no-pager --no-ask-password restart rbuilder-operator" | ||
| rbuilder_stop = "sudo systemctl --no-pager --no-ask-password stop rbuilder-operator" | ||
| fetch_config = "sudo systemctl --no-pager --no-ask-password start fetch-config" | ||
| rbuilder_bidding_restart = "sudo systemctl --no-pager --no-ask-password restart rbuilder-bidding" | ||
| ssh_stop = "sudo systemctl --no-pager --no-ask-password stop ssh.service ssh.socket" | ||
| ssh_start = "sudo systemctl --no-pager --no-ask-password start ssh.service ssh.socket" | ||
| haproxy_restart = "sudo systemctl --no-pager --no-ask-password restart haproxy" | ||
|
|
||
| [file_uploads] | ||
| rbuilder_blocklist = "/var/lib/persistent/rbuilder-operator/rbuilder.blocklist.json" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| [Service] | ||
| # Clear the default ExecStart and use playground testnet config (no checkpoint sync) | ||
| ExecStart= | ||
| ExecStart=/usr/bin/lighthouse bn \ | ||
| --testnet-dir /var/lib/persistent/playground/testnet \ | ||
| --execution-endpoint http://localhost:8551 \ | ||
| --execution-jwt /run/eth-jwt/jwt \ | ||
| --suggested-fee-recipient 0x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990 \ | ||
| --always-prepare-payload \ | ||
| --prepare-payload-lookahead 8000 \ | ||
| --http \ | ||
| --http-port 3500 \ | ||
| --http-address 127.0.0.1 \ | ||
| --port 9000 \ | ||
| --metrics \ | ||
| --metrics-address 127.0.0.1 \ | ||
| --metrics-port 5054 \ | ||
| --datadir %S/persistent/lighthouse \ | ||
| --enable-private-discovery \ | ||
| --disable-peer-scoring \ | ||
| --disable-packet-filter \ | ||
| --libp2p-addresses "{{{playground.cl_libp2p_addr}}}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| [Service] | ||
| # Clear the default ExecStart and use playground genesis | ||
| ExecStart= | ||
| ExecStart=/usr/bin/reth node \ | ||
| --full \ | ||
| --chain /var/lib/persistent/playground/genesis.json \ | ||
| --datadir %S/persistent/reth \ | ||
| --authrpc.addr 127.0.0.1 \ | ||
| --authrpc.jwtsecret /run/eth-jwt/jwt \ | ||
| --authrpc.port 8551 \ | ||
| --http \ | ||
| --http.addr 127.0.0.1 \ | ||
| --http.port 8545 \ | ||
| --http.api "eth,net,web3,trace,rpc,debug,txpool" \ | ||
| --ws \ | ||
| --ws.addr 127.0.0.1 \ | ||
| --ws.port 8546 \ | ||
| --ws.api "eth,net,trace,web3,rpc,debug,txpool" \ | ||
| --log.stdout.format json \ | ||
| --log.file.max-files 0 \ | ||
| --metrics "127.0.0.1:9001" \ | ||
| --engine.persistence-threshold=0 \ | ||
| --engine.memory-block-buffer-target=0 \ | ||
| --ipcpath=%t/reth/reth.ipc \ | ||
| --trusted-peers "{{{playground.el_bootnode}}}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| #!/bin/bash | ||
| # | ||
| # Fetches devnet configuration files from playground HTTP service. | ||
| # Base URL is injected via mustache from builderhub config. | ||
| # | ||
|
|
||
| set -eu -o pipefail | ||
|
|
||
| source /usr/bin/helper-functions.sh | ||
|
|
||
| # Base URL from BuilderHub config (injected via mustache) | ||
| BASE_URL="{{{playground.artifacts_url}}}" | ||
|
|
||
| # Target directory | ||
| PLAYGROUND_DIR="/var/lib/persistent/playground" | ||
|
|
||
| # File mappings: source_path -> target_path | ||
| # Source paths are relative to BASE_URL | ||
| declare -A FILES=( | ||
| ["genesis.json"]="${PLAYGROUND_DIR}/genesis.json" | ||
| ["testnet/config.yaml"]="${PLAYGROUND_DIR}/testnet/config.yaml" | ||
| ["testnet/genesis.ssz"]="${PLAYGROUND_DIR}/testnet/genesis.ssz" | ||
| ["testnet/genesis_validators_root.txt"]="${PLAYGROUND_DIR}/testnet/genesis_validators_root.txt" | ||
| ["testnet/deploy_block.txt"]="${PLAYGROUND_DIR}/testnet/deploy_block.txt" | ||
| ["testnet/deposit_contract_block.txt"]="${PLAYGROUND_DIR}/testnet/deposit_contract_block.txt" | ||
| ["testnet/boot_enr.yaml"]="${PLAYGROUND_DIR}/testnet/boot_enr.yaml" | ||
| ) | ||
|
|
||
| log "playground-config-fetch: Starting download from ${BASE_URL}" | ||
|
|
||
| # Create directories | ||
| mkdir -p "${PLAYGROUND_DIR}/testnet" | ||
|
|
||
| # Download each file | ||
| for src in "${!FILES[@]}"; do | ||
| target="${FILES[$src]}" | ||
| url="${BASE_URL}/${src}" | ||
|
|
||
| log "playground-config-fetch: Downloading ${url} -> ${target}" | ||
|
|
||
| if ! curl -fsSL --retry 5 --retry-delay 2 -o "${target}" "${url}"; then | ||
| log "playground-config-fetch: ERROR: Failed to download ${url}" | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| log "playground-config-fetch: Successfully downloaded all config files" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #!/bin/bash | ||
| set -euo pipefail | ||
|
|
||
| # Mask static units that cannot be disabled via preset | ||
| # (units without [Install] section) | ||
|
|
||
| # Fetches rbuilder-bidding from private GitHub | ||
| # Failing to mask with systemctl mask --force | ||
| # systemctl mask --force rbuilder-bidding-downloader.service | ||
| # error: Failed to mask unit: File '/etc/systemd/system/rbuilder-bidding-downloader.service' already exists | ||
| # Remove existing file first, then create mask symlink | ||
| rm -f /etc/systemd/system/rbuilder-bidding-downloader.service | ||
| ln -sf /dev/null /etc/systemd/system/rbuilder-bidding-downloader.service |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets avoid putting project dependency versions in the Makefile.
mainbranch is using Nix which I think is too heavy for bnet images use-case (we don't need to install system tools).Below you're also opting to use pip for dependency management. Originally, I intentionally avoided relying on any single tool for Python dependency management as there is no one blessed tool in the Python ecosystem and people use whatever (pip, pipx, poetry, uv).
Let's first discuss which dependency management tool we want to use for the project. I personally like
uv.To not block the PR on the tool selection decision let's proceed with the current implementation of the Makefile and come back to it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added TODO to the Makefile to revisit tooling choice.