Skip to content

Commit d3f1bf9

Browse files
Paul Cwolfsoftwaresystemsltd
andcommitted
feat: prebuilt binary support for WolfDisk
Add GitHub Actions release workflow that builds wolfdisk and wolfdiskctl as static musl binaries for x86_64 and aarch64. Update setup.sh to try downloading prebuilt binaries first, falling back to source build. Adds release profile optimizations and bumps version to 2.7.0. Co-Authored-By: CodeWolf <paul@wolf.uk.com> Co-Authored-By: Wolf Software Systems Ltd <paul@wolf.uk.com>
1 parent dbfcdc1 commit d3f1bf9

3 files changed

Lines changed: 272 additions & 63 deletions

File tree

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: WolfDisk — Build Release Binaries
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'wolfdisk/Cargo.toml'
8+
- 'wolfdisk/src/**'
9+
- '.github/workflows/wolfdisk-release.yml'
10+
workflow_dispatch:
11+
12+
defaults:
13+
run:
14+
working-directory: wolfdisk
15+
16+
jobs:
17+
build:
18+
strategy:
19+
matrix:
20+
include:
21+
- target: x86_64-unknown-linux-musl
22+
arch: x86_64
23+
runner: ubuntu-latest
24+
- target: aarch64-unknown-linux-musl
25+
arch: aarch64
26+
runner: ubuntu-latest
27+
28+
runs-on: ${{ matrix.runner }}
29+
steps:
30+
- uses: actions/checkout@v4
31+
32+
- name: Install Rust
33+
uses: dtolnay/rust-toolchain@stable
34+
with:
35+
targets: ${{ matrix.target }}
36+
37+
- name: Install cross
38+
run: cargo install cross --git https://github.com/cross-rs/cross
39+
working-directory: .
40+
41+
- name: Build static binaries
42+
run: cross build --release --target ${{ matrix.target }}
43+
44+
- name: Get version
45+
id: version
46+
run: echo "version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> "$GITHUB_OUTPUT"
47+
48+
- name: Package binaries
49+
run: |
50+
mkdir -p dist
51+
cp target/${{ matrix.target }}/release/wolfdisk dist/wolfdisk-${{ matrix.arch }}
52+
cp target/${{ matrix.target }}/release/wolfdiskctl dist/wolfdiskctl-${{ matrix.arch }}
53+
chmod +x dist/wolfdisk-${{ matrix.arch }}
54+
chmod +x dist/wolfdiskctl-${{ matrix.arch }}
55+
56+
- name: Upload artifacts
57+
uses: actions/upload-artifact@v4
58+
with:
59+
name: wolfdisk-${{ matrix.arch }}
60+
path: wolfdisk/dist/*
61+
62+
release:
63+
needs: build
64+
runs-on: ubuntu-latest
65+
permissions:
66+
contents: write
67+
steps:
68+
- uses: actions/checkout@v4
69+
70+
- name: Get version
71+
id: version
72+
run: echo "version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> "$GITHUB_OUTPUT"
73+
working-directory: wolfdisk
74+
75+
- name: Download all artifacts
76+
uses: actions/download-artifact@v4
77+
with:
78+
path: dist
79+
merge-multiple: true
80+
81+
- name: Create or update release
82+
env:
83+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+
run: |
85+
VERSION="v${{ steps.version.outputs.version }}-wolfdisk"
86+
87+
# Delete existing release if it exists (update scenario)
88+
gh release delete "$VERSION" --yes 2>/dev/null || true
89+
git push --delete origin "$VERSION" 2>/dev/null || true
90+
91+
# Create release with binaries
92+
gh release create "$VERSION" \
93+
--title "WolfDisk ${{ steps.version.outputs.version }}" \
94+
--notes "Prebuilt static binaries for Linux x86_64 and aarch64 (ARM64/Raspberry Pi 4+)." \
95+
dist/wolfdisk-x86_64 \
96+
dist/wolfdisk-aarch64 \
97+
dist/wolfdiskctl-x86_64 \
98+
dist/wolfdiskctl-aarch64
99+
working-directory: .

wolfdisk/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "wolfdisk"
3-
version = "2.6.0"
3+
version = "2.7.0"
44
edition = "2021"
55
authors = ["Wolf Software Systems Ltd"]
66
description = "Distributed file system with replicated and shared storage modes"
@@ -66,3 +66,8 @@ path = "src/main.rs"
6666
[[bin]]
6767
name = "wolfdiskctl"
6868
path = "src/bin/wolfdiskctl.rs"
69+
70+
[profile.release]
71+
strip = "debuginfo"
72+
codegen-units = 1
73+
lto = "thin"

wolfdisk/setup.sh

Lines changed: 167 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,59 @@ if [ "$EUID" -ne 0 ]; then
2626
fi
2727
fi
2828

29+
BRANCH="main"
30+
while [ $# -gt 0 ]; do
31+
case "$1" in
32+
--beta) BRANCH="beta" ;;
33+
esac
34+
shift
35+
done
36+
37+
# Allow git to operate on repos owned by other users
38+
export GIT_CONFIG_COUNT=1
39+
export GIT_CONFIG_KEY_0=safe.directory
40+
export GIT_CONFIG_VALUE_0="*"
41+
42+
# ─── Architecture detection for prebuilt binaries ──────────────────────────
43+
HOST_ARCH=$(uname -m)
44+
case "$HOST_ARCH" in
45+
x86_64) BINARY_ARCH="x86_64" ;;
46+
aarch64) BINARY_ARCH="aarch64" ;;
47+
*) BINARY_ARCH="" ;; # unsupported — will build from source
48+
esac
49+
50+
# Download a prebuilt binary from GitHub Releases.
51+
# Queries the API to find the correct release asset (monorepo-safe).
52+
# Usage: download_prebuilt <binary_name> <dest_path>
53+
# Returns 0 on success, 1 on failure (caller should fall back to source build)
54+
download_prebuilt() {
55+
local binary="$1" dest="$2"
56+
if [ -z "$BINARY_ARCH" ]; then
57+
return 1
58+
fi
59+
local asset="${binary}-${BINARY_ARCH}"
60+
echo " Downloading prebuilt ${binary} for ${BINARY_ARCH}..."
61+
# Find download URL from the latest WolfScale release containing this asset
62+
local url
63+
url=$(curl -sSL "https://api.github.com/repos/wolfsoftwaresystemsltd/WolfScale/releases" \
64+
| grep "browser_download_url.*${asset}" | head -1 | cut -d'"' -f4)
65+
if [ -z "$url" ]; then
66+
echo " ⚠ Prebuilt binary not available — will build from source"
67+
return 1
68+
fi
69+
local tmpfile="${dest}.download"
70+
if curl -fSL --connect-timeout 15 --max-time 300 --retry 2 -o "$tmpfile" "$url" 2>&1; then
71+
mv "$tmpfile" "$dest"
72+
chmod +x "$dest"
73+
echo " ✓ Downloaded prebuilt ${binary} (${BINARY_ARCH})"
74+
return 0
75+
else
76+
echo " ⚠ Prebuilt binary download failed — will build from source"
77+
rm -f "$tmpfile"
78+
return 1
79+
fi
80+
}
81+
2982
echo ""
3083
echo " 🐺 WolfDisk Installer"
3184
echo " ─────────────────────────────────────"
@@ -48,61 +101,21 @@ else
48101
exit 1
49102
fi
50103

51-
# Install dependencies
104+
# Install runtime dependencies (fuse3 is always needed)
52105
echo ""
53106
echo " Installing system dependencies..."
54107

55108
if [ "$PKG_MANAGER" = "apt" ]; then
56109
apt update
57-
apt install -y git curl build-essential pkg-config libssl-dev libfuse3-dev fuse3
110+
apt install -y curl fuse3
58111
elif [ "$PKG_MANAGER" = "dnf" ]; then
59-
dnf install -y git curl gcc gcc-c++ make openssl-devel pkg-config fuse3-devel fuse3
112+
dnf install -y curl fuse3
60113
elif [ "$PKG_MANAGER" = "yum" ]; then
61-
yum install -y git curl gcc gcc-c++ make openssl-devel pkgconfig fuse3-devel fuse3
114+
yum install -y curl fuse3
62115
fi
63116

64117
echo " ✓ System dependencies installed"
65118

66-
# Determine the real user (even when running under sudo)
67-
REAL_USER="${SUDO_USER:-$USER}"
68-
REAL_HOME=$(eval echo "~$REAL_USER")
69-
70-
# Install Rust if not present (for the real user)
71-
if ! su - "$REAL_USER" -c 'command -v rustc' &> /dev/null; then
72-
echo ""
73-
echo " Installing Rust for user $REAL_USER..."
74-
su - "$REAL_USER" -c 'curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y'
75-
echo " ✓ Rust installed"
76-
else
77-
RUST_VER=$(su - "$REAL_USER" -c 'rustc --version' 2>/dev/null)
78-
echo " ✓ Rust already installed ($RUST_VER)"
79-
fi
80-
81-
# Clone or update repository
82-
INSTALL_DIR="/opt/wolfscale-src"
83-
echo ""
84-
echo " Cloning WolfScale repository..."
85-
86-
if [ -d "$INSTALL_DIR" ]; then
87-
echo " Updating existing installation..."
88-
cd "$INSTALL_DIR"
89-
git fetch origin
90-
git reset --hard origin/main
91-
else
92-
git clone https://github.com/wolfsoftwaresystemsltd/WolfScale.git "$INSTALL_DIR"
93-
cd "$INSTALL_DIR"
94-
fi
95-
96-
chown -R "$REAL_USER:$REAL_USER" "$INSTALL_DIR"
97-
echo " ✓ Repository cloned to $INSTALL_DIR"
98-
99-
# Build WolfDisk (as the real user so cargo/rustup are available)
100-
echo ""
101-
echo " Building WolfDisk (this may take a few minutes)..."
102-
cd "$INSTALL_DIR/wolfdisk"
103-
su - "$REAL_USER" -c "cd $INSTALL_DIR/wolfdisk && source \$HOME/.cargo/env && cargo build --release"
104-
echo " ✓ Build complete"
105-
106119
# Stop service if running (for upgrades)
107120
if systemctl is-active --quiet wolfdisk 2>/dev/null; then
108121
echo ""
@@ -115,22 +128,78 @@ else
115128
RESTART_SERVICE=false
116129
fi
117130

118-
# Install binary
131+
# --- Try prebuilt binaries first, fall back to source build ---
119132
echo ""
120-
if [ -f "/usr/local/bin/wolfdisk" ]; then
121-
echo " Upgrading WolfDisk..."
122-
rm -f /usr/local/bin/wolfdisk
123-
else
124-
echo " Installing WolfDisk..."
133+
WOLFDISK_PREBUILT=false
134+
if download_prebuilt "wolfdisk" "/usr/local/bin/wolfdisk"; then
135+
download_prebuilt "wolfdiskctl" "/usr/local/bin/wolfdiskctl" || true
136+
WOLFDISK_PREBUILT=true
125137
fi
126-
cp "$INSTALL_DIR/wolfdisk/target/release/wolfdisk" /usr/local/bin/wolfdisk
127-
chmod +x /usr/local/bin/wolfdisk
128-
echo " ✓ wolfdisk installed to /usr/local/bin/wolfdisk"
129138

130-
# Install wolfdiskctl control utility
131-
cp "$INSTALL_DIR/wolfdisk/target/release/wolfdiskctl" /usr/local/bin/wolfdiskctl
132-
chmod +x /usr/local/bin/wolfdiskctl
133-
echo " ✓ wolfdiskctl installed to /usr/local/bin/wolfdiskctl"
139+
if [ "$WOLFDISK_PREBUILT" = "false" ]; then
140+
echo ""
141+
echo " Building from source..."
142+
143+
# Install build dependencies
144+
if [ "$PKG_MANAGER" = "apt" ]; then
145+
apt install -y git build-essential pkg-config libssl-dev libfuse3-dev
146+
elif [ "$PKG_MANAGER" = "dnf" ]; then
147+
dnf install -y git gcc gcc-c++ make openssl-devel pkg-config fuse3-devel
148+
elif [ "$PKG_MANAGER" = "yum" ]; then
149+
yum install -y git gcc gcc-c++ make openssl-devel pkgconfig fuse3-devel
150+
fi
151+
152+
# Determine the real user (even when running under sudo)
153+
REAL_USER="${SUDO_USER:-$USER}"
154+
REAL_HOME=$(eval echo "~$REAL_USER")
155+
156+
# Install Rust if not present (for the real user)
157+
if ! su - "$REAL_USER" -c 'command -v rustc' &> /dev/null; then
158+
echo ""
159+
echo " Installing Rust for user $REAL_USER..."
160+
su - "$REAL_USER" -c 'curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y'
161+
echo " ✓ Rust installed"
162+
else
163+
RUST_VER=$(su - "$REAL_USER" -c 'rustc --version' 2>/dev/null)
164+
echo " ✓ Rust already installed ($RUST_VER)"
165+
fi
166+
167+
# Clone or update repository
168+
INSTALL_DIR="/opt/wolfscale-src"
169+
echo ""
170+
echo " Cloning WolfScale repository..."
171+
172+
if [ -d "$INSTALL_DIR" ]; then
173+
echo " Updating existing installation..."
174+
cd "$INSTALL_DIR"
175+
git fetch origin
176+
git reset --hard origin/$BRANCH
177+
else
178+
git clone -b "$BRANCH" https://github.com/wolfsoftwaresystemsltd/WolfScale.git "$INSTALL_DIR"
179+
cd "$INSTALL_DIR"
180+
fi
181+
182+
chown -R "$REAL_USER:$REAL_USER" "$INSTALL_DIR"
183+
echo " ✓ Repository cloned to $INSTALL_DIR"
184+
185+
# Build WolfDisk (as the real user so cargo/rustup are available)
186+
echo ""
187+
echo " Building WolfDisk (this may take a few minutes)..."
188+
cd "$INSTALL_DIR/wolfdisk"
189+
su - "$REAL_USER" -c "cd $INSTALL_DIR/wolfdisk && source \$HOME/.cargo/env && cargo build --release"
190+
echo " ✓ Build complete"
191+
192+
# Install binaries
193+
echo ""
194+
echo " Installing WolfDisk..."
195+
cp "$INSTALL_DIR/wolfdisk/target/release/wolfdisk" /usr/local/bin/wolfdisk
196+
chmod +x /usr/local/bin/wolfdisk
197+
echo " ✓ wolfdisk installed to /usr/local/bin/wolfdisk"
198+
199+
cp "$INSTALL_DIR/wolfdisk/target/release/wolfdiskctl" /usr/local/bin/wolfdiskctl
200+
chmod +x /usr/local/bin/wolfdiskctl
201+
echo " ✓ wolfdiskctl installed to /usr/local/bin/wolfdiskctl"
202+
fi
134203

135204
# Create data directory
136205
echo ""
@@ -269,15 +338,51 @@ else
269338
echo " (Upgrade mode - skipping configuration prompts)"
270339
fi
271340

272-
# Run service installer only for new installations
341+
# Service setup
273342
if [ ! -f "/etc/systemd/system/wolfdisk.service" ]; then
274343
echo ""
275344
echo " ─────────────────────────────────────"
276-
echo " Running service setup..."
345+
echo " Creating systemd service..."
277346
echo " ─────────────────────────────────────"
278-
echo ""
279-
280-
bash "$INSTALL_DIR/wolfdisk/install_service.sh"
347+
348+
# Get mount point from config or use default
349+
SVC_MOUNT="/mnt/wolfdisk"
350+
SVC_CONFIG="/etc/wolfdisk/config.toml"
351+
if [ -f "$SVC_CONFIG" ]; then
352+
SVC_MOUNT_CFG=$(grep -E "^path\s*=" "$SVC_CONFIG" | cut -d'"' -f2 | head -1)
353+
[ -n "$SVC_MOUNT_CFG" ] && SVC_MOUNT="$SVC_MOUNT_CFG"
354+
fi
355+
356+
# Enable user_allow_other in /etc/fuse.conf
357+
if ! grep -q "^user_allow_other" /etc/fuse.conf 2>/dev/null; then
358+
echo "user_allow_other" >> /etc/fuse.conf
359+
echo " ✓ Enabled user_allow_other in /etc/fuse.conf"
360+
fi
361+
362+
cat << SVCEOF > /etc/systemd/system/wolfdisk.service
363+
[Unit]
364+
Description=WolfDisk Distributed File System
365+
After=network.target
366+
Wants=network-online.target
367+
368+
[Service]
369+
Type=simple
370+
ExecStart=/usr/local/bin/wolfdisk --config $SVC_CONFIG mount --mountpoint $SVC_MOUNT
371+
ExecStop=/usr/local/bin/wolfdisk unmount --mountpoint $SVC_MOUNT
372+
Restart=on-failure
373+
RestartSec=5
374+
StandardOutput=journal
375+
StandardError=journal
376+
NoNewPrivileges=false
377+
ProtectSystem=false
378+
PrivateTmp=false
379+
380+
[Install]
381+
WantedBy=multi-user.target
382+
SVCEOF
383+
384+
systemctl daemon-reload
385+
echo " ✓ Created wolfdisk.service"
281386
else
282387
echo ""
283388
echo " ✓ Service already installed - reloading systemd"

0 commit comments

Comments
 (0)