A C implementation of a Puppet language parser and interpreter using tree-sitter.
Note: This is an experimental project. It implements a subset of the Puppet language and is not a replacement for the real Puppet.
Prerequisites:
- GCC
- libtree-sitter (tree-sitter runtime library)
- Ruby 3.0-3.3 with development headers (for ERB templates)
- Ruby 3.4+ has incompatible embedding API changes
- Recommended: Ruby 3.2 or 3.3
- libyaml (for Hiera)
- libssl/openssl (for crypto functions)
- libmicrohttpd (for puppetc-server)
- libcurl (for puppetc-agent)
- libsqlite3 (for PuppetDB)
macOS (Homebrew):
brew install pkg-config tree-sitter ruby@3.3 libyaml openssl libmicrohttpd curl sqlite3 autoconf automake libtoolDebian/Ubuntu (APT):
sudo apt-get install build-essential autoconf automake libtool \
libtree-sitter-dev ruby3.0-dev libyaml-dev libssl-dev \
libmicrohttpd-dev libcurl4-openssl-dev libsqlite3-devLinux:
./autogen.sh
./configure
make
make checkmacOS (with Homebrew dependencies):
./autogen.sh
./configure \
--with-treesitter=/opt/homebrew/opt/tree-sitter \
--with-ruby=/opt/homebrew/opt/ruby@3.3 \
--with-yaml=/opt/homebrew/opt/libyaml \
--with-openssl=/opt/homebrew/opt/openssl \
--with-microhttpd=/opt/homebrew/opt/libmicrohttpd \
--with-curl=/opt/homebrew/opt/curl \
--with-sqlite=/opt/homebrew/opt/sqlite3
make
make checkNote: On Intel Macs, use /usr/local/opt/ instead of /opt/homebrew/opt/.
Build and run using Docker (no dependencies needed on host).
Sample manifests, modules, and hiera data are provided in puppetcode/ (shared with Vagrant).
# Build images
docker-compose build
# Start server
docker-compose up -d server
# Run agent once (noop mode)
docker-compose run --rm agent
# Run agent once (apply mode)
docker-compose run --rm agent -a
# Interactive shell for multiple agent runs
docker-compose up -d agent-shell
docker-compose exec agent-shell bash
# Inside container:
# puppetc-agent -n # noop mode
# puppetc-agent -a # apply modeEdit puppetcode/manifests/site.pp on your host - changes are reflected immediately in the server.
# Parse only
./compiler/puppetc-compile manifest.pp
# Parse and evaluate
./compiler/puppetc-compile -e manifest.pp
# With facts
./compiler/puppetc-compile -e -f facts.json manifest.pp
# Compile to catalog JSON
./compiler/puppetc-compile -c manifest.pp
# JSON AST output
./compiler/puppetc-compile -j manifest.ppRun ./compiler/puppetc-compile --help for all options.
# Start server (pass base directory, not manifests/)
./server/puppetc-server -p 8140 /etc/puppet
# With PuppetDB enabled
./server/puppetc-server -p 8140 -P /var/lib/puppetc/puppetdb.sqlite /etc/puppet
# Compile catalog via API
curl -X POST http://localhost:8140/puppet/v4/catalog \
-H 'Content-Type: application/json' \
-d '{"certname": "node1.example.com", "facts": {"hostname": "node1"}}'The server includes an embedded SQLite-based PuppetDB for storing facts and catalogs.
# Query all nodes
curl http://localhost:8140/pdb/query/v4/nodes
# Get facts for a node
curl http://localhost:8140/pdb/query/v4/facts/node1.example.com
# Get catalog for a node
curl http://localhost:8140/pdb/query/v4/catalogs/node1.example.com# Show all facts
./facter/facter_c
# Specific facts
./facter/facter_c hostname ipaddress osfamily
# JSON output
./facter/facter_c -j# Run agent (connects to localhost:8140)
./agent/puppetc-agent
# Apply catalog resources
./agent/puppetc-agent -a
# No-op mode (show what would change)
./agent/puppetc-agent -n
# Specify server
./agent/puppetc-agent -s http://puppet:8140 -a
# Just show collected facts
./agent/puppetc-agent -f- Basic parsing of classes, resources, nodes, defines
- Conditionals: if/elsif/else, unless, case, ternary, selector
- Variable scoping and interpolation, multi-line strings
- ERB templates (via embedded Ruby)
- Hiera lookups (YAML backend)
- Module autoloading
- Virtual resources (
@resource),realize(), collectors (<| |>), and exported collectors (<<| |>>) - Iterator functions:
each(),map(),filter(),reduce() - PuppetDB (SQLite): stores facts and catalogs, query API
- Many stdlib functions (see below)
- Resource providers for: file, package, service, exec, cron, host, group, user, sysctl, mount
- Type matching: The
=~ Typesyntax (e.g.,$var =~ String) is parsed but not yet evaluated
- Exported resources: The
@@resourcesyntax is parsed but exported resources are not yet sent to PuppetDB for cross-node collection - Resource relationships: Chaining arrows (
->,~>) have limited support - Incomplete stdlib coverage: Many stdlib functions are implemented but not all
- No pluginsync: Custom facts and functions must be pre-installed
- Single-threaded server: The catalog server handles requests sequentially
Logging: notice, info, warning, debug, err, fail
Strings: split, join, chomp, strip, upcase, downcase, capitalize, match, regsubst
Arrays: concat, flatten, unique, sort, reverse, first, last, length, member, range
Hashes: keys, values, has_key, merge
Numeric: abs, floor, ceil, round, sqrt, min, max
Types: is_string, is_array, is_hash, is_numeric, is_bool, defined
Path: basename, dirname, extname
Crypto: sha1, md5, base64
Data: lookup
Iterators: each, map, filter, reduce
Resources: realize
The agent supports the following resource types:
| Resource | Description |
|---|---|
| file | Manage files, directories, and symlinks. Supports puppet:/// URLs |
| package | Install/remove packages (apt, dnf) |
| service | Manage systemd services |
| exec | Execute commands with conditions |
| cron | Manage cron jobs |
| host | Manage /etc/hosts entries |
| group | Manage system groups |
| user | Manage system users |
| sysctl | Manage kernel parameters via /proc/sys and /etc/sysctl.d |
| mount | Manage filesystem mounts and /etc/fstab |
| notify | Log messages during catalog application |
┌─────────────────────────────────────────────────────────────┐
│ Libraries │
├─────────────────────┬───────────────────────────────────────┤
│ libpuppetc │ libfacter_c │
│ - Tree-sitter │ - Native fact collection │
│ - AST │ - JSON fact loading │
│ - Interpreter │ - System info (hostname, os, etc.) │
│ - Stdlib │ │
│ - Hiera │ │
│ - Catalog builder │ │
└─────────────────────┴───────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ puppetc-server │ │ puppetc-agent │ │ puppetc-compile │
│ │ │ │ │ │
│ - REST API │ │ - Collect facts │ │ - Parse/eval │
│ - Compile │ │ - Request catalog│ │ - JSON output │
│ catalogs │ │ - Apply catalog │ │ - Catalog gen │
│ - PuppetDB │ │ │ │ │
│ (SQLite) │ │ │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