Document installer release architecture

This commit is contained in:
Jino Jose 2026-07-14 12:06:49 +05:30
parent 21bca7de3f
commit bea082a201
4 changed files with 85 additions and 18 deletions

View File

@ -8,9 +8,10 @@ This repository is the source of truth for the Nexus One AI platform package,
including installer flows, deployment roles, portal assets, backend services,
licensing enforcement, and the bootable ISO build path.
The ISO is only one delivery surface. It stays small by pulling this package
from cgit during setup, then the installer deploys the selected tier and
feature set on the target server.
The ISO is one delivery surface. The online Server installer stays small by
pulling this package and the selected tier payload during setup. Offline
installers embed their approved platform payload and starter models, while
large models are delivered as separate signed model packs.
## Product Structure
@ -43,6 +44,37 @@ Powered by Cezen
four tiers). See [Section 6](#6-tier-and-packaging-guide) and
[Section 8](#8-features-by-tier).
## Installer Release Architecture
Nexus One AI uses four bootable ISO products built from this shared codebase:
| ISO | Connectivity | Selection and payload | Current status |
|---|---|---|---|
| Online Universal Server | Internet required during setup | Hardware/license preflight followed by Server S, M, L, or Max selection | Existing build path; validation continues |
| Offline Workstation | No internet required | Fixed Workstation category with the complete local platform and approved Workstation starter models | In development |
| Offline Server S/M | No internet required | Server S or M selected from hardware and license; small/medium local payload | Planned |
| Offline Server L/Max | No internet required | Server L or Max selected from hardware and license; enterprise platform payload | Planned |
Large Server L/Max models are not bootable installers and are not duplicated
inside the ISO. They are separate signed model packs imported from approved USB
or external storage after platform installation. The same signed offline update
format will patch already-installed systems across all four ISO products; fixed
updates are also rolled into later ISO rebuilds for clean installations.
Expected removable-media guidance:
- Online Universal Server ISO: approximately 2-4 GB; use an 8 GB or larger USB.
- Offline Workstation ISO: currently estimated at 35-50 GB; use a 64 GB minimum,
with 128 GB recommended for reliable flashing and future growth.
- Offline Server S/M and L/Max sizes will be recorded only after their payloads
are built and deduplicated; do not publish speculative final sizes.
- Large model packs may range from a few gigabytes to hundreds of gigabytes and
should normally be carried on dedicated external storage.
An ISO is not labelled offline merely because the source tree is embedded. It
must pass a clean installation with network interfaces disconnected, payload
integrity verification, reboot persistence, and service/model validation.
## Product Collateral
Technical buyer-facing collateral lives in `docs/` for reuse in customer

View File

@ -4,6 +4,17 @@ This directory defines the payload embedded by `build-iso-offline.sh`. The
offline installer is deliberately separate from the existing online bootstrap
ISO until disconnected clean-install validation is complete.
The agreed bootable release matrix is:
1. Online Universal Server ISO with Server S/M/L/Max selection.
2. Offline Workstation ISO.
3. Offline Server S/M ISO.
4. Offline Server L/Max ISO.
Large models remain separate signed model packs. Signed update bundles patch
installed appliances without an operating-system reinstall, and validated
updates are periodically rolled into refreshed ISO builds.
## Offline Workstation contents
- the exact `aipackage` source revision used for the build

View File

@ -35,10 +35,18 @@ if [ "$available_kb" -lt $((80 * 1024 * 1024)) ]; then
fi
rm -rf "$OUTPUT_DIR"
mkdir -p "$PAYLOAD_DIR"/{apt,containers,models,python,runtime,source} "$MANIFEST_DIR"
mkdir -p "$PAYLOAD_DIR"/{apt,containers,models,runtime,source} \
"$PAYLOAD_DIR/python"/{backend,chromadb,platform} "$MANIFEST_DIR"
echo "-> Capturing pinned appliance source"
if git -C "$PACKAGE_DIR" rev-parse HEAD >/dev/null 2>&1; then
git -C "$PACKAGE_DIR" rev-parse HEAD > "$MANIFEST_DIR/source-commit.txt"
elif [ -n "${OFFLINE_SOURCE_COMMIT:-}" ]; then
printf '%s\n' "$OFFLINE_SOURCE_COMMIT" > "$MANIFEST_DIR/source-commit.txt"
else
echo "ERROR: source commit is unavailable; set OFFLINE_SOURCE_COMMIT for exported source trees." >&2
exit 1
fi
rsync -a --delete \
--exclude '.git/' --exclude '*.iso' --exclude 'offline-output/' \
--exclude 'how-it-flows.gif' \
@ -52,9 +60,15 @@ apt-get install -y --download-only --reinstall \
-o "Dir::Cache::archives=$PAYLOAD_DIR/apt" "${apt_packages[@]}"
echo "-> Downloading Python wheelhouse"
python3 -m pip download --dest "$PAYLOAD_DIR/python" \
-r "$PACKAGE_DIR/ansible/roles/cezen-backend/files/requirements.txt" \
-r "$SCRIPT_DIR/python-packages.txt"
python3 -m pip download --dest "$PAYLOAD_DIR/python/backend" \
-r "$PACKAGE_DIR/ansible/roles/cezen-backend/files/requirements.txt"
python3 -m pip download --dest "$PAYLOAD_DIR/python/chromadb" \
'chromadb==0.5.23'
grep -vE '^[[:space:]]*(#|$|chromadb==)' "$SCRIPT_DIR/python-packages.txt" \
> "$OUTPUT_DIR/platform-python-packages.txt"
python3 -m pip download --dest "$PAYLOAD_DIR/python/platform" \
-r "$OUTPUT_DIR/platform-python-packages.txt"
rm -f "$OUTPUT_DIR/platform-python-packages.txt"
echo "-> Capturing Miniconda installer"
curl --fail --location --retry 3 "$MINICONDA_URL" \
@ -76,17 +90,27 @@ echo "-> Capturing Ollama runtime and Starter models"
if ! command -v ollama >/dev/null; then
curl --fail --location --retry 3 https://ollama.com/install.sh | sh
fi
systemctl start ollama 2>/dev/null || true
for model in $OLLAMA_MODELS; do ollama pull "$model"; done
tar -C / -czf "$PAYLOAD_DIR/runtime/ollama-runtime.tar.gz" \
usr/local/bin/ollama usr/local/lib/ollama
ollama_root="${OLLAMA_MODELS_DIR:-/usr/share/ollama/.ollama/models}"
[ -d "$ollama_root" ] || ollama_root="/root/.ollama/models"
[ -d "$ollama_root" ] || {
echo "ERROR: Ollama model store not found after pull." >&2
exit 1
}
tar -C "$(dirname "$ollama_root")" -czf "$PAYLOAD_DIR/models/ollama-models.tar.gz" models
isolated_ollama="$OUTPUT_DIR/ollama-staging"
mkdir -p "$isolated_ollama"
OLLAMA_MODELS="$isolated_ollama/models" OLLAMA_HOST=127.0.0.1:11435 \
ollama serve >"$OUTPUT_DIR/ollama-staging.log" 2>&1 &
ollama_pid=$!
cleanup_ollama() { kill "$ollama_pid" 2>/dev/null || true; }
trap cleanup_ollama EXIT
for _ in $(seq 1 30); do
OLLAMA_HOST=127.0.0.1:11435 ollama list >/dev/null 2>&1 && break
sleep 1
done
for model in $OLLAMA_MODELS; do
OLLAMA_MODELS="$isolated_ollama/models" OLLAMA_HOST=127.0.0.1:11435 \
ollama pull "$model"
done
cleanup_ollama
trap - EXIT
tar -C "$isolated_ollama" -czf "$PAYLOAD_DIR/models/ollama-models.tar.gz" models
rm -rf "$isolated_ollama" "$OUTPUT_DIR/ollama-staging.log"
echo "-> Capturing vLLM Starter model snapshot"
python3 -m pip install --quiet huggingface-hub

View File

@ -23,7 +23,7 @@ for path in "${required[@]}"; do
}
done
for directory in payload/apt payload/containers payload/python payload/models/huggingface; do
for directory in payload/apt payload/containers payload/python/backend payload/python/chromadb payload/python/platform payload/models/huggingface; do
find "$OUTPUT_DIR/$directory" -type f -print -quit | grep -q . || {
echo "ERROR: required offline payload directory is empty: $directory" >&2
exit 1