propellor 0.8.3 → 0.9.0
raw patch · 26 files changed
+387/−322 lines, 26 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Propellor.Property.Ssh: restartSshd :: Property
- Propellor.Property.Tor: restartTor :: Property
- Propellor.Types.OS: DebianRelease :: Release -> DebianSuite
- Propellor.Types.OS: stableRelease :: DebianSuite
+ Propellor.Property.Docker: tweaked :: Property
+ Propellor.Property.Ssh: restarted :: Property
+ Propellor.Property.Tor: restarted :: Property
- Propellor.Property.Apt: backportSuite :: String
+ Propellor.Property.Apt: backportSuite :: DebianSuite -> Maybe String
- Propellor.Types.OS: Stable :: DebianSuite
+ Propellor.Types.OS: Stable :: Release -> DebianSuite
Files
- CHANGELOG +15/−0
- README.md +2/−3
- config-joey.hs +223/−233
- config-simple.hs +1/−1
- config.hs +1/−1
- debian/changelog +15/−0
- doc/README.mdwn +2/−3
- propellor.cabal +1/−1
- src/Propellor/CmdLine.hs +5/−4
- src/Propellor/PrivData.hs +1/−1
- src/Propellor/Property.hs +1/−1
- src/Propellor/Property/Apache.hs +1/−1
- src/Propellor/Property/Apt.hs +20/−14
- src/Propellor/Property/Cmd.hs +1/−1
- src/Propellor/Property/Dns.hs +3/−3
- src/Propellor/Property/Docker.hs +37/−15
- src/Propellor/Property/Obnam.hs +3/−3
- src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs +7/−4
- src/Propellor/Property/SiteSpecific/JoeySites.hs +23/−9
- src/Propellor/Property/Ssh.hs +10/−9
- src/Propellor/Property/Sudo.hs +1/−1
- src/Propellor/Property/Tor.hs +4/−3
- src/Propellor/SimpleSh.hs +2/−2
- src/Propellor/Types.hs +2/−2
- src/Propellor/Types/OS.hs +5/−6
- src/config.hs +1/−1
CHANGELOG view
@@ -1,3 +1,18 @@+propellor (0.9.0) unstable; urgency=medium++ * Avoid encoding the current stable suite in propellor's code,+ since that poses a difficult transition around the release,+ and can easily be wrong if an older version of propellor is used.+ Instead, the os property for a stable system includes the suite name+ to use, eg Stable "wheezy".+ * stdSourcesList uses the stable suite name, to avoid unwanted+ immediate upgrades to the next stable release.+ * debCdn switched from cdn.debian.net to http.debian.net, which seems to be+ better managed now.+ * Docker: Avoid committing container every time it's started up.++ -- Joey Hess <joeyh@debian.org> Fri, 10 Oct 2014 11:37:45 -0400+ propellor (0.8.3) unstable; urgency=medium * The Debian package now includes a single-revision git repository in
README.md view
@@ -44,9 +44,8 @@ 3. If you don't have a gpg private key already, generate one: `gpg --gen-key` 4. Run: `propellor --add-key $KEYID`, which will make propellor trust your gpg key, and will sign your `~/.propellor` repository using it.-5. `cd ~/.propellor/`; use git to push the repository to a central- server (github, or your own git server). Configure that central- server as the origin remote of the repository.+5. Push the git repository to a central server (github or your own):+ `cd ~/.propellor/; git remote add origin ssh://git.example.com/propellor.git; git push -u origin master` 6. Edit `~/.propellor/config.hs`, and add a host you want to manage. You can start by not adding any properties, or only a few. 7. Pick a host and run: `propellor --spin $HOST`
config-joey.hs view
@@ -1,4 +1,5 @@ -- This is the live config file used by propellor's author.+-- https://propellor.branchable.com/ module Main where import Propellor@@ -7,6 +8,7 @@ import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Network as Network+import qualified Propellor.Property.Service as Service import qualified Propellor.Property.Ssh as Ssh import qualified Propellor.Property.Gpg as Gpg import qualified Propellor.Property.Cron as Cron@@ -35,209 +37,240 @@ {- Propellor -- \ / | / ) _.-"-._ Deployed -} -- `/-==__ _/__|/__=-| ( \_ hosts :: [Host] -- * \ | | '--------'-hosts = -- (o) `- [ host "darkstar.kitenet.net"- & ipv6 "2001:4830:1600:187::2" -- sixxs tunnel+hosts = -- (o) `+ [ darkstar+ , clam+ , orca+ , kite+ , diatom+ , elephant+ ] ++ containers ++ monsters - & Apt.buildDep ["git-annex"] `period` Daily- & Docker.configured- ! Docker.docked hosts "android-git-annex"+darkstar :: Host+darkstar = host "darkstar.kitenet.net"+ & ipv6 "2001:4830:1600:187::2" -- sixxs tunnel - , standardSystem "clam.kitenet.net" Unstable "amd64"- [ "Unreliable server. Anything here may be lost at any time!" ]- & ipv4 "162.248.9.29"+ & Apt.buildDep ["git-annex"] `period` Daily+ & Docker.configured+ ! Docker.docked hosts "android-git-annex"+ ! Docker.docked hosts "webserver" - & CloudAtCost.decruft- & Apt.unattendedUpgrades- & Network.ipv6to4- & Tor.isBridge- & Postfix.satellite+clam :: Host+clam = standardSystem "clam.kitenet.net" Unstable "amd64"+ [ "Unreliable server. Anything here may be lost at any time!" ]+ & ipv4 "162.248.9.29" - & Docker.configured- & Docker.garbageCollected `period` Daily- - -- ssh on some extra ports to deal with horrible networks- -- while travelling- & alias "travelling.kitenet.net"- & Ssh.listenPort 80- & Ssh.listenPort 443+ & CloudAtCost.decruft+ & Apt.unattendedUpgrades+ & Network.ipv6to4+ & Tor.isBridge+ & Postfix.satellite++ & Docker.configured+ & Docker.garbageCollected `period` Daily+ & Docker.docked hosts "webserver"+ & File.dirExists "/var/www/html"+ & File.notPresent "/var/www/html/index.html"+ & "/var/www/index.html" `File.hasContent` ["hello, world"]+ & alias "helloworld.kitenet.net" - -- Orca is the main git-annex build box.- , standardSystem "orca.kitenet.net" Unstable "amd64"- [ "Main git-annex build box." ]- & ipv4 "138.38.108.179"+ -- ssh on some extra ports to deal with horrible networks+ -- while travelling+ & alias "travelling.kitenet.net"+ ! Ssh.listenPort 80+ ! Ssh.listenPort 443+ +orca :: Host+orca = standardSystem "orca.kitenet.net" Unstable "amd64"+ [ "Main git-annex build box." ]+ & ipv4 "138.38.108.179" - & Apt.unattendedUpgrades- & Postfix.satellite- & Docker.configured- & Docker.docked hosts "amd64-git-annex-builder"- & Docker.docked hosts "i386-git-annex-builder"- & Docker.docked hosts "android-git-annex-builder"- & Docker.docked hosts "armel-git-annex-builder-companion"- & Docker.docked hosts "armel-git-annex-builder"- & Docker.garbageCollected `period` Daily- & Apt.buildDep ["git-annex"] `period` Daily+ & Apt.unattendedUpgrades+ & Postfix.satellite+ & Docker.configured+ & Docker.docked hosts "amd64-git-annex-builder"+ & Docker.docked hosts "i386-git-annex-builder"+ & Docker.docked hosts "android-git-annex-builder"+ & Docker.docked hosts "armel-git-annex-builder-companion"+ & Docker.docked hosts "armel-git-annex-builder"+ & Docker.garbageCollected `period` Daily+ & Apt.buildDep ["git-annex"] `period` Daily - -- This is not a complete description of kite, since it's a- -- multiuser system with eg, user passwords that are not deployed- -- with propellor.- , standardSystemUnhardened "kite.kitenet.net" Unstable "amd64"- [ "Welcome to the new kitenet.net server!"- , "This is still under construction and not yet live.."- ]- & ipv4 "66.228.36.95"- & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2"- -- & alias "kitenet.net" -- not yet live!+-- This is not a complete description of kite, since it's a+-- multiuser system with eg, user passwords that are not deployed+-- with propellor.+kite :: Host+kite = standardSystemUnhardened "kite.kitenet.net" Unstable "amd64"+ [ "Welcome to the new kitenet.net server!"+ ]+ & ipv4 "66.228.36.95"+ & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2"+ & alias "kitenet.net"+ & alias "wren.kitenet.net" -- temporary - & Apt.installed ["linux-image-amd64"]- & Linode.chainPVGrub 5- & Apt.unattendedUpgrades- & Apt.installed ["systemd"]- & Ssh.hostKeys (Context "kitenet.net")- -- Since ssh password authentication is allowed:- & Apt.serviceInstalledRunning "fail2ban"- & Obnam.backup "/" "33 1 * * *"- [ "--repository=sftp://joey@eubackup.kitenet.net/~/lib/backup/kite.obnam"- , "--client-name=kitenet.net"- , "--encrypt-with="- , "--exclude=/var/cache"- , "--exclude=/var/tmp"- , "--exclude=/home/joey/lib"- , "--exclude=.*/tmp/"- , "--one-file-system"- ] Obnam.OnlyClient- `requires` Gpg.keyImported "98147487" "root"- `requires` Ssh.keyImported SshRsa "root"- (Context "kite.kitenet.net")- `requires` Ssh.knownHost hosts "eubackup.kitenet.net" "root"+ & Apt.installed ["linux-image-amd64"]+ & Linode.chainPVGrub 5+ & Apt.unattendedUpgrades+ & Apt.installed ["systemd"]+ & Ssh.hostKeys (Context "kitenet.net")+ & Ssh.passwordAuthentication True+ -- Since ssh password authentication is allowed:+ & Apt.serviceInstalledRunning "fail2ban"+ & Obnam.backup "/" "33 1 * * *"+ [ "--repository=sftp://joey@eubackup.kitenet.net/~/lib/backup/kite.obnam"+ , "--client-name=kitenet.net"+ , "--encrypt-with=98147487"+ , "--exclude=/var/cache"+ , "--exclude=/var/tmp"+ , "--exclude=/home/joey/lib"+ , "--exclude=.*/tmp/"+ , "--one-file-system"+ ] Obnam.OnlyClient+ `requires` Gpg.keyImported "98147487" "root"+ `requires` Ssh.keyImported SshRsa "root"+ (Context "kite.kitenet.net")+ `requires` Ssh.knownHost hosts "eubackup.kitenet.net" "root"+ & Apt.serviceInstalledRunning "ntp"+ & "/etc/timezone" `File.hasContent` ["US/Eastern"] - -- & alias "smtp.kitenet.net" -- not yet live!- -- & alias "imap.kitenet.net" -- not yet live!- -- & alias "mail.kitenet.net" -- not yet live!- & JoeySites.kiteMailServer+ & alias "smtp.kitenet.net"+ & alias "imap.kitenet.net"+ & alias "pop.kitenet.net"+ & alias "mail.kitenet.net"+ & JoeySites.kiteMailServer - & JoeySites.legacyWebSites+ & JoeySites.legacyWebSites - & Apt.installed- ["git-annex", "myrepos"- , "build-essential", "make"- -- Some users have zsh as their login shell.- , "zsh"- ]+ & alias "bitlbee.kitenet.net"+ & Apt.serviceInstalledRunning "bitlbee"+ & "/etc/bitlbee/bitlbee.conf" `File.hasContent`+ [ "[settings]"+ , "User = bitlbee"+ , "AuthMode = Registered"+ , "[defaults]"+ ] + `onChange` Service.restarted "bitlbee"+ & "/etc/default/bitlbee" `File.containsLine` "BITLBEE_PORT=\"6767\""+ `onChange` Service.restarted "bitlbee" - , standardSystem "diatom.kitenet.net" Stable "amd64"- [ "Important stuff that needs not too much memory or CPU." ]- & ipv4 "107.170.31.195"+ & Apt.installed+ ["git-annex", "myrepos"+ , "build-essential", "make"+ , "rss2email", "archivemail"+ , "devscripts"+ -- Some users have zsh as their login shell.+ , "zsh"+ ] - & DigitalOcean.distroKernel- & Ssh.hostKeys (Context "diatom.kitenet.net")- & Apt.unattendedUpgrades- & Apt.serviceInstalledRunning "ntp"- & Postfix.satellite+diatom :: Host+diatom = standardSystem "diatom.kitenet.net" (Stable "wheezy") "amd64"+ [ "Important stuff that needs not too much memory or CPU." ]+ & ipv4 "107.170.31.195" - -- Diatom has 500 mb of memory, so tune for that.- & JoeySites.obnamLowMem- & Apt.serviceInstalledRunning "swapspace"- - & Apt.serviceInstalledRunning "apache2"- & JoeySites.kitenetHttps- & Apache.multiSSL- & File.ownerGroup "/srv/web" "joey" "joey"- & Apt.installed ["analog"]+ & DigitalOcean.distroKernel+ & Ssh.hostKeys (Context "diatom.kitenet.net")+ & Apt.unattendedUpgrades+ & Apt.serviceInstalledRunning "ntp"+ & Postfix.satellite - & alias "git.kitenet.net"- & alias "git.joeyh.name"- & JoeySites.gitServer hosts+ -- Diatom has 500 mb of memory, so tune for that.+ & JoeySites.obnamLowMem+ & Apt.serviceInstalledRunning "swapspace" - & alias "downloads.kitenet.net"- & JoeySites.annexWebSite "/srv/git/downloads.git"- "downloads.kitenet.net"- "840760dc-08f0-11e2-8c61-576b7e66acfd"- [("usbackup", "ssh://usbackup.kitenet.net/~/lib/downloads/")]- `requires` Ssh.keyImported SshRsa "joey" (Context "downloads.kitenet.net")- `requires` Ssh.knownHost hosts "usbackup.kitenet.net" "joey"- & JoeySites.gitAnnexDistributor+ & Apt.serviceInstalledRunning "apache2"+ & JoeySites.kitenetHttps+ & Apache.multiSSL+ & File.ownerGroup "/srv/web" "joey" "joey"+ & Apt.installed ["analog"] + & alias "git.kitenet.net"+ & alias "git.joeyh.name"+ & JoeySites.gitServer hosts+ + & alias "downloads.kitenet.net"+ & JoeySites.annexWebSite "/srv/git/downloads.git"+ "downloads.kitenet.net"+ "840760dc-08f0-11e2-8c61-576b7e66acfd"+ [("usbackup", "ssh://usbackup.kitenet.net/~/lib/downloads/")]+ `requires` Ssh.keyImported SshRsa "joey" (Context "downloads.kitenet.net")+ `requires` Ssh.knownHost hosts "usbackup.kitenet.net" "joey"+ & JoeySites.gitAnnexDistributor & alias "tmp.kitenet.net"- & JoeySites.annexWebSite "/srv/git/joey/tmp.git"- "tmp.kitenet.net"- "26fd6e38-1226-11e2-a75f-ff007033bdba"- []- & JoeySites.twitRss- & JoeySites.pumpRss- - & alias "nntp.olduse.net"- & alias "resources.olduse.net"- & JoeySites.oldUseNetServer hosts+ & JoeySites.annexWebSite "/srv/git/joey/tmp.git"+ "tmp.kitenet.net"+ "26fd6e38-1226-11e2-a75f-ff007033bdba"+ []+ & JoeySites.twitRss+ & JoeySites.pumpRss - & alias "ns2.kitenet.net"- & myDnsPrimary "kitenet.net" []- & myDnsPrimary "joeyh.name" []- & myDnsPrimary "ikiwiki.info" []- & myDnsPrimary "olduse.net"- [ (RelDomain "article",- CNAME $ AbsDomain "virgil.koldfront.dk") ]+ & alias "nntp.olduse.net"+ & alias "resources.olduse.net"+ & JoeySites.oldUseNetServer hosts - & alias "ns3.branchable.com"- & branchableSecondary- - & Dns.secondaryFor ["animx"] hosts "animx.eu.org"+ & alias "ns2.kitenet.net"+ & myDnsPrimary "kitenet.net" []+ & myDnsPrimary "joeyh.name" []+ & myDnsPrimary "ikiwiki.info" []+ & myDnsPrimary "olduse.net"+ [ (RelDomain "article",+ CNAME $ AbsDomain "virgil.koldfront.dk") ] - , let ctx = Context "elephant.kitenet.net"- in standardSystem "elephant.kitenet.net" Unstable "amd64"- [ "Storage, big data, and backups, omnomnom!"- , "(Encrypt all data stored here.)"- ]- & ipv4 "193.234.225.114"+ & alias "ns3.branchable.com"+ & branchableSecondary+ + & Dns.secondaryFor ["animx"] hosts "animx.eu.org" +elephant :: Host+elephant = standardSystem "elephant.kitenet.net" Unstable "amd64"+ [ "Storage, big data, and backups, omnomnom!"+ , "(Encrypt all data stored here.)"+ ]+ & ipv4 "193.234.225.114" & Grub.chainPVGrub "hd0,0" "xen/xvda1" 30- & Postfix.satellite- & Apt.unattendedUpgrades- & Ssh.hostKeys ctx- & sshPubKey "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJkoPRhUGT8EId6m37uBdYEtq42VNwslKnc9mmO+89ody066q6seHKeFY6ImfwjcyIjM30RTzEwftuVNQnbEB0="- & Ssh.keyImported SshRsa "joey" ctx- & Apt.serviceInstalledRunning "swapspace"-+ & Postfix.satellite+ & Apt.unattendedUpgrades+ & Ssh.hostKeys ctx+ & sshPubKey "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJkoPRhUGT8EId6m37uBdYEtq42VNwslKnc9mmO+89ody066q6seHKeFY6ImfwjcyIjM30RTzEwftuVNQnbEB0="+ & Ssh.keyImported SshRsa "joey" ctx+ & Apt.serviceInstalledRunning "swapspace" & alias "eubackup.kitenet.net"- & Apt.installed ["obnam", "sshfs", "rsync"]- & JoeySites.obnamRepos ["wren", "pell", "kite"]- & JoeySites.githubBackup- & JoeySites.rsyncNetBackup hosts- & JoeySites.backupsBackedupTo hosts "usbackup.kitenet.net" "lib/backup/eubackup"-+ & Apt.installed ["obnam", "sshfs", "rsync"]+ & JoeySites.obnamRepos ["wren", "pell", "kite"]+ & JoeySites.githubBackup+ & JoeySites.rsyncNetBackup hosts+ & JoeySites.backupsBackedupTo hosts "usbackup.kitenet.net" "lib/backup/eubackup" & alias "podcatcher.kitenet.net"- & JoeySites.podcatcher- - & alias "znc.kitenet.net"- & JoeySites.ircBouncer-- -- I'd rather this were on diatom, but it needs unstable.- & alias "kgb.kitenet.net"- & JoeySites.kgbServer-+ & JoeySites.podcatcher+ + & alias "znc.kitenet.net"+ & JoeySites.ircBouncer+ -- I'd rather this were on diatom, but it needs unstable.+ & alias "kgb.kitenet.net"+ & JoeySites.kgbServer & alias "mumble.kitenet.net"- & JoeySites.mumbleServer hosts- - & alias "ns3.kitenet.net"- & myDnsSecondary- - & Docker.configured-+ & JoeySites.mumbleServer hosts+ + & alias "ns3.kitenet.net"+ & myDnsSecondary+ + & Docker.configured & Docker.docked hosts "oldusenet-shellbox"- & Docker.docked hosts "openid-provider"- `requires` Apt.serviceInstalledRunning "ntp"- & Docker.docked hosts "ancient-kitenet"+ & Docker.docked hosts "openid-provider"+ `requires` Apt.serviceInstalledRunning "ntp"+ & Docker.docked hosts "ancient-kitenet" - & Docker.garbageCollected `period` (Weekly (Just 1))- - -- For https port 443, shellinabox with ssh login to- -- kitenet.net- & alias "shell.kitenet.net"- & JoeySites.kiteShellBox- -- Nothing is using http port 80, so listen on- -- that port for ssh, for traveling on bad networks that- -- block 22.- & Ssh.listenPort 80+ & Docker.garbageCollected `period` (Weekly (Just 1))+ + -- For https port 443, shellinabox with ssh login to+ -- kitenet.net+ & alias "shell.kitenet.net"+ & JoeySites.kiteShellBox+ -- Nothing is using http port 80, so listen on+ -- that port for ssh, for traveling on bad networks that+ -- block 22.+ & Ssh.listenPort 80+ where+ ctx = Context "elephant.kitenet.net" --' __|II| ,.@@ -247,30 +280,31 @@ ----------------------- : / ----------------------- ------------------------ \____, o ,' ------------------------ ------------------------- '--,___________,' --------------------------+containers :: [Host]+containers = -- Simple web server, publishing the outside host's /var/www- , standardContainer "webserver" Stable "amd64"- & Docker.publish "8080:80"+ [ standardStableContainer "webserver"+ & Docker.publish "80:80" & Docker.volume "/var/www:/var/www" & Apt.serviceInstalledRunning "apache2" -- My own openid provider. Uses php, so containerized for security -- and administrative sanity.- , standardContainer "openid-provider" Stable "amd64"+ , standardStableContainer "openid-provider" & alias "openid.kitenet.net" & Docker.publish "8081:80" & OpenId.providerFor ["joey", "liw"] "openid.kitenet.net:8081" -- Exhibit: kite's 90's website.- , standardContainer "ancient-kitenet" Stable "amd64"+ , standardStableContainer "ancient-kitenet" & alias "ancient.kitenet.net" & Docker.publish "1994:80" & Apt.serviceInstalledRunning "apache2" & Git.cloned "root" "git://kitenet-net.branchable.com/" "/var/www" (Just "remotes/origin/old-kitenet.net") - , standardContainer "oldusenet-shellbox" Stable "amd64"+ , standardStableContainer "oldusenet-shellbox" & alias "shell.olduse.net" & Docker.publish "4200:4200" & JoeySites.oldUseNetShellBox@@ -287,7 +321,7 @@ , let gitannexdir = GitAnnexBuilder.homedir </> "git-annex" in GitAnnexBuilder.androidContainer dockerImage "android-git-annex" doNothing gitannexdir & Docker.volume ("/home/joey/src/git-annex:" ++ gitannexdir)- ] ++ monsters+ ] type Motd = [String] @@ -321,14 +355,17 @@ & Apt.removed ["exim4", "exim4-daemon-light", "exim4-config", "exim4-base"] `onChange` Apt.autoRemove +standardStableContainer :: Docker.ContainerName -> Host+standardStableContainer name = standardContainer name (Stable "wheezy") "amd64"+ -- This is my standard container setup, featuring automatic upgrades. standardContainer :: Docker.ContainerName -> DebianSuite -> Architecture -> Host standardContainer name suite arch = Docker.container name (dockerImage system) & os system & Apt.stdSourcesList `onChange` Apt.upgrade- & Apt.installed ["systemd"] & Apt.unattendedUpgrades & Apt.cacheCleaned+ & Docker.tweaked where system = System (Debian suite) arch @@ -336,7 +373,7 @@ dockerImage :: System -> Docker.Image dockerImage (System (Debian Unstable) arch) = "joeyh/debian-unstable-" ++ arch dockerImage (System (Debian Testing) arch) = "joeyh/debian-unstable-" ++ arch-dockerImage (System (Debian Stable) arch) = "joeyh/debian-stable-" ++ arch+dockerImage (System (Debian (Stable _)) arch) = "joeyh/debian-stable-" ++ arch dockerImage _ = "debian-stable-official" -- does not currently exist! myDnsSecondary :: Property@@ -376,7 +413,7 @@ monsters :: [Host] -- Systems I don't manage with propellor,-monsters = -- but do want to track their public keys etc.+monsters = -- but do want to track their public keys etc. [ host "usw-s002.rsync.net" & sshPubKey "ssh-dss AAAAB3NzaC1kc3MAAAEBAI6ZsoW8a+Zl6NqUf9a4xXSMcV1akJHDEKKBzlI2YZo9gb9YoCf5p9oby8THUSgfh4kse7LJeY7Nb64NR6Y/X7I2/QzbE1HGGl5mMwB6LeUcJ74T3TQAlNEZkGt/MOIVLolJHk049hC09zLpkUDtX8K0t1yaCirC9SxDGLTCLEhvU9+vVdVrdQlKZ9wpLUNbdAzvbra+O/IVvExxDZ9WCHrnfNA8ddVZIGEWMqsoNgiuCxiXpi8qL+noghsSQNFTXwo7W2Vp9zj1JkCt3GtSz5IzEpARQaXEAWNEM0n1nJ686YUOhou64iRM8bPC1lp3QXvvZNgj3m+QHhIempx+de8AAAAVAKB5vUDaZOg14gRn7Bp81ja/ik+RAAABACPH/bPbW912x1NxNiikzGR6clLh+bLpIp8Qie3J7DwOr8oC1QOKjNDK+UgQ7mDQEgr4nGjNKSvpDi4c1QCw4sbLqQgx1y2VhT0SmUPHf5NQFldRQyR/jcevSSwOBxszz3aq9AwHiv9OWaO3XY18suXPouiuPTpIcZwc2BLDNHFnDURQeGEtmgqj6gZLIkTY0iw7q9Tj5FOyl4AkvEJC5B4CSzaWgey93Wqn1Imt7KI8+H9lApMKziVL1q+K7xAuNkGmx5YOSNlE6rKAPtsIPHZGxR7dch0GURv2jhh0NQYvBRn3ukCjuIO5gx56HLgilq59/o50zZ4NcT7iASF76TcAAAEAC6YxX7rrs8pp13W4YGiJHwFvIO1yXLGOdqu66JM0plO4J1ItV1AQcazOXLiliny3p2/W+wXZZKd5HIRt52YafCA8YNyMk/sF7JcTR4d4z9CfKaAxh0UpzKiAk+0j/Wu3iPoTOsyt7N0j1+dIyrFodY2sKKuBMT4TQ0yqQpbC+IDQv2i1IlZAPneYGfd5MIGygs2QMfaMQ1jWAKJvEO0vstZ7GB6nDAcg4in3ZiBHtomx3PL5w+zg48S4Ed69BiFXLZ1f6MnjpUOP75pD4MP6toS0rgK9b93xCrEQLgm4oD/7TCHHBo2xR7wwcsN2OddtwWsEM2QgOkt/jdCAoVCqwQ==" , host "github.com" @@ -389,55 +426,8 @@ & alias "backup.kitenet.net" & alias "usbackup.kitenet.net" & sshPubKey "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAokMXQiX/NZjA1UbhMdgAscnS5dsmy+Q7bWrQ6tsTZ/o+6N/T5cbjoBHOdpypXJI3y/PiJTDJaQtXIhLa8gFg/EvxMnMz/KG9skADW1361JmfCc4BxicQIO2IOOe6eilPr+YsnOwiHwL0vpUnuty39cppuMWVD25GzxXlS6KQsLCvXLzxLLuNnGC43UAM0q4UwQxDtAZEK1dH2o3HMWhgMP2qEQupc24dbhpO3ecxh2C9678a3oGDuDuNf7mLp3s7ptj5qF3onitpJ82U5o7VajaHoygMaSRFeWxP2c13eM57j3bLdLwxVXFhePcKXARu1iuFTLS5uUf3hN6MkQcOGw=="- , host "wren.kitenet.net"+ , host "old.kitenet.net" & ipv4 "80.68.85.49"- & ipv6 "2001:41c8:125:49::10"- & alias "kitenet.net"- & alias "ns1.kitenet.net"- & alias "ftp.kitenet.net"- & alias "mail.kitenet.net"- & alias "smtp.kitenet.net"- & alias "bitlbee.kitenet.net"- {- Remaining services on kite:- -- - / = ready to go on kite.kitenet.net- - - - mail- - /postfix- - /postgrey- - mailman- - /spamassassin- - sqwebmail (cannot use this with dovecot, alternatives?)- - /imap server- - /pop server- - /apache- - bitlbee (EOL?)- - prosody (EOL?)- - ftpd (EOL)- -- - Pre-transition:- - - re-rsync /home (skip ~joey and .pine*)- - cd /home && rsync -4 --progress -avz root@wren.kitenet.net:/home/ ./ --exclude='.pine*' --exclude='joey/*' --delete- - - - Transition plan:- - - on darkstar: offlineimap run & disable cron job- - & move offlineimap files to tmp- - - take down wren pstfix, imap, pop servers- - - log all users out of wren- - - final /home rsync (skip ~joey and .pine*)- - - rsync /var/mail- - - rsync mailman and mailman list archives dirs- - - switch kitenet.net dns and enable pop.kitenet.net etc aliass- - - point wren.kitenet.net at kite.kitenet.net temporarily- - (make real-wren.kitenet.net alias)- - - reconfigure errol's email client to use new server- - - on darkstar: re-run offlinimap against new server- - - test mail- - - test virus filtering- - - test http://kitenet.net/~kyle/ (user home dirs)- - - test mailman- - - migrate user cron jobs- -} , host "mouse.kitenet.net" & ipv6 "2001:4830:1600:492::2" , host "beaver.kitenet.net"
config-simple.hs view
@@ -38,7 +38,7 @@ -- A generic webserver in a Docker container. , Docker.container "webserver" "joeyh/debian-stable"- & os (System (Debian Stable) "amd64")+ & os (System (Debian (Stable "wheezy")) "amd64") & Apt.stdSourcesList & Docker.publish "80:80" & Docker.volume "/var/www:/var/www"
config.hs view
@@ -38,7 +38,7 @@ -- A generic webserver in a Docker container. , Docker.container "webserver" "joeyh/debian-stable"- & os (System (Debian Stable) "amd64")+ & os (System (Debian (Stable "wheezy")) "amd64") & Apt.stdSourcesList & Docker.publish "80:80" & Docker.volume "/var/www:/var/www"
debian/changelog view
@@ -1,3 +1,18 @@+propellor (0.9.0) unstable; urgency=medium++ * Avoid encoding the current stable suite in propellor's code,+ since that poses a difficult transition around the release,+ and can easily be wrong if an older version of propellor is used.+ Instead, the os property for a stable system includes the suite name+ to use, eg Stable "wheezy".+ * stdSourcesList uses the stable suite name, to avoid unwanted+ immediate upgrades to the next stable release.+ * debCdn switched from cdn.debian.net to http.debian.net, which seems to be+ better managed now.+ * Docker: Avoid committing container every time it's started up.++ -- Joey Hess <joeyh@debian.org> Fri, 10 Oct 2014 11:37:45 -0400+ propellor (0.8.3) unstable; urgency=medium * The Debian package now includes a single-revision git repository in
doc/README.mdwn view
@@ -44,9 +44,8 @@ 3. If you don't have a gpg private key already, generate one: `gpg --gen-key` 4. Run: `propellor --add-key $KEYID`, which will make propellor trust your gpg key, and will sign your `~/.propellor` repository using it.-5. `cd ~/.propellor/`; use git to push the repository to a central- server (github, or your own git server). Configure that central- server as the origin remote of the repository.+5. Push the git repository to a central server (github or your own):+ `cd ~/.propellor/; git remote add origin ssh://git.example.com/propellor.git; git push -u origin master` 6. Edit `~/.propellor/config.hs`, and add a host you want to manage. You can start by not adding any properties, or only a few. 7. Pick a host and run: `propellor --spin $HOST`
propellor.cabal view
@@ -1,5 +1,5 @@ Name: propellor-Version: 0.8.3+Version: 0.9.0 Cabal-Version: >= 1.6 License: BSD3 Maintainer: Joey Hess <joey@kitenet.net>
src/Propellor/CmdLine.hs view
@@ -37,9 +37,9 @@ processCmdLine :: IO CmdLine processCmdLine = go =<< getArgs where- go ("--help":_) = usage- go ("--spin":h:[]) = return $ Spin h- go ("--boot":h:[]) = return $ Boot h+ go ("--help":_) = usage+ go ("--spin":h:[]) = return $ Spin h+ go ("--boot":h:[]) = return $ Boot h go ("--add-key":k:[]) = return $ AddKey k go ("--set":f:c:[]) = withprivfield f c Set go ("--dump":f:c:[]) = withprivfield f c Dump@@ -48,7 +48,7 @@ go ("--continue":s:[]) = case readish s of Just cmdline -> return $ Continue cmdline Nothing -> errorMessage "--continue serialization failure"- go ("--chain":h:[]) = return $ Chain h+ go ("--chain":h:[]) = return $ Chain h go ("--docker":h:[]) = return $ Docker h go (h:[]) | "--" `isPrefixOf` h = usage@@ -237,6 +237,7 @@ sendMarked toh marker s return True +-- Initial git clone, used for bootstrapping. sendGitClone :: HostName -> String -> IO () sendGitClone hn url = void $ actionMessage ("Pushing git repository to " ++ hn) $ do branch <- getCurrentBranch
src/Propellor/PrivData.hs view
@@ -114,7 +114,7 @@ showtable "Data that would be used if set:" $ map mkrow (M.keys $ M.difference wantedmap m) where- header = ["Field", "Context", "Used by"]+ header = ["Field", "Context", "Used by"] mkrow k@(field, (Context context)) = [ shellEscape $ show field , shellEscape context
src/Propellor/Property.hs view
@@ -31,7 +31,7 @@ combineProperties :: Desc -> [Property] -> Property combineProperties desc ps = Property desc (go ps NoChange) (combineInfos ps) where- go [] rs = return rs+ go [] rs = return rs go (l:ls) rs = do r <- ensureProperty l case r of
src/Propellor/Property/Apache.hs view
@@ -54,7 +54,7 @@ installed = Apt.installed ["apache2"] restarted :: Property-restarted = cmdProperty "service" ["apache2", "restart"]+restarted = Service.restarted "apache2" reloaded :: Property reloaded = Service.reloaded "apache2"
src/Propellor/Property/Apt.hs view
@@ -20,14 +20,14 @@ type SourcesGenerator = DebianSuite -> [Line] showSuite :: DebianSuite -> String-showSuite Stable = "stable"+showSuite (Stable s) = s showSuite Testing = "testing" showSuite Unstable = "unstable" showSuite Experimental = "experimental"-showSuite (DebianRelease r) = r -backportSuite :: String-backportSuite = showSuite stableRelease ++ "-backports"+backportSuite :: DebianSuite -> Maybe String+backportSuite (Stable s) = Just (s ++ "-backports")+backportSuite _ = Nothing debLine :: String -> Url -> [Section] -> Line debLine suite mirror sections = unwords $@@ -42,15 +42,20 @@ stdSections = ["main", "contrib", "non-free"] binandsrc :: String -> SourcesGenerator-binandsrc url suite- | isStable suite = [l, srcLine l, bl, srcLine bl]- | otherwise = [l, srcLine l]+binandsrc url suite = catMaybes+ [ Just l+ , Just $ srcLine l+ , bl+ , srcLine <$> bl+ ] where l = debLine (showSuite suite) url stdSections- bl = debLine backportSuite url stdSections+ bl = do+ bs <- backportSuite suite+ return $ debLine bs url stdSections debCdn :: SourcesGenerator-debCdn = binandsrc "http://cdn.debian.net/debian"+debCdn = binandsrc "http://http.debian.net/debian" kernelOrg :: SourcesGenerator kernelOrg = binandsrc "http://mirrors.kernel.org/debian"@@ -128,13 +133,14 @@ installedBackport :: [Package] -> Property installedBackport ps = trivial $ withOS desc $ \o -> case o of Nothing -> error "cannot install backports; os not declared"- (Just (System (Debian suite) _))- | isStable suite -> - ensureProperty $ runApt $ - ["install", "-t", backportSuite, "-y"] ++ ps- _ -> error $ "backports not supported on " ++ show o+ (Just (System (Debian suite) _)) -> case backportSuite suite of+ Nothing -> notsupported o+ Just bs -> ensureProperty $ runApt $ + ["install", "-t", bs, "-y"] ++ ps+ _ -> notsupported o where desc = (unwords $ "apt installed backport":ps)+ notsupported o = error $ "backports not supported on " ++ show o -- | Minimal install of package, without recommends. installedMin :: [Package] -> Property
src/Propellor/Property/Cmd.hs view
@@ -33,7 +33,7 @@ , return FailedChange ) where- desc = unwords $ cmd : params+ desc = unwords $ cmd : params -- | A property that can be satisfied by running a series of shell commands. scriptProperty :: [String] -> Property
src/Propellor/Property/Dns.hs view
@@ -117,7 +117,7 @@ `requires` servingZones cleanup = namedConfWritten - desc = "dns secondary for " ++ domain+ desc = "dns secondary for " ++ domain conf = NamedConf { confDomain = domain , confDnsServerType = Secondary@@ -380,7 +380,7 @@ [] -> [ret (CNAME c)] l -> map (ret . Address) l where- ret record = Right (c, record)+ ret record = Right (c, record) -- Adds any other DNS records for a host located in the zdomain. hostrecords :: Host -> [Either WarningMessage (BindDomain, Record)]@@ -420,7 +420,7 @@ addNamedConf :: NamedConf -> Info addNamedConf conf = mempty { _namedconf = NamedConfMap (M.singleton domain conf) } where- domain = confDomain conf+ domain = confDomain conf getNamedConf :: Propellor (M.Map Domain NamedConf) getNamedConf = asks $ fromNamedConfMap . _namedconf . hostInfo
src/Propellor/Property/Docker.hs view
@@ -13,6 +13,7 @@ docked, memoryLimited, garbageCollected,+ tweaked, Image, ContainerName, -- * Container configuration@@ -102,7 +103,7 @@ where go desc a = property (desc ++ " " ++ cn) $ do hn <- asks hostName- let cid = ContainerId hn cn+ let cid = ContainerId hn cn ensureProperties [findContainer mhost cid cn $ a cid] mhost = findHost hosts (cn2hn cn)@@ -152,7 +153,7 @@ <*> pure (map (\a -> a hn) (_dockerRunParams info)) where info = _dockerinfo $ hostInfo h'- h' = h+ h' = h -- expose propellor directory inside the container & volume (localdir++":"++localdir) -- name the container in a predictable way so we@@ -176,6 +177,16 @@ gcimages = property "docker images garbage collected" $ do liftIO $ report <$> (mapM removeImage =<< listImages) +-- | Tweaks a container to work well with docker.+--+-- Currently, this consists of making pam_loginuid lines optional in+-- the pam config, to work around https://github.com/docker/docker/issues/5663+-- which affects docker 1.2.0.+tweaked :: Property+tweaked = trivial $+ cmdProperty "sh" ["-c", "sed -ri 's/^session\\s+required\\s+pam_loginuid.so$/session optional pam_loginuid.so/' /etc/pam.d/*"]+ `describe` "tweaked for docker"+ -- | Configures the kernel to respect docker memory limits. -- -- This assumes the system boots using grub 2. And that you don't need any@@ -303,30 +314,38 @@ runningContainer cid@(ContainerId hn cn) image runps = containerDesc cid $ property "running" $ do l <- liftIO $ listContainers RunningContainers if cid `elem` l- then do- -- Check if the ident has changed; if so the- -- parameters of the container differ and it must- -- be restarted.- runningident <- liftIO $ getrunningident- if runningident == Just ident- then noChange- else do- void $ liftIO $ stopContainer cid- restartcontainer+ then checkident =<< liftIO (getrunningident simpleShClient) else ifM (liftIO $ elem cid <$> listContainers AllContainers)- ( restartcontainer+ ( do+ -- The container exists, but is not+ -- running. Its parameters may have+ -- changed, but we cannot tell without+ -- starting it up first.+ void $ liftIO $ startContainer cid+ -- It can take a while for the container to+ -- start up enough to get its ident, so+ -- retry for up to 60 seconds.+ checkident =<< liftIO (getrunningident (simpleShClientRetry 60)) , go image ) where ident = ContainerIdent image hn cn runps + -- Check if the ident has changed; if so the+ -- parameters of the container differ and it must+ -- be restarted.+ checkident runningident+ | runningident == Just ident = noChange+ | otherwise = do+ void $ liftIO $ stopContainer cid+ restartcontainer+ restartcontainer = do oldimage <- liftIO $ fromMaybe image <$> commitContainer cid void $ liftIO $ removeContainer cid go oldimage - getrunningident :: IO (Maybe ContainerIdent)- getrunningident = simpleShClient (namedPipe cid) "cat" [propellorIdent] $ \rs -> do+ getrunningident shclient = shclient (namedPipe cid) "cat" [propellorIdent] $ \rs -> do let !v = extractident rs return v @@ -421,6 +440,9 @@ stopContainer :: ContainerId -> IO Bool stopContainer cid = boolSystem dockercmd [Param "stop", Param $ fromContainerId cid ]++startContainer :: ContainerId -> IO Bool+startContainer cid = boolSystem dockercmd [Param "start", Param $ fromContainerId cid ] stoppedContainer :: ContainerId -> Property stoppedContainer cid = containerDesc cid $ property desc $
src/Propellor/Property/Obnam.hs view
@@ -105,12 +105,12 @@ latestVersion :: Property latestVersion = withOS "obnam latest version" $ \o -> case o of (Just (System (Debian suite) _)) | isStable suite -> ensureProperty $- Apt.setSourcesListD stablesources "obnam"+ Apt.setSourcesListD (stablesources suite) "obnam" `requires` toProp (Apt.trustsKey key) _ -> noChange where- stablesources = - [ "deb http://code.liw.fi/debian " ++ Apt.showSuite stableRelease ++ " main"+ stablesources suite = + [ "deb http://code.liw.fi/debian " ++ Apt.showSuite suite ++ " main" ] -- gpg key used by the code.liw.fi repository. key = Apt.AptKey "obnam" $ unlines
src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs view
@@ -98,6 +98,7 @@ & tree arch & buildDepsApt & autobuilder arch (show buildminute ++ " * * * *") timeout+ & Docker.tweaked androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host androidAutoBuilderContainer dockerImage crontimes timeout =@@ -108,8 +109,8 @@ -- Android is cross-built in a Debian i386 container, using the Android NDK. androidContainer :: (System -> Docker.Image) -> Docker.ContainerName -> Property -> FilePath -> Host androidContainer dockerImage name setupgitannexdir gitannexdir = Docker.container name- (dockerImage $ System (Debian Stable) "i386")- & os (System (Debian Stable) "i386")+ (dockerImage osver)+ & os osver & Apt.stdSourcesList & Apt.installed ["systemd"] & User.accountFor builduser@@ -118,6 +119,7 @@ & buildDepsNoHaskellLibs & flagFile chrootsetup ("/chrootsetup") `requires` setupgitannexdir+ & Docker.tweaked -- TODO: automate installing haskell libs -- (Currently have to run -- git-annex/standalone/android/install-haskell-packages@@ -129,6 +131,7 @@ chrootsetup = scriptProperty [ "cd " ++ gitannexdir ++ " && ./standalone/android/buildchroot-inchroot" ]+ osver = System (Debian (Stable "wheezy")) "i386" -- armel builder has a companion container using amd64 that -- runs the build first to get TH splices. They need@@ -139,7 +142,6 @@ & os (System (Debian Testing) "amd64") & Apt.stdSourcesList & Apt.installed ["systemd"]- & Apt.unattendedUpgrades -- This volume is shared with the armel builder. & Docker.volume gitbuilderdir & User.accountFor builduser@@ -151,13 +153,13 @@ & Docker.expose "22" & Apt.serviceInstalledRunning "ssh" & Ssh.authorizedKeys builduser (Context "armel-git-annex-builder")+ & Docker.tweaked armelAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder" (dockerImage $ System (Debian Unstable) "armel") & os (System (Debian Testing) "armel") & Apt.stdSourcesList- & Apt.unattendedUpgrades & Apt.installed ["systemd"] & Apt.installed ["openssh-client"] & Docker.link "armel-git-annex-builder-companion" "companion"@@ -172,6 +174,7 @@ `requires` tree "armel" & Ssh.keyImported SshRsa builduser (Context "armel-git-annex-builder") & trivial writecompanionaddress+ & Docker.tweaked where writecompanionaddress = scriptProperty [ "echo \"$COMPANION_PORT_22_TCP_ADDR\" > " ++ homedir </> "companion_address"
src/Propellor/Property/SiteSpecific/JoeySites.hs view
@@ -70,7 +70,10 @@ datadir = "/var/spool/oldusenet" oldUseNetShellBox :: Property-oldUseNetShellBox = oldUseNetInstalled "oldusenet"+oldUseNetShellBox = propertyList "olduse.net shellbox"+ [ oldUseNetInstalled "oldusenet"+ , Service.running "oldusenet"+ ] oldUseNetInstalled :: Apt.Package -> Property oldUseNetInstalled pkg = check (not <$> Apt.isInstalled pkg) $@@ -376,7 +379,7 @@ obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs) (mkbase : map mkrepo rs) where- mkbase = mkdir "/home/joey/lib/backup"+ mkbase = mkdir "/home/joey/lib/backup" `requires` mkdir "/home/joey/lib" mkrepo r = mkdir ("/home/joey/lib/backup/" ++ r ++ ".obnam") mkdir d = File.dirExists d@@ -452,8 +455,16 @@ ] `onChange` Postfix.reloaded `describe` "postfix mydomain file configured"- , "/etc/postfix/obscure_client_relay.pcre" `File.containsLine`- "/^Received: from ([^.]+)\\.kitenet\\.net.*using TLS.*by kitenet\\.net \\(([^)]+)\\) with (E?SMTPS?A?) id ([A-F[:digit:]]+)(.*)/ IGNORE"+ , "/etc/postfix/obscure_client_relay.pcre" `File.hasContent`+ -- Remove received lines for mails relayed from trusted+ -- clients. These can be a privacy vilation, or trigger+ -- spam filters.+ [ "/^Received: from ([^.]+)\\.kitenet\\.net.*using TLS.*by kitenet\\.net \\(([^)]+)\\) with (E?SMTPS?A?) id ([A-F[:digit:]]+)(.*)/ IGNORE"+ -- Munge local Received line for postfix running on a+ -- trusted client that relays through. These can trigger+ -- spam filters.+ , "/^Received: by ([^.]+)\\.kitenet\\.net.*/ REPLACE Received: by kitenet.net"+ ] `onChange` Postfix.reloaded `describe` "postfix obscure_client_relay file configured" , Postfix.mappedFile "/etc/postfix/virtual"@@ -482,7 +493,7 @@ , "header_checks = pcre:$config_directory/obscure_client_relay.pcre" , "# Enable postgrey."- , "smtpd_recipient_restrictions = permit_mynetworks,reject_unauth_destination,check_policy_service inet:127.0.0.1:10023"+ , "smtpd_recipient_restrictions = permit_tls_clientcerts,permit_mynetworks,reject_unauth_destination,check_policy_service inet:127.0.0.1:10023" , "# Enable spamass-milter and amavis-milter." , "smtpd_milters = unix:/spamass/spamass.sock unix:amavis/amavis.sock"@@ -541,10 +552,13 @@ `onChange` (pinescript `File.mode` combineModes (readModes ++ executeModes)) `describe` "pine wrapper script"- , "/etc/pine.conf" `File.containsLines`- [ "inbox-path={localhost/novalidate-cert}inbox"+ , "/etc/pine.conf" `File.hasContent`+ [ "# deployed with propellor"+ , "inbox-path={localhost/novalidate-cert/NoRsh}inbox" ] `describe` "pine configured to use local imap server"+ + , Apt.serviceInstalledRunning "mailman" ] where ctx = Context "kitenet.net"@@ -705,8 +719,8 @@ ] , alias "joey.kitenet.net" , toProp $ Apache.siteEnabled "joey.kitenet.net" $ apachecfg "joey.kitenet.net" False- [ "DocumentRoot /home/joey/html"- , "<Directory /home/joey/html/>"+ [ "DocumentRoot /var/www"+ , "<Directory /var/www/>" , " Options Indexes ExecCGI" , " AllowOverride None" , Apache.allowAll
src/Propellor/Property/Ssh.hs view
@@ -3,7 +3,7 @@ permitRootLogin, passwordAuthentication, hasAuthorizedKeys,- restartSshd,+ restarted, randomHostKeys, hostKeys, hostKey,@@ -15,6 +15,7 @@ import Propellor import qualified Propellor.Property.File as File+import qualified Propellor.Property.Service as Service import Propellor.Property.User import Utility.SafeCommand import Utility.FileMode@@ -33,7 +34,7 @@ [ sshdConfig `File.lacksLine` (sshline $ not allowed) , sshdConfig `File.containsLine` (sshline allowed) ]- `onChange` restartSshd+ `onChange` restarted `describe` unwords [ "ssh config:", setting, sshBool allowed ] where sshline v = setting ++ " " ++ sshBool v@@ -59,15 +60,15 @@ where go f = not . null <$> catchDefaultIO "" (readFile f) -restartSshd :: Property-restartSshd = cmdProperty "service" ["ssh", "restart"]+restarted :: Property+restarted = Service.restarted "ssh" -- | Blows away existing host keys and make new ones. -- Useful for systems installed from an image that might reuse host keys. -- A flag file is used to only ever do this once. randomHostKeys :: Property randomHostKeys = flagFile prop "/etc/ssh/.unique_host_keys"- `onChange` restartSshd+ `onChange` restarted where prop = property "ssh random host keys" $ do void $ liftIO $ boolSystem "sh"@@ -91,9 +92,9 @@ [ installkey (SshPubKey keytype "") (install writeFile ".pub") , installkey (SshPrivKey keytype "") (install writeFileProtected "") ]- `onChange` restartSshd+ `onChange` restarted where- desc = "known ssh host key (" ++ fromKeyType keytype ++ ")"+ desc = "known ssh host key (" ++ fromKeyType keytype ++ ")" installkey p a = withPrivData p context $ \getkey -> property desc $ getkey a install writer ext key = do@@ -176,7 +177,7 @@ portline = "Port " ++ show port enable = sshdConfig `File.containsLine` portline `describe` ("ssh listening on " ++ portline)- `onChange` restartSshd+ `onChange` restarted disable = sshdConfig `File.lacksLine` portline `describe` ("ssh not listening on " ++ portline)- `onChange` restartSshd+ `onChange` restarted
src/Propellor/Property/Sudo.hs view
@@ -27,6 +27,6 @@ | not (sudobaseline `isPrefixOf` l) = True | "NOPASSWD" `isInfixOf` l = locked | otherwise = True- modify locked ls+ modify locked ls | sudoline locked `elem` ls = ls | otherwise = ls ++ [sudoline locked]
src/Propellor/Property/Tor.hs view
@@ -3,6 +3,7 @@ import Propellor import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt+import qualified Propellor.Property.Service as Service isBridge :: Property isBridge = setup `requires` Apt.installed ["tor"]@@ -13,7 +14,7 @@ , "ORPort 443" , "BridgeRelay 1" , "Exitpolicy reject *:*"- ] `onChange` restartTor+ ] `onChange` restarted -restartTor :: Property-restartTor = cmdProperty "service" ["tor", "restart"]+restarted :: Property+restarted = Service.restarted "tor"
src/Propellor/SimpleSh.hs view
@@ -48,8 +48,8 @@ flip catchIO (\_e -> writeChan chan Done) $ do let p = (proc cmd params)- { std_in = Inherit- , std_out = CreatePipe+ { std_in = Inherit+ , std_out = CreatePipe , std_err = CreatePipe } (Nothing, Just outh, Just errh, pid) <- createProcess p
src/Propellor/Types.hs view
@@ -89,7 +89,7 @@ getInfo = propertyInfo x `requires` y = Property (propertyDesc x) satisfy info where- info = getInfo y <> getInfo x+ info = getInfo y <> getInfo x satisfy = do r <- propertySatisfy y case r of@@ -146,4 +146,4 @@ | Continue CmdLine | Chain HostName | Docker HostName- deriving (Read, Show, Eq)+ deriving (Read, Show, Eq)
src/Propellor/Types/OS.hs view
@@ -13,15 +13,14 @@ | Ubuntu Release deriving (Show, Eq) -data DebianSuite = Experimental | Unstable | Testing | Stable | DebianRelease Release+-- | Debian has several rolling suites, and a number of stable releases,+-- such as Stable "wheezy".+data DebianSuite = Experimental | Unstable | Testing | Stable Release deriving (Show, Eq) --- | The release that currently corresponds to stable.-stableRelease :: DebianSuite-stableRelease = DebianRelease "wheezy"- isStable :: DebianSuite -> Bool-isStable s = s == Stable || s == stableRelease+isStable (Stable _) = True+isStable _ = False type Release = String type Architecture = String
src/config.hs view
@@ -38,7 +38,7 @@ -- A generic webserver in a Docker container. , Docker.container "webserver" "joeyh/debian-stable"- & os (System (Debian Stable) "amd64")+ & os (System (Debian (Stable "wheezy")) "amd64") & Apt.stdSourcesList & Docker.publish "80:80" & Docker.volume "/var/www:/var/www"