Define manifest.json schema and validation

t-266.4·WorkTask·
·
·
·Omni/Deploy.hs
Parent:t-266·Created2 months ago·Updated2 months ago

Description

Edit

Create Pydantic models for manifest.json schema.

Files to Create

  • Omni/Deploy/Manifest.py - Schema definitions and S3 helpers

Schema (Pydantic v2)

from pydantic import BaseModel
from typing import Optional
from datetime import datetime

class Artifact(BaseModel):
    type: str = "nix-closure"  # future: "docker-image"
    storePath: str

class Exec(BaseModel):
    command: Optional[str] = None  # default: bin/<name>
    user: str = "root"
    group: str = "root"

class Http(BaseModel):
    domain: str
    path: str = "/"
    internalPort: int

class Systemd(BaseModel):
    after: list[str] = ["network-online.target"]
    requires: list[str] = []
    restart: str = "on-failure"
    restartSec: int = 5

class Hardening(BaseModel):
    dynamicUser: bool = False
    privateTmp: bool = True
    protectSystem: str = "strict"
    protectHome: bool = True

class Service(BaseModel):
    name: str
    artifact: Artifact
    hosts: list[str] = ["biz"]
    exec: Exec = Exec()
    env: dict[str, str] = {}
    envFile: Optional[str] = None
    http: Optional[Http] = None
    systemd: Systemd = Systemd()
    hardening: Hardening = Hardening()
    revision: Optional[str] = None

class Manifest(BaseModel):
    version: int = 1
    generation: datetime
    services: list[Service]

S3 Helper Functions

def load_manifest_from_s3(bucket: str, key: str = "manifest.json") -> Manifest:
    """Fetch and parse manifest from S3."""

def save_manifest_to_s3(manifest: Manifest, bucket: str, key: str = "manifest.json"):
    """Save manifest to S3, archiving old version first."""

def archive_manifest(bucket: str, manifest: Manifest):
    """Copy current manifest to manifests/manifest-<timestamp>.json."""

Dependencies

Add to Omni/Bild/Deps/Python.nix:

  • pydantic
  • boto3

Testing

bild --test Omni/Deploy/Manifest.py

Note on Python conventions

This codebase uses 'import X as Y' pattern, NOT 'from X import Y'. See AGENTS.md.

Timeline (2)

🔄[human]Open → InProgress2 months ago
🔄[human]InProgress → Done2 months ago