mirror of
https://github.com/CloudNebulaProject/vm-manager.git
synced 2026-04-10 13:20:41 +00:00
Add OmniOS builder VM definition and provisioning scripts
VMFile.kdl defines the omnios-builder VM with cloud-init, SSH config, and a 3-stage provision pipeline (bootstrap packages + Rust, upload forger source tarball, build and install forger). Makefile provides convenience targets wrapping vmctl commands. pack-forger.sh creates a minimal tarball of just the forger + spec-parser crates and image specs from refraction-forger for upload to the VM. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
38bc2fa6fb
commit
eb78c24a8b
6 changed files with 224 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
||||||
/target
|
/target
|
||||||
other-codes/
|
other-codes/
|
||||||
|
scripts/forger-src.tar.gz
|
||||||
|
|
|
||||||
16
Makefile
Normal file
16
Makefile
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
pack-forger:
|
||||||
|
./scripts/pack-forger.sh
|
||||||
|
|
||||||
|
up:
|
||||||
|
cargo run -p vmctl -- up
|
||||||
|
|
||||||
|
down:
|
||||||
|
cargo run -p vmctl -- down
|
||||||
|
|
||||||
|
provision:
|
||||||
|
cargo run -p vmctl -- provision
|
||||||
|
|
||||||
|
reload:
|
||||||
|
cargo run -p vmctl -- reload
|
||||||
|
|
||||||
|
.PHONY: pack-forger up down provision reload
|
||||||
32
VMFile.kdl
Normal file
32
VMFile.kdl
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
vm "omnios-builder" {
|
||||||
|
image-url "https://downloads.omnios.org/media/stable/omnios-r151056.cloud.qcow2"
|
||||||
|
vcpus 4
|
||||||
|
memory 4096
|
||||||
|
disk 20
|
||||||
|
|
||||||
|
cloud-init {
|
||||||
|
hostname "omnios-builder"
|
||||||
|
ssh-key "~/.ssh/id_ed25519.pub"
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh {
|
||||||
|
user "smithy"
|
||||||
|
private-key "~/.ssh/id_ed25519"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage 1: System packages and Rust toolchain
|
||||||
|
provision "shell" {
|
||||||
|
script "scripts/bootstrap-omnios.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage 2: Upload forger source
|
||||||
|
provision "file" {
|
||||||
|
source "scripts/forger-src.tar.gz"
|
||||||
|
destination "/tmp/forger-src.tar.gz"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage 3: Extract and build forger
|
||||||
|
provision "shell" {
|
||||||
|
script "scripts/install-forger.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
75
scripts/bootstrap-omnios.sh
Executable file
75
scripts/bootstrap-omnios.sh
Executable file
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# OmniOS bootstrap: install system packages and Rust toolchain.
|
||||||
|
# Adapted from refraction-forger's bootstrap-illumos.sh.
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Prefer GNU userland (find, xargs, etc.) on OmniOS. Native /usr/bin tools
|
||||||
|
# lack options like -maxdepth and xargs -r.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
for d in \
|
||||||
|
/usr/gnu/bin \
|
||||||
|
/usr/local/gnu/bin \
|
||||||
|
/opt/csw/gnu \
|
||||||
|
/opt/csw/bin \
|
||||||
|
/usr/sfw/bin
|
||||||
|
do
|
||||||
|
if [ -d "$d" ]; then
|
||||||
|
case ":$PATH:" in
|
||||||
|
*":$d:"*) ;;
|
||||||
|
*) PATH="$d:$PATH" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# System packages via IPS (pkg)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
if ! command -v pkg >/dev/null 2>&1; then
|
||||||
|
echo "[bootstrap] pkg not found — expected OmniOS with IPS." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[bootstrap] Refreshing package catalog ..."
|
||||||
|
sudo pkg refresh --full
|
||||||
|
|
||||||
|
echo "[bootstrap] Installing system prerequisites ..."
|
||||||
|
sudo pkg install -v \
|
||||||
|
file/gnu-findutils \
|
||||||
|
developer/gcc14 \
|
||||||
|
developer/build/gnu-make \
|
||||||
|
developer/pkg-config \
|
||||||
|
library/security/openssl \
|
||||||
|
web/curl \
|
||||||
|
compress/unzip \
|
||||||
|
developer/versioning/git \
|
||||||
|
web/ca-bundle || true
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Rust toolchain via rustup
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
if ! command -v cargo >/dev/null 2>&1; then
|
||||||
|
echo "[bootstrap] Installing Rust toolchain via rustup ..."
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
||||||
|
| sh -s -- -y --profile minimal
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$HOME/.cargo/env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Verify critical tools
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
echo "[bootstrap] Verifying installed tools ..."
|
||||||
|
for tool in gcc cargo rustc pkg-config git curl; do
|
||||||
|
if ! command -v "$tool" >/dev/null 2>&1; then
|
||||||
|
echo "[bootstrap] ERROR: $tool not found after installation." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo " $tool: $(command -v "$tool")"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[bootstrap] OmniOS bootstrap complete."
|
||||||
46
scripts/install-forger.sh
Executable file
46
scripts/install-forger.sh
Executable file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Extract forger source, build, and install the binary.
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Cargo environment
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
if [ -f "$HOME/.cargo/env" ]; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$HOME/.cargo/env"
|
||||||
|
fi
|
||||||
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
|
|
||||||
|
ARCHIVE="/tmp/forger-src.tar.gz"
|
||||||
|
DEST="$HOME/forger"
|
||||||
|
|
||||||
|
if [ ! -f "$ARCHIVE" ]; then
|
||||||
|
echo "[install-forger] Archive not found: $ARCHIVE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Extract
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
echo "[install-forger] Extracting $ARCHIVE -> $DEST ..."
|
||||||
|
rm -rf "$DEST"
|
||||||
|
mkdir -p "$DEST"
|
||||||
|
tar xzf "$ARCHIVE" -C "$DEST"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Build
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
echo "[install-forger] Building forger (release) ..."
|
||||||
|
cd "$DEST"
|
||||||
|
cargo build -p forger --release
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Install
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
echo "[install-forger] Installing /usr/local/bin/forger ..."
|
||||||
|
sudo install -m 755 -d /usr/local/bin
|
||||||
|
sudo install -m 755 "$DEST/target/release/forger" /usr/local/bin/forger
|
||||||
|
|
||||||
|
echo "[install-forger] Done."
|
||||||
|
forger --version || true
|
||||||
54
scripts/pack-forger.sh
Executable file
54
scripts/pack-forger.sh
Executable file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Pack the forger + spec-parser crates (and OmniOS image specs) into a tarball
|
||||||
|
# that can be uploaded to the OmniOS builder VM.
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
FORGER_ROOT="$PROJECT_ROOT/other-codes/refraction-forger"
|
||||||
|
OUTPUT="$SCRIPT_DIR/forger-src.tar.gz"
|
||||||
|
|
||||||
|
if [ ! -d "$FORGER_ROOT" ]; then
|
||||||
|
echo "refraction-forger not found at $FORGER_ROOT" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
STAGING="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$STAGING"' EXIT
|
||||||
|
|
||||||
|
echo "[pack-forger] Staging forger source ..."
|
||||||
|
|
||||||
|
# Copy crates
|
||||||
|
cp -a "$FORGER_ROOT/crates/forger" "$STAGING/crates/forger"
|
||||||
|
cp -a "$FORGER_ROOT/crates/spec-parser" "$STAGING/crates/spec-parser"
|
||||||
|
|
||||||
|
# Copy image specs
|
||||||
|
cp -a "$FORGER_ROOT/images" "$STAGING/images"
|
||||||
|
|
||||||
|
# Copy lockfile
|
||||||
|
cp "$FORGER_ROOT/Cargo.lock" "$STAGING/Cargo.lock"
|
||||||
|
|
||||||
|
# Generate a minimal workspace Cargo.toml (only forger + spec-parser)
|
||||||
|
cat > "$STAGING/Cargo.toml" <<'TOML'
|
||||||
|
[workspace]
|
||||||
|
resolver = "2"
|
||||||
|
members = [
|
||||||
|
"crates/forger",
|
||||||
|
"crates/spec-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
clap = { version = "4.5", features = ["derive", "env"] }
|
||||||
|
miette = { version = "7", features = ["fancy"] }
|
||||||
|
thiserror = "2"
|
||||||
|
knuffel = "3.2"
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = "0.3"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
TOML
|
||||||
|
|
||||||
|
echo "[pack-forger] Creating $OUTPUT ..."
|
||||||
|
tar czf "$OUTPUT" -C "$STAGING" .
|
||||||
|
|
||||||
|
echo "[pack-forger] Done ($(du -h "$OUTPUT" | cut -f1))."
|
||||||
Loading…
Add table
Reference in a new issue