Harden workstation tier handling
This commit is contained in:
parent
10b66569b6
commit
9a1d52230d
@ -1950,9 +1950,15 @@ async def readiness_report(admin: dict = Depends(admin_only)):
|
|||||||
entitlement = _entitlement_summary(feasibility)
|
entitlement = _entitlement_summary(feasibility)
|
||||||
readiness = _readiness_score(feasibility, license_payload)
|
readiness = _readiness_score(feasibility, license_payload)
|
||||||
recommended_tier = (feasibility.get("recommendation") or {}).get("recommended_tier", "starter")
|
recommended_tier = (feasibility.get("recommendation") or {}).get("recommended_tier", "starter")
|
||||||
current_rank = list(TIER_MATRIX.keys()).index(entitlement.get("licensed_tier") or license_payload["tier"])
|
current_tier = entitlement.get("licensed_tier") or license_payload["tier"]
|
||||||
recommended_rank = list(TIER_MATRIX.keys()).index(_normalize_tier(recommended_tier))
|
if license_payload.get("category") == CATEGORY_WORKSTATION or tier_category(current_tier) == CATEGORY_WORKSTATION:
|
||||||
commercial_fit = "matched" if current_rank >= recommended_rank else "license_upgrade_recommended"
|
commercial_fit = "workstation_category"
|
||||||
|
commercial_fit_note = "Workstation is a standalone product category, so Server S/M/L/Max upgrade guidance does not apply directly."
|
||||||
|
else:
|
||||||
|
current_rank = list(TIER_MATRIX.keys()).index(current_tier)
|
||||||
|
recommended_rank = list(TIER_MATRIX.keys()).index(_normalize_tier(recommended_tier))
|
||||||
|
commercial_fit = "matched" if current_rank >= recommended_rank else "license_upgrade_recommended"
|
||||||
|
commercial_fit_note = "Current license covers the recommended deployment." if commercial_fit == "matched" else "Quote a higher tier or reduce enabled features for this hardware."
|
||||||
return {
|
return {
|
||||||
"schema": "cezen.readiness_report.v1",
|
"schema": "cezen.readiness_report.v1",
|
||||||
"generated_at": utcnow(),
|
"generated_at": utcnow(),
|
||||||
@ -1963,10 +1969,10 @@ async def readiness_report(admin: dict = Depends(admin_only)):
|
|||||||
"readiness": readiness,
|
"readiness": readiness,
|
||||||
"commercial_fit": {
|
"commercial_fit": {
|
||||||
"status": commercial_fit,
|
"status": commercial_fit,
|
||||||
"current_tier": entitlement.get("licensed_tier") or license_payload["tier"],
|
"current_tier": current_tier,
|
||||||
"provisioned_tier": entitlement.get("provisioned_tier"),
|
"provisioned_tier": entitlement.get("provisioned_tier"),
|
||||||
"recommended_tier": _normalize_tier(recommended_tier),
|
"recommended_tier": _normalize_tier(recommended_tier),
|
||||||
"note": "Current license covers the recommended deployment." if commercial_fit == "matched" else "Quote a higher tier or reduce enabled features for this hardware.",
|
"note": commercial_fit_note,
|
||||||
},
|
},
|
||||||
"proposal_summary": [
|
"proposal_summary": [
|
||||||
f"Recommended Cezen profile: {(feasibility.get('recommendation') or {}).get('recommended_profile', 'core')}",
|
f"Recommended Cezen profile: {(feasibility.get('recommendation') or {}).get('recommended_profile', 'core')}",
|
||||||
@ -2070,6 +2076,10 @@ async def get_branding():
|
|||||||
result["license_support_until"] = license_record.get("support_until", "")
|
result["license_support_until"] = license_record.get("support_until", "")
|
||||||
result["license_status"] = entitlement.get("license_status", "missing")
|
result["license_status"] = entitlement.get("license_status", "missing")
|
||||||
result["provisioned_tier"] = entitlement.get("provisioned_tier", "")
|
result["provisioned_tier"] = entitlement.get("provisioned_tier", "")
|
||||||
|
tier = result.get("tier_slug")
|
||||||
|
if tier in TIER_MATRIX:
|
||||||
|
result["tier_commercial_label"] = TIER_MATRIX[tier].get("commercial_label", TIER_MATRIX[tier]["label"])
|
||||||
|
result["tier_category"] = TIER_MATRIX[tier].get("category", CATEGORY_SERVER)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@app.put("/api/settings/branding")
|
@app.put("/api/settings/branding")
|
||||||
|
|||||||
@ -399,10 +399,10 @@ python3 - <<'PY'
|
|||||||
import json, os, time
|
import json, os, time
|
||||||
|
|
||||||
# NOTE: install.sh (Phase 2) rewrites /opt/cezen/install-record.json after
|
# NOTE: install.sh (Phase 2) rewrites /opt/cezen/install-record.json after
|
||||||
# this, using its own $TIER routing value ("starter" for Workstation) — this
|
# this. For Workstation, it preserves category="workstation" and selected_tier
|
||||||
# is expected: provisioned_tier there reflects the Ansible profile actually
|
# = "workstation", while provisioned_tier becomes "starter" to reflect the
|
||||||
# installed. The persistent Workstation marker is /opt/cezen/tier, not this
|
# Ansible profile actually installed. The persistent Workstation marker is
|
||||||
# file, and install.sh never touches that marker.
|
# still /opt/cezen/tier, and install.sh never touches that marker.
|
||||||
payload = {
|
payload = {
|
||||||
"schema": "cezen.install_record.v1",
|
"schema": "cezen.install_record.v1",
|
||||||
"customer_name": os.environ.get("CUSTOMER_NAME", "").strip(),
|
"customer_name": os.environ.get("CUSTOMER_NAME", "").strip(),
|
||||||
|
|||||||
17
install.sh
17
install.sh
@ -22,6 +22,8 @@ elif [ -f /opt/aipackage/autoinstall/.tier ]; then
|
|||||||
else
|
else
|
||||||
TIER="basic" # default if no marker found
|
TIER="basic" # default if no marker found
|
||||||
fi
|
fi
|
||||||
|
DISPLAY_TIER="$TIER"
|
||||||
|
PRODUCT_CATEGORY="server"
|
||||||
PHASE="1"
|
PHASE="1"
|
||||||
SKIP_ROLES=""
|
SKIP_ROLES=""
|
||||||
SOFTWARE_ONLY=false
|
SOFTWARE_ONLY=false
|
||||||
@ -55,11 +57,19 @@ done
|
|||||||
|
|
||||||
normalize_tier() {
|
normalize_tier() {
|
||||||
case "$TIER" in
|
case "$TIER" in
|
||||||
|
workstation)
|
||||||
|
DISPLAY_TIER="workstation"
|
||||||
|
PRODUCT_CATEGORY="workstation"
|
||||||
|
TIER="starter"
|
||||||
|
;;
|
||||||
entry|basic) TIER="basic" ;;
|
entry|basic) TIER="basic" ;;
|
||||||
mid|pro) TIER="pro" ;;
|
mid|pro) TIER="pro" ;;
|
||||||
advanced|max) TIER="max" ;;
|
advanced|max) TIER="max" ;;
|
||||||
starter) TIER="starter" ;;
|
starter) TIER="starter" ;;
|
||||||
esac
|
esac
|
||||||
|
if [ "$PRODUCT_CATEGORY" = "server" ]; then
|
||||||
|
DISPLAY_TIER="$TIER"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
normalize_tier
|
normalize_tier
|
||||||
@ -191,7 +201,7 @@ PY
|
|||||||
}
|
}
|
||||||
|
|
||||||
write_install_record() {
|
write_install_record() {
|
||||||
python3 - "$INSTALL_RECORD_JSON" "$TIER" "$PROFILE" "$SKIP_ROLES" "$GPU_AVAILABLE" "$FEASIBILITY_JSON" "$LICENSE_EVAL_JSON" <<'PY'
|
python3 - "$INSTALL_RECORD_JSON" "$TIER" "$PROFILE" "$SKIP_ROLES" "$GPU_AVAILABLE" "$FEASIBILITY_JSON" "$LICENSE_EVAL_JSON" "$DISPLAY_TIER" "$PRODUCT_CATEGORY" <<'PY'
|
||||||
import json, sys
|
import json, sys
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -226,8 +236,9 @@ components = {
|
|||||||
payload = {
|
payload = {
|
||||||
"schema": "cezen.install_record.v1",
|
"schema": "cezen.install_record.v1",
|
||||||
"generated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
|
"generated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
|
||||||
"selected_tier": tier,
|
"selected_tier": sys.argv[8],
|
||||||
"provisioned_tier": tier,
|
"provisioned_tier": tier,
|
||||||
|
"category": sys.argv[9],
|
||||||
"provisioned_profile": profile,
|
"provisioned_profile": profile,
|
||||||
"skip_roles": skip_roles,
|
"skip_roles": skip_roles,
|
||||||
"components": components,
|
"components": components,
|
||||||
@ -413,7 +424,7 @@ run_phase2() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo "╔══════════════════════════════════════════╗"
|
echo "╔══════════════════════════════════════════╗"
|
||||||
echo "║ Nexus One AI installation complete! ║"
|
echo "║ Nexus One AI installation complete! ║"
|
||||||
echo "║ Tier: $(printf '%-33s' "$TIER")║"
|
echo "║ Tier: $(printf '%-33s' "$DISPLAY_TIER")║"
|
||||||
echo "║ ║"
|
echo "║ ║"
|
||||||
echo "║ Portal → http://localhost ║"
|
echo "║ Portal → http://localhost ║"
|
||||||
echo "║ Ollama API → http://localhost:11434 ║"
|
echo "║ Ollama API → http://localhost:11434 ║"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user