This module adds conductors to propellor. A conductor is a Host that is responsible for running propellor on other hosts
This eliminates the need to manually run propellor --spin to update the conducted hosts, and can be used to orchestrate updates to hosts.
The conductor needs to be able to ssh to the hosts it conducts,
and run propellor, as root. To this end,
knownHost property is automatically
added to the conductor, so it knows the host keys of the relevant hosts.
Also, each conducted host is configured to let its conductor
ssh in as root, by automatically adding the
For example, if you have some webservers and a dnsserver, and want the master host to conduct all of them:
import Propellor import Propellor.Property.Conductor import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Cron as Cron main = defaultMain (orchestrate hosts) hosts = [ master , dnsserver ] ++ webservers dnsserver = host "dns.example.com" & Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3BJ2GqZiTR2LEoDXyYFgh/BduWefjdKXAsAtzS9zeI")] & ... webservers = [ host "www1.example.com" & Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfFntnesZcYz2B2T41ay45igfckXRSh5uVffkuCQkLv")] & ... , ... ] master = host "master.example.com" & Ssh.userKeys (User "root") [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWD0Hau5FDLeNrDHKilNMKm9c68R3WD+NJOp2jPWvJV")] & conducts webservers `before` conducts dnsserver & Cron.runPropellor
Notice that, in the above example, the the webservers are conducted first. Only once the webservers have successfully been set up is the dnsserver updated. This way, when adding a new web server, the dns won't list it until it's ready.
There can be multiple conductors, and conductors can conduct other conductors if you need such a hierarchy. (Loops in the hierarchy, such as a host conducting itself, are detected and automatically broken.)
While it's allowed for a single host to be conducted by multiple conductors, the results can be discordent. Since only one propellor process can be run on a host at a time, one of the conductors will fail to communicate with it.
Note that a conductor can see all PrivData of the hosts it conducts.
Pass this a list of all your hosts; it will finish setting up
orchestration as configured by the
conducts properties you add to
main = defaultMain $ orchestrate hosts
Class of things that can be conducted.
There are instances for single hosts, and for lists of hosts. With a list, each listed host will be conducted in turn. Failure to conduct one host does not prevent conducting subsequent hosts in the list, but will be propagated as an overall failure of the property.