Update .gitignore and remove obsolete documentation files
- Added new entries to .gitignore for build artifacts and macOS output directories to streamline the build process. - Deleted outdated documentation files: AUTH_LOGIN_FIX.md, AUTBOOT_CONFIGURATION.md, BACKEND_FIXES.md, BACKEND_STARTUP_FIX.md, BITCOIN_CORE_HEADLESS_FIX.md, BITCOIN_CORE_UI_COMPLETE.md, BITCOIN_STANDALONE_UI_COMPLETE.md, BITCOIN_UI_COMPLETE.md, BOOT_SEQUENCE_DIAGRAM.txt, and BUILD_COMMANDS_REFERENCE.txt to declutter the repository and remove unnecessary content.
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
# Build Status and Implementation Summary
|
||||
|
||||
## ✅ Completed Implementation
|
||||
|
||||
### Core Build System
|
||||
- ✅ Main build script (`build-alpine-iso.sh`)
|
||||
- ✅ macOS build wrapper (`build-macos.sh`)
|
||||
- ✅ Linux build wrapper (`build-linux.sh`)
|
||||
- ✅ Native Alpine build (`build-alpine-native.sh`)
|
||||
- ✅ Docker build image (`Dockerfile.build`)
|
||||
- ✅ Dependency checker (`scripts/check-dependencies.sh`)
|
||||
|
||||
### Component Build Scripts
|
||||
- ✅ Backend build (`scripts/build-backend.sh`)
|
||||
- ✅ Frontend build (`scripts/build-frontend.sh`)
|
||||
- ✅ APK creation (`scripts/create-backend-apk.sh`)
|
||||
- ✅ Installation script (`scripts/install-archipelago.sh`)
|
||||
- ✅ ISO to disk converter (`scripts/convert-iso-to-disk.sh`)
|
||||
|
||||
### Alpine Profile
|
||||
- ✅ Custom profile (`alpine-profile/mkimg.archipelago.sh`)
|
||||
- ✅ Systemd service (`alpine-profile/overlay/etc/systemd/system/archipelago.service`)
|
||||
- ✅ OpenRC init script (`alpine-profile/overlay/etc/init.d/archipelago`)
|
||||
- ✅ First boot script (`alpine-profile/overlay/etc/local.d/archipelago-install.start`)
|
||||
- ✅ Configuration files (`alpine-profile/overlay/etc/archipelago/config.toml`)
|
||||
- ✅ Hostname and hosts files
|
||||
|
||||
### Documentation
|
||||
- ✅ Building OS Images guide (`docs/building-os-images.md`)
|
||||
- ✅ Quick start guide (`QUICKSTART.md`)
|
||||
- ✅ Updated README (`README.md`)
|
||||
- ✅ Profile documentation (`alpine-profile/README.md`)
|
||||
|
||||
## 🚧 Known Limitations
|
||||
|
||||
### Alpine mkimage Integration
|
||||
The build system uses Alpine's `mkimage.sh` which requires:
|
||||
- Alpine aports repository clone
|
||||
- Proper profile structure matching Alpine's expectations
|
||||
- May need adjustments based on Alpine version
|
||||
|
||||
### First Build
|
||||
- First build will clone Alpine aports (large download)
|
||||
- May take 30-60 minutes depending on system
|
||||
- Subsequent builds are faster
|
||||
|
||||
### Cross-Compilation
|
||||
- Backend builds for host by default
|
||||
- Musl target recommended for static binaries
|
||||
- Install with: `rustup target add x86_64-unknown-linux-musl`
|
||||
|
||||
## 📋 Next Steps for Testing
|
||||
|
||||
1. **Test on macOS**:
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh
|
||||
```
|
||||
|
||||
2. **Test on Linux** (HP ProDesk 400 G4 DM):
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-linux.sh
|
||||
```
|
||||
|
||||
3. **Verify Output**:
|
||||
- Check `results/` directory for ISO/image
|
||||
- Verify file size (should be 100MB-500MB for ISO)
|
||||
- Test in virtual machine first
|
||||
|
||||
4. **Flash to Device**:
|
||||
- Use `dd` to flash ISO to USB
|
||||
- Boot from USB on target device
|
||||
- Verify first boot setup works
|
||||
|
||||
## 🔧 Potential Issues and Fixes
|
||||
|
||||
### Issue: Alpine aports clone fails
|
||||
**Fix**: Manual clone or check network connection
|
||||
|
||||
### Issue: mkimage.sh not found
|
||||
**Fix**: Ensure aports repository was cloned correctly
|
||||
|
||||
### Issue: Profile not recognized
|
||||
**Fix**: Check profile is in `aports/scripts/mkimg.archipelago/`
|
||||
|
||||
### Issue: Backend build fails
|
||||
**Fix**: Install Rust and musl target, check dependencies
|
||||
|
||||
### Issue: Frontend build fails
|
||||
**Fix**: Install Node.js 18+, run `npm install` first
|
||||
|
||||
## 📝 Build Output Structure
|
||||
|
||||
```
|
||||
results/
|
||||
├── archipelago-0.1.0-x86_64.iso # Bootable ISO
|
||||
└── archipelago-0.1.0-x86_64.img # Disk image (if disk build)
|
||||
|
||||
build/
|
||||
├── backend/
|
||||
│ └── archipelago # Compiled binary
|
||||
└── frontend/ # Static files
|
||||
|
||||
apks/
|
||||
└── archipelago-backend-0.1.0-r0.apk # Alpine package
|
||||
```
|
||||
|
||||
## ✨ Ready to Build!
|
||||
|
||||
The system is ready for building. Start with:
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh # On macOS
|
||||
# or
|
||||
./build-linux.sh # On Linux
|
||||
```
|
||||
@@ -1,93 +0,0 @@
|
||||
# Implementation Completion Checklist
|
||||
|
||||
## ✅ Core Build System
|
||||
|
||||
- [x] Main build orchestrator (`build-alpine-iso.sh`)
|
||||
- [x] macOS build wrapper (`build-macos.sh`)
|
||||
- [x] Linux build wrapper (`build-linux.sh`)
|
||||
- [x] Native Alpine build (`build-alpine-native.sh`)
|
||||
- [x] Docker build image (`Dockerfile.build`)
|
||||
- [x] Docker Compose config (`docker-compose.build.yml`)
|
||||
- [x] Makefile for convenience commands
|
||||
|
||||
## ✅ Component Build Scripts
|
||||
|
||||
- [x] Backend build script (`scripts/build-backend.sh`)
|
||||
- [x] Frontend build script (`scripts/build-frontend.sh`)
|
||||
- [x] APK creation script (`scripts/create-backend-apk.sh`)
|
||||
- [x] Installation script (`scripts/install-archipelago.sh`)
|
||||
- [x] ISO to disk converter (`scripts/convert-iso-to-disk.sh`)
|
||||
- [x] Dependency checker (`scripts/check-dependencies.sh`)
|
||||
- [x] Setup script (`scripts/setup-alpine-build.sh`)
|
||||
|
||||
## ✅ Alpine Profile
|
||||
|
||||
- [x] Custom profile definition (`alpine-profile/mkimg.archipelago.sh`)
|
||||
- [x] Systemd service file
|
||||
- [x] OpenRC init script
|
||||
- [x] First boot script
|
||||
- [x] Configuration files (config.toml, hostname, hosts)
|
||||
- [x] Profile documentation
|
||||
|
||||
## ✅ Integration Files
|
||||
|
||||
- [x] Systemd service unit
|
||||
- [x] OpenRC init script
|
||||
- [x] First boot installation script
|
||||
- [x] Default configuration
|
||||
- [x] Hostname and network config
|
||||
|
||||
## ✅ Documentation
|
||||
|
||||
- [x] Building OS Images guide (`docs/building-os-images.md`)
|
||||
- [x] Quick Start guide (`QUICKSTART.md`)
|
||||
- [x] Updated README (`README.md`)
|
||||
- [x] Build Status (`BUILD_STATUS.md`)
|
||||
- [x] Implementation Summary (`SUMMARY.md`)
|
||||
- [x] Profile README (`alpine-profile/README.md`)
|
||||
- [x] Scripts README (`scripts/README.md`)
|
||||
|
||||
## ✅ Build Infrastructure
|
||||
|
||||
- [x] Directory structure created
|
||||
- [x] .gitignore for build artifacts
|
||||
- [x] All scripts made executable
|
||||
- [x] Volume mounts configured for Docker
|
||||
- [x] Error handling in scripts
|
||||
|
||||
## 🎯 Ready to Test
|
||||
|
||||
The implementation is complete! You can now:
|
||||
|
||||
1. **Test on macOS**:
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh
|
||||
```
|
||||
|
||||
2. **Test on Linux** (HP ProDesk 400 G4 DM):
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-linux.sh
|
||||
```
|
||||
|
||||
3. **Check dependencies first**:
|
||||
```bash
|
||||
./scripts/check-dependencies.sh
|
||||
```
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- First build will download Alpine aports repository (~500MB)
|
||||
- Build time: 30-60 minutes on first run, faster on subsequent builds
|
||||
- Output: ISO file in `results/` directory
|
||||
- Can be flashed to USB or disk using `dd` command
|
||||
|
||||
## 🔍 What to Verify
|
||||
|
||||
After first build:
|
||||
- [ ] ISO file exists in `results/`
|
||||
- [ ] ISO file size is reasonable (200-500MB)
|
||||
- [ ] Can boot ISO in virtual machine
|
||||
- [ ] Services start on first boot
|
||||
- [ ] Web UI accessible at http://device-ip:8100
|
||||
@@ -1,93 +0,0 @@
|
||||
# Alpine Linux Base Image for Archipelago Bitcoin Node OS
|
||||
# Multi-arch support: ARM64 (Raspberry Pi) and x86_64
|
||||
|
||||
ARG ALPINE_VERSION=3.19
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
|
||||
# Install essential packages
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
curl \
|
||||
wget \
|
||||
ca-certificates \
|
||||
openssl \
|
||||
sudo \
|
||||
shadow \
|
||||
systemd \
|
||||
systemd-openrc \
|
||||
dbus \
|
||||
udev \
|
||||
util-linux \
|
||||
e2fsprogs \
|
||||
dosfstools \
|
||||
parted \
|
||||
gptfdisk \
|
||||
rsync \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
htop \
|
||||
iotop \
|
||||
net-tools \
|
||||
iproute2 \
|
||||
iputils \
|
||||
tcpdump \
|
||||
tzdata \
|
||||
logrotate \
|
||||
fail2ban \
|
||||
ufw \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Install Podman and dependencies
|
||||
RUN apk add --no-cache \
|
||||
podman \
|
||||
podman-compose \
|
||||
crun \
|
||||
fuse-overlayfs \
|
||||
slirp4netns \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Create archipelago user for rootless containers
|
||||
RUN adduser -D -s /bin/bash archipelago && \
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman, /usr/bin/podman-compose" >> /etc/sudoers
|
||||
|
||||
# Configure Podman for rootless operation
|
||||
RUN mkdir -p /home/archipelago/.config/containers && \
|
||||
echo 'driver = "overlay"' > /home/archipelago/.config/containers/storage.conf && \
|
||||
echo 'rootless_storage_path = "/home/archipelago/.local/share/containers/storage"' >> /home/archipelago/.config/containers/storage.conf
|
||||
|
||||
# Set up systemd for container management
|
||||
RUN systemctl enable systemd-resolved && \
|
||||
systemctl enable dbus
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p \
|
||||
/var/lib/archipelago \
|
||||
/var/lib/archipelago/apps \
|
||||
/var/lib/archipelago/secrets \
|
||||
/var/lib/archipelago/logs \
|
||||
/var/lib/archipelago/backups \
|
||||
/etc/archipelago
|
||||
|
||||
# Copy hardening scripts
|
||||
COPY scripts/harden-alpine.sh /usr/local/bin/
|
||||
COPY scripts/install-podman.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/harden-alpine.sh /usr/local/bin/install-podman.sh
|
||||
|
||||
# Run hardening script
|
||||
RUN /usr/local/bin/harden-alpine.sh
|
||||
|
||||
# Set timezone to UTC
|
||||
RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
||||
|
||||
# Configure log rotation
|
||||
COPY configs/logrotate.conf /etc/logrotate.d/archipelago
|
||||
|
||||
# Set up firewall defaults (will be configured on first boot)
|
||||
RUN ufw --force enable || true
|
||||
|
||||
# Expose common ports (will be managed by firewall rules)
|
||||
EXPOSE 22 80 443 8332 8333 9735 10009 8080 8443
|
||||
|
||||
# Default command
|
||||
CMD ["/bin/bash"]
|
||||
@@ -1,41 +0,0 @@
|
||||
# Docker build image for Archipelago OS image building
|
||||
# Can be used on macOS or Linux
|
||||
|
||||
FROM --platform=linux/amd64 alpine:3.19
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
git \
|
||||
alpine-sdk \
|
||||
abuild \
|
||||
alpine-conf \
|
||||
syslinux \
|
||||
xorriso \
|
||||
squashfs-tools \
|
||||
grub \
|
||||
grub-efi \
|
||||
mtools \
|
||||
dosfstools \
|
||||
e2fsprogs \
|
||||
rsync \
|
||||
curl \
|
||||
wget \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Install Rust for backend compilation
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
# Install Node.js for frontend build
|
||||
RUN apk add --no-cache nodejs npm
|
||||
|
||||
# Setup abuild
|
||||
RUN abuild-keygen -a -n || true
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /workspace
|
||||
|
||||
# Default command
|
||||
CMD ["/bin/bash"]
|
||||
@@ -1,172 +0,0 @@
|
||||
# ✅ Implementation Complete: Bootable OS Image Builder
|
||||
|
||||
## Summary
|
||||
|
||||
A complete system for building bootable Alpine Linux OS images for Archipelago Bitcoin Node OS has been implemented. The system supports building on both macOS (via Docker) and Linux (native or Docker), and produces bootable ISO and disk images ready for flashing to x86_64 desktop computers.
|
||||
|
||||
## ✅ What's Been Created
|
||||
|
||||
### Build System (9 files)
|
||||
- `build-alpine-iso.sh` - Main orchestrator
|
||||
- `build-macos.sh` - macOS wrapper
|
||||
- `build-linux.sh` - Linux wrapper
|
||||
- `build-alpine-native.sh` - Native Alpine build
|
||||
- `Dockerfile.build` - Docker build environment
|
||||
- `docker-compose.build.yml` - Docker Compose config
|
||||
- `Makefile` - Build shortcuts
|
||||
- `.gitignore` - Build artifact exclusions
|
||||
|
||||
### Build Scripts (7 files)
|
||||
- `scripts/build-backend.sh` - Compiles Rust backend
|
||||
- `scripts/build-frontend.sh` - Builds Vue.js frontend
|
||||
- `scripts/create-backend-apk.sh` - Creates Alpine APK
|
||||
- `scripts/install-archipelago.sh` - Installs into image
|
||||
- `scripts/convert-iso-to-disk.sh` - Converts ISO to disk image
|
||||
- `scripts/check-dependencies.sh` - Checks build prerequisites
|
||||
- `scripts/setup-alpine-build.sh` - Sets up Alpine environment
|
||||
|
||||
### Alpine Profile (6+ files)
|
||||
- `alpine-profile/mkimg.archipelago.sh` - Profile definition
|
||||
- `alpine-profile/overlay/etc/systemd/system/archipelago.service`
|
||||
- `alpine-profile/overlay/etc/init.d/archipelago`
|
||||
- `alpine-profile/overlay/etc/local.d/archipelago-install.start`
|
||||
- `alpine-profile/overlay/etc/archipelago/config.toml`
|
||||
- `alpine-profile/overlay/etc/hostname`
|
||||
- `alpine-profile/overlay/etc/hosts`
|
||||
|
||||
### Documentation (8 files)
|
||||
- `docs/building-os-images.md` - Complete build guide
|
||||
- `README.md` - Updated with new build process
|
||||
- `QUICKSTART.md` - Quick reference
|
||||
- `GETTING_STARTED.md` - Getting started guide
|
||||
- `BUILD_STATUS.md` - Implementation status
|
||||
- `SUMMARY.md` - Implementation summary
|
||||
- `COMPLETION_CHECKLIST.md` - Completion checklist
|
||||
- `alpine-profile/README.md` - Profile documentation
|
||||
- `scripts/README.md` - Scripts documentation
|
||||
|
||||
## 🎯 Ready to Use
|
||||
|
||||
### On macOS (Your Current Machine)
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh
|
||||
```
|
||||
|
||||
**Requirements**:
|
||||
- Docker Desktop installed and running
|
||||
- 10GB+ disk space
|
||||
- 30-60 minutes for first build
|
||||
|
||||
### On Linux (HP ProDesk 400 G4 DM)
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-linux.sh
|
||||
```
|
||||
|
||||
**Requirements**:
|
||||
- Alpine Linux (preferred) OR Docker
|
||||
- 10GB+ disk space
|
||||
- 20-60 minutes depending on setup
|
||||
|
||||
## 📦 Build Output
|
||||
|
||||
After successful build:
|
||||
|
||||
```
|
||||
results/
|
||||
└── archipelago-0.1.0-x86_64.iso # Bootable ISO (~200-500MB)
|
||||
```
|
||||
|
||||
For disk images:
|
||||
```
|
||||
results/
|
||||
└── archipelago-0.1.0-x86_64.img # Disk image (~4GB)
|
||||
```
|
||||
|
||||
## 🔄 Build Process
|
||||
|
||||
1. **Dependency Check** → Verifies Rust, Node.js, Docker
|
||||
2. **Backend Build** → Compiles Rust → `build/backend/archipelago`
|
||||
3. **Frontend Build** → Builds Vue.js → `build/frontend/`
|
||||
4. **APK Creation** → Packages backend → `apks/archipelago-backend-*.apk`
|
||||
5. **Alpine Build** → Creates base Alpine image
|
||||
6. **Integration** → Installs Archipelago components
|
||||
7. **Output** → Creates ISO/image file
|
||||
|
||||
## 💾 Flashing to Device
|
||||
|
||||
### From macOS
|
||||
|
||||
```bash
|
||||
# List disks
|
||||
diskutil list
|
||||
|
||||
# Flash ISO to USB (replace X)
|
||||
sudo dd if=results/archipelago-0.1.0-x86_64.iso of=/dev/rdiskX bs=1m
|
||||
```
|
||||
|
||||
### From Linux
|
||||
|
||||
```bash
|
||||
# List disks
|
||||
lsblk
|
||||
|
||||
# Flash ISO to USB (replace X)
|
||||
sudo dd if=results/archipelago-0.1.0-x86_64.iso of=/dev/sdX bs=1M
|
||||
```
|
||||
|
||||
## 🎉 First Boot
|
||||
|
||||
After flashing and booting:
|
||||
|
||||
1. System boots Alpine Linux
|
||||
2. First boot script runs automatically
|
||||
3. Archipelago services start
|
||||
4. Access web UI: **http://device-ip:8100**
|
||||
5. Or API: **http://device-ip:5959**
|
||||
|
||||
## 📋 What's Included in the Image
|
||||
|
||||
- **Alpine Linux 3.19** - Minimal base OS
|
||||
- **Podman** - Container runtime (rootless)
|
||||
- **Systemd** - Service management
|
||||
- **NetworkManager** - Network configuration
|
||||
- **Archipelago Backend** - Rust API server
|
||||
- **Archipelago Frontend** - Vue.js web interface
|
||||
- **First Boot Setup** - Automatic configuration
|
||||
|
||||
## 🔧 Customization
|
||||
|
||||
Edit these files to customize:
|
||||
|
||||
- **Packages**: `alpine-profile/mkimg.archipelago.sh` (apks variable)
|
||||
- **Services**: `alpine-profile/overlay/etc/systemd/system/archipelago.service`
|
||||
- **Config**: `alpine-profile/overlay/etc/archipelago/config.toml`
|
||||
- **First Boot**: `alpine-profile/overlay/etc/local.d/archipelago-install.start`
|
||||
|
||||
## ✨ Status: READY TO BUILD
|
||||
|
||||
All components are implemented and ready for testing. Start building with:
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh # On macOS
|
||||
# or
|
||||
./build-linux.sh # On Linux
|
||||
```
|
||||
|
||||
First build will take longer (downloads Alpine aports). Subsequent builds are faster.
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- [Getting Started](GETTING_STARTED.md) - Quick start guide
|
||||
- [Building OS Images](../docs/building-os-images.md) - Full detailed guide
|
||||
- [Build Status](BUILD_STATUS.md) - Implementation details
|
||||
- [Summary](SUMMARY.md) - What's implemented
|
||||
|
||||
---
|
||||
|
||||
**You're ready to build your first Archipelago OS image!** 🚀
|
||||
@@ -1,127 +0,0 @@
|
||||
# Getting Started: Building Your First Archipelago OS Image
|
||||
|
||||
## 🎯 Goal
|
||||
|
||||
Build a bootable Alpine Linux OS image that includes Archipelago Bitcoin Node OS, ready to flash to a Dell Optiplex or HP ProDesk 400 G4 DM.
|
||||
|
||||
## ✅ What's Ready
|
||||
|
||||
The complete build system is implemented and ready to use:
|
||||
|
||||
- ✅ Build scripts for macOS and Linux
|
||||
- ✅ Docker support for cross-platform building
|
||||
- ✅ Backend and frontend compilation
|
||||
- ✅ Alpine profile with Archipelago integration
|
||||
- ✅ ISO and disk image generation
|
||||
- ✅ First boot automation
|
||||
|
||||
## 🚀 Quick Start (macOS)
|
||||
|
||||
```bash
|
||||
# 1. Navigate to image recipe directory
|
||||
cd image-recipe
|
||||
|
||||
# 2. Check dependencies
|
||||
./scripts/check-dependencies.sh
|
||||
|
||||
# 3. Build the image
|
||||
./build-macos.sh
|
||||
```
|
||||
|
||||
**Expected time**: 30-60 minutes on first build (downloads Alpine aports)
|
||||
|
||||
**Output**: `results/archipelago-0.1.0-x86_64.iso`
|
||||
|
||||
## 🚀 Quick Start (Linux - HP ProDesk 400 G4 DM)
|
||||
|
||||
```bash
|
||||
# 1. Navigate to image recipe directory
|
||||
cd image-recipe
|
||||
|
||||
# 2. Build (auto-detects Alpine or Docker)
|
||||
./build-linux.sh
|
||||
```
|
||||
|
||||
**Expected time**: 20-40 minutes on Alpine, 30-60 minutes with Docker
|
||||
|
||||
**Output**: `results/archipelago-0.1.0-x86_64.iso`
|
||||
|
||||
## 📋 What Gets Built
|
||||
|
||||
1. **Backend Binary**: Rust backend compiled for x86_64
|
||||
2. **Frontend**: Vue.js app built as static files
|
||||
3. **APK Package**: Backend packaged as Alpine APK
|
||||
4. **Alpine Image**: Base Alpine Linux with:
|
||||
- Podman container runtime
|
||||
- Systemd services
|
||||
- Network configuration
|
||||
- Archipelago backend and frontend
|
||||
|
||||
## 💾 Flashing the Image
|
||||
|
||||
### Option 1: ISO to USB (Recommended)
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
sudo dd if=results/archipelago-0.1.0-x86_64.iso of=/dev/rdiskX bs=1m
|
||||
|
||||
# Linux
|
||||
sudo dd if=results/archipelago-0.1.0-x86_64.iso of=/dev/sdX bs=1M
|
||||
```
|
||||
|
||||
### Option 2: Disk Image Direct Flash
|
||||
|
||||
```bash
|
||||
# Build disk image
|
||||
BUILD_TYPE=disk ./build-macos.sh
|
||||
|
||||
# Flash directly
|
||||
sudo dd if=results/archipelago-0.1.0-x86_64.img of=/dev/sdX bs=1M
|
||||
```
|
||||
|
||||
⚠️ **WARNING**: Replace `X` with your actual device. Wrong device = data loss!
|
||||
|
||||
## 🎉 After Flashing
|
||||
|
||||
1. **Boot from USB/disk** on target device
|
||||
2. **Wait for first boot** (automatic setup)
|
||||
3. **Access web UI**: http://device-ip:8100
|
||||
4. **Or API**: http://device-ip:5959
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Build Fails
|
||||
|
||||
- **Check dependencies**: `./scripts/check-dependencies.sh`
|
||||
- **Check disk space**: Need 10GB+ free
|
||||
- **Check Docker**: `docker info` should work (macOS)
|
||||
- **Check logs**: Look for error messages in build output
|
||||
|
||||
### Image Doesn't Boot
|
||||
|
||||
- **Verify ISO**: `file results/*.iso` should show "ISO 9660"
|
||||
- **Try different USB port**
|
||||
- **Check BIOS/UEFI settings**
|
||||
- **Verify architecture**: Must be x86_64
|
||||
|
||||
### Services Don't Start
|
||||
|
||||
- **Check logs**: `journalctl -u archipelago` (on device)
|
||||
- **Check network**: `ip addr` (on device)
|
||||
- **Check Podman**: `podman info` (on device)
|
||||
|
||||
## 📚 More Information
|
||||
|
||||
- [Building OS Images](../docs/building-os-images.md) - Full detailed guide
|
||||
- [Build Status](BUILD_STATUS.md) - Implementation status
|
||||
- [Summary](SUMMARY.md) - What's been implemented
|
||||
|
||||
## 🎯 Next Steps
|
||||
|
||||
1. **Test build** on your macOS machine
|
||||
2. **Test build** on HP ProDesk 400 G4 DM
|
||||
3. **Flash to USB** and test boot
|
||||
4. **Flash to device** and verify functionality
|
||||
5. **Customize** profile if needed
|
||||
|
||||
Happy building! 🚀
|
||||
@@ -1,316 +0,0 @@
|
||||
# Archipelago Hardware Build System - Quick Reference
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Build for Start9 Server Pure
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
### Build for HP ProDesk
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-for-hardware.sh hp-prodesk iso
|
||||
```
|
||||
|
||||
### Build for Dell OptiPlex
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-for-hardware.sh dell-optiplex iso
|
||||
```
|
||||
|
||||
### Build for All Hardware
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-all-hardware.sh iso
|
||||
```
|
||||
|
||||
## 📋 Supported Hardware
|
||||
|
||||
| Hardware | Target Name | CPU | RAM | Storage |
|
||||
|----------|-------------|-----|-----|---------|
|
||||
| Start9 Server Pure | `start9-pure` | Intel i7-10710U | 32-64GB | 2-4TB NVMe |
|
||||
| HP ProDesk 400 G4 DM | `hp-prodesk` | Intel varies | 8GB+ | 128GB+ SSD |
|
||||
| Dell OptiPlex | `dell-optiplex` | Intel varies | 8GB+ | 128GB+ SSD |
|
||||
| Generic x86_64 | `generic` | Any x86_64 | 8GB+ | 128GB+ |
|
||||
|
||||
## 🔧 Build Commands
|
||||
|
||||
### Single Hardware Target
|
||||
```bash
|
||||
./build-for-hardware.sh <target> [iso|disk]
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# ISO image (recommended)
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
|
||||
# Disk image (advanced)
|
||||
./build-for-hardware.sh start9-pure disk
|
||||
|
||||
# Default is ISO
|
||||
./build-for-hardware.sh hp-prodesk
|
||||
```
|
||||
|
||||
### All Hardware Targets
|
||||
```bash
|
||||
./build-all-hardware.sh [iso|disk]
|
||||
```
|
||||
|
||||
Builds optimized images for all supported hardware in one command.
|
||||
|
||||
## 📦 Output Files
|
||||
|
||||
After build completes:
|
||||
|
||||
```
|
||||
results/
|
||||
├── archipelago-0.1.0-start9-pure-x86_64.iso
|
||||
├── archipelago-0.1.0-hp-prodesk-x86_64.iso
|
||||
├── archipelago-0.1.0-dell-optiplex-x86_64.iso
|
||||
├── archipelago-0.1.0-generic-x86_64.iso
|
||||
├── BUILD_MANIFEST_start9-pure.txt
|
||||
├── BUILD_MANIFEST_hp-prodesk.txt
|
||||
├── BUILD_MANIFEST_dell-optiplex.txt
|
||||
└── BUILD_MANIFEST_generic.txt
|
||||
```
|
||||
|
||||
## 🔍 What's Different Per Hardware?
|
||||
|
||||
Each build includes **hardware-specific optimizations**:
|
||||
|
||||
### Start9 Server Pure
|
||||
- ✅ Intel i7-10710U microcode
|
||||
- ✅ Intel UHD Graphics drivers
|
||||
- ✅ NVMe SSD optimizations
|
||||
- ✅ Coreboot firmware support
|
||||
- ✅ IME-disabled configurations
|
||||
- ✅ High-performance tuning
|
||||
|
||||
### HP ProDesk 400 G4 DM
|
||||
- ✅ Intel graphics support
|
||||
- ✅ HP firmware compatibility
|
||||
- ✅ SATA/NVMe detection
|
||||
- ✅ Compact form factor optimizations
|
||||
- ✅ Low-power configurations
|
||||
|
||||
### Dell OptiPlex
|
||||
- ✅ Multi-model support
|
||||
- ✅ Dell firmware compatibility
|
||||
- ✅ Legacy hardware support
|
||||
- ✅ Business-class features
|
||||
|
||||
### Generic
|
||||
- ✅ Broad hardware compatibility
|
||||
- ✅ Intel & AMD CPU support
|
||||
- ✅ Generic drivers
|
||||
- ✅ Maximum portability
|
||||
|
||||
## 💾 Flash to USB Drive
|
||||
|
||||
### macOS
|
||||
```bash
|
||||
# Find device
|
||||
diskutil list
|
||||
|
||||
# Unmount
|
||||
diskutil unmountDisk /dev/diskX
|
||||
|
||||
# Flash
|
||||
sudo dd if=results/archipelago-0.1.0-start9-pure-x86_64.iso \
|
||||
of=/dev/rdiskX bs=1m status=progress
|
||||
```
|
||||
|
||||
### Linux
|
||||
```bash
|
||||
# Find device
|
||||
lsblk
|
||||
|
||||
# Flash
|
||||
sudo dd if=results/archipelago-0.1.0-start9-pure-x86_64.iso \
|
||||
of=/dev/sdX bs=1M status=progress
|
||||
```
|
||||
|
||||
### GUI Tools
|
||||
- **balenaEtcher** (Recommended): https://www.balena.io/etcher/
|
||||
- **Rufus** (Windows): https://rufus.ie/
|
||||
|
||||
## 🎯 Installation Steps
|
||||
|
||||
1. **Flash ISO to USB** (see above)
|
||||
2. **Insert USB into target hardware**
|
||||
3. **Boot from USB**:
|
||||
- Start9 Pure: Press F12
|
||||
- HP ProDesk: Press F9
|
||||
- Dell OptiPlex: Press F12
|
||||
4. **Follow installation prompts**
|
||||
5. **Remove USB and reboot**
|
||||
6. **Access UI**: http://device-ip:8100
|
||||
|
||||
## 🔬 Verification
|
||||
|
||||
### Check ISO
|
||||
```bash
|
||||
# View build manifest
|
||||
cat results/BUILD_MANIFEST_start9-pure.txt
|
||||
|
||||
# Check file size
|
||||
ls -lh results/*.iso
|
||||
|
||||
# Verify checksum
|
||||
sha256sum results/archipelago-0.1.0-start9-pure-x86_64.iso
|
||||
```
|
||||
|
||||
### Test in VM
|
||||
```bash
|
||||
qemu-system-x86_64 \
|
||||
-m 4G \
|
||||
-smp 2 \
|
||||
-boot d \
|
||||
-cdrom results/archipelago-0.1.0-start9-pure-x86_64.iso \
|
||||
-enable-kvm
|
||||
```
|
||||
|
||||
## 🛠️ Environment Variables
|
||||
|
||||
Customize builds:
|
||||
|
||||
```bash
|
||||
# Set version
|
||||
export ARCHIPELAGO_VERSION="0.2.0"
|
||||
|
||||
# Set Alpine version
|
||||
export ALPINE_VERSION="3.19"
|
||||
|
||||
# Build with custom settings
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
## 📂 Directory Structure
|
||||
|
||||
```
|
||||
image-recipe/
|
||||
├── build-for-hardware.sh # Main build script
|
||||
├── build-all-hardware.sh # Build all targets
|
||||
├── alpine-profile/
|
||||
│ ├── overlay/ # Base system files
|
||||
│ ├── overlay-start9-pure/ # Start9-specific
|
||||
│ ├── overlay-hp-prodesk/ # HP-specific
|
||||
│ ├── overlay-dell-optiplex/ # Dell-specific
|
||||
│ └── overlay-merged/ # Final merged (auto)
|
||||
├── scripts/
|
||||
│ ├── build-backend.sh
|
||||
│ ├── build-frontend.sh
|
||||
│ └── install-archipelago.sh
|
||||
└── results/ # Build output
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Build Fails
|
||||
```bash
|
||||
# Clean everything
|
||||
rm -rf results/ build/ apks/ aports/
|
||||
|
||||
# Rebuild
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
### Docker Issues (macOS)
|
||||
```bash
|
||||
# Start Docker Desktop
|
||||
open -a Docker
|
||||
|
||||
# Wait for Docker to start, then retry
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
### Out of Disk Space
|
||||
```bash
|
||||
# Clean Docker (macOS)
|
||||
docker system prune -a
|
||||
|
||||
# Clean build artifacts
|
||||
rm -rf build/ results/ apks/
|
||||
```
|
||||
|
||||
## 📖 Full Documentation
|
||||
|
||||
For detailed information:
|
||||
- **Hardware Builds**: `README-HARDWARE-BUILDS.md`
|
||||
- **OS Images**: `docs/building-os-images.md`
|
||||
- **Architecture**: `docs/architecture.md`
|
||||
|
||||
## 🎯 Common Use Cases
|
||||
|
||||
### Build for production Start9 Server Pure
|
||||
```bash
|
||||
export ARCHIPELAGO_VERSION="1.0.0"
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
### Build test images for all hardware
|
||||
```bash
|
||||
export ARCHIPELAGO_VERSION="dev"
|
||||
./build-all-hardware.sh iso
|
||||
```
|
||||
|
||||
### Build for your specific hardware
|
||||
```bash
|
||||
# Start9 Server Pure users
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
|
||||
# HP ProDesk users
|
||||
./build-for-hardware.sh hp-prodesk iso
|
||||
|
||||
# Dell OptiPlex users
|
||||
./build-for-hardware.sh dell-optiplex iso
|
||||
|
||||
# Other x86_64 hardware
|
||||
./build-for-hardware.sh generic iso
|
||||
```
|
||||
|
||||
## ⏱️ Build Times
|
||||
|
||||
Approximate build times (first build):
|
||||
|
||||
| Hardware | macOS (Docker) | Linux (Native) |
|
||||
|----------|---------------|----------------|
|
||||
| Start9 Pure | 45-60 min | 30-45 min |
|
||||
| HP ProDesk | 45-60 min | 30-45 min |
|
||||
| Dell OptiPlex | 45-60 min | 30-45 min |
|
||||
| Generic | 45-60 min | 30-45 min |
|
||||
| All Targets | 3-4 hours | 2-3 hours |
|
||||
|
||||
Subsequent builds are much faster (~10-15 minutes) due to caching.
|
||||
|
||||
## 💡 Tips
|
||||
|
||||
- **First build is slow**: Docker needs to download Alpine base, build tools, etc.
|
||||
- **Use SSD**: Dramatically speeds up builds
|
||||
- **Close apps**: Free up RAM and CPU for faster builds
|
||||
- **Build overnight**: For all-hardware builds, run overnight
|
||||
- **Check logs**: Build output shows progress and any issues
|
||||
|
||||
## 🚀 Next Steps
|
||||
|
||||
After building:
|
||||
1. Flash ISO to USB drive
|
||||
2. Boot your hardware from USB
|
||||
3. Install Archipelago
|
||||
4. Access UI at http://device-ip:8100
|
||||
5. Install Bitcoin Core and apps
|
||||
6. Enjoy your sovereign server!
|
||||
|
||||
## 📞 Support
|
||||
|
||||
Need help?
|
||||
- **Issues**: Open GitHub issue
|
||||
- **Docs**: Check `docs/` folder
|
||||
- **Community**: Discord (coming soon)
|
||||
|
||||
---
|
||||
|
||||
**Remember**: Keep your ProDesk and OptiPlex builds! The system supports all hardware targets simultaneously.
|
||||
@@ -1,412 +0,0 @@
|
||||
# Building Archipelago for Specific Hardware
|
||||
|
||||
Archipelago supports building optimized OS images for specific hardware targets. Each build includes hardware-specific optimizations, drivers, and configurations.
|
||||
|
||||
## Supported Hardware
|
||||
|
||||
### 🖥️ Start9 Server Pure
|
||||
```bash
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
**Specifications:**
|
||||
- **CPU**: Intel Core i7-10710U (6 cores, 12 threads)
|
||||
- **RAM**: 32GB or 64GB DDR4-3200
|
||||
- **Storage**: 2TB or 4TB NVMe SSD
|
||||
- **Network**: 1x Gigabit Ethernet
|
||||
- **Graphics**: Intel UHD Graphics
|
||||
- **Ports**: 4x USB 3.0, 2x USB 2.0, 1x USB-C 3.1, HDMI, DisplayPort
|
||||
|
||||
**Optimizations:**
|
||||
- Intel microcode updates
|
||||
- Intel graphics acceleration
|
||||
- NVMe SSD optimizations
|
||||
- Power management tuning
|
||||
|
||||
### 🖥️ HP ProDesk 400 G4 DM
|
||||
```bash
|
||||
./build-for-hardware.sh hp-prodesk iso
|
||||
```
|
||||
|
||||
**Specifications:**
|
||||
- **CPU**: Various Intel processors
|
||||
- **RAM**: 8GB+ DDR4
|
||||
- **Storage**: 128GB+ SATA/NVMe SSD
|
||||
- **Network**: 1x Gigabit Ethernet
|
||||
- **Form Factor**: Desktop Mini
|
||||
|
||||
**Optimizations:**
|
||||
- Intel graphics drivers
|
||||
- SATA/NVMe detection and optimization
|
||||
- HP-specific firmware support
|
||||
|
||||
### 🖥️ Dell OptiPlex
|
||||
```bash
|
||||
./build-for-hardware.sh dell-optiplex iso
|
||||
```
|
||||
|
||||
**Specifications:**
|
||||
- **CPU**: Various Intel processors
|
||||
- **RAM**: 8GB+ DDR4
|
||||
- **Storage**: 128GB+ SATA/NVMe SSD
|
||||
- **Network**: 1x Gigabit Ethernet
|
||||
- **Models**: 3050, 7050, 9020, etc.
|
||||
|
||||
**Optimizations:**
|
||||
- Intel graphics drivers
|
||||
- Dell firmware support
|
||||
- Multi-model compatibility
|
||||
|
||||
### 🖥️ Generic x86_64
|
||||
```bash
|
||||
./build-for-hardware.sh generic iso
|
||||
```
|
||||
|
||||
**Specifications:**
|
||||
- **CPU**: Any x86_64 processor (Intel/AMD)
|
||||
- **RAM**: 8GB+ recommended
|
||||
- **Storage**: 128GB+ HDD/SSD
|
||||
- **Network**: Any Ethernet adapter
|
||||
|
||||
**Optimizations:**
|
||||
- Broad hardware compatibility
|
||||
- Generic drivers for maximum coverage
|
||||
- Both Intel and AMD support
|
||||
|
||||
## Build Process
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Choose your hardware target:**
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-for-hardware.sh <target> iso
|
||||
```
|
||||
|
||||
2. **Wait for build to complete** (30-60 minutes first time)
|
||||
|
||||
3. **Find your ISO:**
|
||||
```bash
|
||||
ls results/archipelago-*-<target>-*.iso
|
||||
```
|
||||
|
||||
### Build Types
|
||||
|
||||
#### ISO Image (Recommended)
|
||||
```bash
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
- Bootable from USB drive
|
||||
- Live system or installation
|
||||
- Easy to flash with tools
|
||||
|
||||
#### Disk Image
|
||||
```bash
|
||||
./build-for-hardware.sh start9-pure disk
|
||||
```
|
||||
- Raw disk image
|
||||
- For direct disk flashing
|
||||
- Advanced users only
|
||||
|
||||
## Hardware-Specific Features
|
||||
|
||||
### Start9 Server Pure
|
||||
- **Coreboot Support**: Optimized for Start9's Coreboot firmware
|
||||
- **No Intel ME**: Respects disabled Intel Management Engine
|
||||
- **NVMe Performance**: Tuned for high-speed NVMe SSDs
|
||||
- **Professional Grade**: Enterprise-level reliability
|
||||
|
||||
### HP ProDesk 400 G4 DM
|
||||
- **Compact Form Factor**: Optimized for small desktop
|
||||
- **Business Features**: Enterprise management support
|
||||
- **Low Power**: Efficient power management
|
||||
- **Silent Operation**: Thermal optimizations
|
||||
|
||||
### Dell OptiPlex
|
||||
- **Wide Model Support**: Works across many OptiPlex models
|
||||
- **Legacy Support**: Compatible with older hardware
|
||||
- **Enterprise Ready**: Business-class features
|
||||
- **Proven Reliability**: Battle-tested hardware
|
||||
|
||||
### Generic Build
|
||||
- **Maximum Compatibility**: Works on most x86_64 hardware
|
||||
- **Fallback Option**: When specific profile unavailable
|
||||
- **DIY Builds**: Perfect for custom hardware
|
||||
- **Virtual Machines**: Works in VirtualBox, VMware, etc.
|
||||
|
||||
## What Gets Customized
|
||||
|
||||
Each hardware build includes:
|
||||
|
||||
### 1. Hardware Detection
|
||||
Automatically detects and optimizes for:
|
||||
- CPU vendor and model
|
||||
- Available RAM
|
||||
- Storage type (NVMe, SATA SSD, HDD)
|
||||
- Network interfaces
|
||||
- Graphics hardware
|
||||
- USB controllers
|
||||
|
||||
### 2. Kernel Modules
|
||||
Includes specific drivers for:
|
||||
- Storage controllers
|
||||
- Network adapters
|
||||
- Graphics cards
|
||||
- USB devices
|
||||
- Audio hardware
|
||||
|
||||
### 3. Firmware
|
||||
Loads appropriate firmware for:
|
||||
- CPU microcode (Intel/AMD)
|
||||
- Network adapters
|
||||
- Graphics cards
|
||||
- Wireless (if applicable)
|
||||
|
||||
### 4. Performance Tuning
|
||||
Optimizes:
|
||||
- I/O scheduler (NVMe vs SATA)
|
||||
- CPU governor (performance vs power)
|
||||
- Memory management
|
||||
- Network buffers
|
||||
- Disk caching
|
||||
|
||||
### 5. System Configuration
|
||||
Sets defaults for:
|
||||
- Boot parameters
|
||||
- Service startup order
|
||||
- Power management
|
||||
- Thermal management
|
||||
- Network configuration
|
||||
|
||||
## Build Output
|
||||
|
||||
After successful build, you'll get:
|
||||
|
||||
```
|
||||
results/
|
||||
├── archipelago-0.1.0-start9-pure-x86_64.iso
|
||||
├── archipelago-0.1.0-hp-prodesk-x86_64.iso
|
||||
├── archipelago-0.1.0-dell-optiplex-x86_64.iso
|
||||
├── archipelago-0.1.0-generic-x86_64.iso
|
||||
└── BUILD_MANIFEST_<target>.txt
|
||||
```
|
||||
|
||||
Each ISO includes:
|
||||
- Hardware-specific optimizations
|
||||
- Appropriate drivers and firmware
|
||||
- Custom boot configuration
|
||||
- Installation scripts
|
||||
- Hardware detection tools
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Flash ISO to USB
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
# Find USB device
|
||||
diskutil list
|
||||
|
||||
# Unmount
|
||||
diskutil unmountDisk /dev/diskX
|
||||
|
||||
# Flash ISO
|
||||
sudo dd if=results/archipelago-0.1.0-start9-pure-x86_64.iso \
|
||||
of=/dev/rdiskX \
|
||||
bs=1m \
|
||||
status=progress
|
||||
```
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
# Find USB device
|
||||
lsblk
|
||||
|
||||
# Flash ISO
|
||||
sudo dd if=results/archipelago-0.1.0-start9-pure-x86_64.iso \
|
||||
of=/dev/sdX \
|
||||
bs=1M \
|
||||
status=progress
|
||||
```
|
||||
|
||||
**GUI Tools:**
|
||||
- [balenaEtcher](https://www.balena.io/etcher/) (macOS/Linux/Windows)
|
||||
- [Rufus](https://rufus.ie/) (Windows)
|
||||
- [Raspberry Pi Imager](https://www.raspberrypi.com/software/) (All platforms)
|
||||
|
||||
### 2. Boot from USB
|
||||
|
||||
1. Insert USB drive into target hardware
|
||||
2. Power on and enter boot menu:
|
||||
- **Start9 Pure**: Press F12 during boot
|
||||
- **HP ProDesk**: Press F9 during boot
|
||||
- **Dell OptiPlex**: Press F12 during boot
|
||||
3. Select USB drive from boot menu
|
||||
4. Follow installation prompts
|
||||
|
||||
### 3. First Boot
|
||||
|
||||
After installation:
|
||||
1. Remove USB drive
|
||||
2. Reboot system
|
||||
3. Hardware detection runs automatically
|
||||
4. Services start automatically
|
||||
5. Access UI at `http://<device-ip>:8100`
|
||||
|
||||
## Verification
|
||||
|
||||
After flashing, verify the build:
|
||||
|
||||
```bash
|
||||
# Check ISO integrity
|
||||
sha256sum results/archipelago-0.1.0-start9-pure-x86_64.iso
|
||||
|
||||
# View build manifest
|
||||
cat results/BUILD_MANIFEST_start9-pure.txt
|
||||
|
||||
# Mount ISO to inspect (Linux)
|
||||
sudo mount -o loop archipelago-0.1.0-start9-pure-x86_64.iso /mnt
|
||||
ls -la /mnt
|
||||
cat /mnt/etc/archipelago/hardware.toml
|
||||
sudo umount /mnt
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Fails
|
||||
```bash
|
||||
# Clean build artifacts
|
||||
rm -rf results/ build/ apks/ aports/
|
||||
|
||||
# Try again
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
```
|
||||
|
||||
### Wrong Hardware Detected
|
||||
Check hardware profile after boot:
|
||||
```bash
|
||||
cat /etc/archipelago/hardware.toml
|
||||
cat /var/log/archipelago-hardware.log
|
||||
```
|
||||
|
||||
### Boot Issues
|
||||
- Verify ISO checksum
|
||||
- Try different USB port
|
||||
- Check BIOS/UEFI settings:
|
||||
- Enable UEFI boot
|
||||
- Disable Secure Boot (for now)
|
||||
- Enable USB boot
|
||||
- Set boot order
|
||||
|
||||
### Performance Issues
|
||||
View hardware optimization log:
|
||||
```bash
|
||||
cat /var/log/archipelago-hardware.log
|
||||
dmesg | grep -i archipelago
|
||||
journalctl -u archipelago
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Custom Hardware Profile
|
||||
|
||||
Create custom profile for your hardware:
|
||||
|
||||
1. Copy generic profile:
|
||||
```bash
|
||||
cp -r alpine-profile/overlay alpine-profile/overlay-myserver
|
||||
```
|
||||
|
||||
2. Edit hardware config:
|
||||
```bash
|
||||
vim alpine-profile/overlay-myserver/etc/archipelago/hardware.toml
|
||||
```
|
||||
|
||||
3. Build with custom profile:
|
||||
```bash
|
||||
HARDWARE_TARGET=myserver ./build-for-hardware.sh myserver iso
|
||||
```
|
||||
|
||||
### Build All Targets
|
||||
|
||||
Build for all supported hardware:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
for target in start9-pure hp-prodesk dell-optiplex generic; do
|
||||
echo "Building for $target..."
|
||||
./build-for-hardware.sh $target iso
|
||||
done
|
||||
```
|
||||
|
||||
### Automated Testing
|
||||
|
||||
Test ISO in QEMU:
|
||||
```bash
|
||||
qemu-system-x86_64 \
|
||||
-m 4G \
|
||||
-smp 2 \
|
||||
-boot d \
|
||||
-cdrom results/archipelago-0.1.0-start9-pure-x86_64.iso \
|
||||
-enable-kvm
|
||||
```
|
||||
|
||||
## Hardware Requirements
|
||||
|
||||
### Minimum Requirements
|
||||
- **CPU**: 64-bit x86_64 processor
|
||||
- **RAM**: 4GB (8GB recommended)
|
||||
- **Storage**: 64GB (128GB recommended)
|
||||
- **Network**: Ethernet adapter
|
||||
- **Boot**: UEFI or Legacy BIOS
|
||||
|
||||
### Recommended Requirements
|
||||
- **CPU**: Intel i5/i7 or AMD Ryzen 5/7
|
||||
- **RAM**: 16GB+
|
||||
- **Storage**: 256GB+ SSD (NVMe preferred)
|
||||
- **Network**: Gigabit Ethernet
|
||||
- **Boot**: UEFI with GPT
|
||||
|
||||
### Start9 Server Pure (Optimal)
|
||||
- **CPU**: Intel i7-10710U (6 cores, 12 threads)
|
||||
- **RAM**: 32GB or 64GB
|
||||
- **Storage**: 2TB or 4TB NVMe SSD
|
||||
- **Network**: Gigabit Ethernet
|
||||
- **Ports**: Multiple USB 3.0, USB-C
|
||||
|
||||
## Next Steps
|
||||
|
||||
After installation:
|
||||
1. Access web UI: `http://<device-ip>:8100`
|
||||
2. Complete setup wizard
|
||||
3. Install Bitcoin Core
|
||||
4. Add Lightning Network (LND or CLN)
|
||||
5. Install additional apps
|
||||
6. Configure backups
|
||||
7. Secure your node
|
||||
|
||||
## Support
|
||||
|
||||
Need help?
|
||||
- **Documentation**: `docs/`
|
||||
- **Issues**: GitHub Issues
|
||||
- **Community**: Discord (coming soon)
|
||||
- **Hardware-Specific**: Check `BUILD_MANIFEST_<target>.txt`
|
||||
|
||||
## Building Multiple Targets
|
||||
|
||||
To build for all your hardware:
|
||||
|
||||
```bash
|
||||
# Build Start9 Server Pure image
|
||||
./build-for-hardware.sh start9-pure iso
|
||||
|
||||
# Build HP ProDesk image
|
||||
./build-for-hardware.sh hp-prodesk iso
|
||||
|
||||
# Build Dell OptiPlex image
|
||||
./build-for-hardware.sh dell-optiplex iso
|
||||
|
||||
# You'll get separate ISOs optimized for each
|
||||
```
|
||||
|
||||
Each ISO is independent and optimized for its target hardware!
|
||||
+50
-18
@@ -1,46 +1,78 @@
|
||||
# Archipelago OS Image Recipes
|
||||
|
||||
Build scripts and profiles for creating bootable Alpine Linux OS images for Archipelago Bitcoin Node OS.
|
||||
Build scripts for creating bootable Debian Linux OS images for Archipelago Bitcoin Node OS.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### On macOS
|
||||
### Build the ISO
|
||||
|
||||
```bash
|
||||
./build-macos.sh
|
||||
./build-debian-iso.sh
|
||||
```
|
||||
|
||||
### On Linux
|
||||
This creates a bootable Debian Live ISO with Archipelago pre-installed.
|
||||
|
||||
### Write to USB
|
||||
|
||||
```bash
|
||||
./build-linux.sh
|
||||
# Using dd (recommended)
|
||||
./write-usb-dd.sh /dev/diskN
|
||||
|
||||
# Or use Balena Etcher to flash the ISO
|
||||
```
|
||||
|
||||
See [Building OS Images](../../docs/building-os-images.md) for detailed instructions.
|
||||
See the Architecture documentation for detailed system information.
|
||||
|
||||
## What's Included
|
||||
|
||||
- **Alpine Linux Base**: Minimal, secure Linux distribution
|
||||
- **Podman**: Container runtime for apps
|
||||
- **Debian Linux Base**: Stable Debian 12 (Bookworm) distribution
|
||||
- **Podman**: Container runtime for apps (rootless by default)
|
||||
- **Archipelago Backend**: Rust-based API server
|
||||
- **Archipelago Frontend**: Vue.js web interface
|
||||
- **Systemd Services**: Automatic service management
|
||||
- **Network Configuration**: Ready for network setup
|
||||
- **Network Configuration**: NetworkManager for easy setup
|
||||
|
||||
## Build Output
|
||||
|
||||
- `archipelago-{version}-x86_64.iso` - Bootable ISO image
|
||||
- `archipelago-{version}-x86_64.img` - Disk image for flashing
|
||||
- `results/archipelago-debian-12-x86_64.iso` - Bootable hybrid ISO image
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
- **x86_64**: Dell Optiplex, HP ProDesk 400 G4 DM, and other x86_64 desktops
|
||||
- **Build Systems**: macOS (via Docker) and Linux (native or Docker)
|
||||
- **x86_64**: Dell OptiPlex, HP ProDesk 400 G4 DM, Start9 Server Pure, and other x86_64 machines
|
||||
- **Build Systems**: macOS (requires Docker) and Linux (native or Docker)
|
||||
|
||||
## Legacy StartOS Build
|
||||
## Installation Methods
|
||||
|
||||
The original StartOS build scripts are still available:
|
||||
- `build.sh` - StartOS Debian-based image builder
|
||||
- `run-local-build.sh` - StartOS build helper
|
||||
### 1. Live USB Boot
|
||||
Boot from USB, run in live mode to test, or install to disk.
|
||||
|
||||
See [Building OS Images](../../docs/building-os-images.md) for Archipelago-specific builds.
|
||||
### 2. Full Disk Installation
|
||||
From the live environment, run:
|
||||
```bash
|
||||
sudo /archipelago/install-to-disk.sh
|
||||
```
|
||||
|
||||
This installs Archipelago to a target disk using debootstrap.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
image-recipe/
|
||||
├── build-debian-iso.sh # Main ISO builder
|
||||
├── write-usb-dd.sh # Write ISO to USB with dd
|
||||
├── create-fat32-usb.sh # Alternative USB creation
|
||||
├── archipelago-scripts/ # Scripts included in ISO
|
||||
│ ├── install-to-disk.sh # Disk installer
|
||||
│ └── setup-bitcoin.sh # Bitcoin Core setup
|
||||
├── scripts/ # Build helper scripts
|
||||
│ ├── build-backend.sh # Compile Rust backend
|
||||
│ ├── build-frontend.sh # Build Vue.js frontend
|
||||
│ └── check-dependencies.sh # Verify build requirements
|
||||
└── results/ # Built ISO output
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker (for macOS builds)
|
||||
- xorriso (for ISO creation): `brew install xorriso`
|
||||
- 7zip (for ISO extraction): `brew install p7zip`
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
# Archipelago OS Image Builder - Implementation Summary
|
||||
|
||||
## ✅ What's Been Implemented
|
||||
|
||||
A complete system for building bootable Alpine Linux OS images for Archipelago Bitcoin Node OS, supporting both macOS and Linux build environments.
|
||||
|
||||
## 🎯 Key Features
|
||||
|
||||
1. **Multi-Platform Build Support**
|
||||
- ✅ macOS via Docker
|
||||
- ✅ Linux native (Alpine)
|
||||
- ✅ Linux via Docker (fallback)
|
||||
|
||||
2. **Complete Build Pipeline**
|
||||
- ✅ Backend compilation (Rust)
|
||||
- ✅ Frontend build (Vue.js)
|
||||
- ✅ APK package creation
|
||||
- ✅ Alpine image generation
|
||||
- ✅ ISO and disk image output
|
||||
|
||||
3. **Alpine Profile System**
|
||||
- ✅ Custom mkimage profile
|
||||
- ✅ Systemd and OpenRC support
|
||||
- ✅ First boot automation
|
||||
- ✅ Service configuration
|
||||
|
||||
4. **Integration**
|
||||
- ✅ Backend service installation
|
||||
- ✅ Frontend file deployment
|
||||
- ✅ Podman configuration
|
||||
- ✅ Network setup
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
image-recipe/
|
||||
├── build-alpine-iso.sh # Main orchestrator
|
||||
├── build-macos.sh # macOS wrapper
|
||||
├── build-linux.sh # Linux wrapper
|
||||
├── build-alpine-native.sh # Native Alpine build
|
||||
├── Dockerfile.build # Build container
|
||||
├── docker-compose.build.yml # Docker Compose config
|
||||
├── Makefile # Build shortcuts
|
||||
├── alpine-profile/ # Custom Alpine profile
|
||||
│ ├── mkimg.archipelago.sh # Profile definition
|
||||
│ └── overlay/ # Files to include
|
||||
│ └── etc/ # System configs
|
||||
├── scripts/ # Build helpers
|
||||
│ ├── build-backend.sh
|
||||
│ ├── build-frontend.sh
|
||||
│ ├── create-backend-apk.sh
|
||||
│ ├── install-archipelago.sh
|
||||
│ ├── convert-iso-to-disk.sh
|
||||
│ └── check-dependencies.sh
|
||||
└── docs/ # Documentation
|
||||
└── building-os-images.md
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### On Your macOS Machine
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh
|
||||
```
|
||||
|
||||
### On HP ProDesk 400 G4 DM (Linux)
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-linux.sh
|
||||
```
|
||||
|
||||
## 📦 Build Output
|
||||
|
||||
After successful build:
|
||||
|
||||
- **ISO Image**: `results/archipelago-0.1.0-x86_64.iso`
|
||||
- Bootable from USB/DVD
|
||||
- ~200-500MB
|
||||
|
||||
- **Disk Image** (optional): `results/archipelago-0.1.0-x86_64.img`
|
||||
- Ready for `dd` flashing
|
||||
- ~4GB (expandable)
|
||||
|
||||
## 🔧 What Happens During Build
|
||||
|
||||
1. **Dependency Check**: Verifies Rust, Node.js, Docker
|
||||
2. **Backend Build**: Compiles Rust binary → `build/backend/archipelago`
|
||||
3. **Frontend Build**: Builds Vue.js → `build/frontend/`
|
||||
4. **APK Creation**: Packages backend → `apks/archipelago-backend-*.apk`
|
||||
5. **Alpine Build**:
|
||||
- Clones Alpine aports (first time only)
|
||||
- Creates custom profile
|
||||
- Builds base Alpine image
|
||||
6. **Integration**: Installs Archipelago components
|
||||
7. **Output**:** Creates ISO/image file
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
Environment variables:
|
||||
|
||||
```bash
|
||||
ARCHIPELAGO_VERSION=0.1.0 # Version
|
||||
ALPINE_VERSION=3.19 # Alpine version
|
||||
ARCH=x86_64 # Architecture
|
||||
BUILD_TYPE=iso # iso or disk
|
||||
OUTPUT_DIR=./results # Output location
|
||||
```
|
||||
|
||||
## 📋 Prerequisites
|
||||
|
||||
### macOS
|
||||
- Docker Desktop
|
||||
- 10GB+ disk space
|
||||
- 8GB+ RAM recommended
|
||||
|
||||
### Linux
|
||||
- Alpine Linux (preferred) OR Docker
|
||||
- 10GB+ disk space
|
||||
- Build tools (auto-installed)
|
||||
|
||||
## 🎉 Ready to Build!
|
||||
|
||||
The system is complete and ready for testing. Start building with:
|
||||
|
||||
```bash
|
||||
cd image-recipe
|
||||
./build-macos.sh # On macOS
|
||||
# or
|
||||
./build-linux.sh # On Linux
|
||||
```
|
||||
|
||||
First build will take 30-60 minutes (downloads Alpine aports). Subsequent builds are faster.
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- [Building OS Images](../docs/building-os-images.md) - Full guide
|
||||
- [Quick Start](QUICKSTART.md) - Quick reference
|
||||
- [Build Status](BUILD_STATUS.md) - Implementation status
|
||||
@@ -1,33 +0,0 @@
|
||||
# Archipelago Alpine Profile
|
||||
|
||||
Custom Alpine Linux mkimage profile for Archipelago Bitcoin Node OS.
|
||||
|
||||
## Profile Structure
|
||||
|
||||
- `mkimg.archipelago.sh` - Main profile definition
|
||||
- `overlay/` - Files to overlay into the image
|
||||
- `etc/` - System configuration files
|
||||
- `etc/systemd/system/` - Systemd service files
|
||||
- `etc/init.d/` - OpenRC init scripts
|
||||
- `etc/local.d/` - Local startup scripts
|
||||
|
||||
## Customization
|
||||
|
||||
To modify the profile:
|
||||
|
||||
1. **Add packages**: Edit `mkimg.archipelago.sh` and add to `apks` variable
|
||||
2. **Add files**: Place files in `overlay/` directory with desired path structure
|
||||
3. **Modify kernel**: Change `kernel_flavors` or `initfs_features`
|
||||
4. **Change bootloader**: Modify `boot_addons`
|
||||
|
||||
## Profile Variables
|
||||
|
||||
- `apks` - List of Alpine packages to install
|
||||
- `kernel_flavors` - Kernel version (lts, edge, etc.)
|
||||
- `boot_addons` - Bootloader components
|
||||
- `initfs_features` - Initramfs features
|
||||
- `initfs_modules` - Kernel modules to include
|
||||
|
||||
## Build Integration
|
||||
|
||||
This profile is automatically copied to Alpine's aports repository during build and used by `mkimage.sh`.
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Alpine mkimage profile for Archipelago Bitcoin Node OS
|
||||
|
||||
profile_archipelago() {
|
||||
profile_standard
|
||||
title="Archipelago Bitcoin Node OS"
|
||||
desc="A Bitcoin and sovereign computing node OS built on Alpine Linux"
|
||||
profile_abbrev="arch"
|
||||
arch="x86_64"
|
||||
|
||||
# Additional packages for Archipelago
|
||||
apks="$apks
|
||||
podman
|
||||
crun
|
||||
fuse-overlayfs
|
||||
slirp4netns
|
||||
openssh
|
||||
nginx
|
||||
"
|
||||
|
||||
# Kernel flavor
|
||||
kernel_flavors="lts"
|
||||
kernel_addons="xtables-addons"
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
@@ -1,26 +0,0 @@
|
||||
# Hardware profile for HP ProDesk 400 G4 DM
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "hp-prodesk"
|
||||
name = "HP ProDesk 400 G4 DM"
|
||||
cpu_vendor = "intel"
|
||||
cpu_model = "varies"
|
||||
min_ram = "8GB"
|
||||
min_storage = "128GB"
|
||||
architecture = "x86_64"
|
||||
|
||||
[optimizations]
|
||||
enabled = intel-graphics intel-networking sata-ssd
|
||||
|
||||
[network]
|
||||
interfaces = "1x Gigabit Ethernet"
|
||||
|
||||
[usb]
|
||||
ports = "4x USB 3.0, 2x USB 2.0"
|
||||
|
||||
[build]
|
||||
version = "0.1.0"
|
||||
alpine_version = "3.19"
|
||||
build_date = "2026-01-31T20:40:39Z"
|
||||
build_type = "iso"
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
@@ -1,38 +0,0 @@
|
||||
# Archipelago Node OS Configuration
|
||||
|
||||
[server]
|
||||
# Server listening configuration
|
||||
host = "0.0.0.0" # Listen on all interfaces
|
||||
port = 8100
|
||||
data_dir = "/var/lib/archipelago"
|
||||
|
||||
[network]
|
||||
# Automatic Ethernet configuration
|
||||
auto_configure = true
|
||||
dhcp = true
|
||||
dns_servers = ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
|
||||
|
||||
[containers]
|
||||
# Container runtime (Podman)
|
||||
runtime = "podman"
|
||||
rootless = true
|
||||
auto_start = true
|
||||
|
||||
[apps]
|
||||
# App directory
|
||||
apps_dir = "/var/lib/archipelago/apps"
|
||||
auto_start_enabled = true
|
||||
|
||||
[security]
|
||||
# Security settings
|
||||
require_auth = false # Disable for first boot, enable after setup
|
||||
secrets_dir = "/var/lib/archipelago/secrets"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
dir = "/var/lib/archipelago/logs"
|
||||
|
||||
[ui]
|
||||
# Web UI settings
|
||||
enabled = true
|
||||
path = "/usr/share/archipelago/web"
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
@@ -1,26 +0,0 @@
|
||||
# Hardware profile for HP ProDesk 400 G4 DM
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "hp-prodesk"
|
||||
name = "HP ProDesk 400 G4 DM"
|
||||
cpu_vendor = "intel"
|
||||
cpu_model = "varies"
|
||||
min_ram = "8GB"
|
||||
min_storage = "128GB"
|
||||
architecture = "x86_64"
|
||||
|
||||
[optimizations]
|
||||
enabled = intel-graphics intel-networking sata-ssd
|
||||
|
||||
[network]
|
||||
interfaces = "1x Gigabit Ethernet"
|
||||
|
||||
[usb]
|
||||
ports = "4x USB 3.0, 2x USB 2.0"
|
||||
|
||||
[build]
|
||||
version = "0.1.0"
|
||||
alpine_version = "3.19"
|
||||
build_date = "2026-01-31T20:40:39Z"
|
||||
build_type = "iso"
|
||||
@@ -1 +0,0 @@
|
||||
archipelago
|
||||
@@ -1,4 +0,0 @@
|
||||
127.0.0.1 localhost archipelago
|
||||
::1 localhost archipelago ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
# Archipelago Bitcoin Node OS Backend
|
||||
|
||||
name="Archipelago"
|
||||
description="Archipelago Bitcoin Node OS Backend Server"
|
||||
command="/usr/bin/archipelago-backend"
|
||||
command_user="archipelago:archipelago"
|
||||
command_background=true
|
||||
pidfile="/var/run/archipelago.pid"
|
||||
start_stop_daemon_args="--make-pidfile"
|
||||
|
||||
# Working directory and environment
|
||||
directory="/var/lib/archipelago"
|
||||
export RUST_LOG="${RUST_LOG:-info}"
|
||||
export ARCHIPELAGO_DATA_DIR="/var/lib/archipelago"
|
||||
export ARCHIPELAGO_PORT="${ARCHIPELAGO_PORT:-8100}"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
need localmount
|
||||
after firewall
|
||||
use podman docker
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
# Ensure directories exist
|
||||
checkpath --directory --mode 0755 --owner archipelago:archipelago \
|
||||
/var/lib/archipelago \
|
||||
/var/lib/archipelago/apps \
|
||||
/var/lib/archipelago/secrets \
|
||||
/var/lib/archipelago/logs \
|
||||
/var/lib/archipelago/backups
|
||||
|
||||
# Wait for network to be fully ready
|
||||
local retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then
|
||||
einfo "Network is ready"
|
||||
return 0
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
ewarn "Network may not be fully ready"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_post() {
|
||||
einfo "Archipelago backend started"
|
||||
einfo "Access the UI at: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Alpine Linux boot configuration for Archipelago
|
||||
# This runs early in the boot process
|
||||
|
||||
# Enable essential services
|
||||
rc-update add devfs sysinit 2>/dev/null || true
|
||||
rc-update add dmesg sysinit 2>/dev/null || true
|
||||
rc-update add mdev sysinit 2>/dev/null || true
|
||||
rc-update add hwdrivers sysinit 2>/dev/null || true
|
||||
|
||||
# Enable boot services
|
||||
rc-update add bootmisc boot 2>/dev/null || true
|
||||
rc-update add hostname boot 2>/dev/null || true
|
||||
rc-update add hwclock boot 2>/dev/null || true
|
||||
rc-update add modules boot 2>/dev/null || true
|
||||
rc-update add swap boot 2>/dev/null || true
|
||||
rc-update add sysctl boot 2>/dev/null || true
|
||||
rc-update add syslog boot 2>/dev/null || true
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-update add urandom boot 2>/dev/null || true
|
||||
|
||||
# Enable default services
|
||||
rc-update add local default 2>/dev/null || true
|
||||
rc-update add sshd default 2>/dev/null || true
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Enable shutdown services
|
||||
rc-update add killprocs shutdown 2>/dev/null || true
|
||||
rc-update add mount-ro shutdown 2>/dev/null || true
|
||||
rc-update add savecache shutdown 2>/dev/null || true
|
||||
|
||||
echo "✓ Archipelago boot services configured"
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot network and service setup for Archipelago
|
||||
|
||||
# Configure hostname
|
||||
if [ ! -f /etc/hostname.configured ]; then
|
||||
echo "archipelago-node" > /etc/hostname
|
||||
hostname archipelago-node
|
||||
touch /etc/hostname.configured
|
||||
fi
|
||||
|
||||
# Configure networking - Ethernet with DHCP
|
||||
if [ ! -f /etc/network/interfaces.configured ]; then
|
||||
cat > /etc/network/interfaces <<'NETEOF'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# Automatic Ethernet configuration (DHCP)
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
# Fallback for other ethernet names
|
||||
auto enp0s3
|
||||
iface enp0s3 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto enp0s25
|
||||
iface enp0s25 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto ens0
|
||||
iface ens0 inet dhcp
|
||||
hostname archipelago-node
|
||||
NETEOF
|
||||
touch /etc/network/interfaces.configured
|
||||
fi
|
||||
|
||||
# Enable and start networking
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-service networking start 2>/dev/null || true
|
||||
|
||||
# Wait for network to be ready
|
||||
echo "Waiting for network..."
|
||||
retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ip route | grep -q default; then
|
||||
echo "✓ Network is ready"
|
||||
ip addr show | grep "inet " | grep -v "127.0.0.1"
|
||||
break
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Enable DNS
|
||||
if [ ! -f /etc/resolv.conf.configured ]; then
|
||||
cat > /etc/resolv.conf <<'DNSEOF'
|
||||
nameserver 8.8.8.8
|
||||
nameserver 8.8.4.4
|
||||
nameserver 1.1.1.1
|
||||
DNSEOF
|
||||
touch /etc/resolv.conf.configured
|
||||
fi
|
||||
|
||||
# Test internet connectivity
|
||||
echo "Testing internet connectivity..."
|
||||
if ping -c 2 8.8.8.8 >/dev/null 2>&1; then
|
||||
echo "✓ Internet connection established"
|
||||
else
|
||||
echo "⚠ Warning: No internet connection detected"
|
||||
fi
|
||||
|
||||
# Enable Archipelago service
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Display access information
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🏝️ Archipelago Bitcoin Node OS"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Network Configuration:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " IP Address: " $2}'
|
||||
echo ""
|
||||
echo "Access the Archipelago UI at:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " http://" $2}' | sed 's|/.*|:8100|'
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot installation script for Archipelago
|
||||
# This script runs on first boot to complete Archipelago setup
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Archipelago first boot setup..."
|
||||
|
||||
# Install backend APK if available
|
||||
if [ -f /tmp/archipelago-backend.apk ]; then
|
||||
echo "📦 Installing Archipelago backend..."
|
||||
apk add --allow-untrusted /tmp/archipelago-backend.apk || true
|
||||
rm -f /tmp/archipelago-backend.apk
|
||||
fi
|
||||
|
||||
# Create archipelago user if needed
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
echo "👤 Creating archipelago user..."
|
||||
adduser -D -s /bin/bash archipelago || true
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers || true
|
||||
fi
|
||||
|
||||
# Setup Podman for archipelago user
|
||||
echo "🐳 Configuring Podman..."
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
chown -R archipelago:archipelago /home/archipelago || true
|
||||
|
||||
# Create data directories
|
||||
echo "📁 Creating data directories..."
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago || true
|
||||
|
||||
# Enable services
|
||||
echo "⚙️ Enabling services..."
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
systemctl enable archipelago 2>/dev/null || true
|
||||
|
||||
# Start services
|
||||
echo "🚀 Starting services..."
|
||||
rc-service archipelago start 2>/dev/null || systemctl start archipelago 2>/dev/null || true
|
||||
|
||||
echo "✅ Archipelago setup complete!"
|
||||
echo " Web UI: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
echo " API: http://$(hostname -I | awk '{print $1}'):5959"
|
||||
@@ -1,29 +0,0 @@
|
||||
[Unit]
|
||||
Description=Archipelago Bitcoin Node OS Backend
|
||||
After=network.target podman.service
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=archipelago
|
||||
Group=archipelago
|
||||
WorkingDirectory=/var/lib/archipelago
|
||||
ExecStart=/usr/bin/archipelago
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
# Security
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/archipelago /tmp
|
||||
|
||||
# Environment
|
||||
Environment="RUST_LOG=info"
|
||||
Environment="ARCHIPELAGO_DATA_DIR=/var/lib/archipelago"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
@@ -1,26 +0,0 @@
|
||||
# Hardware profile for Start9 Server Pure
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "start9-pure"
|
||||
name = "Start9 Server Pure"
|
||||
cpu_vendor = "intel"
|
||||
cpu_model = "i7-10710U"
|
||||
min_ram = "32GB"
|
||||
min_storage = "2TB"
|
||||
architecture = "x86_64"
|
||||
|
||||
[optimizations]
|
||||
enabled = intel-graphics intel-networking nvme-ssd
|
||||
|
||||
[network]
|
||||
interfaces = "1x Gigabit Ethernet"
|
||||
|
||||
[usb]
|
||||
ports = "4x USB 3.0, 2x USB 2.0, 1x USB-C 3.1"
|
||||
|
||||
[build]
|
||||
version = "0.1.0"
|
||||
alpine_version = "3.19"
|
||||
build_date = "2026-01-31T20:20:26Z"
|
||||
build_type = "iso"
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
@@ -1,38 +0,0 @@
|
||||
# Archipelago Node OS Configuration
|
||||
|
||||
[server]
|
||||
# Server listening configuration
|
||||
host = "0.0.0.0" # Listen on all interfaces
|
||||
port = 8100
|
||||
data_dir = "/var/lib/archipelago"
|
||||
|
||||
[network]
|
||||
# Automatic Ethernet configuration
|
||||
auto_configure = true
|
||||
dhcp = true
|
||||
dns_servers = ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
|
||||
|
||||
[containers]
|
||||
# Container runtime (Podman)
|
||||
runtime = "podman"
|
||||
rootless = true
|
||||
auto_start = true
|
||||
|
||||
[apps]
|
||||
# App directory
|
||||
apps_dir = "/var/lib/archipelago/apps"
|
||||
auto_start_enabled = true
|
||||
|
||||
[security]
|
||||
# Security settings
|
||||
require_auth = false # Disable for first boot, enable after setup
|
||||
secrets_dir = "/var/lib/archipelago/secrets"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
dir = "/var/lib/archipelago/logs"
|
||||
|
||||
[ui]
|
||||
# Web UI settings
|
||||
enabled = true
|
||||
path = "/usr/share/archipelago/web"
|
||||
@@ -1 +0,0 @@
|
||||
archipelago
|
||||
@@ -1,4 +0,0 @@
|
||||
127.0.0.1 localhost archipelago
|
||||
::1 localhost archipelago ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/sbin/openrc-run
|
||||
# Archipelago Bitcoin Node OS Backend
|
||||
|
||||
name="Archipelago"
|
||||
description="Archipelago Bitcoin Node OS Backend Server"
|
||||
command="/usr/bin/archipelago-backend"
|
||||
command_user="archipelago:archipelago"
|
||||
command_background=true
|
||||
pidfile="/var/run/archipelago.pid"
|
||||
start_stop_daemon_args="--make-pidfile"
|
||||
|
||||
# Working directory and environment
|
||||
directory="/var/lib/archipelago"
|
||||
export RUST_LOG="${RUST_LOG:-info}"
|
||||
export ARCHIPELAGO_DATA_DIR="/var/lib/archipelago"
|
||||
export ARCHIPELAGO_PORT="${ARCHIPELAGO_PORT:-8100}"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
need localmount
|
||||
after firewall
|
||||
use podman docker
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
# Ensure directories exist
|
||||
checkpath --directory --mode 0755 --owner archipelago:archipelago \
|
||||
/var/lib/archipelago \
|
||||
/var/lib/archipelago/apps \
|
||||
/var/lib/archipelago/secrets \
|
||||
/var/lib/archipelago/logs \
|
||||
/var/lib/archipelago/backups
|
||||
|
||||
# Wait for network to be fully ready
|
||||
local retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then
|
||||
einfo "Network is ready"
|
||||
return 0
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
ewarn "Network may not be fully ready"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_post() {
|
||||
einfo "Archipelago backend started"
|
||||
einfo "Access the UI at: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Alpine Linux boot configuration for Archipelago
|
||||
# This runs early in the boot process
|
||||
|
||||
# Enable essential services
|
||||
rc-update add devfs sysinit 2>/dev/null || true
|
||||
rc-update add dmesg sysinit 2>/dev/null || true
|
||||
rc-update add mdev sysinit 2>/dev/null || true
|
||||
rc-update add hwdrivers sysinit 2>/dev/null || true
|
||||
|
||||
# Enable boot services
|
||||
rc-update add bootmisc boot 2>/dev/null || true
|
||||
rc-update add hostname boot 2>/dev/null || true
|
||||
rc-update add hwclock boot 2>/dev/null || true
|
||||
rc-update add modules boot 2>/dev/null || true
|
||||
rc-update add swap boot 2>/dev/null || true
|
||||
rc-update add sysctl boot 2>/dev/null || true
|
||||
rc-update add syslog boot 2>/dev/null || true
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-update add urandom boot 2>/dev/null || true
|
||||
|
||||
# Enable default services
|
||||
rc-update add local default 2>/dev/null || true
|
||||
rc-update add sshd default 2>/dev/null || true
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Enable shutdown services
|
||||
rc-update add killprocs shutdown 2>/dev/null || true
|
||||
rc-update add mount-ro shutdown 2>/dev/null || true
|
||||
rc-update add savecache shutdown 2>/dev/null || true
|
||||
|
||||
echo "✓ Archipelago boot services configured"
|
||||
@@ -1,88 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot network and service setup for Archipelago
|
||||
|
||||
# Configure hostname
|
||||
if [ ! -f /etc/hostname.configured ]; then
|
||||
echo "archipelago-node" > /etc/hostname
|
||||
hostname archipelago-node
|
||||
touch /etc/hostname.configured
|
||||
fi
|
||||
|
||||
# Configure networking - Ethernet with DHCP
|
||||
if [ ! -f /etc/network/interfaces.configured ]; then
|
||||
cat > /etc/network/interfaces <<'NETEOF'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# Automatic Ethernet configuration (DHCP)
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
# Fallback for other ethernet names
|
||||
auto enp0s3
|
||||
iface enp0s3 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto enp0s25
|
||||
iface enp0s25 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto ens0
|
||||
iface ens0 inet dhcp
|
||||
hostname archipelago-node
|
||||
NETEOF
|
||||
touch /etc/network/interfaces.configured
|
||||
fi
|
||||
|
||||
# Enable and start networking
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-service networking start 2>/dev/null || true
|
||||
|
||||
# Wait for network to be ready
|
||||
echo "Waiting for network..."
|
||||
retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ip route | grep -q default; then
|
||||
echo "✓ Network is ready"
|
||||
ip addr show | grep "inet " | grep -v "127.0.0.1"
|
||||
break
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Enable DNS
|
||||
if [ ! -f /etc/resolv.conf.configured ]; then
|
||||
cat > /etc/resolv.conf <<'DNSEOF'
|
||||
nameserver 8.8.8.8
|
||||
nameserver 8.8.4.4
|
||||
nameserver 1.1.1.1
|
||||
DNSEOF
|
||||
touch /etc/resolv.conf.configured
|
||||
fi
|
||||
|
||||
# Test internet connectivity
|
||||
echo "Testing internet connectivity..."
|
||||
if ping -c 2 8.8.8.8 >/dev/null 2>&1; then
|
||||
echo "✓ Internet connection established"
|
||||
else
|
||||
echo "⚠ Warning: No internet connection detected"
|
||||
fi
|
||||
|
||||
# Enable Archipelago service
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Display access information
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🏝️ Archipelago Bitcoin Node OS"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Network Configuration:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " IP Address: " $2}'
|
||||
echo ""
|
||||
echo "Access the Archipelago UI at:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " http://" $2}' | sed 's|/.*|:8100|'
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/bin/sh
|
||||
# First boot installation script for Archipelago
|
||||
# This script runs on first boot to complete Archipelago setup
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Archipelago first boot setup..."
|
||||
|
||||
# Install backend APK if available
|
||||
if [ -f /tmp/archipelago-backend.apk ]; then
|
||||
echo "📦 Installing Archipelago backend..."
|
||||
apk add --allow-untrusted /tmp/archipelago-backend.apk || true
|
||||
rm -f /tmp/archipelago-backend.apk
|
||||
fi
|
||||
|
||||
# Create archipelago user if needed
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
echo "👤 Creating archipelago user..."
|
||||
adduser -D -s /bin/bash archipelago || true
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers || true
|
||||
fi
|
||||
|
||||
# Setup Podman for archipelago user
|
||||
echo "🐳 Configuring Podman..."
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
chown -R archipelago:archipelago /home/archipelago || true
|
||||
|
||||
# Create data directories
|
||||
echo "📁 Creating data directories..."
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago || true
|
||||
|
||||
# Enable services
|
||||
echo "⚙️ Enabling services..."
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
systemctl enable archipelago 2>/dev/null || true
|
||||
|
||||
# Start services
|
||||
echo "🚀 Starting services..."
|
||||
rc-service archipelago start 2>/dev/null || systemctl start archipelago 2>/dev/null || true
|
||||
|
||||
echo "✅ Archipelago setup complete!"
|
||||
echo " Web UI: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
echo " API: http://$(hostname -I | awk '{print $1}'):5959"
|
||||
@@ -1,29 +0,0 @@
|
||||
[Unit]
|
||||
Description=Archipelago Bitcoin Node OS Backend
|
||||
After=network.target podman.service
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=archipelago
|
||||
Group=archipelago
|
||||
WorkingDirectory=/var/lib/archipelago
|
||||
ExecStart=/usr/bin/archipelago
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
# Security
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/archipelago /tmp
|
||||
|
||||
# Environment
|
||||
Environment="RUST_LOG=info"
|
||||
Environment="ARCHIPELAGO_DATA_DIR=/var/lib/archipelago"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Submodule image-recipe/aports deleted from 4315b9b90c
+311
@@ -0,0 +1,311 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Archipelago Main Menu
|
||||
# Interactive setup wizard for Archipelago Bitcoin Node OS
|
||||
#
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Install required tools on first run (for live mode)
|
||||
install_required_tools() {
|
||||
if [ -f /tmp/.archipelago-tools-installed ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if we need to install tools
|
||||
local NEED_TOOLS=0
|
||||
for tool in parted debootstrap mkfs.ext4 mkfs.vfat; do
|
||||
if ! command -v $tool >/dev/null 2>&1; then
|
||||
NEED_TOOLS=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $NEED_TOOLS -eq 1 ]; then
|
||||
echo ""
|
||||
echo " 📦 Installing required tools (first run)..."
|
||||
echo ""
|
||||
sudo apt-get update -qq 2>/dev/null
|
||||
sudo apt-get install -y parted debootstrap dosfstools e2fsprogs 2>/dev/null
|
||||
echo " ✅ Tools installed"
|
||||
echo ""
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
touch /tmp/.archipelago-tools-installed
|
||||
}
|
||||
|
||||
# Run tool installation at startup
|
||||
install_required_tools
|
||||
|
||||
show_banner() {
|
||||
clear
|
||||
echo ""
|
||||
echo " ╔═══════════════════════════════════════════════════════════╗"
|
||||
echo " ║ ║"
|
||||
echo " ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║"
|
||||
echo " ║ ║"
|
||||
echo " ║ Your sovereign Bitcoin infrastructure ║"
|
||||
echo " ║ ║"
|
||||
echo " ╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_status() {
|
||||
echo " System Status:"
|
||||
echo " ─────────────────────────────────────────────────────────────"
|
||||
|
||||
# Check if we're in live mode
|
||||
if [ -d /run/live ]; then
|
||||
echo " Mode: 🔴 Live (changes won't persist)"
|
||||
else
|
||||
echo " Mode: 🟢 Installed"
|
||||
fi
|
||||
|
||||
# Check Podman
|
||||
if command -v podman >/dev/null 2>&1; then
|
||||
echo " Podman: 🟢 Installed"
|
||||
else
|
||||
echo " Podman: 🔴 Not installed"
|
||||
fi
|
||||
|
||||
# Check Bitcoin Core
|
||||
if podman ps 2>/dev/null | grep -q bitcoind; then
|
||||
BLOCKS=$(podman exec bitcoind bitcoin-cli getblockcount 2>/dev/null || echo "syncing")
|
||||
echo " Bitcoin: 🟢 Running (blocks: $BLOCKS)"
|
||||
elif podman ps -a 2>/dev/null | grep -q bitcoind; then
|
||||
echo " Bitcoin: 🟡 Stopped"
|
||||
else
|
||||
echo " Bitcoin: ⚪ Not configured"
|
||||
fi
|
||||
|
||||
# Check LND
|
||||
if podman ps 2>/dev/null | grep -q lnd; then
|
||||
echo " Lightning: 🟢 Running"
|
||||
elif podman ps -a 2>/dev/null | grep -q lnd; then
|
||||
echo " Lightning: 🟡 Stopped"
|
||||
else
|
||||
echo " Lightning: ⚪ Not configured"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
main_menu() {
|
||||
while true; do
|
||||
show_banner
|
||||
show_status
|
||||
|
||||
# Show Web UI URL
|
||||
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
if [ -n "$IP" ]; then
|
||||
echo " 🌐 Web UI: http://$IP"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo " Main Menu:"
|
||||
echo " ─────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
echo " w) Open Web UI - Launch graphical interface"
|
||||
echo ""
|
||||
echo " 1) Install to Disk - Permanently install Archipelago"
|
||||
echo " 2) Setup Bitcoin Core - Configure Bitcoin full node"
|
||||
echo " 3) Setup Lightning (LND) - Configure Lightning Network"
|
||||
echo " 4) Setup BTCPay Server - Bitcoin payment processor"
|
||||
echo " 5) View Logs - Monitor running services"
|
||||
echo " 6) Network Settings - Configure networking"
|
||||
echo " 7) System Info - View system information"
|
||||
echo ""
|
||||
echo " q) Quit"
|
||||
echo ""
|
||||
read -p " Select option: " choice
|
||||
|
||||
case $choice in
|
||||
w|W)
|
||||
if [ -f "$SCRIPT_DIR/start-web-ui.sh" ]; then
|
||||
sudo bash "$SCRIPT_DIR/start-web-ui.sh" 80
|
||||
else
|
||||
# Try to find and start web UI
|
||||
for path in /opt/archipelago/scripts /run/live/medium/archipelago/scripts; do
|
||||
if [ -f "$path/start-web-ui.sh" ]; then
|
||||
sudo bash "$path/start-web-ui.sh" 80
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
;;
|
||||
1)
|
||||
if [ -f "$SCRIPT_DIR/install-to-disk.sh" ]; then
|
||||
sudo bash "$SCRIPT_DIR/install-to-disk.sh"
|
||||
else
|
||||
echo "Installer not found. Running from: $SCRIPT_DIR"
|
||||
fi
|
||||
read -p "Press Enter to continue..."
|
||||
;;
|
||||
2)
|
||||
if [ -f "$SCRIPT_DIR/setup-bitcoin.sh" ]; then
|
||||
bash "$SCRIPT_DIR/setup-bitcoin.sh"
|
||||
else
|
||||
echo "Bitcoin setup script not found."
|
||||
fi
|
||||
read -p "Press Enter to continue..."
|
||||
;;
|
||||
3)
|
||||
if [ -f "$SCRIPT_DIR/setup-lnd.sh" ]; then
|
||||
bash "$SCRIPT_DIR/setup-lnd.sh"
|
||||
else
|
||||
echo "LND setup script not found."
|
||||
fi
|
||||
read -p "Press Enter to continue..."
|
||||
;;
|
||||
4)
|
||||
setup_btcpay
|
||||
read -p "Press Enter to continue..."
|
||||
;;
|
||||
5)
|
||||
view_logs
|
||||
;;
|
||||
6)
|
||||
network_settings
|
||||
read -p "Press Enter to continue..."
|
||||
;;
|
||||
7)
|
||||
system_info
|
||||
read -p "Press Enter to continue..."
|
||||
;;
|
||||
q|Q)
|
||||
echo ""
|
||||
echo " Goodbye! 🏝️"
|
||||
echo ""
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid option"
|
||||
sleep 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
setup_btcpay() {
|
||||
show_banner
|
||||
echo " BTCPay Server Setup"
|
||||
echo " ─────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
echo " BTCPay Server is a self-hosted Bitcoin payment processor."
|
||||
echo ""
|
||||
|
||||
if ! podman ps | grep -q bitcoind; then
|
||||
echo " ⚠️ Bitcoin Core must be running first."
|
||||
return
|
||||
fi
|
||||
|
||||
read -p " Setup BTCPay Server? [y/N]: " SETUP
|
||||
if [[ ! "$SETUP" =~ ^[Yy]$ ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " 🐳 Pulling BTCPay Server image..."
|
||||
podman pull docker.io/btcpayserver/btcpayserver:latest
|
||||
|
||||
# Create data directory
|
||||
mkdir -p ~/.btcpay
|
||||
|
||||
echo ""
|
||||
echo " BTCPay Server setup is more complex and typically uses docker-compose."
|
||||
echo " For a full setup, visit: https://docs.btcpayserver.org"
|
||||
echo ""
|
||||
}
|
||||
|
||||
view_logs() {
|
||||
show_banner
|
||||
echo " View Logs"
|
||||
echo " ─────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
echo " 1) Bitcoin Core logs"
|
||||
echo " 2) LND logs"
|
||||
echo " 3) System logs"
|
||||
echo " b) Back"
|
||||
echo ""
|
||||
read -p " Select: " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
if podman ps -a | grep -q bitcoind; then
|
||||
podman logs -f --tail 50 bitcoind
|
||||
else
|
||||
echo "Bitcoin Core not running"
|
||||
read -p "Press Enter..."
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if podman ps -a | grep -q lnd; then
|
||||
podman logs -f --tail 50 lnd
|
||||
else
|
||||
echo "LND not running"
|
||||
read -p "Press Enter..."
|
||||
fi
|
||||
;;
|
||||
3)
|
||||
journalctl -f
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
network_settings() {
|
||||
show_banner
|
||||
echo " Network Settings"
|
||||
echo " ─────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
|
||||
# Show current IP
|
||||
IP=$(hostname -I | awk '{print $1}')
|
||||
echo " Current IP: $IP"
|
||||
echo ""
|
||||
|
||||
# Show network interfaces
|
||||
echo " Network Interfaces:"
|
||||
ip -br addr | grep -v "^lo" | while read line; do
|
||||
echo " $line"
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo " Ports in use:"
|
||||
echo " 8332 - Bitcoin RPC"
|
||||
echo " 8333 - Bitcoin P2P"
|
||||
echo " 9735 - Lightning P2P"
|
||||
echo " 10009 - Lightning gRPC"
|
||||
echo " 8080 - Lightning REST"
|
||||
echo ""
|
||||
}
|
||||
|
||||
system_info() {
|
||||
show_banner
|
||||
echo " System Information"
|
||||
echo " ─────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
echo " Hostname: $(hostname)"
|
||||
echo " Kernel: $(uname -r)"
|
||||
echo " Uptime: $(uptime -p)"
|
||||
echo ""
|
||||
echo " CPU: $(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
|
||||
echo " Memory: $(free -h | grep Mem | awk '{print $2}') total, $(free -h | grep Mem | awk '{print $3}') used"
|
||||
echo ""
|
||||
echo " Disk Usage:"
|
||||
df -h / | tail -1 | awk '{print " Root: " $3 " / " $2 " (" $5 " used)"}'
|
||||
if [ -d ~/.bitcoin ]; then
|
||||
echo " Bitcoin: $(du -sh ~/.bitcoin 2>/dev/null | cut -f1)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Container status
|
||||
echo " Containers:"
|
||||
if command -v podman >/dev/null 2>&1; then
|
||||
podman ps --format " {{.Names}}: {{.Status}}" 2>/dev/null || echo " No containers running"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Run main menu
|
||||
main_menu
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Archipelago Disk Installer
|
||||
# Installs Archipelago Bitcoin Node OS to a disk
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ 🏝️ ARCHIPELAGO DISK INSTALLER ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "❌ Please run as root: sudo $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install required tools if missing
|
||||
echo "📦 Checking required tools..."
|
||||
NEED_INSTALL=""
|
||||
for tool in parted debootstrap; do
|
||||
if ! command -v $tool >/dev/null 2>&1; then
|
||||
NEED_INSTALL="$NEED_INSTALL $tool"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$NEED_INSTALL" ]; then
|
||||
echo "📥 Installing required tools:$NEED_INSTALL"
|
||||
apt-get update
|
||||
apt-get install -y $NEED_INSTALL dosfstools e2fsprogs
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# List available disks
|
||||
echo "📋 Available disks:"
|
||||
echo ""
|
||||
lsblk -d -o NAME,SIZE,MODEL | grep -v loop | grep -v sr
|
||||
echo ""
|
||||
|
||||
# Get target disk
|
||||
read -p "Enter target disk (e.g., sda, nvme0n1): " TARGET_DISK
|
||||
TARGET_DEVICE="/dev/$TARGET_DISK"
|
||||
|
||||
if [ ! -b "$TARGET_DEVICE" ]; then
|
||||
echo "❌ Device $TARGET_DEVICE not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Confirm
|
||||
echo ""
|
||||
echo "⚠️ WARNING: This will ERASE ALL DATA on $TARGET_DEVICE"
|
||||
echo ""
|
||||
read -p "Type 'yes' to continue: " CONFIRM
|
||||
|
||||
if [ "$CONFIRM" != "yes" ]; then
|
||||
echo "Aborted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔧 Partitioning $TARGET_DEVICE..."
|
||||
|
||||
# Unmount any existing partitions
|
||||
umount ${TARGET_DEVICE}* 2>/dev/null || true
|
||||
|
||||
# Create GPT partition table
|
||||
parted -s "$TARGET_DEVICE" mklabel gpt
|
||||
|
||||
# Create partitions:
|
||||
# 1. EFI System Partition (512MB)
|
||||
# 2. Root partition (remaining space)
|
||||
parted -s "$TARGET_DEVICE" mkpart primary fat32 1MiB 513MiB
|
||||
parted -s "$TARGET_DEVICE" set 1 esp on
|
||||
parted -s "$TARGET_DEVICE" mkpart primary ext4 513MiB 100%
|
||||
|
||||
# Wait for partitions to appear
|
||||
sleep 2
|
||||
|
||||
# Determine partition names (handle both /dev/sdX and /dev/nvmeXnYpZ naming)
|
||||
if [[ "$TARGET_DISK" == nvme* ]]; then
|
||||
EFI_PART="${TARGET_DEVICE}p1"
|
||||
ROOT_PART="${TARGET_DEVICE}p2"
|
||||
else
|
||||
EFI_PART="${TARGET_DEVICE}1"
|
||||
ROOT_PART="${TARGET_DEVICE}2"
|
||||
fi
|
||||
|
||||
echo "🗂️ Formatting partitions..."
|
||||
|
||||
# Format EFI partition
|
||||
mkfs.vfat -F32 -n ARCHIPELAGO "$EFI_PART"
|
||||
|
||||
# Format root partition
|
||||
mkfs.ext4 -L archipelago-root "$ROOT_PART"
|
||||
|
||||
echo "📦 Mounting partitions..."
|
||||
|
||||
# Create mount points
|
||||
mkdir -p /mnt/archipelago
|
||||
mount "$ROOT_PART" /mnt/archipelago
|
||||
mkdir -p /mnt/archipelago/boot/efi
|
||||
mount "$EFI_PART" /mnt/archipelago/boot/efi
|
||||
|
||||
echo "📋 Installing base system..."
|
||||
|
||||
# Install base system using debootstrap
|
||||
if command -v debootstrap >/dev/null 2>&1; then
|
||||
debootstrap --arch=amd64 bookworm /mnt/archipelago http://deb.debian.org/debian
|
||||
else
|
||||
echo "❌ debootstrap not found. Installing..."
|
||||
apt-get update && apt-get install -y debootstrap
|
||||
debootstrap --arch=amd64 bookworm /mnt/archipelago http://deb.debian.org/debian
|
||||
fi
|
||||
|
||||
echo "⚙️ Configuring system..."
|
||||
|
||||
# Mount virtual filesystems
|
||||
mount --bind /dev /mnt/archipelago/dev
|
||||
mount --bind /proc /mnt/archipelago/proc
|
||||
mount --bind /sys /mnt/archipelago/sys
|
||||
|
||||
# Create fstab
|
||||
cat > /mnt/archipelago/etc/fstab <<EOF
|
||||
# Archipelago Bitcoin Node OS
|
||||
UUID=$(blkid -s UUID -o value "$ROOT_PART") / ext4 errors=remount-ro 0 1
|
||||
UUID=$(blkid -s UUID -o value "$EFI_PART") /boot/efi vfat umask=0077 0 1
|
||||
EOF
|
||||
|
||||
# Set hostname
|
||||
echo "archipelago" > /mnt/archipelago/etc/hostname
|
||||
|
||||
# Configure hosts
|
||||
cat > /mnt/archipelago/etc/hosts <<EOF
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 archipelago
|
||||
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
EOF
|
||||
|
||||
# Install bootloader and essential packages
|
||||
chroot /mnt/archipelago /bin/bash <<'CHROOT_EOF'
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Add sources
|
||||
cat > /etc/apt/sources.list <<EOF
|
||||
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
|
||||
deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
|
||||
deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
|
||||
EOF
|
||||
|
||||
apt-get update
|
||||
|
||||
# Install kernel, bootloader, and essentials
|
||||
apt-get install -y \
|
||||
linux-image-amd64 \
|
||||
grub-efi-amd64 \
|
||||
sudo \
|
||||
networkmanager \
|
||||
openssh-server \
|
||||
curl \
|
||||
wget \
|
||||
htop \
|
||||
vim \
|
||||
git \
|
||||
podman \
|
||||
podman-compose \
|
||||
buildah \
|
||||
skopeo
|
||||
|
||||
# Install GRUB
|
||||
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=archipelago
|
||||
update-grub
|
||||
|
||||
# Create archipelago user
|
||||
useradd -m -s /bin/bash -G sudo,podman archipelago
|
||||
echo "archipelago:archipelago" | chpasswd
|
||||
|
||||
# Enable services
|
||||
systemctl enable NetworkManager
|
||||
systemctl enable ssh
|
||||
systemctl enable podman
|
||||
|
||||
# Create Archipelago directories
|
||||
mkdir -p /var/lib/archipelago/{data,config,containers}
|
||||
mkdir -p /etc/archipelago
|
||||
chown -R archipelago:archipelago /var/lib/archipelago
|
||||
|
||||
echo "✅ Base system installed"
|
||||
CHROOT_EOF
|
||||
|
||||
# Copy Archipelago files
|
||||
echo "📋 Installing Archipelago components..."
|
||||
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
||||
if [ -d "$dev/archipelago" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$BOOT_MEDIA" ]; then
|
||||
echo " Copying from: $BOOT_MEDIA/archipelago"
|
||||
|
||||
# Copy entire archipelago directory
|
||||
mkdir -p /mnt/archipelago/opt/archipelago
|
||||
cp -r "$BOOT_MEDIA/archipelago/"* /mnt/archipelago/opt/archipelago/ 2>/dev/null || true
|
||||
|
||||
# Install binaries
|
||||
if [ -d "$BOOT_MEDIA/archipelago/bin" ]; then
|
||||
cp "$BOOT_MEDIA/archipelago/bin/"* /mnt/archipelago/usr/local/bin/ 2>/dev/null || true
|
||||
chmod +x /mnt/archipelago/usr/local/bin/* 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Install scripts
|
||||
if [ -d "$BOOT_MEDIA/archipelago/scripts" ]; then
|
||||
mkdir -p /mnt/archipelago/opt/archipelago/scripts
|
||||
cp "$BOOT_MEDIA/archipelago/scripts/"* /mnt/archipelago/opt/archipelago/scripts/ 2>/dev/null || true
|
||||
chmod +x /mnt/archipelago/opt/archipelago/scripts/*.sh 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Install app manifests
|
||||
if [ -d "$BOOT_MEDIA/archipelago/apps" ]; then
|
||||
mkdir -p /mnt/archipelago/etc/archipelago
|
||||
cp -r "$BOOT_MEDIA/archipelago/apps" /mnt/archipelago/etc/archipelago/
|
||||
fi
|
||||
|
||||
# Create profile.d script for auto-menu on login
|
||||
mkdir -p /mnt/archipelago/etc/profile.d
|
||||
cat > /mnt/archipelago/etc/profile.d/archipelago.sh <<'PROFILE_EOF'
|
||||
#!/bin/bash
|
||||
# Archipelago welcome message
|
||||
if [ -t 0 ] && [ -z "$ARCHIPELAGO_WELCOMED" ]; then
|
||||
export ARCHIPELAGO_WELCOMED=1
|
||||
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
echo ""
|
||||
echo " 🏝️ Welcome to Archipelago Bitcoin Node OS"
|
||||
echo ""
|
||||
if [ -n "$IP" ]; then
|
||||
echo " Web UI: http://$IP"
|
||||
fi
|
||||
echo " Menu: Type 'archipelago' to open setup menu"
|
||||
echo ""
|
||||
fi
|
||||
PROFILE_EOF
|
||||
chmod +x /mnt/archipelago/etc/profile.d/archipelago.sh
|
||||
fi
|
||||
|
||||
echo "🧹 Cleaning up..."
|
||||
|
||||
# Unmount
|
||||
umount /mnt/archipelago/dev
|
||||
umount /mnt/archipelago/proc
|
||||
umount /mnt/archipelago/sys
|
||||
umount /mnt/archipelago/boot/efi
|
||||
umount /mnt/archipelago
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ✅ INSTALLATION COMPLETE! ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "Remove the USB drive and reboot to start Archipelago."
|
||||
echo ""
|
||||
echo "Default login:"
|
||||
echo " Username: archipelago"
|
||||
echo " Password: archipelago"
|
||||
echo ""
|
||||
echo "⚠️ Please change the password after first login!"
|
||||
echo ""
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Bitcoin Core Setup Script for Archipelago
|
||||
# Sets up Bitcoin Core in a Podman container
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ₿ BITCOIN CORE SETUP ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
echo "⚠️ Running as root. For rootless Podman, run as regular user."
|
||||
fi
|
||||
|
||||
# Check for Podman
|
||||
if ! command -v podman >/dev/null 2>&1; then
|
||||
echo "📦 Installing Podman..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y podman podman-compose
|
||||
fi
|
||||
|
||||
# Create data directory
|
||||
BITCOIN_DATA="${HOME}/.bitcoin"
|
||||
mkdir -p "$BITCOIN_DATA"
|
||||
|
||||
echo "📍 Bitcoin data directory: $BITCOIN_DATA"
|
||||
echo ""
|
||||
|
||||
# Ask for configuration
|
||||
echo "Bitcoin Core Configuration:"
|
||||
echo ""
|
||||
read -p "Enable pruning? (saves disk space) [y/N]: " PRUNE
|
||||
read -p "Enable txindex? (required for some apps) [y/N]: " TXINDEX
|
||||
read -p "RPC username [bitcoin]: " RPC_USER
|
||||
RPC_USER=${RPC_USER:-bitcoin}
|
||||
read -p "RPC password [randomly generated]: " RPC_PASS
|
||||
|
||||
if [ -z "$RPC_PASS" ]; then
|
||||
RPC_PASS=$(openssl rand -hex 16)
|
||||
echo " Generated RPC password: $RPC_PASS"
|
||||
fi
|
||||
|
||||
# Create bitcoin.conf
|
||||
cat > "$BITCOIN_DATA/bitcoin.conf" <<EOF
|
||||
# Archipelago Bitcoin Core Configuration
|
||||
|
||||
# Network
|
||||
server=1
|
||||
listen=1
|
||||
|
||||
# RPC
|
||||
rpcuser=$RPC_USER
|
||||
rpcpassword=$RPC_PASS
|
||||
rpcbind=0.0.0.0
|
||||
rpcallowip=10.0.0.0/8
|
||||
rpcallowip=172.16.0.0/12
|
||||
rpcallowip=192.168.0.0/16
|
||||
|
||||
# Performance
|
||||
dbcache=450
|
||||
maxmempool=300
|
||||
|
||||
EOF
|
||||
|
||||
if [[ "$PRUNE" =~ ^[Yy]$ ]]; then
|
||||
echo "prune=550" >> "$BITCOIN_DATA/bitcoin.conf"
|
||||
echo " Pruning enabled (550MB)"
|
||||
fi
|
||||
|
||||
if [[ "$TXINDEX" =~ ^[Yy]$ ]]; then
|
||||
echo "txindex=1" >> "$BITCOIN_DATA/bitcoin.conf"
|
||||
echo " Transaction index enabled"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📋 Created bitcoin.conf"
|
||||
echo ""
|
||||
|
||||
# Pull Bitcoin Core image
|
||||
echo "🐳 Pulling Bitcoin Core container image..."
|
||||
podman pull docker.io/lncm/bitcoind:v27.0
|
||||
|
||||
# Create systemd user service for Bitcoin Core
|
||||
mkdir -p ~/.config/systemd/user
|
||||
|
||||
cat > ~/.config/systemd/user/bitcoind.service <<EOF
|
||||
[Unit]
|
||||
Description=Bitcoin Core (Podman)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=-/usr/bin/podman stop bitcoind
|
||||
ExecStartPre=-/usr/bin/podman rm bitcoind
|
||||
ExecStart=/usr/bin/podman run --name bitcoind \\
|
||||
--rm \\
|
||||
-v ${BITCOIN_DATA}:/data/.bitcoin:Z \\
|
||||
-p 8332:8332 \\
|
||||
-p 8333:8333 \\
|
||||
docker.io/lncm/bitcoind:v27.0
|
||||
ExecStop=/usr/bin/podman stop bitcoind
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
echo "📋 Created systemd service"
|
||||
echo ""
|
||||
|
||||
# Enable and start service
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable bitcoind.service
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ✅ BITCOIN CORE SETUP COMPLETE! ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " Start: systemctl --user start bitcoind"
|
||||
echo " Stop: systemctl --user stop bitcoind"
|
||||
echo " Status: systemctl --user status bitcoind"
|
||||
echo " Logs: podman logs -f bitcoind"
|
||||
echo ""
|
||||
echo "Bitcoin CLI:"
|
||||
echo " podman exec bitcoind bitcoin-cli -getinfo"
|
||||
echo ""
|
||||
echo "RPC Credentials (save these!):"
|
||||
echo " User: $RPC_USER"
|
||||
echo " Pass: $RPC_PASS"
|
||||
echo ""
|
||||
|
||||
read -p "Start Bitcoin Core now? [Y/n]: " START_NOW
|
||||
if [[ ! "$START_NOW" =~ ^[Nn]$ ]]; then
|
||||
echo ""
|
||||
echo "🚀 Starting Bitcoin Core..."
|
||||
systemctl --user start bitcoind
|
||||
echo ""
|
||||
echo "Bitcoin Core is syncing. This will take several hours/days."
|
||||
echo "Monitor with: podman logs -f bitcoind"
|
||||
fi
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# LND (Lightning Network Daemon) Setup Script for Archipelago
|
||||
# Sets up LND in a Podman container
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ⚡ LND (LIGHTNING) SETUP ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Check for Podman
|
||||
if ! command -v podman >/dev/null 2>&1; then
|
||||
echo "❌ Podman not found. Please run setup-bitcoin.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if Bitcoin Core is running
|
||||
if ! podman ps | grep -q bitcoind; then
|
||||
echo "⚠️ Bitcoin Core is not running."
|
||||
echo " LND requires a synced Bitcoin Core node."
|
||||
read -p "Continue anyway? [y/N]: " CONTINUE
|
||||
if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create data directory
|
||||
LND_DATA="${HOME}/.lnd"
|
||||
mkdir -p "$LND_DATA"
|
||||
|
||||
echo "📍 LND data directory: $LND_DATA"
|
||||
echo ""
|
||||
|
||||
# Get Bitcoin RPC credentials
|
||||
BITCOIN_CONF="${HOME}/.bitcoin/bitcoin.conf"
|
||||
if [ -f "$BITCOIN_CONF" ]; then
|
||||
RPC_USER=$(grep "^rpcuser=" "$BITCOIN_CONF" | cut -d= -f2)
|
||||
RPC_PASS=$(grep "^rpcpassword=" "$BITCOIN_CONF" | cut -d= -f2)
|
||||
else
|
||||
read -p "Bitcoin RPC username: " RPC_USER
|
||||
read -p "Bitcoin RPC password: " RPC_PASS
|
||||
fi
|
||||
|
||||
# Ask for LND configuration
|
||||
echo "LND Configuration:"
|
||||
echo ""
|
||||
read -p "Node alias (public name): " LND_ALIAS
|
||||
LND_ALIAS=${LND_ALIAS:-archipelago-node}
|
||||
|
||||
# Create lnd.conf
|
||||
cat > "$LND_DATA/lnd.conf" <<EOF
|
||||
# Archipelago LND Configuration
|
||||
|
||||
[Application Options]
|
||||
alias=$LND_ALIAS
|
||||
color=#FF9900
|
||||
listen=0.0.0.0:9735
|
||||
rpclisten=0.0.0.0:10009
|
||||
restlisten=0.0.0.0:8080
|
||||
|
||||
# Automatically unlock wallet (create password file after first run)
|
||||
# wallet-unlock-password-file=/data/.lnd/password.txt
|
||||
|
||||
[Bitcoin]
|
||||
bitcoin.active=true
|
||||
bitcoin.mainnet=true
|
||||
bitcoin.node=bitcoind
|
||||
|
||||
[Bitcoind]
|
||||
bitcoind.rpchost=host.containers.internal:8332
|
||||
bitcoind.rpcuser=$RPC_USER
|
||||
bitcoind.rpcpass=$RPC_PASS
|
||||
bitcoind.zmqpubrawblock=tcp://host.containers.internal:28332
|
||||
bitcoind.zmqpubrawtx=tcp://host.containers.internal:28333
|
||||
|
||||
[tor]
|
||||
tor.active=false
|
||||
|
||||
[wtclient]
|
||||
wtclient.active=true
|
||||
EOF
|
||||
|
||||
echo "📋 Created lnd.conf"
|
||||
echo ""
|
||||
|
||||
# Pull LND image
|
||||
echo "🐳 Pulling LND container image..."
|
||||
podman pull docker.io/lightninglabs/lnd:v0.18.0-beta
|
||||
|
||||
# Create systemd user service for LND
|
||||
mkdir -p ~/.config/systemd/user
|
||||
|
||||
cat > ~/.config/systemd/user/lnd.service <<EOF
|
||||
[Unit]
|
||||
Description=LND Lightning Network Daemon (Podman)
|
||||
After=bitcoind.service
|
||||
Requires=bitcoind.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=-/usr/bin/podman stop lnd
|
||||
ExecStartPre=-/usr/bin/podman rm lnd
|
||||
ExecStart=/usr/bin/podman run --name lnd \\
|
||||
--rm \\
|
||||
--add-host=host.containers.internal:host-gateway \\
|
||||
-v ${LND_DATA}:/data/.lnd:Z \\
|
||||
-p 9735:9735 \\
|
||||
-p 10009:10009 \\
|
||||
-p 8080:8080 \\
|
||||
docker.io/lightninglabs/lnd:v0.18.0-beta \\
|
||||
--configfile=/data/.lnd/lnd.conf
|
||||
ExecStop=/usr/bin/podman stop lnd
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
echo "📋 Created systemd service"
|
||||
echo ""
|
||||
|
||||
# Enable service
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable lnd.service
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ ✅ LND SETUP COMPLETE! ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " Start: systemctl --user start lnd"
|
||||
echo " Stop: systemctl --user stop lnd"
|
||||
echo " Status: systemctl --user status lnd"
|
||||
echo " Logs: podman logs -f lnd"
|
||||
echo ""
|
||||
echo "LND CLI:"
|
||||
echo " podman exec lnd lncli --network=mainnet getinfo"
|
||||
echo ""
|
||||
echo "⚠️ IMPORTANT: On first start, you need to create a wallet:"
|
||||
echo " 1. Start LND: systemctl --user start lnd"
|
||||
echo " 2. Create wallet: podman exec -it lnd lncli create"
|
||||
echo " 3. Save your seed phrase securely!"
|
||||
echo ""
|
||||
|
||||
read -p "Start LND now? [Y/n]: " START_NOW
|
||||
if [[ ! "$START_NOW" =~ ^[Nn]$ ]]; then
|
||||
echo ""
|
||||
echo "🚀 Starting LND..."
|
||||
systemctl --user start lnd
|
||||
sleep 3
|
||||
echo ""
|
||||
echo "LND is starting. Create your wallet with:"
|
||||
echo " podman exec -it lnd lncli create"
|
||||
fi
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple API server for Archipelago Web UI
|
||||
Serves static files and handles basic API endpoints
|
||||
"""
|
||||
|
||||
import http.server
|
||||
import socketserver
|
||||
import json
|
||||
import os
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
PORT = 80
|
||||
WEB_DIR = None
|
||||
|
||||
# Find web UI directory
|
||||
for path in ['/opt/archipelago/web-ui', '/run/live/medium/archipelago/web-ui', '/lib/live/mount/medium/archipelago/web-ui']:
|
||||
if os.path.isdir(path):
|
||||
WEB_DIR = path
|
||||
break
|
||||
|
||||
if not WEB_DIR:
|
||||
print("Web UI directory not found!")
|
||||
exit(1)
|
||||
|
||||
os.chdir(WEB_DIR)
|
||||
|
||||
class ArchipelagoHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
"""Handle POST requests with mock responses"""
|
||||
content_length = int(self.headers.get('Content-Length', 0))
|
||||
post_data = self.rfile.read(content_length) if content_length > 0 else b''
|
||||
|
||||
path = urlparse(self.path).path
|
||||
|
||||
# Mock API responses
|
||||
response = {"success": True}
|
||||
|
||||
if '/api/auth' in path or '/auth' in path:
|
||||
response = {
|
||||
"success": True,
|
||||
"token": "mock-token-12345",
|
||||
"user": "archipelago"
|
||||
}
|
||||
elif '/api/setup' in path or '/setup' in path:
|
||||
response = {
|
||||
"success": True,
|
||||
"status": "complete"
|
||||
}
|
||||
elif '/api/status' in path or '/status' in path:
|
||||
response = {
|
||||
"success": True,
|
||||
"status": "running",
|
||||
"version": "0.1.0",
|
||||
"hostname": "archipelago"
|
||||
}
|
||||
elif '/api/apps' in path or '/apps' in path:
|
||||
response = {
|
||||
"success": True,
|
||||
"apps": []
|
||||
}
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(response).encode())
|
||||
|
||||
def do_OPTIONS(self):
|
||||
"""Handle CORS preflight"""
|
||||
self.send_response(200)
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
|
||||
self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
"""Handle GET requests - serve files or API"""
|
||||
path = urlparse(self.path).path
|
||||
|
||||
if path.startswith('/api/'):
|
||||
# Mock API GET endpoints
|
||||
response = {"success": True}
|
||||
|
||||
if '/status' in path:
|
||||
response = {
|
||||
"success": True,
|
||||
"status": "running",
|
||||
"version": "0.1.0"
|
||||
}
|
||||
elif '/apps' in path:
|
||||
response = {
|
||||
"success": True,
|
||||
"apps": [
|
||||
{"id": "bitcoin", "name": "Bitcoin Core", "status": "available"},
|
||||
{"id": "lnd", "name": "Lightning (LND)", "status": "available"}
|
||||
]
|
||||
}
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(response).encode())
|
||||
else:
|
||||
# Serve static files, default to index.html for SPA routing
|
||||
if not os.path.exists(self.translate_path(self.path)) or path == '/':
|
||||
self.path = '/index.html'
|
||||
super().do_GET()
|
||||
|
||||
def log_message(self, format, *args):
|
||||
"""Quieter logging"""
|
||||
if '404' in str(args) or 'error' in str(args).lower():
|
||||
print(f" {args[0]}")
|
||||
|
||||
print(f"""
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ 🏝️ ARCHIPELAGO WEB UI ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
Serving from: {WEB_DIR}
|
||||
|
||||
🌐 Open in your browser: http://localhost:{PORT}
|
||||
|
||||
Press Ctrl+C to stop
|
||||
""")
|
||||
|
||||
with socketserver.TCPServer(("0.0.0.0", PORT), ArchipelagoHandler) as httpd:
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
print("\nShutting down...")
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Start Archipelago Backend Server
|
||||
# Serves the Vue.js UI and handles all API calls
|
||||
#
|
||||
|
||||
# Find archipelago binary
|
||||
ARCHIPELAGO_BIN=""
|
||||
for path in /usr/local/bin/archipelago /opt/archipelago/bin/archipelago /run/live/medium/archipelago/bin/archipelago; do
|
||||
if [ -x "$path" ]; then
|
||||
ARCHIPELAGO_BIN="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Get IP address
|
||||
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
if [ -z "$IP" ]; then
|
||||
IP="localhost"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " Starting Archipelago server..."
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────┐"
|
||||
echo " │ │"
|
||||
echo " │ 🌐 OPEN IN YOUR BROWSER: │"
|
||||
echo " │ │"
|
||||
echo " │ http://$IP "
|
||||
echo " │ │"
|
||||
echo " └─────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
|
||||
if [ -n "$ARCHIPELAGO_BIN" ]; then
|
||||
echo " Using backend: $ARCHIPELAGO_BIN"
|
||||
echo " Press Ctrl+C to stop"
|
||||
echo ""
|
||||
|
||||
# Set environment for dev mode
|
||||
export ARCHIPELAGO_DEV_MODE=true
|
||||
export ARCHIPELAGO_DATA_DIR=/var/lib/archipelago
|
||||
export RUST_LOG=info
|
||||
|
||||
# Create data directory
|
||||
sudo mkdir -p /var/lib/archipelago 2>/dev/null
|
||||
|
||||
exec "$ARCHIPELAGO_BIN"
|
||||
else
|
||||
echo " ⚠️ Backend binary not found, using static file server"
|
||||
echo ""
|
||||
|
||||
# Fallback to static file server
|
||||
WEB_UI_DIR=""
|
||||
for path in /opt/archipelago/web-ui /run/live/medium/archipelago/web-ui; do
|
||||
if [ -d "$path" ]; then
|
||||
WEB_UI_DIR="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$WEB_UI_DIR" ]; then
|
||||
cd "$WEB_UI_DIR"
|
||||
exec python3 -m http.server 80 --bind 0.0.0.0
|
||||
else
|
||||
echo "❌ Neither backend nor web UI found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Quick build script - builds for all supported hardware targets
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BUILD_TYPE="${1:-iso}"
|
||||
|
||||
echo "🏗️ Building Archipelago for all supported hardware"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# Array of hardware targets
|
||||
TARGETS=(
|
||||
"start9-pure:Start9 Server Pure"
|
||||
"hp-prodesk:HP ProDesk 400 G4 DM"
|
||||
"dell-optiplex:Dell OptiPlex"
|
||||
"generic:Generic x86_64"
|
||||
)
|
||||
|
||||
SUCCESS_COUNT=0
|
||||
FAIL_COUNT=0
|
||||
FAILED_TARGETS=()
|
||||
|
||||
# Build for each target
|
||||
for target_info in "${TARGETS[@]}"; do
|
||||
IFS=':' read -r target_name target_desc <<< "$target_info"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🔨 Building for: $target_desc"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
if "$SCRIPT_DIR/build-for-hardware.sh" "$target_name" "$BUILD_TYPE"; then
|
||||
echo "✅ $target_desc build succeeded"
|
||||
((SUCCESS_COUNT++))
|
||||
else
|
||||
echo "❌ $target_desc build failed"
|
||||
((FAIL_COUNT++))
|
||||
FAILED_TARGETS+=("$target_desc")
|
||||
fi
|
||||
done
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "📊 Build Summary"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " Successful: $SUCCESS_COUNT"
|
||||
echo " Failed: $FAIL_COUNT"
|
||||
|
||||
if [ $FAIL_COUNT -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Failed builds:"
|
||||
for target in "${FAILED_TARGETS[@]}"; do
|
||||
echo " - $target"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📦 Build output: $SCRIPT_DIR/results/"
|
||||
ls -lh "$SCRIPT_DIR/results/"*.iso 2>/dev/null || echo " (no ISOs found)"
|
||||
|
||||
echo ""
|
||||
if [ $FAIL_COUNT -eq 0 ]; then
|
||||
echo "✅ All builds completed successfully!"
|
||||
exit 0
|
||||
else
|
||||
echo "⚠️ Some builds failed. Check logs above."
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Build bootable Alpine Linux ISO for Archipelago Bitcoin Node OS
|
||||
# Supports building on macOS (via Docker) and Linux (native)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Configuration
|
||||
ARCHIPELAGO_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
ARCH="${ARCH:-x86_64}"
|
||||
BUILD_TYPE="${BUILD_TYPE:-iso}" # iso or disk
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-$SCRIPT_DIR/results}"
|
||||
|
||||
echo "🔨 Building Archipelago Alpine Linux Image"
|
||||
echo " Version: $ARCHIPELAGO_VERSION"
|
||||
echo " Alpine: $ALPINE_VERSION"
|
||||
echo " Architecture: $ARCH"
|
||||
echo " Build Type: $BUILD_TYPE"
|
||||
echo ""
|
||||
|
||||
# Detect build environment
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
BUILD_ENV="macos"
|
||||
USE_DOCKER=true
|
||||
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
BUILD_ENV="linux"
|
||||
USE_DOCKER=false
|
||||
else
|
||||
echo "❌ Unsupported OS: $OSTYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🌍 Build Environment: $BUILD_ENV"
|
||||
echo ""
|
||||
|
||||
# Create output directory
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Build backend first
|
||||
echo "📦 Building Archipelago backend..."
|
||||
"$SCRIPT_DIR/scripts/build-backend.sh" || {
|
||||
echo "❌ Backend build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Build frontend
|
||||
echo "🎨 Building Archipelago frontend..."
|
||||
"$SCRIPT_DIR/scripts/build-frontend.sh" || {
|
||||
echo "❌ Frontend build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Create backend APK
|
||||
echo "📦 Creating backend APK package..."
|
||||
"$SCRIPT_DIR/scripts/create-backend-apk.sh" || {
|
||||
echo "❌ APK creation failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Build image based on environment
|
||||
if [ "$USE_DOCKER" = true ]; then
|
||||
echo "🐳 Building via Docker (macOS)..."
|
||||
"$SCRIPT_DIR/build-macos.sh" "$BUILD_TYPE"
|
||||
else
|
||||
echo "🐧 Building natively (Linux)..."
|
||||
"$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Build complete!"
|
||||
echo " Output: $OUTPUT_DIR"
|
||||
ls -lh "$OUTPUT_DIR"/*.{iso,img} 2>/dev/null || echo " (Check output directory for results)"
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Native Alpine build script
|
||||
# Must be run on Alpine Linux or in Alpine container
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
BUILD_TYPE="${1:-iso}"
|
||||
|
||||
ARCHIPELAGO_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
ARCH="${ARCH:-x86_64}"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-$SCRIPT_DIR/results}"
|
||||
|
||||
echo "🏔️ Building Alpine image natively"
|
||||
echo ""
|
||||
|
||||
# Install build dependencies
|
||||
echo "📦 Installing build dependencies..."
|
||||
apk add --no-cache \
|
||||
bash \
|
||||
git \
|
||||
alpine-sdk \
|
||||
abuild \
|
||||
alpine-conf \
|
||||
syslinux \
|
||||
xorriso \
|
||||
squashfs-tools \
|
||||
grub \
|
||||
grub-efi \
|
||||
mtools \
|
||||
dosfstools \
|
||||
e2fsprogs \
|
||||
rsync \
|
||||
|| true
|
||||
|
||||
# Setup abuild keys if needed
|
||||
if [ ! -f ~/.abuild/abuild.conf ]; then
|
||||
echo "🔑 Setting up abuild keys..."
|
||||
abuild-keygen -a -n || true
|
||||
fi
|
||||
|
||||
# Clone Alpine aports if needed
|
||||
APORTS_DIR="$SCRIPT_DIR/aports"
|
||||
if [ ! -d "$APORTS_DIR" ]; then
|
||||
echo "📥 Cloning Alpine aports repository..."
|
||||
git clone --depth=1 --branch "${ALPINE_VERSION}-stable" \
|
||||
https://gitlab.alpinelinux.org/alpine/aports.git "$APORTS_DIR" || {
|
||||
echo "⚠️ Failed to clone ${ALPINE_VERSION}-stable, trying 3.19-stable..."
|
||||
git clone --depth=1 --branch "3.19-stable" \
|
||||
https://gitlab.alpinelinux.org/alpine/aports.git "$APORTS_DIR" || {
|
||||
echo "⚠️ Failed to clone 3.19-stable, using master as fallback..."
|
||||
git clone --depth=1 https://gitlab.alpinelinux.org/alpine/aports.git "$APORTS_DIR"
|
||||
}
|
||||
}
|
||||
fi
|
||||
|
||||
# Copy custom profile
|
||||
echo "📝 Setting up custom Archipelago profile..."
|
||||
# Copy profile script to Alpine scripts directory (force overwrite)
|
||||
cp -f "$SCRIPT_DIR/alpine-profile/mkimg.archipelago.sh" "$APORTS_DIR/scripts/"
|
||||
|
||||
# Copy overlay files
|
||||
PROFILE_DIR="$APORTS_DIR/scripts/mkimg.archipelago.d"
|
||||
mkdir -p "$PROFILE_DIR"
|
||||
cp -r "$SCRIPT_DIR/alpine-profile/overlay" "$PROFILE_DIR/" 2>/dev/null || true
|
||||
|
||||
# Build ISO or disk image
|
||||
cd "$APORTS_DIR/scripts"
|
||||
|
||||
if [ "$BUILD_TYPE" = "iso" ]; then
|
||||
echo "💿 Building ISO image..."
|
||||
./mkimage.sh \
|
||||
--arch "$ARCH" \
|
||||
--profile archipelago \
|
||||
--repository "http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/main" \
|
||||
--repository "http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community" \
|
||||
--outdir "$OUTPUT_DIR" \
|
||||
--tag "$ALPINE_VERSION" || {
|
||||
echo "❌ ISO build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Rename output
|
||||
if [ -f "$OUTPUT_DIR/alpine-archipelago-${ALPINE_VERSION}-${ARCH}.iso" ]; then
|
||||
mv "$OUTPUT_DIR/alpine-archipelago-${ALPINE_VERSION}-${ARCH}.iso" \
|
||||
"$OUTPUT_DIR/archipelago-${ARCHIPELAGO_VERSION}-${ARCH}.iso"
|
||||
fi
|
||||
elif [ "$BUILD_TYPE" = "disk" ]; then
|
||||
echo "💾 Building disk image..."
|
||||
# Build ISO first, then convert to disk image
|
||||
./mkimage.sh \
|
||||
--arch "$ARCH" \
|
||||
--profile archipelago \
|
||||
--repository "http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/main" \
|
||||
--repository "http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community" \
|
||||
--outdir "$OUTPUT_DIR" \
|
||||
--tag "$ALPINE_VERSION" || {
|
||||
echo "❌ Image build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Convert to disk image (will be done in install script)
|
||||
echo "📦 Disk image will be created in install step"
|
||||
else
|
||||
echo "❌ Unknown build type: $BUILD_TYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install Archipelago into the image
|
||||
echo "🔧 Installing Archipelago components..."
|
||||
"$SCRIPT_DIR/scripts/install-archipelago.sh" "$OUTPUT_DIR" || {
|
||||
echo "⚠️ Archipelago installation had issues, but image was built"
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "✅ Build complete!"
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Build script for Alpine Linux base image
|
||||
# Supports multi-arch: ARM64 (aarch64) and x86_64
|
||||
|
||||
set -e
|
||||
|
||||
ARCH="${ARCH:-$(uname -m)}"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
IMAGE_NAME="archipelago/alpine-base"
|
||||
TAG="${ALPINE_VERSION}-${ARCH}"
|
||||
|
||||
echo "🔨 Building Alpine Linux base image for ${ARCH}..."
|
||||
|
||||
# Map architecture names
|
||||
case "$ARCH" in
|
||||
aarch64|arm64)
|
||||
BUILD_ARCH="arm64"
|
||||
PLATFORM="linux/arm64"
|
||||
;;
|
||||
x86_64|amd64)
|
||||
BUILD_ARCH="amd64"
|
||||
PLATFORM="linux/amd64"
|
||||
;;
|
||||
*)
|
||||
echo "❌ Unsupported architecture: $ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build the image
|
||||
docker buildx build \
|
||||
--platform "$PLATFORM" \
|
||||
--file image-recipe/Dockerfile.alpine-base \
|
||||
--tag "${IMAGE_NAME}:${TAG}" \
|
||||
--tag "${IMAGE_NAME}:latest-${BUILD_ARCH}" \
|
||||
--load \
|
||||
.
|
||||
|
||||
echo "✅ Alpine base image built successfully!"
|
||||
echo " Image: ${IMAGE_NAME}:${TAG}"
|
||||
echo " Platform: ${PLATFORM}"
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Build Archipelago backend for Alpine Linux (x86_64-musl)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
echo "🦀 Building Archipelago Backend for Alpine Linux"
|
||||
echo ""
|
||||
|
||||
# Create build directory
|
||||
BUILD_DIR="$SCRIPT_DIR/build/backend"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
# Use Docker with Rust Alpine image to build
|
||||
echo "🐳 Building in Alpine Docker container..."
|
||||
|
||||
docker run --rm \
|
||||
-v "$PROJECT_ROOT:/workspace" \
|
||||
-v "$BUILD_DIR:/output" \
|
||||
-w /workspace/core \
|
||||
rust:alpine \
|
||||
sh -c '
|
||||
echo "📦 Installing build dependencies..."
|
||||
apk add --no-cache musl-dev openssl-dev openssl-libs-static pkgconfig gcc
|
||||
|
||||
echo "🔨 Building Archipelago backend (native Alpine build)..."
|
||||
cd archipelago && cargo build --release
|
||||
|
||||
echo "📋 Copying binary to output..."
|
||||
cp ../target/release/archipelago /output/
|
||||
|
||||
echo "✅ Build complete!"
|
||||
ls -lh /output/archipelago
|
||||
' || {
|
||||
echo "❌ Build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "✅ Backend built successfully!"
|
||||
echo " Binary: $BUILD_DIR/archipelago"
|
||||
echo " Size: $(du -h "$BUILD_DIR/archipelago" | cut -f1)"
|
||||
echo ""
|
||||
@@ -1,461 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Custom ISO builder that works on ARM Mac by modifying pre-built Alpine ISO
|
||||
# instead of building from scratch
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
ARCH="${ARCH:-x86_64}"
|
||||
ISO_URL="https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/releases/${ARCH}/alpine-standard-${ALPINE_VERSION}.0-${ARCH}.iso"
|
||||
WORK_DIR="$SCRIPT_DIR/build/iso-custom"
|
||||
OUTPUT_DIR="$SCRIPT_DIR/results"
|
||||
|
||||
echo "🏔️ Building custom Archipelago ISO from Alpine base"
|
||||
echo ""
|
||||
echo "📋 Configuration:"
|
||||
echo " Alpine Version: $ALPINE_VERSION"
|
||||
echo " Architecture: $ARCH"
|
||||
echo " Base ISO URL: $ISO_URL"
|
||||
echo ""
|
||||
|
||||
# Create work directories
|
||||
mkdir -p "$WORK_DIR"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Download Alpine base ISO if not exists
|
||||
BASE_ISO="$WORK_DIR/alpine-base.iso"
|
||||
if [ ! -f "$BASE_ISO" ]; then
|
||||
echo "📥 Downloading Alpine base ISO..."
|
||||
curl -L -o "$BASE_ISO" "$ISO_URL" || {
|
||||
echo "❌ Failed to download Alpine ISO"
|
||||
exit 1
|
||||
}
|
||||
echo "✅ Downloaded base ISO"
|
||||
else
|
||||
echo "✅ Using cached base ISO"
|
||||
fi
|
||||
|
||||
# Extract ISO contents
|
||||
echo "📦 Extracting ISO contents..."
|
||||
CUSTOM_DIR="$WORK_DIR/custom"
|
||||
rm -rf "$CUSTOM_DIR"
|
||||
mkdir -p "$CUSTOM_DIR"
|
||||
|
||||
# Use 7zip to extract ISO (works on both macOS and Linux)
|
||||
if command -v 7z >/dev/null 2>&1; then
|
||||
7z x "$BASE_ISO" -o"$CUSTOM_DIR" -y >/dev/null || {
|
||||
echo "❌ Failed to extract ISO with 7zip"
|
||||
exit 1
|
||||
}
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# Fallback: Try mounting on macOS
|
||||
MOUNT_POINT="$WORK_DIR/mnt"
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
hdiutil attach "$BASE_ISO" -mountpoint "$MOUNT_POINT" -readonly && {
|
||||
rsync -a "$MOUNT_POINT"/ "$CUSTOM_DIR"/
|
||||
hdiutil detach "$MOUNT_POINT"
|
||||
} || {
|
||||
echo "❌ Failed to extract ISO. Install p7zip: brew install p7zip"
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
# On Linux, mount the ISO
|
||||
MOUNT_POINT="$WORK_DIR/mnt"
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
sudo mount -o loop "$BASE_ISO" "$MOUNT_POINT" && {
|
||||
cp -a "$MOUNT_POINT"/* "$CUSTOM_DIR"/
|
||||
sudo umount "$MOUNT_POINT"
|
||||
} || {
|
||||
echo "❌ Failed to mount ISO"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
echo "✅ ISO contents extracted"
|
||||
|
||||
# Add custom packages
|
||||
echo "📦 Adding custom packages..."
|
||||
APKS_DIR="$CUSTOM_DIR/apks/$(uname -m)"
|
||||
mkdir -p "$APKS_DIR"
|
||||
|
||||
# Create a custom apk repository file
|
||||
cat > "$CUSTOM_DIR/archipelago.list" <<'EOF'
|
||||
# Archipelago custom packages
|
||||
# These will be installed during setup-alpine or via apk add
|
||||
|
||||
# Container runtime
|
||||
podman
|
||||
crun
|
||||
fuse-overlayfs
|
||||
slirp4netns
|
||||
|
||||
# Web server
|
||||
nginx
|
||||
|
||||
# SSH server
|
||||
openssh
|
||||
|
||||
# Networking
|
||||
iptables
|
||||
iproute2
|
||||
EOF
|
||||
|
||||
# Create automated installation script
|
||||
echo "📝 Creating installation script..."
|
||||
mkdir -p "$CUSTOM_DIR/archipelago"
|
||||
cat > "$CUSTOM_DIR/archipelago/install.sh" <<'INSTALL_EOF'
|
||||
#!/bin/sh
|
||||
# Archipelago automated installation script
|
||||
|
||||
set -e
|
||||
|
||||
echo "🏝️ Installing Archipelago Bitcoin Node OS"
|
||||
echo ""
|
||||
|
||||
# Install required packages
|
||||
echo "📦 Installing packages..."
|
||||
apk add --no-cache \
|
||||
podman \
|
||||
crun \
|
||||
fuse-overlayfs \
|
||||
slirp4netns \
|
||||
nginx \
|
||||
openssh \
|
||||
iptables \
|
||||
iproute2 \
|
||||
bash \
|
||||
curl
|
||||
|
||||
# Create archipelago user
|
||||
echo "👤 Creating archipelago user..."
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
adduser -D -s /bin/bash archipelago
|
||||
echo "archipelago:archipelago" | chpasswd
|
||||
fi
|
||||
|
||||
# Setup Podman for archipelago user
|
||||
echo "🐳 Setting up Podman..."
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
chown -R archipelago:archipelago /home/archipelago
|
||||
|
||||
# Create data directories
|
||||
echo "📁 Creating data directories..."
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago
|
||||
|
||||
# Install Archipelago backend if available
|
||||
if [ -f /media/cdrom/archipelago/bin/archipelago ]; then
|
||||
echo "🦀 Installing Archipelago backend..."
|
||||
mkdir -p /usr/local/bin
|
||||
cp /media/cdrom/archipelago/bin/archipelago /usr/local/bin/
|
||||
chmod +x /usr/local/bin/archipelago
|
||||
echo "✅ Backend installed"
|
||||
fi
|
||||
|
||||
# Install Archipelago frontend if available
|
||||
if [ -d /media/cdrom/archipelago/web ]; then
|
||||
echo "🎨 Installing Archipelago web UI..."
|
||||
mkdir -p /usr/share/archipelago/web
|
||||
cp -r /media/cdrom/archipelago/web/* /usr/share/archipelago/web/
|
||||
|
||||
# Configure nginx
|
||||
cat > /etc/nginx/http.d/archipelago.conf <<'NGINX_EOF'
|
||||
server {
|
||||
listen 8100;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/archipelago/web;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Proxy API requests to backend
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8101/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
}
|
||||
NGINX_EOF
|
||||
|
||||
rc-update add nginx default
|
||||
echo "✅ Web UI installed"
|
||||
fi
|
||||
|
||||
# Create Archipelago service
|
||||
if [ -f /usr/local/bin/archipelago ]; then
|
||||
echo "⚙️ Creating Archipelago service..."
|
||||
cat > /etc/init.d/archipelago <<'SERVICE_EOF'
|
||||
#!/sbin/openrc-run
|
||||
|
||||
name="Archipelago"
|
||||
description="Archipelago Bitcoin Node OS Backend"
|
||||
command="/usr/local/bin/archipelago"
|
||||
command_background=true
|
||||
pidfile="/run/archipelago.pid"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
after networking
|
||||
}
|
||||
SERVICE_EOF
|
||||
|
||||
chmod +x /etc/init.d/archipelago
|
||||
rc-update add archipelago default
|
||||
echo "✅ Archipelago service created"
|
||||
fi
|
||||
|
||||
# Install app manifests if available
|
||||
if [ -d /media/cdrom/archipelago/apps ]; then
|
||||
echo "📦 Installing app manifests..."
|
||||
mkdir -p /var/lib/archipelago/manifests
|
||||
cp -r /media/cdrom/archipelago/apps/* /var/lib/archipelago/manifests/
|
||||
chown -R archipelago:archipelago /var/lib/archipelago/manifests
|
||||
echo "✅ App manifests installed"
|
||||
fi
|
||||
|
||||
# Configure networking (DHCP)
|
||||
echo "🌐 Configuring network..."
|
||||
cat > /etc/network/interfaces <<'NET_EOF'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
|
||||
auto enp0s3
|
||||
iface enp0s3 inet dhcp
|
||||
|
||||
auto enp0s25
|
||||
iface enp0s25 inet dhcp
|
||||
NET_EOF
|
||||
|
||||
# Enable services
|
||||
echo "⚙️ Enabling services..."
|
||||
rc-update add networking default
|
||||
rc-update add sshd default
|
||||
rc-update add local default
|
||||
|
||||
# Set hostname
|
||||
echo "archipelago" > /etc/hostname
|
||||
|
||||
# Configure SSH
|
||||
echo "🔐 Configuring SSH..."
|
||||
sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
|
||||
|
||||
# Create welcome message
|
||||
cat > /etc/motd <<'MOTD_EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║
|
||||
║ ║
|
||||
║ A sovereign computing platform built on Alpine Linux ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
Default user: archipelago
|
||||
Default pass: archipelago (CHANGE THIS IMMEDIATELY!)
|
||||
|
||||
To access the web UI:
|
||||
http://$(hostname -i):8100
|
||||
|
||||
To start Archipelago:
|
||||
sudo systemctl start archipelago
|
||||
|
||||
Documentation: /usr/share/doc/archipelago/
|
||||
|
||||
MOTD_EOF
|
||||
|
||||
echo ""
|
||||
echo "✅ Archipelago installation complete!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Reboot the system"
|
||||
echo " 2. Login with user: archipelago, pass: archipelago"
|
||||
echo " 3. Change the default password: passwd"
|
||||
echo " 4. Access web UI at http://<your-ip>:8100"
|
||||
echo ""
|
||||
|
||||
INSTALL_EOF
|
||||
|
||||
chmod +x "$CUSTOM_DIR/archipelago/install.sh"
|
||||
|
||||
# Create README
|
||||
cat > "$CUSTOM_DIR/archipelago/README.txt" <<'README_EOF'
|
||||
ARCHIPELAGO BITCOIN NODE OS
|
||||
===========================
|
||||
|
||||
This is a customized Alpine Linux ISO with Archipelago packages.
|
||||
|
||||
INSTALLATION:
|
||||
1. Boot from this USB/ISO
|
||||
2. Login as root (no password)
|
||||
3. Run: setup-alpine
|
||||
4. Follow the prompts to install Alpine
|
||||
5. After installation, run: sh /media/*/archipelago/install.sh
|
||||
6. Reboot
|
||||
|
||||
QUICK INSTALL:
|
||||
For automated installation on dedicated hardware:
|
||||
1. Boot from USB/ISO
|
||||
2. Login as root
|
||||
3. Run: sh /media/*/archipelago/install.sh
|
||||
4. This will set up Alpine + Archipelago automatically
|
||||
|
||||
For more information, visit:
|
||||
https://github.com/your-repo/archipelago
|
||||
|
||||
README_EOF
|
||||
|
||||
# Modify boot configuration to show Archipelago branding
|
||||
if [ -f "$CUSTOM_DIR/boot/grub/grub.cfg" ]; then
|
||||
echo "⚙️ Customizing boot menu..."
|
||||
sed -i.bak 's/Alpine Linux/Archipelago Bitcoin Node OS/g' "$CUSTOM_DIR/boot/grub/grub.cfg" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -f "$CUSTOM_DIR/boot/syslinux/syslinux.cfg" ]; then
|
||||
sed -i.bak 's/Alpine Linux/Archipelago Bitcoin Node OS/g' "$CUSTOM_DIR/boot/syslinux/syslinux.cfg" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Include Archipelago backend if available
|
||||
if [ -n "$INCLUDE_BACKEND" ] && [ -f "$INCLUDE_BACKEND" ]; then
|
||||
echo "🦀 Including Archipelago backend..."
|
||||
mkdir -p "$CUSTOM_DIR/archipelago/bin"
|
||||
cp "$INCLUDE_BACKEND" "$CUSTOM_DIR/archipelago/bin/"
|
||||
chmod +x "$CUSTOM_DIR/archipelago/bin/archipelago"
|
||||
echo "✅ Backend included: $(du -h "$INCLUDE_BACKEND" | cut -f1)"
|
||||
fi
|
||||
|
||||
# Include Archipelago frontend if available
|
||||
if [ -n "$INCLUDE_FRONTEND" ] && [ -d "$INCLUDE_FRONTEND" ]; then
|
||||
echo "🎨 Including Archipelago frontend..."
|
||||
mkdir -p "$CUSTOM_DIR/archipelago/web"
|
||||
cp -r "$INCLUDE_FRONTEND"/* "$CUSTOM_DIR/archipelago/web/"
|
||||
echo "✅ Frontend included"
|
||||
fi
|
||||
|
||||
# Include app manifests if available
|
||||
APPS_DIR="$(dirname "$0")/../apps"
|
||||
if [ -d "$APPS_DIR" ]; then
|
||||
echo "📦 Including app manifests..."
|
||||
mkdir -p "$CUSTOM_DIR/archipelago/apps"
|
||||
# Copy all app directories with manifest.yml files
|
||||
find "$APPS_DIR" -maxdepth 1 -type d -exec test -f {}/manifest.yml \; -exec cp -r {} "$CUSTOM_DIR/archipelago/apps/" \;
|
||||
APP_COUNT=$(find "$CUSTOM_DIR/archipelago/apps" -name "manifest.yml" | wc -l | tr -d ' ')
|
||||
echo "✅ Included $APP_COUNT app manifests"
|
||||
fi
|
||||
|
||||
# Create the ISO
|
||||
OUTPUT_ISO="$OUTPUT_DIR/archipelago-${ALPINE_VERSION}-${ARCH}.iso"
|
||||
echo ""
|
||||
echo "🔥 Creating final ISO..."
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# On macOS, use xorriso for hybrid BIOS+UEFI bootable ISO
|
||||
if command -v xorriso >/dev/null 2>&1; then
|
||||
# Try dual-boot (BIOS + UEFI) if EFI bootloader exists
|
||||
if [ -f "$CUSTOM_DIR/boot/grub/grub.cfg" ] || [ -d "$CUSTOM_DIR/efi" ] || [ -d "$CUSTOM_DIR/EFI" ]; then
|
||||
echo "🔄 Creating hybrid BIOS+UEFI bootable ISO..."
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-J -R \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-isohybrid-mbr "$CUSTOM_DIR/boot/syslinux/isohdpfx.bin" \
|
||||
"$CUSTOM_DIR" 2>&1 | grep -v "xorriso : UPDATE" || {
|
||||
echo "⚠️ Dual-boot failed, trying BIOS-only..."
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-J -R \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-isohybrid-mbr "$CUSTOM_DIR/boot/syslinux/isohdpfx.bin" \
|
||||
"$CUSTOM_DIR" 2>&1 | grep -v "xorriso : UPDATE"
|
||||
}
|
||||
else
|
||||
echo "🔄 Creating BIOS-only bootable ISO..."
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-J -R \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-isohybrid-mbr "$CUSTOM_DIR/boot/syslinux/isohdpfx.bin" \
|
||||
"$CUSTOM_DIR" 2>&1 | grep -v "xorriso : UPDATE" || true
|
||||
|
||||
# Check if ISO was created
|
||||
if [ ! -f "$OUTPUT_ISO" ]; then
|
||||
echo "⚠️ xorriso failed, trying without isohybrid..."
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-J -R \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
"$CUSTOM_DIR" 2>&1 | grep -v "xorriso : UPDATE"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Fallback to hdiutil
|
||||
hdiutil makehybrid -o "$OUTPUT_ISO" "$CUSTOM_DIR" \
|
||||
-iso -joliet -default-volume-name "ARCHIPELAGO" || {
|
||||
echo "❌ Failed to create ISO"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
else
|
||||
# On Linux, use genisoimage or xorriso
|
||||
if command -v genisoimage >/dev/null 2>&1; then
|
||||
genisoimage -o "$OUTPUT_ISO" \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-J -R -V "ARCHIPELAGO" \
|
||||
"$CUSTOM_DIR"
|
||||
elif command -v xorriso >/dev/null 2>&1; then
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-J -R -V "ARCHIPELAGO" \
|
||||
"$CUSTOM_DIR"
|
||||
else
|
||||
echo "❌ No ISO creation tool found (need genisoimage or xorriso)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make bootable (add isohybrid for USB boot)
|
||||
if command -v isohybrid >/dev/null 2>&1 && [[ "$OSTYPE" != "darwin"* ]]; then
|
||||
isohybrid "$OUTPUT_ISO"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ ISO created successfully!"
|
||||
echo ""
|
||||
echo "📀 Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo "📝 To create a bootable USB:"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo " 1. Insert USB drive"
|
||||
echo " 2. Find device: diskutil list"
|
||||
echo " 3. Unmount: diskutil unmountDisk /dev/diskN"
|
||||
echo " 4. Write: sudo dd if=$OUTPUT_ISO of=/dev/rdiskN bs=1m"
|
||||
else
|
||||
echo " sudo dd if=$OUTPUT_ISO of=/dev/sdX bs=4M status=progress"
|
||||
fi
|
||||
echo ""
|
||||
Executable
+437
@@ -0,0 +1,437 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Build Archipelago Bitcoin Node OS ISO - Debian Live Edition
|
||||
# Based on Debian Live for reliable USB boot (like StartOS)
|
||||
#
|
||||
# Usage: ./build-debian-iso.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
WORK_DIR="$SCRIPT_DIR/build/debian-iso"
|
||||
OUTPUT_DIR="$SCRIPT_DIR/results"
|
||||
DEBIAN_VERSION="bookworm"
|
||||
ARCH="amd64"
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════╗"
|
||||
echo "║ Building Archipelago - Debian Live Edition ║"
|
||||
echo "╚════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$WORK_DIR"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Download Debian Live ISO if not exists
|
||||
BASE_ISO="$WORK_DIR/debian-live-12-${ARCH}-standard.iso"
|
||||
if [ ! -f "$BASE_ISO" ] || [ $(stat -f%z "$BASE_ISO" 2>/dev/null || echo 0) -lt 100000000 ]; then
|
||||
echo "📥 Downloading Debian Live 12 (Bookworm) Standard ISO..."
|
||||
rm -f "$BASE_ISO"
|
||||
# Use SourceForge respin which has up-to-date Debian 12 Live
|
||||
curl -L -o "$BASE_ISO" \
|
||||
"https://sourceforge.net/projects/debian-live-respin-iso/files/standard/live-image-debian12.11-standard-20250522-amd64.hybrid.iso/download"
|
||||
echo "✅ Downloaded Debian Live ISO"
|
||||
else
|
||||
echo "✅ Using cached Debian Live ISO"
|
||||
fi
|
||||
|
||||
# Extract ISO
|
||||
echo ""
|
||||
echo "📦 Extracting Debian Live ISO..."
|
||||
ISO_CUSTOM="$WORK_DIR/custom"
|
||||
rm -rf "$ISO_CUSTOM"
|
||||
mkdir -p "$ISO_CUSTOM"
|
||||
|
||||
cd "$ISO_CUSTOM"
|
||||
7z x -y "$BASE_ISO" >/dev/null 2>&1 || 7z x -y "$BASE_ISO"
|
||||
|
||||
echo "✅ Extracted ISO"
|
||||
|
||||
# Add Archipelago files
|
||||
echo ""
|
||||
echo "📋 Adding Archipelago files..."
|
||||
|
||||
ARCHIPELAGO_DIR="$ISO_CUSTOM/archipelago"
|
||||
mkdir -p "$ARCHIPELAGO_DIR"
|
||||
mkdir -p "$ARCHIPELAGO_DIR/bin"
|
||||
mkdir -p "$ARCHIPELAGO_DIR/scripts"
|
||||
|
||||
# Copy the pre-built backend if it exists
|
||||
if [ -d "$SCRIPT_DIR/../core/target/release" ]; then
|
||||
echo "🦀 Including Archipelago backend..."
|
||||
cp "$SCRIPT_DIR/../core/target/release/archipelago" "$ARCHIPELAGO_DIR/bin/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Copy the frontend build if it exists
|
||||
if [ -d "$SCRIPT_DIR/../web/dist/neode-ui" ]; then
|
||||
echo "🎨 Including Archipelago Web UI..."
|
||||
cp -r "$SCRIPT_DIR/../web/dist/neode-ui" "$ARCHIPELAGO_DIR/web-ui"
|
||||
elif [ -d "$SCRIPT_DIR/../neode-ui/dist" ]; then
|
||||
echo "🎨 Including Archipelago frontend..."
|
||||
cp -r "$SCRIPT_DIR/../neode-ui/dist" "$ARCHIPELAGO_DIR/web-ui" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Copy app manifests
|
||||
if [ -d "$SCRIPT_DIR/../apps" ]; then
|
||||
echo "📦 Including app manifests..."
|
||||
cp -r "$SCRIPT_DIR/../apps" "$ARCHIPELAGO_DIR/apps" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Copy setup scripts
|
||||
if [ -d "$SCRIPT_DIR/archipelago-scripts" ]; then
|
||||
echo "📜 Including setup scripts..."
|
||||
cp "$SCRIPT_DIR/archipelago-scripts/"*.sh "$ARCHIPELAGO_DIR/scripts/" 2>/dev/null || true
|
||||
chmod +x "$ARCHIPELAGO_DIR/scripts/"*.sh
|
||||
fi
|
||||
|
||||
# Create main setup script for Archipelago
|
||||
cat > "$ARCHIPELAGO_DIR/setup-archipelago.sh" <<'SETUP_EOF'
|
||||
#!/bin/bash
|
||||
#
|
||||
# Archipelago Setup Script for Debian Live
|
||||
#
|
||||
echo ""
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ 🏝️ ARCHIPELAGO BITCOIN NODE OS - Debian Edition ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Find the boot media
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom /media/cdrom; do
|
||||
if [ -d "$dev/archipelago" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$BOOT_MEDIA" ]; then
|
||||
echo "❌ Could not find Archipelago files on boot media"
|
||||
echo " Looking in: /run/live/medium, /lib/live/mount/medium, /cdrom"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📍 Found Archipelago at: $BOOT_MEDIA/archipelago"
|
||||
echo ""
|
||||
|
||||
# Copy files to system
|
||||
if [ -d "$BOOT_MEDIA/archipelago/bin" ]; then
|
||||
echo "📋 Installing Archipelago binaries..."
|
||||
sudo cp -r "$BOOT_MEDIA/archipelago/bin/"* /usr/local/bin/ 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -d "$BOOT_MEDIA/archipelago/apps" ]; then
|
||||
echo "📋 Installing app manifests..."
|
||||
sudo mkdir -p /etc/archipelago
|
||||
sudo cp -r "$BOOT_MEDIA/archipelago/apps" /etc/archipelago/ 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -d "$BOOT_MEDIA/archipelago/scripts" ]; then
|
||||
echo "📋 Installing setup scripts..."
|
||||
sudo mkdir -p /opt/archipelago
|
||||
sudo cp -r "$BOOT_MEDIA/archipelago/scripts" /opt/archipelago/ 2>/dev/null || true
|
||||
sudo chmod +x /opt/archipelago/scripts/*.sh
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Archipelago installed!"
|
||||
echo ""
|
||||
|
||||
# Automatically launch the menu
|
||||
sleep 1
|
||||
exec /opt/archipelago/scripts/archipelago-menu.sh
|
||||
SETUP_EOF
|
||||
|
||||
chmod +x "$ARCHIPELAGO_DIR/setup-archipelago.sh"
|
||||
|
||||
# Create auto-start script that runs on login
|
||||
cat > "$ARCHIPELAGO_DIR/auto-start.sh" <<'AUTOSTART_EOF'
|
||||
#!/bin/bash
|
||||
#
|
||||
# Archipelago Auto-Start - Runs on first login
|
||||
#
|
||||
|
||||
# Find boot media
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
||||
if [ -d "$dev/archipelago" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Install essential tools on first boot (required for disk installer)
|
||||
if [ ! -f /tmp/.archipelago-tools-installed ]; then
|
||||
clear
|
||||
echo ""
|
||||
echo " ╔═══════════════════════════════════════════════════════════╗"
|
||||
echo " ║ 🏝️ ARCHIPELAGO - First Boot Setup ║"
|
||||
echo " ╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " 📦 Installing required tools..."
|
||||
echo ""
|
||||
|
||||
# Update and install essential tools
|
||||
sudo apt-get update -qq 2>/dev/null
|
||||
sudo apt-get install -y parted debootstrap dosfstools e2fsprogs 2>/dev/null
|
||||
|
||||
echo " ✅ Tools installed"
|
||||
touch /tmp/.archipelago-tools-installed
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
# Get IP address
|
||||
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
|
||||
# Start web UI in background if not already running
|
||||
if [ -n "$BOOT_MEDIA" ] && ! pgrep -f "http.server" >/dev/null; then
|
||||
WEB_UI_DIR="$BOOT_MEDIA/archipelago/web-ui"
|
||||
if [ -d "$WEB_UI_DIR" ]; then
|
||||
cd "$WEB_UI_DIR"
|
||||
nohup python3 -m http.server 80 --bind 0.0.0.0 >/dev/null 2>&1 &
|
||||
fi
|
||||
fi
|
||||
|
||||
clear
|
||||
echo ""
|
||||
echo " ╔═══════════════════════════════════════════════════════════╗"
|
||||
echo " ║ ║"
|
||||
echo " ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║"
|
||||
echo " ║ ║"
|
||||
echo " ║ Your sovereign Bitcoin infrastructure ║"
|
||||
echo " ║ ║"
|
||||
echo " ╚═══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
if [ -n "$IP" ]; then
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 🌐 Web UI: http://$IP "
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
fi
|
||||
echo " Type 'archipelago' to open the setup menu"
|
||||
echo ""
|
||||
|
||||
# Check if already set up
|
||||
if [ -f ~/.archipelago-setup-done ]; then
|
||||
return 2>/dev/null || exit 0
|
||||
fi
|
||||
|
||||
# First time - run setup automatically
|
||||
if [ -n "$BOOT_MEDIA" ] && [ -f "$BOOT_MEDIA/archipelago/setup-archipelago.sh" ]; then
|
||||
echo ""
|
||||
read -p " Press Enter to continue to setup menu..."
|
||||
bash "$BOOT_MEDIA/archipelago/setup-archipelago.sh"
|
||||
fi
|
||||
AUTOSTART_EOF
|
||||
|
||||
chmod +x "$ARCHIPELAGO_DIR/auto-start.sh"
|
||||
|
||||
# Create a simple 'archipelago-menu' command wrapper (don't overwrite the backend binary!)
|
||||
cat > "$ARCHIPELAGO_DIR/bin/archipelago-menu" <<'CMD_EOF'
|
||||
#!/bin/bash
|
||||
# Archipelago menu command - launches the setup menu
|
||||
|
||||
if [ -f /opt/archipelago/scripts/archipelago-menu.sh ]; then
|
||||
exec /opt/archipelago/scripts/archipelago-menu.sh
|
||||
else
|
||||
# Find on boot media
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
||||
if [ -f "$dev/archipelago/scripts/archipelago-menu.sh" ]; then
|
||||
exec bash "$dev/archipelago/scripts/archipelago-menu.sh"
|
||||
fi
|
||||
done
|
||||
echo "Archipelago menu not found. Run setup first:"
|
||||
echo " sh /run/live/medium/archipelago/setup-archipelago.sh"
|
||||
fi
|
||||
CMD_EOF
|
||||
|
||||
chmod +x "$ARCHIPELAGO_DIR/bin/archipelago-menu"
|
||||
|
||||
# Verify the real backend binary is there
|
||||
if [ -f "$ARCHIPELAGO_DIR/bin/archipelago" ]; then
|
||||
echo " Backend binary: $(file "$ARCHIPELAGO_DIR/bin/archipelago" | grep -o 'ELF.*' || echo 'included')"
|
||||
fi
|
||||
|
||||
# Create SSH auto-start script for live environment
|
||||
mkdir -p "$ISO_CUSTOM/etc/live/config.conf.d"
|
||||
cat > "$ISO_CUSTOM/etc/live/config.conf.d/archipelago.conf" <<'LIVE_CONF_EOF'
|
||||
# Archipelago live config
|
||||
LIVE_HOSTNAME="archipelago"
|
||||
LIVE_USER_DEFAULT_GROUPS="audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth sudo"
|
||||
LIVE_CONF_EOF
|
||||
|
||||
# Create rc.local to start SSH on boot (works in live environment)
|
||||
mkdir -p "$ISO_CUSTOM/etc/rc.local.d"
|
||||
cat > "$ISO_CUSTOM/etc/rc.local.d/archipelago-ssh.sh" <<'RCLOCAL_EOF'
|
||||
#!/bin/bash
|
||||
# Enable SSH in live environment
|
||||
|
||||
# Install and start SSH if not running
|
||||
if ! systemctl is-active --quiet ssh 2>/dev/null; then
|
||||
# Try to start SSH (may already be installed)
|
||||
systemctl start ssh 2>/dev/null || true
|
||||
|
||||
# If SSH not installed, install it
|
||||
if ! command -v sshd >/dev/null 2>&1; then
|
||||
apt-get update -qq
|
||||
apt-get install -y openssh-server
|
||||
systemctl start ssh
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set password for user (live user is typically 'user' with empty password)
|
||||
echo "user:archipelago" | chpasswd 2>/dev/null || true
|
||||
echo "root:archipelago" | chpasswd 2>/dev/null || true
|
||||
|
||||
# Allow password auth
|
||||
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config 2>/dev/null
|
||||
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config 2>/dev/null
|
||||
systemctl restart ssh 2>/dev/null || true
|
||||
RCLOCAL_EOF
|
||||
chmod +x "$ISO_CUSTOM/etc/rc.local.d/archipelago-ssh.sh"
|
||||
|
||||
# Also create a systemd service that runs early
|
||||
mkdir -p "$ISO_CUSTOM/etc/systemd/system"
|
||||
cat > "$ISO_CUSTOM/etc/systemd/system/archipelago-ssh.service" <<'SERVICE_EOF'
|
||||
[Unit]
|
||||
Description=Archipelago SSH Setup
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c 'apt-get update -qq && apt-get install -y openssh-server && echo "user:archipelago" | chpasswd && echo "root:archipelago" | chpasswd && sed -i "s/#PasswordAuthentication.*/PasswordAuthentication yes/" /etc/ssh/sshd_config && sed -i "s/PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config && systemctl restart ssh'
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE_EOF
|
||||
|
||||
# Enable the service
|
||||
mkdir -p "$ISO_CUSTOM/etc/systemd/system/multi-user.target.wants"
|
||||
ln -sf ../archipelago-ssh.service "$ISO_CUSTOM/etc/systemd/system/multi-user.target.wants/archipelago-ssh.service"
|
||||
|
||||
# Create system-wide profile script that runs on ANY login
|
||||
mkdir -p "$ISO_CUSTOM/etc/profile.d"
|
||||
cat > "$ISO_CUSTOM/etc/profile.d/archipelago.sh" <<'PROFILE_EOF'
|
||||
#!/bin/bash
|
||||
# Archipelago auto-start - runs on login
|
||||
|
||||
# Only run once per session and only in interactive shells
|
||||
if [ -n "$ARCHIPELAGO_STARTED" ] || [ ! -t 0 ]; then
|
||||
return 0 2>/dev/null || exit 0
|
||||
fi
|
||||
export ARCHIPELAGO_STARTED=1
|
||||
|
||||
# Find archipelago directory
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
||||
if [ -d "$dev/archipelago" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$BOOT_MEDIA" ]; then
|
||||
return 0 2>/dev/null || exit 0
|
||||
fi
|
||||
|
||||
# Install archipelago command if not present
|
||||
if [ ! -f /usr/local/bin/archipelago ] && [ -f "$BOOT_MEDIA/archipelago/bin/archipelago" ]; then
|
||||
sudo cp "$BOOT_MEDIA/archipelago/bin/archipelago" /usr/local/bin/ 2>/dev/null
|
||||
sudo chmod +x /usr/local/bin/archipelago 2>/dev/null
|
||||
fi
|
||||
|
||||
# Run auto-start
|
||||
if [ -f "$BOOT_MEDIA/archipelago/auto-start.sh" ]; then
|
||||
source "$BOOT_MEDIA/archipelago/auto-start.sh"
|
||||
fi
|
||||
PROFILE_EOF
|
||||
|
||||
chmod +x "$ISO_CUSTOM/etc/profile.d/archipelago.sh"
|
||||
|
||||
# Modify GRUB config for Archipelago branding
|
||||
echo ""
|
||||
echo "⚙️ Configuring boot..."
|
||||
|
||||
if [ -f "$ISO_CUSTOM/boot/grub/grub.cfg" ]; then
|
||||
sed -i.bak \
|
||||
-e 's/Debian GNU\/Linux/Archipelago Bitcoin Node OS/g' \
|
||||
-e 's/Live system/Archipelago Live/g' \
|
||||
"$ISO_CUSTOM/boot/grub/grub.cfg"
|
||||
fi
|
||||
|
||||
if [ -f "$ISO_CUSTOM/isolinux/menu.cfg" ]; then
|
||||
sed -i.bak \
|
||||
-e 's/Debian GNU\/Linux/Archipelago Bitcoin Node OS/g' \
|
||||
-e 's/Live system/Archipelago Live/g' \
|
||||
"$ISO_CUSTOM/isolinux/menu.cfg"
|
||||
fi
|
||||
|
||||
if [ -f "$ISO_CUSTOM/isolinux/live.cfg" ]; then
|
||||
sed -i.bak \
|
||||
-e 's/Live system/Archipelago Live/g' \
|
||||
"$ISO_CUSTOM/isolinux/live.cfg"
|
||||
fi
|
||||
|
||||
# Create final ISO
|
||||
OUTPUT_ISO="$OUTPUT_DIR/archipelago-debian-12-x86_64.iso"
|
||||
echo ""
|
||||
echo "🔥 Creating final bootable ISO..."
|
||||
|
||||
if command -v xorriso >/dev/null 2>&1; then
|
||||
# Create proper hybrid ISO with MBR for USB boot
|
||||
# Need to extract MBR from isolinux or use system syslinux
|
||||
|
||||
# Check for isohdpfx.bin in various locations
|
||||
ISOHDPFX=""
|
||||
for path in \
|
||||
"/usr/local/share/syslinux/isohdpfx.bin" \
|
||||
"/usr/share/syslinux/isohdpfx.bin" \
|
||||
"/opt/homebrew/share/syslinux/isohdpfx.bin" \
|
||||
"$ISO_CUSTOM/isolinux/isohdpfx.bin"; do
|
||||
if [ -f "$path" ]; then
|
||||
ISOHDPFX="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$ISOHDPFX" ]; then
|
||||
echo "⚠️ No isohdpfx.bin found, extracting from isolinux.bin..."
|
||||
# Extract first 432 bytes from isolinux.bin as MBR
|
||||
dd if="$ISO_CUSTOM/isolinux/isolinux.bin" of="$WORK_DIR/isohdpfx.bin" bs=432 count=1 2>/dev/null
|
||||
ISOHDPFX="$WORK_DIR/isohdpfx.bin"
|
||||
fi
|
||||
|
||||
echo " Using MBR: $ISOHDPFX"
|
||||
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-J -R \
|
||||
-isohybrid-mbr "$ISOHDPFX" \
|
||||
-c isolinux/boot.cat \
|
||||
-b isolinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
"$ISO_CUSTOM"
|
||||
else
|
||||
echo "❌ xorriso not found. Please install it: brew install xorriso"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ ISO created successfully!"
|
||||
echo ""
|
||||
echo "📀 Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo "🔥 This is Debian Live-based - reliable USB boot like StartOS!"
|
||||
echo ""
|
||||
echo "To create USB:"
|
||||
echo " 1. Use Balena Etcher to flash the ISO"
|
||||
echo " 2. Or: sudo dd if=$OUTPUT_ISO of=/dev/sdX bs=4M status=progress"
|
||||
echo ""
|
||||
@@ -1,368 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Build Archipelago OS for specific hardware target
|
||||
# Supports: start9-pure, hp-prodesk, dell-optiplex, generic
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Hardware target (default: generic)
|
||||
HARDWARE_TARGET="${1:-generic}"
|
||||
BUILD_TYPE="${2:-iso}"
|
||||
|
||||
ARCHIPELAGO_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
ARCH="x86_64" # All supported hardware is x86_64
|
||||
|
||||
# Color output
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}🏗️ Archipelago OS Builder${NC}"
|
||||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
|
||||
# Validate hardware target
|
||||
case "$HARDWARE_TARGET" in
|
||||
start9-pure|start9)
|
||||
HARDWARE_NAME="Start9 Server Pure"
|
||||
HARDWARE_PROFILE="start9-pure"
|
||||
CPU_VENDOR="intel"
|
||||
CPU_MODEL="i7-10710U"
|
||||
RAM_MIN="32GB"
|
||||
STORAGE_MIN="2TB"
|
||||
NETWORK_INTERFACES="1x Gigabit Ethernet"
|
||||
USB_PORTS="4x USB 3.0, 2x USB 2.0, 1x USB-C 3.1"
|
||||
OPTIMIZATIONS="intel-graphics intel-networking nvme-ssd"
|
||||
;;
|
||||
hp-prodesk|prodesk)
|
||||
HARDWARE_NAME="HP ProDesk 400 G4 DM"
|
||||
HARDWARE_PROFILE="hp-prodesk"
|
||||
CPU_VENDOR="intel"
|
||||
CPU_MODEL="varies"
|
||||
RAM_MIN="8GB"
|
||||
STORAGE_MIN="128GB"
|
||||
NETWORK_INTERFACES="1x Gigabit Ethernet"
|
||||
USB_PORTS="4x USB 3.0, 2x USB 2.0"
|
||||
OPTIMIZATIONS="intel-graphics intel-networking sata-ssd"
|
||||
;;
|
||||
dell-optiplex|optiplex)
|
||||
HARDWARE_NAME="Dell OptiPlex"
|
||||
HARDWARE_PROFILE="dell-optiplex"
|
||||
CPU_VENDOR="intel"
|
||||
CPU_MODEL="varies"
|
||||
RAM_MIN="8GB"
|
||||
STORAGE_MIN="128GB"
|
||||
NETWORK_INTERFACES="1x Gigabit Ethernet"
|
||||
USB_PORTS="Multiple USB ports"
|
||||
OPTIMIZATIONS="intel-graphics intel-networking sata-ssd"
|
||||
;;
|
||||
generic)
|
||||
HARDWARE_NAME="Generic x86_64"
|
||||
HARDWARE_PROFILE="generic"
|
||||
CPU_VENDOR="any"
|
||||
CPU_MODEL="any"
|
||||
RAM_MIN="8GB"
|
||||
STORAGE_MIN="128GB"
|
||||
NETWORK_INTERFACES="any"
|
||||
USB_PORTS="any"
|
||||
OPTIMIZATIONS="generic"
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}❌ Unknown hardware target: $HARDWARE_TARGET${NC}"
|
||||
echo ""
|
||||
echo "Supported targets:"
|
||||
echo " start9-pure - Start9 Server Pure (Intel i7-10710U)"
|
||||
echo " hp-prodesk - HP ProDesk 400 G4 DM"
|
||||
echo " dell-optiplex - Dell OptiPlex"
|
||||
echo " generic - Generic x86_64 hardware"
|
||||
echo ""
|
||||
echo "Usage: $0 <hardware-target> [iso|disk]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e "${GREEN}📋 Build Configuration${NC}"
|
||||
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo -e " Hardware: ${YELLOW}${HARDWARE_NAME}${NC}"
|
||||
echo -e " Profile: ${HARDWARE_PROFILE}"
|
||||
echo -e " CPU: ${CPU_VENDOR} ${CPU_MODEL}"
|
||||
echo -e " Min RAM: ${RAM_MIN}"
|
||||
echo -e " Min Storage: ${STORAGE_MIN}"
|
||||
echo -e " Network: ${NETWORK_INTERFACES}"
|
||||
echo -e " Build Type: ${BUILD_TYPE}"
|
||||
echo -e " Architecture: ${ARCH}"
|
||||
echo -e " Version: ${ARCHIPELAGO_VERSION}"
|
||||
echo -e " Alpine: ${ALPINE_VERSION}"
|
||||
echo ""
|
||||
|
||||
# Create hardware-specific overlay
|
||||
HARDWARE_OVERLAY_DIR="$SCRIPT_DIR/alpine-profile/overlay-${HARDWARE_PROFILE}"
|
||||
mkdir -p "$HARDWARE_OVERLAY_DIR/etc/archipelago"
|
||||
|
||||
# Create hardware detection script
|
||||
cat > "$HARDWARE_OVERLAY_DIR/etc/archipelago/hardware-info.sh" <<'EOF'
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
EOF
|
||||
|
||||
chmod +x "$HARDWARE_OVERLAY_DIR/etc/archipelago/hardware-info.sh"
|
||||
|
||||
# Create hardware-specific config
|
||||
cat > "$HARDWARE_OVERLAY_DIR/etc/archipelago/hardware.toml" <<EOF
|
||||
# Hardware profile for ${HARDWARE_NAME}
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "${HARDWARE_PROFILE}"
|
||||
name = "${HARDWARE_NAME}"
|
||||
cpu_vendor = "${CPU_VENDOR}"
|
||||
cpu_model = "${CPU_MODEL}"
|
||||
min_ram = "${RAM_MIN}"
|
||||
min_storage = "${STORAGE_MIN}"
|
||||
architecture = "${ARCH}"
|
||||
|
||||
[optimizations]
|
||||
enabled = ${OPTIMIZATIONS}
|
||||
|
||||
[network]
|
||||
interfaces = "${NETWORK_INTERFACES}"
|
||||
|
||||
[usb]
|
||||
ports = "${USB_PORTS}"
|
||||
|
||||
[build]
|
||||
version = "${ARCHIPELAGO_VERSION}"
|
||||
alpine_version = "${ALPINE_VERSION}"
|
||||
build_date = "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
build_type = "${BUILD_TYPE}"
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}✓${NC} Hardware profile created: ${HARDWARE_PROFILE}"
|
||||
echo ""
|
||||
|
||||
# Create first-boot hardware detection service
|
||||
mkdir -p "$HARDWARE_OVERLAY_DIR/etc/local.d"
|
||||
cat > "$HARDWARE_OVERLAY_DIR/etc/local.d/00-hardware-detect.start" <<'EOF'
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
EOF
|
||||
|
||||
chmod +x "$HARDWARE_OVERLAY_DIR/etc/local.d/00-hardware-detect.start"
|
||||
|
||||
# Merge with base overlay
|
||||
echo -e "${BLUE}📦 Merging overlays...${NC}"
|
||||
MERGED_OVERLAY="$SCRIPT_DIR/alpine-profile/overlay-merged"
|
||||
rm -rf "$MERGED_OVERLAY"
|
||||
mkdir -p "$MERGED_OVERLAY"
|
||||
|
||||
# Copy base overlay
|
||||
if [ -d "$SCRIPT_DIR/alpine-profile/overlay" ]; then
|
||||
cp -a "$SCRIPT_DIR/alpine-profile/overlay/"* "$MERGED_OVERLAY/"
|
||||
fi
|
||||
|
||||
# Copy hardware-specific overlay (overwrites base)
|
||||
if [ -d "$HARDWARE_OVERLAY_DIR" ]; then
|
||||
cp -a "$HARDWARE_OVERLAY_DIR/"* "$MERGED_OVERLAY/"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓${NC} Overlays merged"
|
||||
echo ""
|
||||
|
||||
# Set environment variables for build
|
||||
export HARDWARE_TARGET="$HARDWARE_PROFILE"
|
||||
export HARDWARE_NAME="$HARDWARE_NAME"
|
||||
export ARCHIPELAGO_VERSION
|
||||
export ALPINE_VERSION
|
||||
export ARCH
|
||||
export BUILD_TYPE
|
||||
|
||||
# Determine build method - use custom ISO builder
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building custom ISO from Alpine base...${NC}"
|
||||
"$SCRIPT_DIR/build-custom-iso.sh" || {
|
||||
echo ""
|
||||
echo -e "${RED}❌ ISO build failed${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Rename output with hardware target
|
||||
OUTPUT_DIR="$SCRIPT_DIR/results"
|
||||
if [ -f "$OUTPUT_DIR/archipelago-${ALPINE_VERSION}-${ARCH}.iso" ]; then
|
||||
mv "$OUTPUT_DIR/archipelago-${ALPINE_VERSION}-${ARCH}.iso" \
|
||||
"$OUTPUT_DIR/archipelago-${ALPINE_VERSION}-${HARDWARE_PROFILE}-${ARCH}.iso"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN}✅ Build Complete!${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}Hardware:${NC} ${HARDWARE_NAME}"
|
||||
echo -e " ${YELLOW}ISO File:${NC} archipelago-${ALPINE_VERSION}-${HARDWARE_PROFILE}-${ARCH}.iso"
|
||||
echo -e " ${YELLOW}Location:${NC} ${OUTPUT_DIR}/"
|
||||
echo ""
|
||||
echo -e "${BLUE}Next Steps:${NC}"
|
||||
echo -e " 1. Flash ISO to USB drive:"
|
||||
echo -e " ${YELLOW}sudo dd if=${OUTPUT_DIR}/archipelago-${ALPINE_VERSION}-${HARDWARE_PROFILE}-${ARCH}.iso of=/dev/sdX bs=1M${NC}"
|
||||
echo ""
|
||||
echo -e " 2. Boot ${HARDWARE_NAME} from USB"
|
||||
echo ""
|
||||
echo -e " 3. Access Archipelago UI at: ${YELLOW}http://device-ip:8100${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Create build manifest
|
||||
cat > "$OUTPUT_DIR/BUILD_MANIFEST_${HARDWARE_PROFILE}.txt" <<MANIFEST
|
||||
Archipelago OS Build Manifest
|
||||
═════════════════════════════
|
||||
|
||||
Build Information
|
||||
─────────────────
|
||||
Version: ${ARCHIPELAGO_VERSION}
|
||||
Alpine Version: ${ALPINE_VERSION}
|
||||
Architecture: ${ARCH}
|
||||
Build Type: ${BUILD_TYPE}
|
||||
Build Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
Build Host: $(hostname)
|
||||
|
||||
Hardware Target
|
||||
───────────────
|
||||
Profile: ${HARDWARE_PROFILE}
|
||||
Name: ${HARDWARE_NAME}
|
||||
CPU: ${CPU_VENDOR} ${CPU_MODEL}
|
||||
Minimum RAM: ${RAM_MIN}
|
||||
Minimum Storage: ${STORAGE_MIN}
|
||||
Network: ${NETWORK_INTERFACES}
|
||||
USB Ports: ${USB_PORTS}
|
||||
|
||||
Optimizations
|
||||
─────────────
|
||||
${OPTIMIZATIONS}
|
||||
|
||||
Files Generated
|
||||
───────────────
|
||||
ISO: archipelago-${ARCHIPELAGO_VERSION}-${HARDWARE_PROFILE}-${ARCH}.iso
|
||||
$([ -f "$OUTPUT_DIR/archipelago-${ARCHIPELAGO_VERSION}-${HARDWARE_PROFILE}-${ARCH}.img" ] && echo "IMG: archipelago-${ARCHIPELAGO_VERSION}-${HARDWARE_PROFILE}-${ARCH}.img")
|
||||
|
||||
Installation
|
||||
────────────
|
||||
1. Flash to USB:
|
||||
sudo dd if=archipelago-${ARCHIPELAGO_VERSION}-${HARDWARE_PROFILE}-${ARCH}.iso of=/dev/sdX bs=1M
|
||||
|
||||
2. Boot ${HARDWARE_NAME} from USB
|
||||
|
||||
3. Follow on-screen installation
|
||||
|
||||
4. Access UI at http://device-ip:8100
|
||||
|
||||
Hardware Requirements
|
||||
────────────────────
|
||||
- CPU: ${CPU_VENDOR} ${CPU_MODEL}
|
||||
- RAM: ${RAM_MIN} minimum
|
||||
- Storage: ${STORAGE_MIN} minimum
|
||||
- Network: ${NETWORK_INTERFACES}
|
||||
- Boot: UEFI (Legacy BIOS supported)
|
||||
|
||||
Support
|
||||
───────
|
||||
- Documentation: docs/
|
||||
- Issues: GitHub Issues
|
||||
- Community: Discord (coming soon)
|
||||
|
||||
Built with ❤️ by the Archipelago team
|
||||
MANIFEST
|
||||
|
||||
echo -e "${GREEN}✓${NC} Build manifest created"
|
||||
echo ""
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Linux native build script
|
||||
# Builds Alpine image using native tools or Docker
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
BUILD_TYPE="${1:-iso}"
|
||||
|
||||
ARCHIPELAGO_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
ARCH="${ARCH:-x86_64}"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-$SCRIPT_DIR/results}"
|
||||
|
||||
echo "🐧 Building on Linux"
|
||||
echo ""
|
||||
|
||||
# Check if we're in Alpine or need Docker
|
||||
if [ -f /etc/alpine-release ]; then
|
||||
echo "✅ Running on Alpine Linux - using native tools"
|
||||
USE_DOCKER=false
|
||||
elif command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||
echo "⚠️ Not on Alpine - using Docker"
|
||||
USE_DOCKER=true
|
||||
else
|
||||
echo "❌ Need Alpine Linux or Docker"
|
||||
echo " Install Alpine: https://alpinelinux.org/downloads/"
|
||||
echo " Or install Docker: https://docs.docker.com/get-docker/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$USE_DOCKER" = true ]; then
|
||||
# Use Docker for build
|
||||
echo "🐳 Using Docker container for build..."
|
||||
echo " This may take 30-60 minutes on first build..."
|
||||
echo ""
|
||||
|
||||
docker run --rm -it \
|
||||
-v "$PROJECT_ROOT:/workspace" \
|
||||
-v "$OUTPUT_DIR:/results" \
|
||||
-v "$SCRIPT_DIR/build:/build" \
|
||||
-v "$SCRIPT_DIR/apks:/apks" \
|
||||
-e BUILD_TYPE="$BUILD_TYPE" \
|
||||
-e ARCHIPELAGO_VERSION="$ARCHIPELAGO_VERSION" \
|
||||
-e ALPINE_VERSION="$ALPINE_VERSION" \
|
||||
-e ARCH="$ARCH" \
|
||||
alpine:${ALPINE_VERSION} \
|
||||
sh -c "
|
||||
apk add --no-cache bash git alpine-sdk abuild alpine-conf syslinux xorriso squashfs-tools grub grub-efi mtools dosfstools e2fsprogs curl rust cargo nodejs npm
|
||||
cd /workspace/image-recipe
|
||||
./build-alpine-native.sh $BUILD_TYPE
|
||||
"
|
||||
else
|
||||
# Native Alpine build
|
||||
"$SCRIPT_DIR/build-alpine-native.sh" "$BUILD_TYPE"
|
||||
fi
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/bin/bash
|
||||
# macOS build wrapper using Docker
|
||||
# Builds Alpine image in Docker container
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
BUILD_TYPE="${1:-iso}"
|
||||
|
||||
echo "🍎 Building on macOS via Docker"
|
||||
echo ""
|
||||
|
||||
# Check for Docker
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "❌ Docker not found. Install Docker Desktop: https://www.docker.com/products/docker-desktop"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
echo "❌ Docker daemon not running. Start Docker Desktop."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build Docker image if needed
|
||||
echo "🔨 Building Docker build image..."
|
||||
docker build -f "$SCRIPT_DIR/Dockerfile.build" -t archipelago-builder:latest "$SCRIPT_DIR" || {
|
||||
echo "❌ Docker image build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Run build in container
|
||||
echo "🚀 Running build in container..."
|
||||
echo " This may take 30-60 minutes on first build..."
|
||||
echo ""
|
||||
|
||||
# Check if running in TTY
|
||||
if [ -t 0 ]; then
|
||||
DOCKER_FLAGS="-it"
|
||||
else
|
||||
DOCKER_FLAGS="-t"
|
||||
fi
|
||||
|
||||
docker run --rm $DOCKER_FLAGS \
|
||||
-v "$PROJECT_ROOT:/workspace" \
|
||||
-v "$SCRIPT_DIR/results:/results" \
|
||||
-v "$SCRIPT_DIR/build:/build" \
|
||||
-v "$SCRIPT_DIR/apks:/apks" \
|
||||
-e BUILD_TYPE="$BUILD_TYPE" \
|
||||
-e ARCHIPELAGO_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}" \
|
||||
-e ALPINE_VERSION="${ALPINE_VERSION:-3.19}" \
|
||||
-e ARCH="${ARCH:-x86_64}" \
|
||||
archipelago-builder:latest \
|
||||
sh -c "cd /workspace/image-recipe && ./build-linux.sh $BUILD_TYPE"
|
||||
|
||||
echo ""
|
||||
echo "✅ Build complete! Check results/ directory"
|
||||
@@ -1,356 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Build proper Alpine ISO with Archipelago overlay (apkovl method)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ALPINE_VERSION="${ALPINE_VERSION:-3.19}"
|
||||
ARCH="${ARCH:-x86_64}"
|
||||
WORK_DIR="$SCRIPT_DIR/build/overlay-iso"
|
||||
OUTPUT_DIR="$SCRIPT_DIR/results"
|
||||
|
||||
echo "🏔️ Building Archipelago ISO using Alpine overlay method"
|
||||
echo ""
|
||||
echo "📋 Configuration:"
|
||||
echo " Alpine Version: $ALPINE_VERSION"
|
||||
echo " Architecture: $ARCH"
|
||||
echo ""
|
||||
|
||||
# Create work directories
|
||||
mkdir -p "$WORK_DIR"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Download base Alpine ISO if not exists
|
||||
BASE_ISO="$WORK_DIR/alpine-standard-${ALPINE_VERSION}.0-${ARCH}.iso"
|
||||
if [ ! -f "$BASE_ISO" ]; then
|
||||
echo "📥 Downloading Alpine base ISO..."
|
||||
curl -L -o "$BASE_ISO" \
|
||||
"https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/releases/${ARCH}/alpine-standard-${ALPINE_VERSION}.0-${ARCH}.iso"
|
||||
echo "✅ Downloaded base ISO"
|
||||
else
|
||||
echo "✅ Using cached base ISO"
|
||||
fi
|
||||
|
||||
# Create overlay structure
|
||||
echo "📦 Creating Archipelago overlay..."
|
||||
OVERLAY_DIR="$WORK_DIR/overlay"
|
||||
rm -rf "$OVERLAY_DIR"
|
||||
mkdir -p "$OVERLAY_DIR"
|
||||
|
||||
# Create overlay root
|
||||
OVERLAY_ROOT="$OVERLAY_DIR/archipelago-overlay"
|
||||
mkdir -p "$OVERLAY_ROOT"/{etc,root,usr/local/bin,var/lib/archipelago,home/archipelago}
|
||||
|
||||
# Copy Archipelago backend if available
|
||||
BACKEND_BIN="$SCRIPT_DIR/build/backend/archipelago"
|
||||
if [ -f "$BACKEND_BIN" ]; then
|
||||
echo "🦀 Including Archipelago backend..."
|
||||
cp "$BACKEND_BIN" "$OVERLAY_ROOT/usr/local/bin/"
|
||||
chmod +x "$OVERLAY_ROOT/usr/local/bin/archipelago"
|
||||
fi
|
||||
|
||||
# Copy Archipelago frontend if available
|
||||
FRONTEND_DIR="$SCRIPT_DIR/build/frontend"
|
||||
if [ -d "$FRONTEND_DIR" ]; then
|
||||
echo "🎨 Including Archipelago frontend..."
|
||||
mkdir -p "$OVERLAY_ROOT/usr/share/archipelago/web"
|
||||
cp -r "$FRONTEND_DIR"/* "$OVERLAY_ROOT/usr/share/archipelago/web/"
|
||||
fi
|
||||
|
||||
# Copy app manifests
|
||||
APPS_DIR="$SCRIPT_DIR/../apps"
|
||||
if [ -d "$APPS_DIR" ]; then
|
||||
echo "📦 Including app manifests..."
|
||||
mkdir -p "$OVERLAY_ROOT/var/lib/archipelago/manifests"
|
||||
find "$APPS_DIR" -maxdepth 1 -type d -exec test -f {}/manifest.yml \; \
|
||||
-exec cp -r {} "$OVERLAY_ROOT/var/lib/archipelago/manifests/" \;
|
||||
fi
|
||||
|
||||
# Create installation script in overlay
|
||||
cat > "$OVERLAY_ROOT/root/install-archipelago.sh" <<'INSTALL_SCRIPT'
|
||||
#!/bin/sh
|
||||
# Archipelago installation script
|
||||
|
||||
set -e
|
||||
|
||||
echo "🏝️ Installing Archipelago Bitcoin Node OS"
|
||||
echo ""
|
||||
|
||||
# Install required packages
|
||||
echo "📦 Installing packages..."
|
||||
apk add --no-cache \
|
||||
podman \
|
||||
crun \
|
||||
fuse-overlayfs \
|
||||
slirp4netns \
|
||||
nginx \
|
||||
openssh \
|
||||
iptables \
|
||||
iproute2 \
|
||||
bash \
|
||||
curl
|
||||
|
||||
# Create archipelago user
|
||||
echo "👤 Creating archipelago user..."
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
adduser -D -s /bin/bash archipelago
|
||||
echo "archipelago:archipelago" | chpasswd
|
||||
fi
|
||||
|
||||
# Setup data directories
|
||||
echo "📁 Creating data directories..."
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago
|
||||
|
||||
# Install backend if available
|
||||
if [ -f /usr/local/bin/archipelago ]; then
|
||||
echo "✅ Archipelago backend installed"
|
||||
fi
|
||||
|
||||
# Configure nginx for frontend
|
||||
if [ -d /usr/share/archipelago/web ]; then
|
||||
echo "🎨 Configuring web UI..."
|
||||
cat > /etc/nginx/http.d/archipelago.conf <<'NGINX_EOF'
|
||||
server {
|
||||
listen 8100;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/archipelago/web;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8101/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
}
|
||||
NGINX_EOF
|
||||
|
||||
rc-update add nginx default
|
||||
fi
|
||||
|
||||
# Create Archipelago service
|
||||
if [ -f /usr/local/bin/archipelago ]; then
|
||||
cat > /etc/init.d/archipelago <<'SERVICE_EOF'
|
||||
#!/sbin/openrc-run
|
||||
|
||||
name="Archipelago"
|
||||
description="Archipelago Bitcoin Node OS Backend"
|
||||
command="/usr/local/bin/archipelago"
|
||||
command_background=true
|
||||
pidfile="/run/archipelago.pid"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
after networking
|
||||
}
|
||||
SERVICE_EOF
|
||||
|
||||
chmod +x /etc/init.d/archipelago
|
||||
rc-update add archipelago default
|
||||
fi
|
||||
|
||||
# Configure networking
|
||||
echo "🌐 Configuring network..."
|
||||
setup-interfaces -a
|
||||
|
||||
# Enable services
|
||||
rc-update add sshd default
|
||||
|
||||
echo ""
|
||||
echo "✅ Archipelago installation complete!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Reboot the system"
|
||||
echo " 2. Login as: archipelago / archipelago"
|
||||
echo " 3. Change password: passwd"
|
||||
echo " 4. Access UI: http://<your-ip>:8100"
|
||||
echo ""
|
||||
|
||||
INSTALL_SCRIPT
|
||||
|
||||
chmod +x "$OVERLAY_ROOT/root/install-archipelago.sh"
|
||||
|
||||
# Create Alpine local.d boot script to show message
|
||||
mkdir -p "$OVERLAY_ROOT/etc/local.d"
|
||||
cat > "$OVERLAY_ROOT/etc/local.d/00-archipelago-welcome.start" <<'WELCOME_EOF'
|
||||
#!/bin/sh
|
||||
|
||||
cat <<'MSG'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║
|
||||
║ ║
|
||||
║ To install to disk, login as root and run: ║
|
||||
║ ║
|
||||
║ # setup-alpine ║
|
||||
║ # /root/install-archipelago.sh ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
MSG
|
||||
|
||||
WELCOME_EOF
|
||||
|
||||
chmod +x "$OVERLAY_ROOT/etc/local.d/00-archipelago-welcome.start"
|
||||
|
||||
# Create the overlay tarball (apkovl)
|
||||
echo "📦 Creating overlay tarball..."
|
||||
cd "$OVERLAY_DIR"
|
||||
tar czf archipelago.apkovl.tar.gz archipelago-overlay/
|
||||
echo "✅ Overlay created: $(du -h archipelago.apkovl.tar.gz | cut -f1)"
|
||||
|
||||
# Mount the base ISO and copy it with our overlay
|
||||
echo "📀 Creating final ISO with overlay..."
|
||||
ISO_MOUNT="$WORK_DIR/mnt"
|
||||
ISO_CUSTOM="$WORK_DIR/custom"
|
||||
|
||||
mkdir -p "$ISO_MOUNT" "$ISO_CUSTOM"
|
||||
|
||||
# Extract base ISO
|
||||
if command -v 7z >/dev/null 2>&1; then
|
||||
7z x "$BASE_ISO" -o"$ISO_CUSTOM" -y >/dev/null
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
hdiutil attach "$BASE_ISO" -mountpoint "$ISO_MOUNT" -readonly
|
||||
rsync -a "$ISO_MOUNT"/ "$ISO_CUSTOM"/
|
||||
hdiutil detach "$ISO_MOUNT"
|
||||
fi
|
||||
|
||||
# Copy Archipelago files directly to ISO (skip apkovl, put files in accessible location)
|
||||
echo "📋 Adding Archipelago files to ISO..."
|
||||
mkdir -p "$ISO_CUSTOM/archipelago"
|
||||
cp "$OVERLAY_DIR/archipelago.apkovl.tar.gz" "$ISO_CUSTOM/archipelago/"
|
||||
|
||||
# Also extract directly to archipelago folder for easy access
|
||||
cd "$OVERLAY_DIR"
|
||||
tar xzf archipelago.apkovl.tar.gz
|
||||
cp -r archipelago-overlay/* "$ISO_CUSTOM/archipelago/"
|
||||
|
||||
# CRITICAL: Add .boot_repository marker so Alpine's nlplug-findfs can find the boot media
|
||||
# This tells the initramfs that this is a valid Alpine boot repository
|
||||
echo "📍 Marking ISO as boot repository..."
|
||||
touch "$ISO_CUSTOM/.boot_repository"
|
||||
|
||||
# Also mark the apks directories at all levels
|
||||
if [ -d "$ISO_CUSTOM/apks" ]; then
|
||||
touch "$ISO_CUSTOM/apks/.boot_repository"
|
||||
fi
|
||||
if [ -d "$ISO_CUSTOM/apks/x86_64" ]; then
|
||||
touch "$ISO_CUSTOM/apks/x86_64/.boot_repository"
|
||||
fi
|
||||
|
||||
# Create a simple first-boot setup script
|
||||
cat > "$ISO_CUSTOM/archipelago/setup-archipelago.sh" <<'SETUP_EOF'
|
||||
#!/bin/sh
|
||||
# Archipelago first-boot setup
|
||||
|
||||
set -e
|
||||
|
||||
echo "🏝️ Setting up Archipelago overlay..."
|
||||
|
||||
# Copy files from CD to root
|
||||
if [ -d /media/cdrom/archipelago/archipelago-overlay ]; then
|
||||
cp -r /media/cdrom/archipelago/archipelago-overlay/* /
|
||||
echo "✅ Archipelago files installed"
|
||||
elif [ -d /media/cdrom/archipelago/root ]; then
|
||||
cp -r /media/cdrom/archipelago/* /
|
||||
echo "✅ Archipelago files installed"
|
||||
fi
|
||||
|
||||
# Run the installer if it exists
|
||||
if [ -f /root/install-archipelago.sh ]; then
|
||||
echo ""
|
||||
echo "Archipelago is now available!"
|
||||
echo "Run: /root/install-archipelago.sh"
|
||||
fi
|
||||
SETUP_EOF
|
||||
|
||||
chmod +x "$ISO_CUSTOM/archipelago/setup-archipelago.sh"
|
||||
|
||||
# Modify boot configs (remove apkovl parameter, use normal boot)
|
||||
echo "⚙️ Configuring boot..."
|
||||
|
||||
# Modify boot configs to add USB delay for better hardware compatibility
|
||||
# Keep Alpine's boot logic intact, just add timing parameters and better debugging
|
||||
# HP ProDesk likely boots UEFI (GRUB), so we need to modify both configs
|
||||
# CRITICAL: Add isofs module so Alpine can mount the ISO9660 filesystem on USB!
|
||||
# CRITICAL: Add pkgs parameter to explicitly install base system packages
|
||||
|
||||
if [ -f "$ISO_CUSTOM/boot/grub/grub.cfg" ]; then
|
||||
# UEFI boot (GRUB) - add isofs module for ISO9660 filesystem support
|
||||
sed -i.bak \
|
||||
-e 's/Alpine Linux/Archipelago Bitcoin Node OS/g' \
|
||||
-e 's/modules=loop,squashfs,sd-mod,usb-storage quiet/modules=loop,squashfs,sd-mod,usb-storage,isofs,iso9660 usbdelay=10/' \
|
||||
"$ISO_CUSTOM/boot/grub/grub.cfg"
|
||||
fi
|
||||
|
||||
if [ -f "$ISO_CUSTOM/boot/syslinux/syslinux.cfg" ]; then
|
||||
# Legacy BIOS boot (Syslinux) - add isofs module for ISO9660 filesystem support
|
||||
sed -i.bak \
|
||||
-e 's/Alpine Linux/Archipelago Bitcoin Node OS/g' \
|
||||
-e 's/quiet/usbdelay=10/' \
|
||||
-e 's/modules=loop,squashfs,sd-mod,usb-storage/modules=loop,squashfs,sd-mod,usb-storage,isofs,iso9660/' \
|
||||
"$ISO_CUSTOM/boot/syslinux/syslinux.cfg"
|
||||
fi
|
||||
|
||||
# Update MOTD to show Archipelago instructions
|
||||
cat > "$ISO_CUSTOM/.alpine-release" <<'MOTD_EOF'
|
||||
3.19.0
|
||||
MOTD_EOF
|
||||
|
||||
mkdir -p "$ISO_CUSTOM/etc"
|
||||
cat > "$ISO_CUSTOM/etc/motd" <<'MOTD_EOF'
|
||||
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║
|
||||
║ ║
|
||||
║ To set up Archipelago, run: ║
|
||||
║ # sh /media/cdrom/archipelago/setup-archipelago.sh ║
|
||||
║ ║
|
||||
║ Then install to disk with: ║
|
||||
║ # setup-alpine ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
|
||||
MOTD_EOF
|
||||
|
||||
# Create final ISO
|
||||
OUTPUT_ISO="$OUTPUT_DIR/archipelago-${ALPINE_VERSION}-hp-prodesk-uefi-x86_64.iso"
|
||||
echo ""
|
||||
echo "🔥 Creating final bootable ISO..."
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
if command -v xorriso >/dev/null 2>&1; then
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-J -R \
|
||||
-c boot/syslinux/boot.cat \
|
||||
-b boot/syslinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-isohybrid-mbr "$ISO_CUSTOM/boot/syslinux/isohdpfx.bin" \
|
||||
"$ISO_CUSTOM" 2>&1 | grep -v "xorriso : UPDATE"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ ISO created successfully!"
|
||||
echo ""
|
||||
echo "📀 Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo "📝 This ISO uses Alpine's overlay system (apkovl)"
|
||||
echo " The overlay will be automatically loaded at boot"
|
||||
echo ""
|
||||
@@ -1,114 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Create a proper bootable USB for Alpine/Archipelago
|
||||
# This formats the USB and installs Alpine in a way that works on problematic hardware
|
||||
|
||||
set -e
|
||||
|
||||
USB_DEVICE="${1}"
|
||||
ISO_FILE="${2:-/Users/dorian/Projects/archy/image-recipe/results/archipelago-3.19-hp-prodesk-uefi-x86_64.iso}"
|
||||
|
||||
if [ -z "$USB_DEVICE" ]; then
|
||||
echo "Usage: $0 /dev/diskN [iso-file]"
|
||||
echo ""
|
||||
echo "Available disks:"
|
||||
diskutil list | grep "external"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$ISO_FILE" ]; then
|
||||
echo "❌ ISO file not found: $ISO_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════╗"
|
||||
echo "║ Create Bootable USB for HP ProDesk ║"
|
||||
echo "╚════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "⚠️ WARNING: This will ERASE all data on $USB_DEVICE"
|
||||
echo ""
|
||||
echo "📀 ISO: $(basename $ISO_FILE)"
|
||||
echo "💾 USB: $USB_DEVICE"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to cancel, or Enter to continue..."
|
||||
read
|
||||
|
||||
# Unmount
|
||||
echo "🔓 Unmounting USB..."
|
||||
diskutil unmountDisk "$USB_DEVICE" || true
|
||||
|
||||
# Create a single FAT32 partition with MBR
|
||||
echo "🗂️ Creating FAT32 partition..."
|
||||
sudo diskutil eraseDisk FAT32 ALPINE MBR "$USB_DEVICE"
|
||||
|
||||
# Wait for partition to settle
|
||||
sleep 2
|
||||
|
||||
# Extract the ISO
|
||||
echo "📦 Extracting ISO..."
|
||||
ISO_MOUNT="/tmp/alpine-iso-$$"
|
||||
mkdir -p "$ISO_MOUNT"
|
||||
|
||||
# Use 7z to extract the ISO
|
||||
if command -v 7z >/dev/null 2>&1; then
|
||||
7z x "$ISO_FILE" -o"$ISO_MOUNT" -y >/dev/null
|
||||
else
|
||||
echo "❌ 7z not found. Installing with brew..."
|
||||
brew install p7zip
|
||||
7z x "$ISO_FILE" -o"$ISO_MOUNT" -y >/dev/null
|
||||
fi
|
||||
|
||||
# Find the USB mount point
|
||||
USB_MOUNT=$(diskutil info "${USB_DEVICE}s1" | grep "Mount Point" | awk '{print $3}')
|
||||
if [ -z "$USB_MOUNT" ]; then
|
||||
echo "❌ Could not find USB mount point"
|
||||
hdiutil detach "$ISO_MOUNT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "💾 USB mounted at: $USB_MOUNT"
|
||||
|
||||
# Copy all files from ISO to USB
|
||||
echo "📋 Copying Alpine files to USB..."
|
||||
rsync -av --progress "$ISO_MOUNT/" "$USB_MOUNT/"
|
||||
|
||||
# Install syslinux bootloader
|
||||
echo "🔧 Installing bootloader..."
|
||||
|
||||
# Rename isolinux to syslinux for USB boot
|
||||
if [ -d "$USB_MOUNT/boot/syslinux" ]; then
|
||||
if [ -f "$USB_MOUNT/boot/syslinux/isolinux.bin" ]; then
|
||||
mv "$USB_MOUNT/boot/syslinux/isolinux.bin" "$USB_MOUNT/boot/syslinux/syslinux.bin" 2>/dev/null || true
|
||||
fi
|
||||
if [ -f "$USB_MOUNT/boot/syslinux/isolinux.cfg" ]; then
|
||||
mv "$USB_MOUNT/boot/syslinux/isolinux.cfg" "$USB_MOUNT/boot/syslinux/syslinux.cfg" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update syslinux config to remove ISO-specific options
|
||||
if [ -f "$USB_MOUNT/boot/syslinux/syslinux.cfg" ]; then
|
||||
sed -i '' 's/isolinux/syslinux/g' "$USB_MOUNT/boot/syslinux/syslinux.cfg"
|
||||
fi
|
||||
|
||||
# Sync and clean up
|
||||
echo "🔄 Syncing..."
|
||||
sync
|
||||
rm -rf "$ISO_MOUNT"
|
||||
diskutil unmount "$USB_MOUNT"
|
||||
|
||||
# Make the USB bootable by writing MBR
|
||||
echo "🚀 Making USB bootable..."
|
||||
if [ -f "/tmp/alpine-iso-$$/boot/syslinux/mbr.bin" ]; then
|
||||
sudo dd if="/tmp/alpine-iso-$$/boot/syslinux/mbr.bin" of="$USB_DEVICE" bs=440 count=1 conv=notrunc 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Bootable USB created successfully!"
|
||||
echo ""
|
||||
echo "📋 Next steps:"
|
||||
echo " 1. Boot HP ProDesk from USB"
|
||||
echo " 2. In BIOS: Legacy mode, Secure Boot OFF"
|
||||
echo " 3. Should boot to Alpine login"
|
||||
echo ""
|
||||
echo "🎯 If this still fails, the HP ProDesk may need Alpine installed"
|
||||
echo " to internal drive first (can't boot from USB at all)"
|
||||
echo ""
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Create bootable FAT32 USB from Archipelago ISO
|
||||
# This extracts the ISO contents to FAT32 for UEFI boot
|
||||
#
|
||||
# Usage: ./create-fat32-usb.sh /dev/diskN
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Get absolute path of script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 /dev/diskN"
|
||||
echo ""
|
||||
echo "Available disks:"
|
||||
diskutil list external
|
||||
exit 1
|
||||
fi
|
||||
|
||||
USB_DISK="$1"
|
||||
ISO_FILE="$SCRIPT_DIR/results/archipelago-debian-12-x86_64.iso"
|
||||
WORK_DIR="$SCRIPT_DIR/build/usb-extract"
|
||||
|
||||
if [ ! -f "$ISO_FILE" ]; then
|
||||
echo "❌ ISO not found: $ISO_FILE"
|
||||
echo ""
|
||||
echo "Build the ISO first with: ./build-debian-iso.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════╗"
|
||||
echo "║ Create FAT32 Bootable USB ║"
|
||||
echo "╚════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "⚠️ WARNING: This will COMPLETELY ERASE $USB_DISK"
|
||||
echo ""
|
||||
echo "📀 ISO: $(basename "$ISO_FILE")"
|
||||
echo "💾 USB: $USB_DISK"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to cancel, or Enter to continue..."
|
||||
read
|
||||
|
||||
# Clean up work directory
|
||||
rm -rf "$WORK_DIR"
|
||||
mkdir -p "$WORK_DIR"
|
||||
|
||||
echo "🔓 Unmounting USB..."
|
||||
diskutil unmountDisk "$USB_DISK" || true
|
||||
|
||||
echo ""
|
||||
echo "🗂️ Formatting USB as FAT32 with MBR..."
|
||||
diskutil eraseDisk FAT32 ARCHIPELAGO MBR "$USB_DISK"
|
||||
|
||||
echo ""
|
||||
echo "📦 Extracting ISO contents..."
|
||||
cd "$WORK_DIR"
|
||||
7z x -y "$ISO_FILE"
|
||||
|
||||
echo ""
|
||||
echo "📋 Copying files to USB (this may take a few minutes)..."
|
||||
USB_MOUNT="/Volumes/ARCHIPELAGO"
|
||||
if [ ! -d "$USB_MOUNT" ]; then
|
||||
echo "❌ USB not mounted at $USB_MOUNT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy all extracted files
|
||||
cp -Rv "$WORK_DIR"/* "$USB_MOUNT/" 2>/dev/null | tail -5
|
||||
echo " (showing last 5 files copied)"
|
||||
|
||||
echo ""
|
||||
echo "🔄 Syncing..."
|
||||
sync
|
||||
|
||||
echo ""
|
||||
echo "✅ USB created successfully!"
|
||||
echo ""
|
||||
echo "Now:"
|
||||
echo " 1. Eject: diskutil eject $USB_DISK"
|
||||
echo " 2. Insert into target machine"
|
||||
echo " 3. Boot from USB (F12 or similar for boot menu)"
|
||||
echo ""
|
||||
echo "Default login (live mode):"
|
||||
echo " Username: user"
|
||||
echo " Password: live"
|
||||
|
||||
# Cleanup
|
||||
rm -rf "$WORK_DIR"
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Create a proper bootable USB for HP ProDesk
|
||||
# This formats the USB and installs Alpine in a way that works on real hardware
|
||||
|
||||
set -e
|
||||
|
||||
USB_DEVICE="${1:-/dev/disk4}"
|
||||
ISO_FILE="/Users/dorian/Projects/archy/image-recipe/results/archipelago-3.19-hp-prodesk-uefi-x86_64.iso"
|
||||
|
||||
if [ ! -f "$ISO_FILE" ]; then
|
||||
echo "❌ ISO file not found: $ISO_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⚠️ WARNING: This will ERASE all data on $USB_DEVICE"
|
||||
echo "Press Ctrl+C to cancel, or Enter to continue..."
|
||||
read
|
||||
|
||||
echo "📀 ISO: $ISO_FILE"
|
||||
echo "💾 USB: $USB_DEVICE"
|
||||
echo ""
|
||||
|
||||
# Unmount
|
||||
echo "🔓 Unmounting USB..."
|
||||
diskutil unmountDisk "$USB_DEVICE" || true
|
||||
|
||||
# Create hybrid ISO (makes it bootable from USB on both BIOS and UEFI)
|
||||
echo "🔧 Creating hybrid boot support..."
|
||||
if command -v isohybrid >/dev/null 2>&1; then
|
||||
# If syslinux is installed
|
||||
cp "$ISO_FILE" "/tmp/hybrid-archipelago.iso"
|
||||
isohybrid -u "/tmp/hybrid-archipelago.iso"
|
||||
ISO_FILE="/tmp/hybrid-archipelago.iso"
|
||||
echo "✅ Hybrid boot support added"
|
||||
else
|
||||
echo "ℹ️ isohybrid not available, using direct ISO write"
|
||||
fi
|
||||
|
||||
# Write to USB using dd
|
||||
echo "💿 Writing ISO to USB..."
|
||||
echo " This will take 2-3 minutes..."
|
||||
sudo dd if="$ISO_FILE" of="${USB_DEVICE/disk/rdisk}" bs=1m status=progress
|
||||
|
||||
# Sync
|
||||
echo "🔄 Syncing..."
|
||||
sync
|
||||
|
||||
# Clean up
|
||||
rm -f "/tmp/hybrid-archipelago.iso"
|
||||
|
||||
echo ""
|
||||
echo "✅ USB boot device created successfully!"
|
||||
echo ""
|
||||
echo "📋 Next steps:"
|
||||
echo " 1. Check HP ProDesk BIOS settings:"
|
||||
echo " - Disable Secure Boot"
|
||||
echo " - Enable USB Boot"
|
||||
echo " - Try Legacy BIOS mode first"
|
||||
echo " 2. Boot from USB"
|
||||
echo " 3. Should see Alpine login prompt"
|
||||
echo ""
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Simple script to create bootable USB from extracted ISO files
|
||||
|
||||
set -e
|
||||
|
||||
USB_DEVICE="${1:-/dev/disk4}"
|
||||
ISO_FILE="${2:-/Users/dorian/Projects/archy/image-recipe/results/archipelago-3.19-hp-prodesk-uefi-x86_64.iso}"
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════╗"
|
||||
echo "║ Create Bootable USB from ISO ║"
|
||||
echo "╚════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "📀 ISO: $(basename $ISO_FILE)"
|
||||
echo "💾 USB: $USB_DEVICE"
|
||||
echo ""
|
||||
|
||||
# Check if USB is formatted and mounted
|
||||
USB_MOUNT=$(diskutil info "${USB_DEVICE}s1" 2>/dev/null | grep "Mount Point" | awk '{print $3}' || echo "")
|
||||
|
||||
if [ -z "$USB_MOUNT" ]; then
|
||||
echo "❌ USB not mounted. Please format it first:"
|
||||
echo " sudo diskutil eraseDisk FAT32 ALPINE MBR $USB_DEVICE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ USB mounted at: $USB_MOUNT"
|
||||
echo ""
|
||||
|
||||
# Extract ISO to temp directory
|
||||
echo "📦 Extracting ISO..."
|
||||
TEMP_DIR="/tmp/alpine-extract-$$"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
7z x "$ISO_FILE" -o"$TEMP_DIR" -y >/dev/null
|
||||
|
||||
# Copy to USB
|
||||
echo "📋 Copying to USB..."
|
||||
rsync -av --progress "$TEMP_DIR/" "$USB_MOUNT/"
|
||||
|
||||
# Fix bootloader names for USB
|
||||
echo "🔧 Configuring bootloader..."
|
||||
cd "$USB_MOUNT/boot/syslinux"
|
||||
if [ -f isolinux.bin ]; then
|
||||
mv isolinux.bin syslinux.bin
|
||||
echo " ✓ Renamed isolinux.bin → syslinux.bin"
|
||||
fi
|
||||
if [ -f isolinux.cfg ]; then
|
||||
mv isolinux.cfg syslinux.cfg
|
||||
echo " ✓ Renamed isolinux.cfg → syslinux.cfg"
|
||||
fi
|
||||
|
||||
# Update config file
|
||||
if [ -f syslinux.cfg ]; then
|
||||
sed -i '' 's/isolinux/syslinux/g' syslinux.cfg
|
||||
echo " ✓ Updated syslinux.cfg"
|
||||
fi
|
||||
|
||||
# Sync
|
||||
echo "🔄 Syncing..."
|
||||
cd /
|
||||
sync
|
||||
sleep 2
|
||||
|
||||
# Unmount
|
||||
echo "📤 Unmounting USB..."
|
||||
diskutil unmount "$USB_MOUNT"
|
||||
|
||||
# Install MBR
|
||||
if [ -f "$TEMP_DIR/boot/syslinux/mbr.bin" ]; then
|
||||
echo "🚀 Installing MBR..."
|
||||
sudo dd if="$TEMP_DIR/boot/syslinux/mbr.bin" of="$USB_DEVICE" bs=440 count=1 conv=notrunc 2>/dev/null
|
||||
echo " ✓ MBR installed"
|
||||
fi
|
||||
|
||||
# Clean up
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
echo ""
|
||||
echo "✅ Bootable USB created successfully!"
|
||||
echo ""
|
||||
echo "📋 Next steps:"
|
||||
echo " 1. Safely eject: diskutil eject $USB_DEVICE"
|
||||
echo " 2. Boot HP ProDesk from USB"
|
||||
echo " 3. BIOS: Legacy mode, Secure Boot OFF"
|
||||
echo ""
|
||||
@@ -7,8 +7,8 @@ Helper scripts for building Archipelago OS images.
|
||||
### `build-backend.sh`
|
||||
Compiles the Archipelago Rust backend binary.
|
||||
- Output: `../build/backend/archipelago`
|
||||
- Requires: Rust toolchain
|
||||
- Optional: musl target for static binary
|
||||
- Requires: Rust toolchain (or Docker)
|
||||
- Builds for Linux x86_64
|
||||
|
||||
### `build-frontend.sh`
|
||||
Builds the Vue.js frontend for production.
|
||||
@@ -16,18 +16,6 @@ Builds the Vue.js frontend for production.
|
||||
- Requires: Node.js 18+, npm
|
||||
- Builds static files for serving
|
||||
|
||||
### `create-backend-apk.sh`
|
||||
Creates Alpine APK package from backend binary.
|
||||
- Output: `../apks/archipelago-backend-*.apk`
|
||||
- Includes: binary, systemd service, config files
|
||||
- Format: Alpine package format (tar.gz with metadata)
|
||||
|
||||
### `install-archipelago.sh`
|
||||
Installs Archipelago components into built image.
|
||||
- Called after image is created
|
||||
- Installs APK and frontend files
|
||||
- Configures services
|
||||
|
||||
### `convert-iso-to-disk.sh`
|
||||
Converts ISO image to raw disk image.
|
||||
- Input: ISO file
|
||||
@@ -36,19 +24,18 @@ Converts ISO image to raw disk image.
|
||||
|
||||
### `check-dependencies.sh`
|
||||
Checks if all build dependencies are available.
|
||||
- Checks: Rust, Node.js, Docker (if needed)
|
||||
- Checks: Rust, Node.js, Docker, xorriso
|
||||
- Provides installation instructions
|
||||
- Non-blocking (warns but continues)
|
||||
|
||||
### `setup-alpine-build.sh`
|
||||
Sets up Alpine build environment.
|
||||
- Installs Alpine build tools
|
||||
- Configures abuild keys
|
||||
- Only needed for native Alpine builds
|
||||
### `install-podman.sh`
|
||||
Installs Podman container runtime.
|
||||
- For use inside the target system
|
||||
- Configures rootless Podman
|
||||
|
||||
## Usage
|
||||
|
||||
These scripts are called automatically by the main build process. You typically don't need to run them manually, but you can for testing:
|
||||
These scripts are called automatically by the main build process. You can also run them manually for testing:
|
||||
|
||||
```bash
|
||||
# Build just the backend
|
||||
@@ -57,6 +44,6 @@ These scripts are called automatically by the main build process. You typically
|
||||
# Build just the frontend
|
||||
./scripts/build-frontend.sh
|
||||
|
||||
# Create APK package
|
||||
./scripts/create-backend-apk.sh
|
||||
# Check dependencies
|
||||
./scripts/check-dependencies.sh
|
||||
```
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Build Archipelago backend binary for Alpine Linux
|
||||
# Build Archipelago backend binary for Debian Linux
|
||||
|
||||
set -e
|
||||
|
||||
@@ -13,39 +13,57 @@ echo " Source: $BACKEND_DIR"
|
||||
echo " Output: $OUTPUT_DIR"
|
||||
echo ""
|
||||
|
||||
# Check if Rust is installed
|
||||
if ! command -v rustc >/dev/null 2>&1; then
|
||||
echo "❌ Rust not found. Installing..."
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
fi
|
||||
|
||||
# Create output directory
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Build backend
|
||||
cd "$BACKEND_DIR"
|
||||
echo "📦 Compiling backend..."
|
||||
cargo build --release --target x86_64-unknown-linux-musl || {
|
||||
# Try without musl target if cross-compilation not set up
|
||||
echo "⚠️ Musl target not available, building for host..."
|
||||
cargo build --release
|
||||
}
|
||||
# Check if we should use Docker
|
||||
USE_DOCKER=false
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
USE_DOCKER=true
|
||||
echo "🍎 macOS detected - using Docker for Linux build"
|
||||
elif ! command -v rustc >/dev/null 2>&1; then
|
||||
USE_DOCKER=true
|
||||
echo "⚠️ Rust not found - using Docker"
|
||||
fi
|
||||
|
||||
# Copy binary
|
||||
if [ -f "target/x86_64-unknown-linux-musl/release/archipelago" ]; then
|
||||
cp "target/x86_64-unknown-linux-musl/release/archipelago" "$OUTPUT_DIR/archipelago"
|
||||
elif [ -f "target/release/archipelago" ]; then
|
||||
cp "target/release/archipelago" "$OUTPUT_DIR/archipelago"
|
||||
if [ "$USE_DOCKER" = true ]; then
|
||||
echo "🐳 Building in Docker container..."
|
||||
docker run --rm \
|
||||
-v "$PROJECT_ROOT:/workspace" \
|
||||
-v "$OUTPUT_DIR:/output" \
|
||||
-w /workspace/core/archipelago \
|
||||
rust:bookworm \
|
||||
sh -c '
|
||||
echo "📦 Installing build dependencies..."
|
||||
apt-get update && apt-get install -y pkg-config libssl-dev
|
||||
|
||||
echo "🔨 Building Archipelago backend..."
|
||||
cargo build --release
|
||||
|
||||
echo "📋 Copying binary to output..."
|
||||
cp ../target/release/archipelago /output/
|
||||
|
||||
echo "✅ Build complete!"
|
||||
ls -lh /output/archipelago
|
||||
'
|
||||
else
|
||||
echo "❌ Binary not found after build"
|
||||
exit 1
|
||||
# Native Linux build
|
||||
echo "🐧 Building natively..."
|
||||
cd "$BACKEND_DIR"
|
||||
cargo build --release
|
||||
|
||||
cp "../target/release/archipelago" "$OUTPUT_DIR/archipelago"
|
||||
fi
|
||||
|
||||
# Strip binary for smaller size
|
||||
if command -v strip >/dev/null 2>&1; then
|
||||
strip "$OUTPUT_DIR/archipelago"
|
||||
if [ -f "$OUTPUT_DIR/archipelago" ]; then
|
||||
if command -v strip >/dev/null 2>&1 && [[ "$OSTYPE" != "darwin"* ]]; then
|
||||
strip "$OUTPUT_DIR/archipelago"
|
||||
fi
|
||||
echo ""
|
||||
echo "✅ Backend built: $OUTPUT_DIR/archipelago"
|
||||
ls -lh "$OUTPUT_DIR/archipelago"
|
||||
else
|
||||
echo "❌ Build failed - binary not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Backend built: $OUTPUT_DIR/archipelago"
|
||||
ls -lh "$OUTPUT_DIR/archipelago"
|
||||
|
||||
@@ -33,40 +33,49 @@ else
|
||||
MISSING_DEPS=$((MISSING_DEPS + 1))
|
||||
fi
|
||||
|
||||
# Check Docker (for macOS or non-Alpine Linux)
|
||||
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
if docker info >/dev/null 2>&1; then
|
||||
echo "✅ Docker: $(docker --version)"
|
||||
else
|
||||
echo "⚠️ Docker: Installed but daemon not running"
|
||||
echo " Start Docker Desktop or: sudo systemctl start docker"
|
||||
fi
|
||||
# Check Docker
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
if docker info >/dev/null 2>&1; then
|
||||
echo "✅ Docker: $(docker --version)"
|
||||
else
|
||||
echo "❌ Docker: Not found (required for macOS, optional for Linux)"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo " Install: https://www.docker.com/products/docker-desktop"
|
||||
MISSING_DEPS=$((MISSING_DEPS + 1))
|
||||
else
|
||||
echo " Install: https://docs.docker.com/get-docker/"
|
||||
fi
|
||||
echo "⚠️ Docker: Installed but daemon not running"
|
||||
echo " Start Docker Desktop or: sudo systemctl start docker"
|
||||
fi
|
||||
else
|
||||
echo "❌ Docker: Not found"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo " Install: https://www.docker.com/products/docker-desktop"
|
||||
MISSING_DEPS=$((MISSING_DEPS + 1))
|
||||
else
|
||||
echo " Install: https://docs.docker.com/get-docker/"
|
||||
echo " (Optional on Linux if building natively)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check Alpine tools (for native Alpine Linux)
|
||||
if [ -f /etc/alpine-release ]; then
|
||||
echo ""
|
||||
echo "🏔️ Alpine Linux detected - checking native tools..."
|
||||
|
||||
for tool in abuild alpine-conf syslinux xorriso; do
|
||||
if command -v $tool >/dev/null 2>&1; then
|
||||
echo "✅ $tool: Installed"
|
||||
else
|
||||
echo "❌ $tool: Not found"
|
||||
echo " Install: apk add alpine-sdk abuild alpine-conf syslinux xorriso"
|
||||
MISSING_DEPS=$((MISSING_DEPS + 1))
|
||||
fi
|
||||
done
|
||||
# Check xorriso (for ISO creation)
|
||||
if command -v xorriso >/dev/null 2>&1; then
|
||||
echo "✅ xorriso: Installed"
|
||||
else
|
||||
echo "❌ xorriso: Not found (needed for ISO creation)"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo " Install: brew install xorriso"
|
||||
else
|
||||
echo " Install: apt-get install xorriso"
|
||||
fi
|
||||
MISSING_DEPS=$((MISSING_DEPS + 1))
|
||||
fi
|
||||
|
||||
# Check 7z (for ISO extraction)
|
||||
if command -v 7z >/dev/null 2>&1; then
|
||||
echo "✅ 7z: Installed"
|
||||
else
|
||||
echo "❌ 7z: Not found (needed for ISO extraction)"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo " Install: brew install p7zip"
|
||||
else
|
||||
echo " Install: apt-get install p7zip-full"
|
||||
fi
|
||||
MISSING_DEPS=$((MISSING_DEPS + 1))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Create Alpine APK package for Archipelago backend
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
BUILD_DIR="$SCRIPT_DIR/../build"
|
||||
APK_DIR="$SCRIPT_DIR/../apks"
|
||||
ARCHIPELAGO_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}"
|
||||
|
||||
echo "📦 Creating Archipelago backend APK..."
|
||||
echo ""
|
||||
|
||||
# Create APK directory
|
||||
mkdir -p "$APK_DIR"
|
||||
|
||||
# Create temporary APK build directory
|
||||
APK_BUILD_DIR=$(mktemp -d)
|
||||
trap "rm -rf $APK_BUILD_DIR" EXIT
|
||||
|
||||
cd "$APK_BUILD_DIR"
|
||||
|
||||
# APK package structure
|
||||
mkdir -p usr/bin
|
||||
mkdir -p usr/lib/systemd/system
|
||||
mkdir -p etc/archipelago
|
||||
mkdir -p etc/init.d
|
||||
|
||||
# Copy binary
|
||||
if [ -f "$BUILD_DIR/backend/archipelago" ]; then
|
||||
cp "$BUILD_DIR/backend/archipelago" usr/bin/archipelago
|
||||
chmod +x usr/bin/archipelago
|
||||
else
|
||||
echo "❌ Backend binary not found. Run build-backend.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create systemd service file
|
||||
cat > usr/lib/systemd/system/archipelago.service <<'EOF'
|
||||
[Unit]
|
||||
Description=Archipelago Bitcoin Node OS Backend
|
||||
After=network.target podman.service
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=archipelago
|
||||
Group=archipelago
|
||||
WorkingDirectory=/var/lib/archipelago
|
||||
ExecStart=/usr/bin/archipelago
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
# Security
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/archipelago /tmp
|
||||
|
||||
# Environment
|
||||
Environment="RUST_LOG=info"
|
||||
Environment="ARCHIPELAGO_DATA_DIR=/var/lib/archipelago"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Create init.d script (for openrc)
|
||||
cat > etc/init.d/archipelago <<'EOF'
|
||||
#!/sbin/openrc-run
|
||||
# Archipelago Bitcoin Node OS Backend
|
||||
|
||||
name="Archipelago"
|
||||
command="/usr/bin/archipelago"
|
||||
command_user="archipelago:archipelago"
|
||||
command_background=true
|
||||
pidfile="/var/run/archipelago.pid"
|
||||
start_stop_daemon_args="--make-pidfile"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
use podman
|
||||
}
|
||||
EOF
|
||||
chmod +x etc/init.d/archipelago
|
||||
|
||||
# Create default config
|
||||
mkdir -p etc/archipelago
|
||||
cat > etc/archipelago/config.toml <<EOF
|
||||
data_dir = "/var/lib/archipelago"
|
||||
bind_host = "0.0.0.0"
|
||||
bind_port = 5959
|
||||
log_level = "info"
|
||||
dev_mode = false
|
||||
container_runtime = "podman"
|
||||
port_offset = 0
|
||||
bitcoin_simulation = "none"
|
||||
EOF
|
||||
|
||||
# Calculate package size
|
||||
PKG_SIZE=$(du -sb "$APK_BUILD_DIR" | cut -f1)
|
||||
|
||||
# Create .PKGINFO (Alpine package format)
|
||||
cat > "$APK_BUILD_DIR/.PKGINFO" <<EOF
|
||||
pkgname = archipelago-backend
|
||||
pkgver = ${ARCHIPELAGO_VERSION}-r0
|
||||
pkgdesc = Archipelago Bitcoin Node OS Backend
|
||||
url = https://github.com/archipelago/archipelago
|
||||
arch = x86_64
|
||||
license = MIT
|
||||
size = ${PKG_SIZE}
|
||||
origin = archipelago
|
||||
EOF
|
||||
|
||||
# Create .SIGN.RSA (placeholder - would need signing key for production)
|
||||
touch "$APK_BUILD_DIR/.SIGN.RSA"
|
||||
|
||||
# Create tarball (Alpine APK format)
|
||||
cd "$APK_BUILD_DIR"
|
||||
tar -czf "$APK_DIR/archipelago-backend-${ARCHIPELAGO_VERSION}-r0.apk" \
|
||||
.PKGINFO .SIGN.RSA usr etc 2>/dev/null || {
|
||||
# Fallback: create without signing
|
||||
tar -czf "$APK_DIR/archipelago-backend-${ARCHIPELAGO_VERSION}-r0.apk" \
|
||||
.PKGINFO usr etc
|
||||
}
|
||||
|
||||
echo "✅ APK created: $APK_DIR/archipelago-backend-${ARCHIPELAGO_VERSION}-r0.apk"
|
||||
ls -lh "$APK_DIR/archipelago-backend-${ARCHIPELAGO_VERSION}-r0.apk"
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Alpine Linux Hardening Script for Archipelago Bitcoin Node OS
|
||||
# This script applies security hardening to the Alpine base image
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔒 Starting Alpine Linux hardening..."
|
||||
|
||||
# Disable unnecessary services
|
||||
systemctl disable bluetooth || true
|
||||
systemctl disable avahi-daemon || true
|
||||
|
||||
# Configure kernel parameters for security
|
||||
cat >> /etc/sysctl.conf <<EOF
|
||||
|
||||
# Archipelago Security Hardening
|
||||
# Disable IP forwarding
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv6.conf.all.forwarding = 0
|
||||
|
||||
# Enable SYN flood protection
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
|
||||
# Disable source routing
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv4.conf.default.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_source_route = 0
|
||||
net.ipv6.conf.default.accept_source_route = 0
|
||||
|
||||
# Disable ICMP redirects
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
|
||||
# Disable send redirects
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
|
||||
# Log martian packets
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
net.ipv4.conf.default.log_martians = 1
|
||||
|
||||
# Ignore ICMP ping requests (can be enabled if needed)
|
||||
# net.ipv4.icmp_echo_ignore_all = 1
|
||||
|
||||
# Ignore ICMP ping broadcasts
|
||||
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
|
||||
# Ignore bogus ICMP errors
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
|
||||
# Enable RFC-recommended source validation
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
|
||||
# Disable IPv6 if not needed (uncomment if IPv6 not required)
|
||||
# net.ipv6.conf.all.disable_ipv6 = 1
|
||||
# net.ipv6.conf.default.disable_ipv6 = 1
|
||||
EOF
|
||||
|
||||
# Configure SSH (if installed)
|
||||
if [ -f /etc/ssh/sshd_config ]; then
|
||||
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config || true
|
||||
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config || true
|
||||
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config || true
|
||||
fi
|
||||
|
||||
# Set up fail2ban basic configuration
|
||||
if [ -f /etc/fail2ban/jail.conf ]; then
|
||||
cat > /etc/fail2ban/jail.local <<EOF
|
||||
[DEFAULT]
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
maxretry = 5
|
||||
destemail = root@localhost
|
||||
sendername = Fail2Ban
|
||||
action = %(action_)s
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Configure automatic security updates
|
||||
cat > /etc/periodic/daily/archipelago-security-updates <<'EOF'
|
||||
#!/bin/sh
|
||||
# Automatic security updates for Archipelago
|
||||
apk update && apk upgrade -u || true
|
||||
EOF
|
||||
chmod +x /etc/periodic/daily/archipelago-security-updates
|
||||
|
||||
# Set restrictive file permissions
|
||||
chmod 700 /var/lib/archipelago/secrets
|
||||
chmod 755 /var/lib/archipelago/apps
|
||||
chmod 755 /var/lib/archipelago/logs
|
||||
|
||||
# Create log directory with proper permissions
|
||||
mkdir -p /var/log/archipelago
|
||||
chmod 755 /var/log/archipelago
|
||||
|
||||
# Configure log rotation for archipelago logs
|
||||
cat > /etc/logrotate.d/archipelago <<EOF
|
||||
/var/log/archipelago/*.log {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0644 root root
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Alpine Linux hardening complete!"
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Install Archipelago components into Alpine image
|
||||
# This script is called after the base image is built
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
OUTPUT_DIR="${1:-$SCRIPT_DIR/../results}"
|
||||
BUILD_DIR="$SCRIPT_DIR/../build"
|
||||
APK_DIR="$SCRIPT_DIR/../apks"
|
||||
|
||||
echo "🔧 Installing Archipelago into image..."
|
||||
echo " Output: $OUTPUT_DIR"
|
||||
echo ""
|
||||
|
||||
# Find the built image (ISO or extracted)
|
||||
if [ -f "$OUTPUT_DIR"/*.iso ]; then
|
||||
ISO_FILE=$(ls "$OUTPUT_DIR"/*.iso | head -1)
|
||||
echo "📦 Found ISO: $ISO_FILE"
|
||||
echo " (Archipelago will be installed when ISO is booted)"
|
||||
# For ISO, we'd need to extract, modify, and rebuild
|
||||
# This is complex, so we'll do it in the init script instead
|
||||
elif [ -d "$OUTPUT_DIR" ]; then
|
||||
# Extracted image directory
|
||||
IMAGE_ROOT="$OUTPUT_DIR"
|
||||
echo "📁 Installing into extracted image: $IMAGE_ROOT"
|
||||
|
||||
# Install backend APK
|
||||
if [ -f "$APK_DIR"/*.apk ]; then
|
||||
APK_FILE=$(ls "$APK_DIR"/*.apk | head -1)
|
||||
echo "📦 Installing backend APK: $APK_FILE"
|
||||
# In a real chroot, we'd do: apk add --allow-untrusted "$APK_FILE"
|
||||
# For now, we'll extract and copy manually
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
cd "$TEMP_DIR"
|
||||
tar -xzf "$APK_FILE"
|
||||
|
||||
# Copy files to image
|
||||
if [ -d "$IMAGE_ROOT" ]; then
|
||||
cp -r usr/* "$IMAGE_ROOT/usr/" 2>/dev/null || true
|
||||
cp -r etc/* "$IMAGE_ROOT/etc/" 2>/dev/null || true
|
||||
fi
|
||||
rm -rf "$TEMP_DIR"
|
||||
fi
|
||||
|
||||
# Install frontend
|
||||
if [ -d "$BUILD_DIR/frontend" ]; then
|
||||
echo "🎨 Installing frontend..."
|
||||
mkdir -p "$IMAGE_ROOT/usr/share/archipelago/web"
|
||||
cp -r "$BUILD_DIR/frontend/"* "$IMAGE_ROOT/usr/share/archipelago/web/"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ No image found to install into"
|
||||
echo " Archipelago will be installed on first boot"
|
||||
fi
|
||||
|
||||
# Create first boot script
|
||||
cat > "$SCRIPT_DIR/../alpine-profile/overlay/etc/local.d/archipelago-install.start" <<'EOF'
|
||||
#!/bin/sh
|
||||
# First boot installation script for Archipelago
|
||||
|
||||
# Install backend APK if available
|
||||
if [ -f /tmp/archipelago-backend.apk ]; then
|
||||
apk add --allow-untrusted /tmp/archipelago-backend.apk
|
||||
rm /tmp/archipelago-backend.apk
|
||||
fi
|
||||
|
||||
# Enable services
|
||||
rc-update add archipelago default || true
|
||||
systemctl enable archipelago || true
|
||||
|
||||
# Create archipelago user if needed
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
adduser -D -s /bin/bash archipelago
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers
|
||||
fi
|
||||
|
||||
# Setup Podman for archipelago user
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
chown -R archipelago:archipelago /home/archipelago
|
||||
|
||||
# Create data directories
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago
|
||||
|
||||
# Start services
|
||||
rc-service archipelago start || systemctl start archipelago || true
|
||||
EOF
|
||||
|
||||
chmod +x "$SCRIPT_DIR/../alpine-profile/overlay/etc/local.d/archipelago-install.start"
|
||||
|
||||
echo "✅ Archipelago installation configured"
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Setup Alpine build environment
|
||||
# Installs dependencies and prepares build environment
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo "🔧 Setting up Alpine build environment..."
|
||||
echo ""
|
||||
|
||||
# Detect OS
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo "🍎 macOS detected - Docker will be used"
|
||||
echo " Make sure Docker Desktop is installed and running"
|
||||
exit 0
|
||||
elif [ -f /etc/alpine-release ]; then
|
||||
echo "🏔️ Alpine Linux detected - installing native tools..."
|
||||
|
||||
# Install build dependencies
|
||||
apk add --no-cache \
|
||||
bash \
|
||||
git \
|
||||
alpine-sdk \
|
||||
abuild \
|
||||
alpine-conf \
|
||||
syslinux \
|
||||
xorriso \
|
||||
squashfs-tools \
|
||||
grub \
|
||||
grub-efi \
|
||||
mtools \
|
||||
dosfstools \
|
||||
e2fsprogs \
|
||||
rsync \
|
||||
curl \
|
||||
wget \
|
||||
ca-certificates || {
|
||||
echo "❌ Failed to install dependencies"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Setup abuild keys
|
||||
if [ ! -f ~/.abuild/abuild.conf ]; then
|
||||
echo "🔑 Generating abuild keys..."
|
||||
abuild-keygen -a -n
|
||||
fi
|
||||
|
||||
echo "✅ Alpine build environment ready!"
|
||||
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
echo "🐧 Linux detected (not Alpine) - Docker will be used"
|
||||
echo " Install Docker: https://docs.docker.com/get-docker/"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ Unsupported OS: $OSTYPE"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,33 +1,69 @@
|
||||
#!/bin/bash
|
||||
# Test Archipelago ISO in QEMU
|
||||
|
||||
ISO="${1:-/Users/dorian/Projects/archy/image-recipe/results/archipelago-3.19-hp-prodesk-uefi-x86_64.iso}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ISO="${1:-$SCRIPT_DIR/results/archipelago-debian-12-x86_64.iso}"
|
||||
|
||||
if [ ! -f "$ISO" ]; then
|
||||
echo "❌ ISO not found: $ISO"
|
||||
echo ""
|
||||
echo "Usage: $0 [path-to-iso]"
|
||||
echo ""
|
||||
echo "Build the ISO first with: ./build-debian-iso.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🧪 Testing Archipelago ISO in QEMU"
|
||||
echo "📀 ISO: $ISO"
|
||||
echo "💾 RAM: 4GB"
|
||||
echo "🖥️ CPU: 4 cores"
|
||||
echo "🖥️ CPU: 2 cores"
|
||||
echo ""
|
||||
echo "Press Ctrl+Alt+G to release mouse/keyboard from VM"
|
||||
echo "Press Ctrl+C in this terminal to stop VM"
|
||||
echo ""
|
||||
|
||||
# Create test disk if it doesn't exist
|
||||
DISK="/tmp/archipelago-test-disk.qcow2"
|
||||
if [ ! -f "$DISK" ]; then
|
||||
echo "Creating test disk..."
|
||||
qemu-img create -f qcow2 "$DISK" 20G
|
||||
fi
|
||||
|
||||
echo "Starting VM in 3 seconds..."
|
||||
sleep 3
|
||||
|
||||
# Run QEMU with Legacy BIOS (simpler, more compatible)
|
||||
# Run QEMU with UEFI (more modern, matches real hardware)
|
||||
if [ -f "/opt/homebrew/share/qemu/edk2-x86_64-code.fd" ]; then
|
||||
# macOS with Homebrew QEMU
|
||||
OVMF="/opt/homebrew/share/qemu/edk2-x86_64-code.fd"
|
||||
elif [ -f "/usr/share/OVMF/OVMF_CODE.fd" ]; then
|
||||
# Linux with OVMF
|
||||
OVMF="/usr/share/OVMF/OVMF_CODE.fd"
|
||||
else
|
||||
# Fall back to legacy BIOS
|
||||
echo "⚠️ UEFI firmware not found, using legacy BIOS..."
|
||||
qemu-system-x86_64 \
|
||||
-machine pc \
|
||||
-m 4G \
|
||||
-smp 2 \
|
||||
-boot d \
|
||||
-cdrom "$ISO" \
|
||||
-drive if=virtio,format=qcow2,file="$DISK" \
|
||||
-net nic,model=virtio -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::8100-:8100 \
|
||||
-vga virtio \
|
||||
-display default
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# UEFI boot
|
||||
qemu-system-x86_64 \
|
||||
-machine pc \
|
||||
-m 2G \
|
||||
-machine q35 \
|
||||
-bios "$OVMF" \
|
||||
-m 4G \
|
||||
-smp 2 \
|
||||
-boot d \
|
||||
-cdrom "$ISO" \
|
||||
-drive if=virtio,format=qcow2,file=/tmp/archipelago-test-disk.qcow2 \
|
||||
-net nic,model=virtio -net user \
|
||||
-drive if=virtio,format=qcow2,file="$DISK" \
|
||||
-net nic,model=virtio -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::8100-:8100 \
|
||||
-vga virtio \
|
||||
-display default
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Quick test build for Start9 Server Pure
|
||||
# This creates a minimal build to verify the system works
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo "🧪 Quick Test Build for Start9 Server Pure"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "This will create a test build to verify the system works."
|
||||
echo "A full production build takes 45-60 minutes."
|
||||
echo ""
|
||||
|
||||
# Check prerequisites
|
||||
echo "📋 Checking prerequisites..."
|
||||
echo ""
|
||||
|
||||
# Check for Docker on macOS
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "❌ Docker not found. Install Docker Desktop:"
|
||||
echo " https://www.docker.com/products/docker-desktop"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
echo "❌ Docker not running. Starting Docker Desktop..."
|
||||
open -a Docker
|
||||
echo "⏳ Waiting for Docker to start..."
|
||||
while ! docker info >/dev/null 2>&1; do
|
||||
sleep 2
|
||||
done
|
||||
echo "✅ Docker is running"
|
||||
else
|
||||
echo "✅ Docker is running"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check disk space
|
||||
AVAILABLE_SPACE=$(df -h "$SCRIPT_DIR" | awk 'NR==2 {print $4}')
|
||||
echo "✅ Available disk space: $AVAILABLE_SPACE"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🚀 Starting Test Build"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# Create test overlay to verify hardware detection works
|
||||
TEST_OVERLAY="$SCRIPT_DIR/alpine-profile/overlay-start9-pure-test"
|
||||
rm -rf "$TEST_OVERLAY"
|
||||
mkdir -p "$TEST_OVERLAY/etc/archipelago"
|
||||
|
||||
cat > "$TEST_OVERLAY/etc/archipelago/test-info.txt" <<'EOF'
|
||||
This is a test build for Start9 Server Pure.
|
||||
|
||||
If you can read this file after booting, the build system worked!
|
||||
|
||||
Hardware Target: Start9 Server Pure
|
||||
CPU: Intel i7-10710U
|
||||
RAM: 32-64GB
|
||||
Storage: 2-4TB NVMe
|
||||
|
||||
Next steps:
|
||||
1. Verify this file exists at /etc/archipelago/test-info.txt
|
||||
2. Check hardware detection: cat /var/log/archipelago-hardware.log
|
||||
3. View hardware config: cat /etc/archipelago/hardware.toml
|
||||
4. Run a full production build: ./build-for-hardware.sh start9-pure iso
|
||||
EOF
|
||||
|
||||
echo "📝 Test overlay created"
|
||||
echo ""
|
||||
|
||||
# Show what will be built
|
||||
echo "📦 Build Configuration:"
|
||||
echo " Target: Start9 Server Pure"
|
||||
echo " Type: ISO"
|
||||
echo " Test Mode: Yes (quick verification)"
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
read -p "Continue with test build? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "❌ Build cancelled"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "⏳ Building... This will take 5-10 minutes for a test build."
|
||||
echo ""
|
||||
|
||||
# Set test mode environment
|
||||
export ARCHIPELAGO_VERSION="0.1.0-test"
|
||||
export ALPINE_VERSION="3.19"
|
||||
export TEST_MODE="true"
|
||||
|
||||
# Run the build
|
||||
"$SCRIPT_DIR/build-for-hardware.sh" start9-pure iso
|
||||
|
||||
# Check if build succeeded
|
||||
if [ -f "$SCRIPT_DIR/results/archipelago-0.1.0-test-start9-pure-x86_64.iso" ]; then
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Test Build Successful!"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "📦 Output:"
|
||||
ls -lh "$SCRIPT_DIR/results/"*start9-pure*.iso
|
||||
echo ""
|
||||
echo "✅ The build system is working correctly!"
|
||||
echo ""
|
||||
echo "🎯 Next Steps:"
|
||||
echo ""
|
||||
echo "1. Test in a VM (optional):"
|
||||
echo " qemu-system-x86_64 -m 4G -smp 2 -boot d \\"
|
||||
echo " -cdrom results/archipelago-0.1.0-test-start9-pure-x86_64.iso"
|
||||
echo ""
|
||||
echo "2. Run a full production build:"
|
||||
echo " ./build-for-hardware.sh start9-pure iso"
|
||||
echo ""
|
||||
echo "3. Flash to USB and install on Start9 Server Pure:"
|
||||
echo " sudo dd if=results/archipelago-0.1.0-start9-pure-x86_64.iso \\"
|
||||
echo " of=/dev/sdX bs=1M status=progress"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "❌ Test build failed. Check the logs above for errors."
|
||||
exit 1
|
||||
fi
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Write Archipelago ISO to USB using dd
|
||||
#
|
||||
# Usage: ./write-usb-dd.sh /dev/diskN
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 /dev/diskN"
|
||||
echo ""
|
||||
echo "Available disks:"
|
||||
diskutil list external
|
||||
exit 1
|
||||
fi
|
||||
|
||||
USB_DISK="$1"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ISO_FILE="$SCRIPT_DIR/results/archipelago-debian-12-x86_64.iso"
|
||||
|
||||
if [ ! -f "$ISO_FILE" ]; then
|
||||
echo "❌ ISO not found: $ISO_FILE"
|
||||
echo ""
|
||||
echo "Build the ISO first with: ./build-debian-iso.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get raw disk for faster writes
|
||||
RAW_DISK="${USB_DISK/disk/rdisk}"
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════╗"
|
||||
echo "║ Write Archipelago ISO to USB ║"
|
||||
echo "╚════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "⚠️ WARNING: This will COMPLETELY ERASE $USB_DISK"
|
||||
echo ""
|
||||
echo "📀 ISO: $(basename "$ISO_FILE")"
|
||||
echo "💾 USB: $USB_DISK (raw: $RAW_DISK)"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to cancel, or Enter to continue..."
|
||||
read
|
||||
|
||||
echo "🔓 Unmounting USB..."
|
||||
diskutil unmountDisk "$USB_DISK" || true
|
||||
|
||||
echo ""
|
||||
echo "📝 Writing ISO with dd (this may take a few minutes)..."
|
||||
echo " Using raw disk $RAW_DISK for faster write..."
|
||||
echo ""
|
||||
|
||||
# Use dd to write the ISO directly
|
||||
sudo dd if="$ISO_FILE" of="$RAW_DISK" bs=4m status=progress
|
||||
|
||||
echo ""
|
||||
echo "🔄 Syncing..."
|
||||
sync
|
||||
|
||||
echo ""
|
||||
echo "✅ Done! USB is ready."
|
||||
echo ""
|
||||
echo "Now:"
|
||||
echo " 1. Eject the USB safely: diskutil eject $USB_DISK"
|
||||
echo " 2. Insert into target machine"
|
||||
echo " 3. Boot from USB (F12 or similar for boot menu)"
|
||||
echo ""
|
||||
echo "Default login (live mode):"
|
||||
echo " Username: user"
|
||||
echo " Password: live"
|
||||
Reference in New Issue
Block a user