propellor-2.10.0: property-based host configuration management in haskell

Safe HaskellNone




data ControlHeir Source

A hierarchy of control. When propellor is run on a host that is a Controller, it in turn spins each of the hosts in its control list.

There can be multiple levels of controllers in the hierarchy.

Multiple controllers can control the same hosts. However, when propellor is already running on a host, a controller will fail to spin it. So, if two controllers both try to control the same host at the same time, one will fail.

(Loops in the hierarchy, such as a host controlling itself, are detected and automatically broken.)

data ControlList Source


ControlList [ControlHeir]

A list of hosts to control. Failure to spin one host does not prevent spinning later hosts in the list.

ControlReq ControlHeir ControlList

Requires the first host to be successfully spinned before proceeding to spin the hosts in the ControlList.

addControlHeir :: [Host] -> ControlHeir -> [Host] Source

Applies a ControlHeir to a list of hosts.

This eliminates the need to manually run propellor --spin to update the controlled hosts. Each time propellor is run on the controller host, it will in turn run propellor on each of the controlled Hosts.

The controller needs to be able to ssh to the hosts it controls, and run propellor, as root. To this end, the knownHost property is added to the controller, so it knows the host keys of the hosts it controlls.

Each controlled host is configured to let its controller ssh in as root. This is done by adding the authorizedKeysFrom property, with `User "root"`.

It's left up to you to use userKeys to configure the ssh keys for the root user on controller hosts, and to use hostKeys to configure the host keys for the controlled hosts.

For example, if you have some webservers and a dnsserver, and want a master that runs propellor on all of them:

 import Propellor
 import Propellor.Property.ControlHeir
 import qualified Propellor.Property.Ssh as Ssh
 import qualified Propellor.Property.Cron as Cron
 main = defaultMain (hosts `addControlHeir` control)

 hosts =
 	[ master
	, dnsserver
	] ++ webservers
 control = Controller master (ControlList (map Controlled (dnsserver:webservers)))

 dnsserver = host ""
	& Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB3BJ2GqZiTR2LEoDXyYFgh/BduWefjdKXAsAtzS9zeI")]
	& ...
 webservers =
    [ host ""
		& Ssh.hostKeys hostContext [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICfFntnesZcYz2B2T41ay45igfckXRSh5uVffkuCQkLv")]
		& ...
	, ...

 master = host ""
	& Ssh.userKeys (User "root") [(SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWD0Hau5FDLeNrDHKilNMKm9c68R3WD+NJOp2jPWvJV")]
	& Cron.runPropellor

Note that a controller can see all PrivData of the hosts below it in the ControlHeir.

newtype ControllerOf Source

Each Host's info contains a list of the names of hosts it's controlling.


ControllerOf [HostName]