Open-source project
purpleidea/mgmt avatar
purpleidea/mgmt

purpleidea/mgmt: an event-driven config manager that reacts to time, not just to runs

Next generation distributed, event-driven, parallel config management!

4,327 stars357 forksGoGPL-3.0

At a glance

What is it?
Mgmt is a Go engine and a language, mcl, for closed-loop configuration: it can keep running and change state the moment an input changes. Here is what that buys you, how to build it, and where it stops being the right tool.
Who is it for?
Adopt mgmt if your problem is genuinely stateful or time-dependent: file modes that must flip on a weekday, a resource that should run on at most two hosts out of a pool, anything where a periodic converge is the wrong shape. Do not adopt it as a drop-in replacement for a fleet-wide Puppet or Ansible codebase, because the language and the resource set are its own and the README does not document a migration path.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem mgmt is aimed at: state that must change between runs

Most configuration management tools answer one question on a schedule. What should this machine look like, and does it match? The answer is computed, applied, and then the tool exits until the next run. Mgmt was built around a different question. What should this machine look like right now, and what should happen the instant that answer changes?

The README makes the distinction concrete with a file server whose permissions depend on the day of the week. In a conventional tool you would write a conditional and wait for the next converge to pick up the change. The README's example uses an if expression inside the mode field, and the comment in that snippet states that the mode updates the instant it changes. That is the whole pitch: the graph is live, not recomputed from scratch on a timer.

The audience follows from that. This is for people automating something with a feedback loop, not a checklist. A DHCP server, a TFTP server, a BMC-facing workflow, a cluster where only some hosts should hold a role. The repository layout backs this up: there are top-level directories for dhcp, tftp and mockbmc examples under examples/, and the module list in go.mod includes coredhcp, insomniacslk/dhcp, pin/tftp, bmclib and hcloud. Those are not the dependencies of a tool that only writes files and installs packages.

How mgmt works: an engine, a graph, and mcl as the front end

The README states the project contains an engine and a language, and the repository layout matches that split. The engine/ directory holds the core, pgraph/ holds the graph implementation, lang/ holds the language front end, and cli/ holds the command line. Resources are the nodes; the engine watches for changes and re-evaluates the affected part of the graph rather than replaying the whole configuration.

mcl is the language you write. It has imports, variables, resources with field blocks, and expressions. The README shows two imports by name, datetime and sys, plus world for scheduling. Resources appear as a type name followed by a quoted identifier and a block, as in file "/srv/files/" { ... }. Fields use a fat arrow, so state => $const.res.file.state.exists. That $const reference is worth noting: the language has a built-in constants namespace, and the README's own example uses it rather than a bare string.

The distributed side runs through the scheduler. The README's second example defines a schedule block with a strategy of rr, a max of 2 and a ttl of 10, reads the result with world.schedule("mygroup42"), and tests membership with sys.hostname() in $set. The documented behaviour is that as hosts join and leave, the schedule function re-elects up to two hosts from the pool. That is leader election expressed as a language primitive, and the README says new functions of this kind can be added.

Transport is not spelled out in the README beyond the topic list, which names etcd, and a top-level etcd/ directory in the repository. Treat the clustering story as something to confirm against the documentation site before you design around it.

Building mgmt and running a first real configuration

The README does not give install commands. It points at the official website and lists a quick start guide and an introductory guide under mgmtconfig.com/docs. The repository does contain a Makefile with a build target and a run target, plus run.sh, so building from source is the path the repository itself supports.

The Makefile declares its targets in a .PHONY list at the top, and build, build-debug, run and race are among them. From the repository root, the build target is the shortest route to a binary:

bash
make build

The same Makefile also exposes run, and the repository ships run.sh, which is the quickest way to see the engine start without assembling a service unit by hand:

bash
make run

For a first configuration, start with the README's own file example. Save it as a .mcl file and point the engine at it:

mcl
import "datetime"
$is_friday = datetime.weekday(datetime.now()) == "friday"
file "/srv/files/" {
	state => $const.res.file.state.exists,
	mode => if $is_friday {
		"0550"
	} else {
		"0770"
	},
}

What you should see depends on how you run it. In the continuous mode the README describes, the engine stays resident and the mode field follows the clock; on a Friday the directory becomes read-only without a second invocation. In a one-shot run, the engine converges once and exits, and you get whatever the condition evaluates to at that moment. The repository includes examples/purpleidea.service and examples/purpleidea-oneshot.service, which map onto those two modes.

The README's second example, the schedule block, needs a cluster to be meaningful. Running it on a single host will not exercise the election.

Where mgmt is the wrong tool

The cost of a live graph is that the graph is live. A tool that re-evaluates on change needs a reliable change signal for every input it watches. If your automation is a one-time bootstrap of a machine that then never changes, you are paying for an engine, a language and a resident process to do what a shell script and a package manager already do.

