Last active
January 14, 2026 01:39
-
-
Save ashebanow/0e3d8759a11ed4bc32776a51aca84968 to your computer and use it in GitHub Desktop.
This document defines the structure of pkg.kdl configuration files. NOTE: this is already out of date, but gives the general idea. Rework in progress to provide full Jinja templating support and to improve remote deployment via machine templates (in a different sense than textual templating).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // pkg Configuration File Schema (KDL) | |
| // This document defines the structure of pkg.kdl configuration files. | |
| // NOTE: this is already out of date, but gives the general idea. Rework in | |
| // progress to provide full Jinja templating support and to improve remote | |
| // deployment via machine templates (in a different sense than textual templating). | |
| // | |
| // This schema incorporates: | |
| // - Automatic role library downloads via metadata.ensure | |
| // - User-defined variables via env section | |
| // - Command substitution with security allowlist | |
| // - Package preferences as attributes | |
| // - Flat role library structure (use '/' in names as naming convention) | |
| // - System definitions with package manager priorities | |
| // - Deployment specifications | |
| // - Cargo-style version constraints | |
| // - Multi-instance support via count attribute | |
| // ============================================================================= | |
| // ENVIRONMENT VARIABLES | |
| // ============================================================================= | |
| // User-defined variables (take precedence over system environment variables) | |
| env { | |
| // Custom variables (any name allowed) | |
| USER_ID "johndoe" | |
| PROJECT_NAME "my-project" | |
| DOMAIN "example.com" | |
| EMAIL "user@example.com" | |
| // System configuration | |
| KDL_PATH "$PROJECT_ROOT;$XDG_CONFIG_HOME;$HOME/.local/share;/etc/share" | |
| } | |
| // USAGE: Reference with $VARIABLE_NAME or ${VARIABLE_NAME} throughout config | |
| // Example: hostname "$USER_ID-workstation" // Expands to: johndoe-workstation | |
| // ============================================================================= | |
| // METADATA - Role Library Management | |
| // ============================================================================= | |
| // Controls privacy-aware role bundle acquisition | |
| // Role bundles are automatically downloaded and cached locally | |
| metadata { | |
| // Required: Role bundles to download for privacy-preserving package resolution | |
| // We will automatically download these bundles before resolving packages | |
| ensure "ubuntu-desktop" "development-tools" "gaming-tools" | |
| // Optional: Optimization level for metadata acquisition | |
| optimization "balanced" // "minimal" | "balanced" | "comprehensive" | |
| // Optional: Auto-refresh metadata when stale | |
| auto_refresh true // true | false (default: true) | |
| // Optional: Cache time-to-live for metadata | |
| cache_ttl "24h" // Format: "1h", "6h", "1d", "1w" (default: "24h") | |
| } | |
| // ============================================================================= | |
| // GLOBAL SETTINGS (Defaults that can be overridden) | |
| // ============================================================================= | |
| settings { | |
| // Version of config format (for future compatibility) | |
| version "2.0.0" | |
| // Default package manager preferences (hierarchical - lowest priority) | |
| // Can be overridden by system definitions or machine specs | |
| // Format: space-separated list, left = highest priority | |
| package-manager-preferences platform="ubuntu" "apt" "flatpak" "snap" | |
| package-manager-preferences platform="arch" "yay" "pacman" "flatpak" "snap" | |
| package-manager-preferences platform="macos" "homebrew" | |
| package-manager "dnf" { | |
| copr-repo "foo/bar" | |
| copr-repo "https://coprs.rus/foo/baz" | |
| } | |
| package-manager "yay" { | |
| install-if-needed: true | |
| allow-aur: true # not really needed, but for illustration purposes | |
| } | |
| // Default platform if not specified per machine | |
| default-platform "ubuntu-22.04" | |
| } | |
| // ============================================================================= | |
| // SYSTEM DEFINITIONS (OS-specific configuration) | |
| // ============================================================================= | |
| // Define operating system configurations | |
| // These override global settings for specific OS types | |
| system "ubuntu-desktop" { | |
| // System hierarchy | |
| base "ubuntu" | |
| version "22.04" | |
| atomic false // Whether OS is atomic/immutable (e.g., Fedora Silverblue) | |
| // Package manager priorities (overrides global settings) | |
| package_managers { | |
| "apt" priority=1 | |
| "flatpak" priority=2 | |
| "snap" priority=3 disabled=true // Can explicitly disable | |
| } | |
| } | |
| system "bazzite" { | |
| base "fedora" | |
| version "39" | |
| atomic true // Atomic/immutable OS | |
| package_managers { | |
| "flatpak" priority=1 // Flatpak preferred on atomic systems | |
| "rpm-ostree" priority=2 | |
| } | |
| } | |
| // ============================================================================= | |
| // MACHINE DEFINITIONS | |
| // ============================================================================= | |
| machines { | |
| // Single machine definition | |
| machine "dev-workstation" { | |
| // Required: Machine specifications | |
| specs { | |
| os "ubuntu" // Required: Operating system | |
| arch "amd64" // Required: Architecture (amd64, arm64, x86) | |
| hostname "dev-box" // Optional: Machine hostname | |
| // Optional: Deployment configuration | |
| deploy "distrobox" // Simple: deployment platform | |
| // OR complex deployment with credentials: | |
| // deploy { | |
| // platform "google-cloud" | |
| // token "$(bw get item MY_GCP_TOKEN password)" | |
| // region "us-west1" | |
| // } | |
| } | |
| // Optional: Override package manager priorities for this machine | |
| // (overrides both global settings and system definitions) | |
| package_managers { | |
| "apt" priority=1 | |
| "flatpak" priority=2 | |
| } | |
| // Optional: Roles assigned to this machine | |
| roles { | |
| // Simple role references (strings) | |
| "ubuntu-desktop/core" // '/' in role names is allowed as naming convention | |
| "development-tools/rust" | |
| // Complex role with configuration | |
| tailscale { | |
| auth_token "$(bw get token tailscale_auth)" // Command substitution! | |
| ssh true | |
| accept_routes false | |
| } | |
| // Role with version constraint (Cargo-style) | |
| "development-tools/python" version="^3.11.0" | |
| } | |
| // Optional: Explicit package requirements | |
| packages { | |
| // Simple package references (strings) | |
| "git" | |
| "vim" | |
| // Package with preferences (as attributes - cleaner syntax) | |
| code prefer_flatpak=true version="^1.85.0" | |
| neovim prefer_native=true | |
| firefox version="^120.0.0" | |
| // Package with configuration block | |
| docker { | |
| edition "ce" | |
| compose_version "2.23.0" | |
| } | |
| // Package with version constraint (Cargo-style semantics) | |
| gcc version=">=12.0.0, <14.0.0" // Range | |
| nodejs version="^20.0.0" // Compatible (>=20.0.0, <21.0.0) | |
| python version="3.11.6" // Exact version | |
| } | |
| // Optional: Machine-specific settings | |
| settings { | |
| auto_update true | |
| parallel_installs 6 | |
| } | |
| // Optional: User definitions (for dotfile integration - post-MVP) | |
| users { | |
| user "developer" { | |
| dotfiles-repo "https://github.com/$USER_ID/dotfiles" | |
| dotfiles-manager "chezmoi" | |
| packages { | |
| "tmux" | |
| "htop" | |
| } | |
| } | |
| } | |
| } | |
| // Multi-instance machine (count attribute) | |
| machine "web-server" { | |
| count 5 // Deploy 5 instances with identical configuration | |
| specs { | |
| os "ubuntu" | |
| arch "amd64" | |
| deploy "docker" | |
| } | |
| packages { | |
| "nginx" | |
| nodejs version="^20.0.0" | |
| } | |
| } | |
| // Container-based machine | |
| machine "test-container" { | |
| specs { | |
| os "alpine" | |
| arch "amd64" | |
| deploy { | |
| platform "podman" | |
| network "host" | |
| volumes { | |
| "/data" "/host/data" | |
| } | |
| } | |
| } | |
| packages { | |
| "python" | |
| "pytest" | |
| } | |
| } | |
| } | |
| // ============================================================================= | |
| // ROLE DEFINITIONS (Reusable package bundles) | |
| // ============================================================================= | |
| // Define custom roles that can be referenced by machines | |
| role "my-dev-tools" { | |
| description "Personal development tools" | |
| tags "development" "personal" "terminal" | |
| packages { | |
| "htop" | |
| "tmux" | |
| neovim prefer_native=true | |
| lazygit { | |
| github_username "$EMAIL" | |
| } | |
| } | |
| } | |
| role "work-setup" { | |
| description "Corporate development environment" | |
| tags "work" "development" | |
| packages { | |
| "slack" | |
| "zoom" | |
| code prefer_flatpak=true version="^1.85.0" | |
| } | |
| } | |
| // ============================================================================= | |
| // CUSTOM MAPPINGS (Private repos, custom builds) | |
| // ============================================================================= | |
| custom-mappings { | |
| // Override or add package mappings for private repositories | |
| mapping "internal-tool" { | |
| platform "ubuntu-22.04" | |
| package-manager "apt" | |
| package-name "internal-tool-deb" | |
| repo-url "https://repo.internal.example.com" | |
| } | |
| mapping "custom-build" { | |
| platform "macos-14" | |
| package-manager "homebrew" | |
| package-name "company/custom-build" | |
| repo-url "https://homebrew.company.com" | |
| } | |
| } | |
| // ============================================================================= | |
| // VALIDATION RULES (for implementation reference) | |
| // ============================================================================= | |
| // | |
| // 1. metadata.ensure is required (at least one role bundle) | |
| // 2. metadata.ensure triggers automatic download before package resolution | |
| // 3. env variables are expanded BEFORE system environment variables | |
| // 4. Command substitution $(...) is expanded AFTER variable expansion | |
| // 5. Command substitution security: only allowlisted commands permitted | |
| // 6. settings.version must match parser MAJOR version compatibility | |
| // 7. machines must have at least one machine definition | |
| // 8. machine.specs.os and machine.specs.arch are required | |
| // 9. machine.count defaults to 1 if not specified | |
| // 10. Package manager priorities resolve hierarchically: | |
| // - Global settings (lowest priority) | |
| // - System definitions (medium priority) | |
| // - Machine specs (highest priority) | |
| // 11. Version constraints follow Cargo semantics: | |
| // - "1.2.3" = exactly 1.2.3 | |
| // - "^1.2.0" = >=1.2.0, <2.0.0 (compatible with 1.x) | |
| // - "~1.2.3" = >=1.2.3, <1.3.0 (approximately 1.2.x) | |
| // - ">=1.2.0" = any version >= 1.2.0 | |
| // - ">=1.2.0, <2.0.0" = range (comma-separated constraints) | |
| // 12. Role names can contain '/' as a naming convention (e.g., "desktop/gnome", "dev/python") | |
| // 13. Package preferences are attributes: prefer_native=true, prefer_flatpak=true | |
| // 14. Custom mappings override base definitions (warn on conflicts) | |
| // ============================================================================= | |
| // SMART STRING FEATURES | |
| // ============================================================================= | |
| // | |
| // Strings support environment variable expansion and command substitution | |
| // | |
| // EXPANSION ORDER (important!): | |
| // 1. User-defined variables from env section ($USER_ID, $PROJECT_NAME) | |
| // 2. System environment variables ($HOME, $USER, $PATH) | |
| // 3. Command substitution $(command arg1 arg2) | |
| // | |
| // ENVIRONMENT VARIABLES: | |
| // hostname "$USER_ID-workstation" // → johndoe-workstation | |
| // path "$HOME/.config" // → /home/johndoe/.config | |
| // | |
| // COMMAND SUBSTITUTION (Security: allowlist required): | |
| // auth_token "$(bw get token my_token)" // Bitwarden CLI | |
| // api_key "$(op read op://vault/item/field)" // 1Password CLI | |
| // username "$(whoami)" // Shell command | |
| // current_date "$(date +%Y-%m-%d)" // Date command | |
| // | |
| // SECURITY CONFIGURATION (~/.config/pkg/config.json): | |
| // { | |
| // "security": { | |
| // "allowed_commands": ["bw", "op", "pass", "gpg", "echo", "whoami", "hostname"], | |
| // "command_timeout_seconds": 30 | |
| // } | |
| // } | |
| // | |
| // DEFAULT ALLOWLIST: | |
| // ["bw", "op", "pass", "gpg", "echo", "printf", "date", "whoami", | |
| // "hostname", "uname", "pwd", "env"] | |
| // ============================================================================= | |
| // CARGO-STYLE VERSION CONSTRAINT REFERENCE | |
| // ============================================================================= | |
| // | |
| // pkg uses Cargo's version constraint syntax for flexibility: | |
| // | |
| // EXACT VERSION: | |
| // version="1.2.3" → Exactly 1.2.3 | |
| // | |
| // COMPATIBLE UPDATES (caret ^): | |
| // version="^1.2.3" → >=1.2.3, <2.0.0 (allow 1.x updates) | |
| // version="^0.2.3" → >=0.2.3, <0.3.0 (0.x is unstable) | |
| // version="^0.0.3" → >=0.0.3, <0.0.4 (0.0.x is very unstable) | |
| // | |
| // APPROXIMATE UPDATES (tilde ~): | |
| // version="~1.2.3" → >=1.2.3, <1.3.0 (allow patch updates) | |
| // version="~1.2" → >=1.2.0, <1.3.0 (equivalent) | |
| // | |
| // COMPARISON OPERATORS: | |
| // version=">=1.2.0" → Any version >= 1.2.0 | |
| // version=">1.2.0" → Any version > 1.2.0 | |
| // version="<2.0.0" → Any version < 2.0.0 | |
| // version="<=1.9.9" → Any version <= 1.9.9 | |
| // | |
| // RANGES (comma-separated): | |
| // version=">=1.2.0, <2.0.0" → Between 1.2.0 and 2.0.0 | |
| // version=">=1.2.0, <1.3.0" → Patch updates only | |
| // | |
| // WILDCARD (*): | |
| // version="1.2.*" → >=1.2.0, <1.3.0 (any patch in 1.2.x) | |
| // version="1.*" → >=1.0.0, <2.0.0 (any minor in 1.x) | |
| // | |
| // WHY CARGO SEMANTICS? | |
| // - Industry-standard (Rust, JavaScript npm uses similar) | |
| // - Expressive: supports exact, compatible, approximate, ranges | |
| // - Safe defaults: ^ prevents breaking changes | |
| // - Familiar: developers already know this from other tools | |
| // | |
| // EXAMPLES IN CONTEXT: | |
| // nodejs version="^20.0.0" → Latest 20.x (21.x would be breaking) | |
| // python version="3.11.*" → Any 3.11.x (3.12.x is different) | |
| // gcc version=">=12.0, <14.0" → GCC 12.x or 13.x (not 14.x) | |
| // ============================================================================= | |
| // EXAMPLE: Complete Multi-Machine Configuration | |
| // ============================================================================= | |
| // | |
| // env { | |
| // USER_ID "johndoe" | |
| // COMPANY_DOMAIN "example.com" | |
| // } | |
| // | |
| // metadata { | |
| // ensure "ubuntu-desktop" "development-tools" "gaming-tools" | |
| // optimization "balanced" | |
| // cache_ttl "6h" | |
| // } | |
| // | |
| // settings { | |
| // version "2.0.0" | |
| // package-manager-preferences platform="ubuntu" "apt" "flatpak" "snap" | |
| // } | |
| // | |
| // system "ubuntu-desktop" { | |
| // base "ubuntu" | |
| // version "22.04" | |
| // atomic false | |
| // package_managers { | |
| // "apt" priority=1 | |
| // "flatpak" priority=2 | |
| // } | |
| // } | |
| // | |
| // machines { | |
| // machine "workstation" { | |
| // specs { | |
| // os "ubuntu" | |
| // arch "amd64" | |
| // hostname "$USER_ID-workstation" | |
| // deploy "distrobox" | |
| // } | |
| // | |
| // roles { | |
| // "ubuntu-desktop/core" | |
| // tailscale { | |
| // auth_token "$(bw get token tailscale_$USER_ID)" | |
| // ssh true | |
| // } | |
| // } | |
| // | |
| // packages { | |
| // "git" | |
| // code prefer_flatpak=true version="^1.85.0" | |
| // docker { | |
| // edition "ce" | |
| // } | |
| // } | |
| // | |
| // settings { | |
| // auto_update true | |
| // parallel_installs 6 | |
| // } | |
| // } | |
| // | |
| // machine "web-server" { | |
| // count 5 | |
| // | |
| // specs { | |
| // os "ubuntu" | |
| // arch "amd64" | |
| // deploy { | |
| // platform "google-cloud" | |
| // token "$(bw get item GCP_TOKEN password)" | |
| // region "us-west1" | |
| // } | |
| // } | |
| // | |
| // packages { | |
| // "nginx" | |
| // nodejs version="^20.0.0" | |
| // } | |
| // } | |
| // } | |
| // | |
| // role "my-dev-tools" { | |
| // description "Personal development stack" | |
| // tags "development" "personal" | |
| // packages { | |
| // "htop" | |
| // "tmux" | |
| // neovim prefer_native=true | |
| // } | |
| // } | |
| // | |
| // custom-mappings { | |
| // mapping "internal-api" { | |
| // platform "ubuntu-22.04" | |
| // package-manager "apt" | |
| // repo-url "https://repo.${COMPANY_DOMAIN}" | |
| // } | |
| // } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment