Add signed licensing enforcement and ISO notes

This commit is contained in:
Jino Jose committed 2026-07-08 10:47:49 +05:30
1 parent dee4486826
commit d645249a13
14 files changed
+1526 -103

No files matched your search

+128
View File
@@ -31,7 +31,12 @@ PROFILE="auto"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ANSIBLE_DIR="$SCRIPT_DIR/ansible"
FEASIBILITY_SCRIPT="$SCRIPT_DIR/scripts/cezen-feasibility.sh"
LICENSE_CHECK_SCRIPT="$SCRIPT_DIR/scripts/cezen-license-check.py"
FEASIBILITY_JSON="/opt/cezen/feasibility.json"
LICENSE_JSON="/opt/cezen/license.json"
OVERRIDE_JSON="/opt/cezen/license.override.json"
INSTALL_RECORD_JSON="/opt/cezen/install-record.json"
PUBLIC_KEY_PATH="${CEZEN_LICENSE_PUBLIC_KEY:-$SCRIPT_DIR/autoinstall/keys/cezen-license-public.pem}"
# Load saved config (written by web setup UI before phase 1)
[ -f /opt/cezen/install.conf ] && source /opt/cezen/install.conf
@@ -119,6 +124,126 @@ except Exception:
PY
}
license_eval_field() {
local expr="$1"
python3 - "$LICENSE_EVAL_JSON" "$expr" <<'PY'
import json, sys
try:
d=json.load(open(sys.argv[1]))
cur=d
for part in sys.argv[2].split("."):
cur=cur[part]
print(cur)
except Exception:
print("")
PY
}
run_license_evaluation() {
LICENSE_EVAL_JSON="/tmp/cezen-license-eval.json"
if [ -f "$LICENSE_CHECK_SCRIPT" ]; then
python3 "$LICENSE_CHECK_SCRIPT" \
--license "$LICENSE_JSON" \
--override "$OVERRIDE_JSON" \
--feasibility "$FEASIBILITY_JSON" \
--public-key "$PUBLIC_KEY_PATH" > "$LICENSE_EVAL_JSON"
else
echo "ERROR: License checker not found: $LICENSE_CHECK_SCRIPT"
exit 1
fi
}
enforce_tier_constraints() {
run_license_evaluation
local license_status allowed_tier hardware_tier selected_state
license_status="$(license_eval_field license.status)"
allowed_tier="$(license_eval_field license.allowed_tier)"
hardware_tier="$(license_eval_field hardware.recommended_tier)"
selected_state="$(python3 - "$LICENSE_EVAL_JSON" "$TIER" <<'PY'
import json, sys
d=json.load(open(sys.argv[1]))
tier=sys.argv[2]
for opt in d.get("tier_options", []):
if opt.get("tier") == tier:
print(opt.get("state", "disabled_by_license"))
break
else:
print("disabled_by_license")
PY
)"
echo "→ License status: ${license_status:-missing} | Allowed tier: ${allowed_tier:-basic} | Hardware tier: ${hardware_tier:-starter}"
case "$selected_state" in
enabled|override_required)
;;
disabled_by_license)
echo "ERROR: Selected tier '$TIER' exceeds the current license allowance (${allowed_tier:-basic})."
exit 1
;;
disabled_by_hardware)
echo "ERROR: Selected tier '$TIER' exceeds hardware feasibility (${hardware_tier:-starter})."
exit 1
;;
*)
echo "ERROR: Selected tier '$TIER' is not allowed (state: $selected_state)."
exit 1
;;
esac
}
write_install_record() {
python3 - "$INSTALL_RECORD_JSON" "$TIER" "$PROFILE" "$SKIP_ROLES" "$GPU_AVAILABLE" "$FEASIBILITY_JSON" "$LICENSE_EVAL_JSON" <<'PY'
import json, sys
from datetime import datetime, timezone
from pathlib import Path
out = Path(sys.argv[1])
tier = sys.argv[2]
profile = sys.argv[3]
skip_roles = [r for r in sys.argv[4].split(",") if r]
gpu_available = sys.argv[5].lower() == "true"
feasibility = {}
license_eval = {}
for src, dest in ((sys.argv[6], "feasibility"), (sys.argv[7], "license_eval")):
try:
with open(src) as fh:
data = json.load(fh)
if dest == "feasibility":
feasibility = data
else:
license_eval = data
except Exception:
pass
components = {
"ollama": "ollama" not in skip_roles,
"jupyterlab": "jupyterlab" not in skip_roles,
"chromadb": "chromadb" not in skip_roles,
"vllm": "vllm" not in skip_roles,
"mlflow": "mlflow" not in skip_roles,
"minio": "minio" not in skip_roles,
"monitoring": "monitoring" not in skip_roles,
"k3s": "k3s" not in skip_roles,
}
payload = {
"schema": "cezen.install_record.v1",
"generated_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
"selected_tier": tier,
"provisioned_tier": tier,
"provisioned_profile": profile,
"skip_roles": skip_roles,
"components": components,
"gpu_available": gpu_available,
"hardware_recommended_tier": ((feasibility.get("recommendation") or {}).get("recommended_tier") or "starter"),
"hardware_recommended_profile": ((feasibility.get("recommendation") or {}).get("recommended_profile") or "core"),
"licensed_tier": (((license_eval.get("license") or {}).get("allowed_tier")) or "basic"),
"license_status": ((license_eval.get("license") or {}).get("status") or "missing"),
"install_type": ((license_eval.get("license") or {}).get("install_type") or "field-staging"),
"override_active": bool(((license_eval.get("override") or {}).get("allow_hardware_mismatch"))),
}
out.parent.mkdir(parents=True, exist_ok=True)
out.write_text(json.dumps(payload, indent=2))
PY
}
apply_profile_from_feasibility() {
[ -f "$FEASIBILITY_JSON" ] || return 0
local detected_profile
@@ -263,6 +388,7 @@ run_phase2() {
echo "→ Tier: $TIER | Skip: ${SKIP_ROLES:-none}"
echo "→ GPU available: $GPU_AVAILABLE"
echo "→ Skip model pull: $SKIP_MODEL_PULL"
write_install_record
# Select Ansible playbook by tier
case "$TIER" in
@@ -311,6 +437,8 @@ if [ "$SOFTWARE_ONLY" = true ]; then
PHASE="2"
fi
enforce_tier_constraints
install_ansible
if [ "$PHASE" = "1" ]; then