Migrate to Rust workspace with git subtrees
MAJOR ARCHITECTURAL CHANGE: - Add Rust components as git subtrees: zinit, mycelium, rfs - Replace git submodules with unified Rust workspace - Update compile-components.sh to use workspace build - Remove obsolete setup-submodules.sh script - Keep CoreX handling in fetch-github.sh (Go binary) BENEFITS: - Unified dependency management across Rust components - Single 'cargo build --workspace' command - Better IDE support and shared target directory - Improved build caching and version consistency Components structure: - components/zinit (subtree from threefoldtech/zinit) - components/mycelium (subtree from threefoldtech/mycelium) - components/rfs (subtree from threefoldtech/rfs) - CoreX handled by fetch-github.sh (binary download)
This commit is contained in:
@@ -2,244 +2,132 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
ALPINE_ROOT="/build/initramfs"
|
ALPINE_ROOT="/build/initramfs"
|
||||||
COMPONENTS_DIR="/build/components"
|
OUTPUT_DIR="/build/output"
|
||||||
CACHE_DIR="/build/cache/source"
|
WORKSPACE_ROOT="/build"
|
||||||
|
|
||||||
echo "[+] Compiling Zero-OS components from git submodules..."
|
echo "[+] Compiling Zero-OS components using Rust workspace..."
|
||||||
|
|
||||||
# Create build directories
|
# Check if workspace is available
|
||||||
mkdir -p "$CACHE_DIR"
|
if [ ! -f "$WORKSPACE_ROOT/Cargo.toml" ]; then
|
||||||
|
echo "Error: Cargo workspace not found at $WORKSPACE_ROOT/Cargo.toml"
|
||||||
# Check if submodules are available
|
|
||||||
if [ ! -d "$COMPONENTS_DIR" ]; then
|
|
||||||
echo "Error: Components directory not found. Run setup-submodules.sh first."
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Function to prepare component for building
|
# Check if components exist
|
||||||
prepare_component() {
|
if [ ! -d "$WORKSPACE_ROOT/components" ]; then
|
||||||
local component_name="$1"
|
echo "Error: Components directory not found. Workspace is not properly set up."
|
||||||
local component_dir="$COMPONENTS_DIR/$component_name"
|
exit 1
|
||||||
|
|
||||||
if [ ! -d "$component_dir" ]; then
|
|
||||||
echo " Warning: $component_name submodule not found at $component_dir"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " Preparing $component_name..."
|
|
||||||
cd "$component_dir"
|
|
||||||
|
|
||||||
# Update submodule if needed
|
|
||||||
if [ -d ".git" ]; then
|
|
||||||
git pull origin main 2>/dev/null || git pull origin master 2>/dev/null || echo " Using existing checkout"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to build Rust project from submodule
|
|
||||||
build_rust_component() {
|
|
||||||
local component_name="$1"
|
|
||||||
local binary_name="$2"
|
|
||||||
local install_path="$3"
|
|
||||||
|
|
||||||
echo " Building Rust component: $component_name"
|
|
||||||
|
|
||||||
if ! prepare_component "$component_name"; then
|
|
||||||
echo " Skipping $component_name (not available)"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build the project
|
|
||||||
echo " Compiling with cargo for musl target..."
|
|
||||||
|
|
||||||
# Source cargo environment
|
|
||||||
. ~/.cargo/env
|
|
||||||
|
|
||||||
# Build with musl target for static linking
|
|
||||||
cargo build --release --target x86_64-unknown-linux-musl
|
|
||||||
|
|
||||||
# Debug: Check what was actually built
|
|
||||||
echo " Checking build results..."
|
|
||||||
ls -la target/x86_64-unknown-linux-musl/release/ | grep -v "\.d$" | grep -v "\.rlib$" || true
|
|
||||||
|
|
||||||
# Try to find the actual binary (might have different name)
|
|
||||||
local actual_binary=""
|
|
||||||
if [ -f "target/x86_64-unknown-linux-musl/release/$binary_name" ]; then
|
|
||||||
actual_binary="$binary_name"
|
|
||||||
else
|
|
||||||
# Look for executable files that might be our binary
|
|
||||||
actual_binary=$(find target/x86_64-unknown-linux-musl/release/ -maxdepth 1 -type f -executable ! -name "*.d" | head -1 | xargs basename 2>/dev/null || echo "")
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$actual_binary" ] && [ -f "target/x86_64-unknown-linux-musl/release/$actual_binary" ]; then
|
|
||||||
# Install binary to Alpine root
|
|
||||||
mkdir -p "$ALPINE_ROOT$install_path"
|
|
||||||
cp "target/x86_64-unknown-linux-musl/release/$actual_binary" "$ALPINE_ROOT$install_path/$binary_name"
|
|
||||||
chmod +x "$ALPINE_ROOT$install_path/$binary_name"
|
|
||||||
echo " Success: $install_path/$binary_name installed to Alpine root (musl static, actual binary: $actual_binary)"
|
|
||||||
else
|
|
||||||
echo " Error: No executable binary found in target/x86_64-unknown-linux-musl/release/"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to build Go project from submodule
|
|
||||||
build_go_component() {
|
|
||||||
local component_name="$1"
|
|
||||||
local binary_name="$2"
|
|
||||||
local install_path="$3"
|
|
||||||
local build_cmd="$4"
|
|
||||||
|
|
||||||
echo " Building Go component: $component_name"
|
|
||||||
|
|
||||||
if ! prepare_component "$component_name"; then
|
|
||||||
echo " Skipping $component_name (not available)"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build the project
|
|
||||||
echo " Compiling with go..."
|
|
||||||
if command -v go >/dev/null; then
|
|
||||||
if [ -n "$build_cmd" ]; then
|
|
||||||
eval "$build_cmd"
|
|
||||||
else
|
|
||||||
go build -o "$binary_name"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install binary to Alpine root
|
|
||||||
mkdir -p "$ALPINE_ROOT$install_path"
|
|
||||||
cp "$binary_name" "$ALPINE_ROOT$install_path/"
|
|
||||||
chmod +x "$ALPINE_ROOT$install_path/$binary_name"
|
|
||||||
|
|
||||||
echo " Success: $install_path/$binary_name installed to Alpine root"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo " Error: go not found - installing Go..."
|
|
||||||
apk add --no-cache go
|
|
||||||
if [ -n "$build_cmd" ]; then
|
|
||||||
eval "$build_cmd"
|
|
||||||
else
|
|
||||||
go build -o "$binary_name"
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$ALPINE_ROOT$install_path"
|
|
||||||
cp "$binary_name" "$ALPINE_ROOT$install_path/"
|
|
||||||
chmod +x "$ALPINE_ROOT$install_path/$binary_name"
|
|
||||||
|
|
||||||
echo " Success: $install_path/$binary_name installed to Alpine root"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to build mycelium (special case - builds from myceliumd subdirectory)
|
|
||||||
build_mycelium_component() {
|
|
||||||
local component_name="$1"
|
|
||||||
local binary_name="$2"
|
|
||||||
local install_path="$3"
|
|
||||||
|
|
||||||
echo " Building Mycelium component: $component_name"
|
|
||||||
|
|
||||||
if ! prepare_component "$component_name"; then
|
|
||||||
echo " Skipping $component_name (not available)"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Change to myceliumd subdirectory
|
|
||||||
if [ ! -d "myceliumd" ]; then
|
|
||||||
echo " Error: myceliumd subdirectory not found in $component_name"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " Building from myceliumd subdirectory..."
|
|
||||||
cd myceliumd
|
|
||||||
|
|
||||||
# Source cargo environment
|
|
||||||
. ~/.cargo/env
|
|
||||||
|
|
||||||
# Build with musl target for static linking from myceliumd directory
|
|
||||||
# Note: Removed --features vendored-openssl as it doesn't exist in current version
|
|
||||||
cargo build --release --target x86_64-unknown-linux-musl
|
|
||||||
|
|
||||||
# Debug: Check what was actually built
|
|
||||||
echo " Checking build results..."
|
|
||||||
ls -la target/x86_64-unknown-linux-musl/release/ | grep -v "\.d$" | grep -v "\.rlib$" || true
|
|
||||||
|
|
||||||
# The binary is in target/x86_64-unknown-linux-musl/release/ (relative to myceliumd directory)
|
|
||||||
if [ ! -f "target/x86_64-unknown-linux-musl/release/$binary_name" ]; then
|
|
||||||
echo " Error: Binary not found at target/x86_64-unknown-linux-musl/release/$binary_name"
|
|
||||||
echo " Available files:"
|
|
||||||
ls -la target/x86_64-unknown-linux-musl/release/ || true
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install binary to Alpine root
|
|
||||||
mkdir -p "$ALPINE_ROOT$install_path"
|
|
||||||
cp "target/x86_64-unknown-linux-musl/release/$binary_name" "$ALPINE_ROOT$install_path/"
|
|
||||||
chmod +x "$ALPINE_ROOT$install_path/$binary_name"
|
|
||||||
|
|
||||||
echo " Success: $install_path/$binary_name installed to Alpine root (musl static)"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Install build dependencies if needed
|
|
||||||
echo " Checking build dependencies..."
|
|
||||||
if ! command -v git >/dev/null; then
|
|
||||||
echo " Installing git..."
|
|
||||||
apk add --no-cache git
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo " Workspace components found:"
|
||||||
|
ls -1 "$WORKSPACE_ROOT/components/" | sed 's/^/ - /'
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Function to build entire workspace
|
||||||
|
build_workspace() {
|
||||||
|
echo " Building Rust workspace for musl target..."
|
||||||
|
|
||||||
|
cd "$WORKSPACE_ROOT"
|
||||||
|
|
||||||
|
# Source cargo environment
|
||||||
|
. ~/.cargo/env
|
||||||
|
|
||||||
|
# Build all workspace members with musl target for static linking
|
||||||
|
echo " Running: cargo build --workspace --release --target x86_64-unknown-linux-musl"
|
||||||
|
CARGO_TARGET_DIR="$WORKSPACE_ROOT/target" cargo build --workspace --release --target x86_64-unknown-linux-musl
|
||||||
|
|
||||||
|
echo " Workspace build completed successfully"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install workspace binaries
|
||||||
|
install_workspace_binaries() {
|
||||||
|
local target_dir="$WORKSPACE_ROOT/target/x86_64-unknown-linux-musl/release"
|
||||||
|
|
||||||
|
echo " Installing workspace binaries..."
|
||||||
|
echo " Target directory: $target_dir"
|
||||||
|
|
||||||
|
# Debug: Show what was built
|
||||||
|
echo " Built binaries:"
|
||||||
|
ls -la "$target_dir" 2>/dev/null | grep -E '^-.*x.*' | awk '{print " " $9 " (" $5 " bytes)"}' || echo " No binaries found"
|
||||||
|
|
||||||
|
# Create output and alpine root directories
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
mkdir -p "$ALPINE_ROOT/sbin"
|
||||||
|
mkdir -p "$ALPINE_ROOT/usr/bin"
|
||||||
|
|
||||||
|
# Install specific binaries
|
||||||
|
local installed=0
|
||||||
|
|
||||||
|
# Install zinit
|
||||||
|
if [ -f "$target_dir/zinit" ]; then
|
||||||
|
cp "$target_dir/zinit" "$ALPINE_ROOT/sbin/"
|
||||||
|
cp "$target_dir/zinit" "$OUTPUT_DIR/"
|
||||||
|
chmod +x "$ALPINE_ROOT/sbin/zinit"
|
||||||
|
echo " ✓ zinit -> /sbin/zinit"
|
||||||
|
installed=$((installed + 1))
|
||||||
|
else
|
||||||
|
echo " ✗ zinit binary not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install rfs (check for different possible names)
|
||||||
|
local rfs_binary=""
|
||||||
|
for name in "rfs" "rfs-server" "rfs-bin"; do
|
||||||
|
if [ -f "$target_dir/$name" ]; then
|
||||||
|
rfs_binary="$name"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$rfs_binary" ]; then
|
||||||
|
cp "$target_dir/$rfs_binary" "$ALPINE_ROOT/usr/bin/rfs"
|
||||||
|
cp "$target_dir/$rfs_binary" "$OUTPUT_DIR/rfs"
|
||||||
|
chmod +x "$ALPINE_ROOT/usr/bin/rfs"
|
||||||
|
echo " ✓ $rfs_binary -> /usr/bin/rfs"
|
||||||
|
installed=$((installed + 1))
|
||||||
|
else
|
||||||
|
echo " ✗ rfs binary not found (checked: rfs, rfs-server, rfs-bin)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install mycelium (check in myceliumd subdirectory build)
|
||||||
|
if [ -f "$target_dir/mycelium" ]; then
|
||||||
|
cp "$target_dir/mycelium" "$ALPINE_ROOT/usr/bin/"
|
||||||
|
cp "$target_dir/mycelium" "$OUTPUT_DIR/"
|
||||||
|
chmod +x "$ALPINE_ROOT/usr/bin/mycelium"
|
||||||
|
echo " ✓ mycelium -> /usr/bin/mycelium"
|
||||||
|
installed=$((installed + 1))
|
||||||
|
else
|
||||||
|
echo " ✗ mycelium binary not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " Installed $installed out of 3 expected binaries"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# Ensure Alpine root directory exists
|
# Ensure Alpine root directory exists
|
||||||
if [ ! -d "$ALPINE_ROOT" ]; then
|
if [ ! -d "$ALPINE_ROOT" ]; then
|
||||||
echo "Creating Alpine initramfs root at $ALPINE_ROOT"
|
echo " Creating Alpine initramfs root at $ALPINE_ROOT"
|
||||||
mkdir -p "$ALPINE_ROOT"
|
mkdir -p "$ALPINE_ROOT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build each Zero-OS component from submodules
|
# Build workspace
|
||||||
echo "Building Zero-OS components from submodules:"
|
if build_workspace; then
|
||||||
|
echo " ✓ Workspace build completed"
|
||||||
# 1. Zinit - Init system (Rust) - master branch
|
|
||||||
if build_rust_component "zinit" "zinit" "/sbin"; then
|
|
||||||
echo " Zinit built successfully"
|
|
||||||
else
|
else
|
||||||
echo " Warning: Failed to build zinit"
|
echo " ✗ Workspace build failed"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. RFS - Rust filesystem (Rust) - v2.0.6 with musl
|
# Install binaries
|
||||||
if build_rust_component "rfs" "rfs" "/usr/bin"; then
|
install_workspace_binaries
|
||||||
echo " RFS built successfully"
|
|
||||||
else
|
|
||||||
echo " Warning: Failed to build rfs"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. CoreX - Container control (static binary) - v2.1.4
|
|
||||||
echo " Installing CoreX static binary..."
|
|
||||||
if [ -f "$COMPONENTS_DIR/corex/corex" ]; then
|
|
||||||
mkdir -p "$ALPINE_ROOT/usr/bin"
|
|
||||||
cp "$COMPONENTS_DIR/corex/corex" "$ALPINE_ROOT/usr/bin/"
|
|
||||||
chmod +x "$ALPINE_ROOT/usr/bin/corex"
|
|
||||||
echo " CoreX installed successfully"
|
|
||||||
else
|
|
||||||
echo " Warning: CoreX binary not found"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. Mycelium - Networking layer (Rust) - 0.6.1 with musl (special build from myceliumd subdirectory)
|
|
||||||
if build_mycelium_component "mycelium" "mycelium" "/usr/bin"; then
|
|
||||||
echo " Mycelium built successfully"
|
|
||||||
else
|
|
||||||
echo " Warning: Failed to build mycelium"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[+] Zero-OS component compilation completed"
|
echo "[+] Zero-OS component compilation completed using Rust workspace"
|
||||||
|
|
||||||
# Show installed binaries info
|
# Show installed binaries info
|
||||||
echo ""
|
echo ""
|
||||||
echo "[+] Compiled Zero-OS components in Alpine root:"
|
echo "[+] Compiled Zero-OS components in Alpine root:"
|
||||||
for binary in "/sbin/zinit" "/usr/bin/rfs" "/usr/bin/corex" "/usr/bin/mycelium"; do
|
for binary in "/sbin/zinit" "/usr/bin/rfs" "/usr/bin/mycelium"; do
|
||||||
if [ -x "$ALPINE_ROOT$binary" ]; then
|
if [ -x "$ALPINE_ROOT$binary" ]; then
|
||||||
size=$(stat -c%s "$ALPINE_ROOT$binary" 2>/dev/null || echo "unknown")
|
size=$(stat -c%s "$ALPINE_ROOT$binary" 2>/dev/null || echo "unknown")
|
||||||
echo " $binary (${size} bytes)"
|
echo " $binary (${size} bytes)"
|
||||||
@@ -248,4 +136,6 @@ for binary in "/sbin/zinit" "/usr/bin/rfs" "/usr/bin/corex" "/usr/bin/mycelium";
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "[+] Zero-OS binaries installed to Alpine root filesystem"
|
echo ""
|
||||||
|
echo "[+] Compiled binaries also saved to: $OUTPUT_DIR"
|
||||||
|
echo "[+] Zero-OS Rust workspace compilation complete!"
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "[+] Setting up Zero-OS components..."
|
|
||||||
|
|
||||||
# Check if we're in git repository
|
|
||||||
if [ ! -d ".git" ]; then
|
|
||||||
echo "Error: Not in a git repository. Please run 'git init' first."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create components directory
|
|
||||||
mkdir -p components
|
|
||||||
|
|
||||||
# 1. Zinit - master branch
|
|
||||||
echo " Adding zinit (init system) from master branch..."
|
|
||||||
if [ ! -d "components/zinit" ]; then
|
|
||||||
git submodule add https://github.com/threefoldtech/zinit.git components/zinit
|
|
||||||
cd components/zinit
|
|
||||||
git checkout master
|
|
||||||
cd ../..
|
|
||||||
else
|
|
||||||
echo " zinit submodule already exists"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. RFS - tag v2.0.6 (musl build)
|
|
||||||
echo " Adding rfs (rust filesystem) tag v2.0.6..."
|
|
||||||
if [ ! -d "components/rfs" ]; then
|
|
||||||
git submodule add https://github.com/threefoldtech/rfs.git components/rfs
|
|
||||||
cd components/rfs
|
|
||||||
git checkout v2.0.6
|
|
||||||
cd ../..
|
|
||||||
else
|
|
||||||
echo " rfs submodule already exists"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Mycelium - tag v0.6.1 (musl build)
|
|
||||||
echo " Adding mycelium (networking layer) tag v0.6.1..."
|
|
||||||
if [ ! -d "components/mycelium" ]; then
|
|
||||||
git submodule add https://github.com/threefoldtech/mycelium.git components/mycelium
|
|
||||||
cd components/mycelium
|
|
||||||
git checkout v0.6.1
|
|
||||||
cd ../..
|
|
||||||
else
|
|
||||||
echo " mycelium submodule already exists"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. CoreX - direct download (static binary)
|
|
||||||
echo " Downloading CoreX static binary v2.1.4..."
|
|
||||||
mkdir -p components/corex
|
|
||||||
if [ ! -f "components/corex/corex" ]; then
|
|
||||||
curl -L -o components/corex/corex https://github.com/threefoldtech/corex/releases/download/2.1.4/corex-2.1.4-amd64-linux-static
|
|
||||||
chmod +x components/corex/corex
|
|
||||||
echo " CoreX binary downloaded successfully"
|
|
||||||
else
|
|
||||||
echo " CoreX binary already exists"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Initialize and update submodules
|
|
||||||
echo " Initializing submodules..."
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
|
|
||||||
echo "[+] Zero-OS components setup complete"
|
|
||||||
echo ""
|
|
||||||
echo "Components added:"
|
|
||||||
echo " - zinit (master): $(ls -la components/zinit 2>/dev/null | wc -l) files"
|
|
||||||
echo " - rfs (v2.0.6): $(ls -la components/rfs 2>/dev/null | wc -l) files"
|
|
||||||
echo " - mycelium (v0.6.1): $(ls -la components/mycelium 2>/dev/null | wc -l) files"
|
|
||||||
echo " - corex (v2.1.4): $(ls -la components/corex/corex 2>/dev/null && echo "downloaded" || echo "missing")"
|
|
||||||
echo ""
|
|
||||||
echo "To update submodules later, run:"
|
|
||||||
echo " git submodule update --remote"
|
|
||||||
Reference in New Issue
Block a user