Document installer release architecture
This commit is contained in:
parent
21bca7de3f
commit
bea082a201
38
README.md
38
README.md
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user