In just released Propellor 0.3.0, I've improved improved Propellor's config file DSL significantly. Now properties can set attributes of a host, that can be looked up by its other properties, using a Reader monad.
This saves needing to repeat yourself:
hosts = [ host "orca.kitenet.net" & stdSourcesList Unstable & Hostname.sane -- uses hostname from above
And it simplifies docker setup, with no longer a need to differentiate between properties that configure docker vs properties of the container:
-- A generic webserver in a Docker container. , Docker.container "webserver" "joeyh/debian-unstable" & Docker.publish "80:80" & Docker.volume "/var/www:/var/www" & Apt.serviceInstalledRunning "apache2"
But the really useful thing is, it allows automating DNS zone file creation, using attributes of hosts that are set and used alongside their other properties:
hosts = [ host "clam.kitenet.net" & ipv4 "10.1.1.1" & cname "openid.kitenet.net" & Docker.docked hosts "openid-provider" & cname "ancient.kitenet.net" & Docker.docked hosts "ancient-kitenet" , host "diatom.kitenet.net" & Dns.primary "kitenet.net" hosts ]
hosts is passed into
Dns.primary, inside the definition
hosts! Tying the knot like this is a fun haskell laziness trick. :)
Now I just need to write a little function to look over the hosts and generate a zone file from their hostname, cname, and address attributes:
extractZoneFile :: Domain -> [Host] -> ZoneFile extractZoneFile = gen . map hostAttr where gen = -- TODO
The eventual plan is that the
cname property won't be defined as a
property of the host, but of the container running inside it.
Then I'll be able to cut-n-paste move docker containers between hosts,
or duplicate the same container onto several hosts to deal with load,
and propellor will provision them, and update the zone file appropriately.
Also, Chris Webber had suggested that Propellor be able to separate values from properties, so that eg, a web wizard could configure the values easily. I think this gets it much of the way there. All that's left to do is two easy functions:
overrideAttrsFromJSON :: Host -> JSON -> Host exportJSONAttrs :: Host -> JSON
With these, propellor's configuration could be adjusted at run time using JSON from a file or other source. For example, here's a containerized webserver that publishes a directory from the external host, as configured by JSON that it exports:
demo :: Host demo = Docker.container "webserver" "joeyh/debian-unstable" & Docker.publish "80:80" & dir_to_publish "/home/mywebsite" -- dummy default & Docker.volume (getAttr dir_to_publish ++":/var/www") & Apt.serviceInstalledRunning "apache2" main = do json <- readJSON "my.json" let demo' = overrideAttrsFromJSON demo writeJSON "my.json" (exportJSONAttrs demo') defaultMain [demo']