Over the past few weeks things have been pretty hectic. Since I'm not working at the moment I'm mostly doing childcare instead. I need a break, now and again, so I've been sending our child to päiväkoti two days a week with him home the rest of the time.
I love taking care of the child, because he's seriously awesome, but it's a hell of a lot of work when most of our usual escapes are unavailable. For example we can't go to the (awesome) Helsinki Central Library as that is closed.
Instead of doing things outdoors we've been baking bread together, painting, listening to music and similar. He's a big fan of any music with drums and shouting, so we've been listening to Rammstein, The Prodigy, and as much Queen as I can slip in without him complaining ("more bang bang!").
I've also signed up for some courses at the Helsinki open university, including Devops with Docker so perhaps I have a future career working with computers? I'm hazy.
Finally I saw a fun post the other day on reddit asking about the creation of a DSL for server-setup. I wrote a reply which basically said two things:
- First of all you need to define the minimum set of primitives you can execute.
- (Creating a file, fetching a package, reloading services when a configuration file changes, etc.)
- Then you need to define a syntax for expressing those rules.
- Not using YAML. Because Ansible fucked up bigtime with that.
- It needs to be easy to explain, it needs to be consistent, and you need to decide before you begin if you want "toy syntax" or "programming syntax".
- Because adding on conditionals, loops, and similar, will ruin everything if you add it once you've started with the wrong syntax. Again, see Ansible.
Anyway I had an idea of just expressing things in a simple fashion, borrowing Puppet syntax (which I guess is just Ruby hash literals). So a module to do stuff with files would just look like this:
file { name => "This is my rule",
target => "/tmp/blah",
ensure => "absent" }
The next thing to do is to allow that to notify another rule, when it results in a change. So you add in:
notify => "Name of rule"
# or
notify => [ "Name of rule", "Name of another rule" ]
You could also express dependencies the other way round:
shell { name => "Do stuff",
command => "wc -l /etc/passwd > /tmp/foo",
requires => [ "Rule 1", "Rule 2"] }
Anyway the end result is a simple syntax which allows you to do things; I wrote a file to allow me to take a clean system and configure it to run a simple golang application in an hour or so.
The downside? Well the obvious one is that there's no support for setting up cron
jobs, setting up docker images, MySQL usernames/passwords, etc. Just a core set of primitives.
Adding new things is easy, but also an endless job. So I added the ability to run external/binary plugins stored outside the project. To support that is simple with the syntax we have:
- We pass the parameters, as JSON, to STDIN of the binary.
- We read the result from STDOUT
- Did the rule result in a change to the system?
- Or was it a NOP?
All good. People can write modules, if they like, and they can do that in any language they like.
Fun times.
We'll call it marionette since it's all puppet-inspired:
And that concludes this irregular update.
Tags: github, marionette, markdownshare, oodi, puppet, university 4 comments
https://mjturner.net
Couldn’t agree with you more about Ansible’s choice of YAML… Just thought I’d drop you a line to mention that there’s already a puppet-related project that references marionettes - https://puppet.com/docs/mcollective/current/index.html