Files
2026-09-04 15:48:04 +02:00

285 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Testing NaxOS on macOS
This guide provides step-by-step instructions for testing and running the complete **NaxOS** appliance on macOS. It covers full live virtual machine testing with QEMU, rapid local frontend/API development, and headless automated verification.
---
## Testing Methods Overview
| Method | Target Use Case | Requirements |
| :--- | :--- | :--- |
| **Method 1: Full Live QEMU VM** | Complete appliance test: Linux 6.18 kernel, real OpenZFS pool `tank`, live `naxos-api` daemon, and `naxos-ui` web interface. | `qemu-system-x86_64` (Homebrew or Nix) |
| **Method 2: Local UI / API Dev** | Rapid UI development, styling iteration, and component testing on macOS without a VM. | Node.js 20+, npm |
| **Method 3: Headless Verification** | Automated end-to-end browser capture and visual validation. | Python 3 + Playwright or Chromium |
---
## Method 1: Full Appliance VM Testing via QEMU
This method boots the actual NaxOS NixOS 26.05 operating system with Linux kernel 6.18, creates a virtual target disk, provisions a real OpenZFS pool (`tank`), and runs the full API daemon and Web UI with port forwarding to macOS.
### 1. Prerequisites
Install QEMU on macOS using Homebrew (or via Nix):
```bash
# Using Homebrew
brew install qemu
# Or if you use Nix on macOS:
nix-shell -p qemu
```
Verify that `qemu-system-x86_64` is available:
```bash
qemu-system-x86_64 --version
```
> [!NOTE]
> **Apple Silicon (M1/M2/M3/M4) Note**: When running `qemu-system-x86_64` on Apple Silicon Macs, QEMU uses TCG (Tiny Code Generator) software emulation. Because it is emulating x86_64 on ARM64, boot times will take approximately 1530 seconds.
---
### 2. Download the NaxOS Installation Media
Download the official bootable ISO from the Gitea package registry:
```bash
curl -fSL -o /tmp/naxos-installer.iso \
"https://git.lholz.de/api/packages/naxos/generic/naxos-installer-iso/1.0.0/naxos-installer-x86_64-linux.iso"
```
---
### 3. Prepare Boot Artifacts & Virtual Drive
Extract the direct-boot kernel and initrd from the ISO (or boot directly from the ISO cdrom):
```bash
# Create a 20 GB QCOW2 virtual drive for OpenZFS testing
qemu-img create -f qcow2 /tmp/naxos-target-disk.qcow2 20G
# Mount or extract the ISO to retrieve the kernel and initrd
mkdir -p /tmp/naxos-iso-mnt /tmp/naxos-boot
hdiutil attach -nobrowse -readonly -mountpoint /tmp/naxos-iso-mnt /tmp/naxos-installer.iso
cp -R /tmp/naxos-iso-mnt/boot /tmp/naxos-boot/
hdiutil detach /tmp/naxos-iso-mnt
```
Find the extracted kernel and initrd paths:
```bash
KERNEL=$(find /tmp/naxos-boot -name bzImage | head -n 1)
INITRD=$(find /tmp/naxos-boot -name initrd | head -n 1)
echo "Kernel: $KERNEL"
echo "Initrd: $INITRD"
```
---
### 4. Launch the NaxOS Virtual Appliance
Start QEMU with:
- **RAM**: 2048 MB (2 GB)
- **CPU**: 2 cores (`-smp 2`)
- **Storage**: VirtIO disk attached to `/tmp/naxos-target-disk.qcow2` (appears as `/dev/vda` in the VM)
- **Networking**: User-mode networking with port forwarding:
- Host port `18080` -> VM port `80` (NaxOS Web UI)
- Host port `18443` -> VM port `8443` (NaxOS HTTPS / API)
- **Serial Console**: Stdio redirected to your terminal for real-time kernel and shell access.
```bash
qemu-system-x86_64 \
-m 2048 \
-smp 2 \
-kernel "$KERNEL" \
-initrd "$INITRD" \
-append "init=/nix/store/*-nixos-system-nixos-*/init console=ttyS0,115200n8 loglevel=6" \
-drive file=/tmp/naxos-target-disk.qcow2,if=virtio,format=qcow2 \
-net nic,model=virtio \
-net user,hostfwd=tcp::18443-:8443,hostfwd=tcp::18080-:80 \
-nographic
```
Once booted, press **Enter** to get the root prompt:
```text
<<< Welcome to NixOS 26.05! >>>
[root@nixos:~]#
```
---
### 5. Initialize the OpenZFS Storage Pool in the VM
Inside the VM terminal, create the real OpenZFS pool `tank` on the virtual drive `/dev/vda`:
```bash
# Create OpenZFS pool
zpool create tank /dev/vda -f
# Create standard appliance datasets
zfs create tank/media
zfs create tank/backup
zfs create tank/container
# Verify pool health and status
zpool status
zpool list
zfs list
```
You should see:
```text
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 19.5G 832K 19.5G - - 0% 0% 1.00x ONLINE -
```
---
### 6. Verify Real System Metrics & Declarative Rebuild
The NaxOS Management Daemon (`naxos-api`) queries real kernel interfaces rather than mocked data:
- **ZFS ARC Cache**: `/proc/spl/kstat/zfs/arcstats`
- **Uptime**: `/proc/uptime`
- **Memory**: `os.totalmem()` and `os.freemem()`
- **Disk I/O**: `/proc/diskstats`
- **Journal Logs**: Real `journalctl -n 100 -o json --no-pager`
Test the API daemon endpoints from inside the VM or from macOS:
```bash
# Check system metrics from your Mac:
curl http://localhost:18443/api/v1/system/metrics
# Check real ZFS pools:
curl http://localhost:18443/api/v1/storage/pools
# Check active system services:
curl http://localhost:18443/api/v1/system/services
```
#### Testing "Apply Changes" (Live SSE Stream)
Trigger a declarative system rebuild from macOS:
```bash
curl -N -X POST http://localhost:18443/api/v1/system/rebuild
```
You will receive real Server-Sent Events (SSE) streaming live steps:
1. `validating` - Synthesizing declarative NixOS configuration.
2. `building` - Executing `/run/current-system/sw/bin/nixos-rebuild dry-activate`.
3. `reloading` - Applying dataset quotas and reloading Samba shares.
4. `completed` - Generation activated successfully.
---
### 7. Accessing the Web Dashboard
Open your web browser on macOS and navigate to:
```text
http://localhost:18080
```
You will see:
1. **Glassmorphism Appliance Dashboard**: Live storage capacity, real ARC hit ratio (100%), ARC cache size, CPU and memory gauges.
2. **Storage Management**: Visual hierarchy of pool `tank`, datasets (`media`, `backup`, `container`), and snapshots.
3. **App Store**: Curated 1-click catalog (Immich, Jellyfin, Nextcloud, Vaultwarden).
4. **Apply Changes Modal**: Interactive rebuild viewer streaming real systemd activation logs.
---
### 8. Clean VM Shutdown
To cleanly unmount OpenZFS datasets, export the storage pool, and power down the virtual machine, execute inside the VM console:
```bash
poweroff
```
Or press `Ctrl+A` then `X` to exit QEMU immediately.
---
## Method 2: Local UI & API Rapid Development
To develop or preview the Web UI directly on macOS without launching QEMU:
### 1. Build and Run the Web UI
```bash
cd naxos-ui
# Install dependencies
npm install
# Start Vite development server
npm run dev
```
Open `http://localhost:5173` in your browser.
### 2. Previewing the Production SPA Build
```bash
cd naxos-ui
npm run build
npm run preview -- --port 3000
```
Open `http://localhost:3000` to inspect the production asset bundle.
### 3. Running the Management Daemon Locally (Mock Fallback)
If running `naxos-api` on macOS outside of Linux, it automatically falls back gracefully when Linux-specific paths (`/proc/spl/kstat/zfs/arcstats`, `zpool`) are unavailable:
```bash
cd naxos-api
npm install
npm run build
npm start
```
The API daemon listens on `http://localhost:8088`.
---
## Method 3: Headless Automated Browser Verification
To run headless end-to-end tests or re-generate screenshots automatically:
```bash
# Using Python Playwright
python3 -m pip install playwright
python3 -m playwright install chromium
# Run headless screenshot verification
python3 - << 'EOF'
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={"width": 1440, "height": 900})
page.goto("http://localhost:18080")
page.wait_for_selector("text=System Healthy")
page.screenshot(path="test-overview.png")
print("Screenshot captured successfully!")
browser.close()
EOF
```
---
## Troubleshooting & FAQ
### Port `18080` or `18443` is already in use
Check which process is listening on the port:
```bash
lsof -i :18080
lsof -i :18443
```
Kill the stale process or change the `-net user,hostfwd=tcp::18080-:80` parameter in the QEMU launch command to an alternate port (e.g. `hostfwd=tcp::28080-:80`).
### Strict MIME Type Errors (`Failed to load module script`)
Browsers enforce strict MIME checking for ES modules (`Content-Type: text/javascript; charset=utf-8`). If serving files via Python or custom static servers, ensure MIME types are explicitly configured:
```python
import mimetypes
mimetypes.add_type('application/javascript', '.js')
mimetypes.add_type('text/css', '.css')
```
The standard `naxos-api` and production `nginx` containers already include appropriate MIME headers out of the box.