Skip to content

Instantly share code, notes, and snippets.

@ashebanow
Last active January 14, 2026 01:39
Show Gist options
  • Select an option

  • Save ashebanow/0e3d8759a11ed4bc32776a51aca84968 to your computer and use it in GitHub Desktop.

Select an option

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).
// 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