The language is the second constraint. mcl is not YAML and it is not a Puppet or Ansible dialect. Anything you already have has to be rewritten, and the README does not document an import path for existing manifests. The project's own documentation table separates a language guide, a function guide and a resource guide, which tells you the surface area is large enough to need three documents. Budget for learning it.

The third is operational. The README states mgmt is over ten years old and used in production, but it also points bug reporters at a specific step: set the DEBUG constant in main.go to true and post the logs, along with the full mcl code and the exact command used. That is a source-level debugging instruction, not a flag. If your team cannot rebuild the binary to get useful logs, incident response will be slower than you expect.

Finally, the README's own framing is honest about the stage of the ecosystem. It says the scheduling functions are not intrinsic to the core design and that new ones can be added. Useful, but it also means the set of live inputs you can wire up is whatever has been written so far.

mgmt against a pull-based tool like Ansible

The clearest contrast is with Ansible. Ansible connects to hosts, pushes a playbook, applies it, and disconnects. State that drifts between runs stays drifted until the next run. That model is easy to reason about, needs no agent, and scales to thousands of hosts with nothing more than SSH and an inventory file.

Mgmt inverts that. The engine runs on the host, holds a graph, and reacts. The README describes running as a decentralized cluster of agents across your network, each exchanging information with the others in real time. The scheduling example only makes sense in that world: world.schedule("mygroup42") is a live stream of which hosts currently hold a role, and it changes as the pool changes.

So the difference is not speed. It is whether the tool can express a condition that is only knowable at runtime and must be acted on immediately. Ansible can approximate this with polling and cron, and for many fleets that approximation is entirely adequate. Mgmt is for the cases where it is not: where the correct state depends on the current membership of a cluster, or on the clock, and where a five-minute window of wrongness has a cost.

Pick Ansible when your configuration is mostly static and your team already knows it. Pick mgmt when the configuration is a control loop.

Licence, maintenance and what an upgrade costs

Mgmt is GPL-3.0. The Makefile header carries the full notice and adds an additional permission under section 7 covering linking or combining with embedded mcl code and modules under other licences. That additional permission is the part to read closely if you intend to ship mcl modules alongside the binary, because it is the clause that decides whether your combination is conveyable. This is not legal advice; if the combination matters commercially, have someone qualified read section 7 and the additional permission together.

On maintenance, the repository is not archived and the last push was on 2026-09-19. The most recent release listed is 1.1.0 from 2026-06-23, preceded by 1.0.2 in February 2026 and 1.0.1 in October 2025. That is a release cadence measured in months, not weeks.

Upgrade cost is dominated by the language, not the binary. The go.mod file pins go 1.25.7 and a long dependency list including docker, etcd, consul, nftables, bmclib and the AWS SDK. Building from source means tracking those. The README does not document a rollback procedure or a compatibility policy for mcl between releases, so pin the version you build, keep the mcl for each configuration under version control, and re-run your configurations against the new binary before you replace the old one on the fleet.

Editorial conclusion

Adopt mgmt if your problem is genuinely stateful or time-dependent: file modes that must flip on a weekday, a resource that should run on at most two hosts out of a pool, anything where a periodic converge is the wrong shape. Do not adopt it as a drop-in replacement for a fleet-wide Puppet or Ansible codebase, because the language and the resource set are its own and the README does not document a migration path. Before committing, verify three things against the version you build: that the resources you need exist in the resource reference, that your chosen etcd or cluster transport is one the project documents, and that you can read the mcl you wrote six months later.

Frequently asked questions

What is purpleidea/mgmt?

It is a configuration management tool built around an engine and a language called mcl, written in Go and licensed GPL-3.0. The README describes it as a real-time automation tool that can build closed-loop feedback systems, and it can run continuously, intermittently, or on demand.

How do I build purpleidea/mgmt from source?

The README does not list install commands and points at the official website and its quick start guide. The repository ships a Makefile whose .PHONY list includes build and run, along with a run.sh, so building from the checkout is the path the repository itself supports. The go.mod file sets the Go version to 1.25.7.

What does an mcl configuration look like?

The README's example imports datetime, assigns a boolean for whether today is Friday, and then declares a file resource with state and mode fields, where mode uses an if expression. The comment in that snippet states the mode updates the instant it changes.

Can purpleidea/mgmt schedule a resource onto only some hosts?

Yes. The README shows a schedule block with strategy rr, max 2 and ttl 10, read back through world.schedule, with membership tested using sys.hostname(). As hosts are added and removed, the schedule function dynamically elects up to two hosts from the available pool.

What should I include when reporting a bug in purpleidea/mgmt?

The README asks you to set the DEBUG constant in main.go to true, then post the logs along with the full mcl code you used and the exact command you ran. Bugs go to the discussions category for bugs.

Official sources

  1. License: GPL-3.0
  2. Project website
  3. purpleidea/mgmt on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/purpleidea-mgmt.svg)](https://hysenlabs.com/projects/purpleidea-mgmt)