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, including installer flows, deployment roles, portal assets, backend services,
licensing enforcement, and the bootable ISO build path. licensing enforcement, and the bootable ISO build path.
The ISO is only one delivery surface. It stays small by pulling this package The ISO is one delivery surface. The online Server installer stays small by
from cgit during setup, then the installer deploys the selected tier and pulling this package and the selected tier payload during setup. Offline
feature set on the target server. installers embed their approved platform payload and starter models, while
large models are delivered as separate signed model packs.
## Product Structure ## Product Structure
@ -43,6 +44,37 @@ Powered by Cezen
four tiers). See [Section 6](#6-tier-and-packaging-guide) and four tiers). See [Section 6](#6-tier-and-packaging-guide) and
[Section 8](#8-features-by-tier). [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 ## Product Collateral
Technical buyer-facing collateral lives in `docs/` for reuse in customer 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 offline installer is deliberately separate from the existing online bootstrap
ISO until disconnected clean-install validation is complete. 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 ## Offline Workstation contents
- the exact `aipackage` source revision used for the build - the exact `aipackage` source revision used for the build

View File

@ -35,10 +35,18 @@ if [ "$available_kb" -lt $((80 * 1024 * 1024)) ]; then
fi fi
rm -rf "$OUTPUT_DIR" 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" echo "-> Capturing pinned appliance source"
git -C "$PACKAGE_DIR" rev-parse HEAD > "$MANIFEST_DIR/source-commit.txt" 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 \ rsync -a --delete \
--exclude '.git/' --exclude '*.iso' --exclude 'offline-output/' \ --exclude '.git/' --exclude '*.iso' --exclude 'offline-output/' \
--exclude 'how-it-flows.gif' \ --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[@]}" -o "Dir::Cache::archives=$PAYLOAD_DIR/apt" "${apt_packages[@]}"
echo "-> Downloading Python wheelhouse" echo "-> Downloading Python wheelhouse"
python3 -m pip download --dest "$PAYLOAD_DIR/python" \ python3 -m pip download --dest "$PAYLOAD_DIR/python/backend" \
-r "$PACKAGE_DIR/ansible/roles/cezen-backend/files/requirements.txt" \ -r "$PACKAGE_DIR/ansible/roles/cezen-backend/files/requirements.txt"
-r "$SCRIPT_DIR/python-packages.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" echo "-> Capturing Miniconda installer"
curl --fail --location --retry 3 "$MINICONDA_URL" \ 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 if ! command -v ollama >/dev/null; then
curl --fail --location --retry 3 https://ollama.com/install.sh | sh curl --fail --location --retry 3 https://ollama.com/install.sh | sh
fi 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" \ tar -C / -czf "$PAYLOAD_DIR/runtime/ollama-runtime.tar.gz" \
usr/local/bin/ollama usr/local/lib/ollama usr/local/bin/ollama usr/local/lib/ollama
ollama_root="${OLLAMA_MODELS_DIR:-/usr/share/ollama/.ollama/models}" isolated_ollama="$OUTPUT_DIR/ollama-staging"
[ -d "$ollama_root" ] || ollama_root="/root/.ollama/models" mkdir -p "$isolated_ollama"
[ -d "$ollama_root" ] || { OLLAMA_MODELS="$isolated_ollama/models" OLLAMA_HOST=127.0.0.1:11435 \
echo "ERROR: Ollama model store not found after pull." >&2 ollama serve >"$OUTPUT_DIR/ollama-staging.log" 2>&1 &
exit 1 ollama_pid=$!
} cleanup_ollama() { kill "$ollama_pid" 2>/dev/null || true; }
tar -C "$(dirname "$ollama_root")" -czf "$PAYLOAD_DIR/models/ollama-models.tar.gz" models 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" echo "-> Capturing vLLM Starter model snapshot"
python3 -m pip install --quiet huggingface-hub python3 -m pip install --quiet huggingface-hub

View File

@ -23,7 +23,7 @@ for path in "${required[@]}"; do
} }
done 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 . || { find "$OUTPUT_DIR/$directory" -type f -print -quit | grep -q . || {
echo "ERROR: required offline payload directory is empty: $directory" >&2 echo "ERROR: required offline payload directory is empty: $directory" >&2
exit 1 exit 1