Record propellor (0.8.1) in archive suite sid

This commit is contained in:
Joey Hess 2014-07-09 22:11:31 -04:00
commit f118c369d3
36 changed files with 1050 additions and 947 deletions

9
.gitignore vendored
View File

@ -1,9 +0,0 @@
dist/*
propellor
tags
privdata/local
privdata/keyring.gpg~
Setup
Setup.hi
Setup.o
docker

View File

@ -1,5 +1,7 @@
CABAL?=cabal
DEBDEPS=gnupg ghc cabal-install libghc-missingh-dev libghc-ansi-terminal-dev libghc-ifelse-dev libghc-unix-compat-dev libghc-hslogger-dev libghc-network-dev libghc-quickcheck2-dev libghc-mtl-dev libghc-monadcatchio-transformers-dev
run: deps build
./propellor
@ -10,7 +12,7 @@ build: dist/setup-config
ln -sf dist/build/propellor-config/propellor-config propellor
deps:
@if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install gnupg ghc cabal-install libghc-missingh-dev libghc-ansi-terminal-dev libghc-ifelse-dev libghc-unix-compat-dev libghc-hslogger-dev libghc-network-dev libghc-quickcheck2-dev libghc-mtl-dev libghc-monadcatchio-transformers-dev; fi || true
@if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS) || (apt-get update && apt-get --no-upgrade --no-install-recommends -y install $(DEBDEPS)); fi || true
@if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev || (cabal update; cabal install async); fi || true
dist/setup-config: propellor.cabal

View File

@ -21,8 +21,10 @@ import qualified Propellor.Property.Git as Git
import qualified Propellor.Property.Apache as Apache
import qualified Propellor.Property.Postfix as Postfix
import qualified Propellor.Property.Service as Service
import qualified Propellor.Property.Grub as Grub
import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean
import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost
import qualified Propellor.Property.HostingProvider.Linode as Linode
import qualified Propellor.Property.SiteSpecific.GitHome as GitHome
import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder
import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites
@ -34,7 +36,6 @@ main = defaultMain hosts -- / \___-=O`/|O`/__| (____.'
Deployed -} -- `/-==__ _/__|/__=-| ( \_
hosts :: [Host] -- * \ | | '--------'
hosts = -- (o) `
-- My laptop
[ host "darkstar.kitenet.net"
& ipv6 "2001:4830:1600:187::2" -- sixxs tunnel
@ -42,52 +43,22 @@ hosts = -- (o) `
& Docker.configured
& Docker.docked hosts "android-git-annex"
-- Nothing super-important lives here and mostly it's docker containers.
, standardSystem "clam.kitenet.net" Unstable "amd64"
& ipv4 "162.248.143.249"
& ipv6 "2002:5044:5531::1"
[ "Unreliable server. Anything here may be lost at any time!" ]
& ipv4 "162.248.9.29"
& CloudAtCost.decruft
& Apt.unattendedUpgrades
& Network.ipv6to4
& Tor.isBridge
& Postfix.satellite
& Docker.configured
& Docker.docked hosts "oldusenet-shellbox"
& Docker.docked hosts "openid-provider"
`requires` Apt.serviceInstalledRunning "ntp"
& Docker.docked hosts "ancient-kitenet"
-- 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 "ns9.kitenet.net"
& myDnsSecondary
& alias "znc.kitenet.net"
& JoeySites.ircBouncer
-- For https port 443, shellinabox with ssh login to
-- kitenet.net
& alias "shell.kitenet.net"
& JoeySites.kiteShellBox
-- Nothing is using http port 80 on clam, so listen on
-- that port for ssh, for traveling on bad networks that
-- block 22.
& "/etc/ssh/sshd_config" `File.containsLine` "Port 80"
`onChange` Service.restarted "ssh"
& Docker.garbageCollected `period` Daily
& Apt.installed ["git-annex", "mtr", "screen"]
-- Orca is the main git-annex build box.
, standardSystem "orca.kitenet.net" Unstable "amd64"
[ "Main git-annex build box." ]
& ipv4 "138.38.108.179"
& Hostname.sane
@ -102,15 +73,27 @@ hosts = -- (o) `
& Docker.garbageCollected `period` Daily
& Apt.buildDep ["git-annex"] `period` Daily
-- Important stuff that needs not too much memory or CPU.
, standardSystem "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"
& Apt.installed ["linux-image-amd64"]
& Linode.chainPVGrub 5
& Hostname.sane
& Apt.unattendedUpgrades
& Apt.installed ["systemd"]
& Ssh.hostKeys (Context "kitenet.net")
, standardSystem "diatom.kitenet.net" Stable "amd64"
[ "Important stuff that needs not too much memory or CPU." ]
& ipv4 "107.170.31.195"
& DigitalOcean.distroKernel
& Hostname.sane
& Ssh.hostKey SshDsa
& Ssh.hostKey SshRsa
& Ssh.hostKey SshEcdsa
& Ssh.hostKeys (Context "diatom.kitenet.net")
& Apt.unattendedUpgrades
& Apt.serviceInstalledRunning "ntp"
& Postfix.satellite
@ -120,9 +103,9 @@ hosts = -- (o) `
& Apt.serviceInstalledRunning "swapspace"
& Apt.serviceInstalledRunning "apache2"
& File.hasPrivContent "/etc/ssl/certs/web.pem"
& File.hasPrivContent "/etc/ssl/private/web.pem"
& File.hasPrivContent "/etc/ssl/certs/startssl.pem"
& File.hasPrivContent "/etc/ssl/certs/web.pem" (Context "kitenet.net")
& File.hasPrivContent "/etc/ssl/private/web.pem" (Context "kitenet.net")
& File.hasPrivContent "/etc/ssl/certs/startssl.pem" (Context "kitenet.net")
& Apache.modEnabled "ssl"
& Apache.multiSSL
& File.ownerGroup "/srv/web" "joey" "joey"
@ -163,34 +146,18 @@ hosts = -- (o) `
& Dns.secondaryFor ["animx"] hosts "animx.eu.org"
-- storage and backup server
, standardSystem "elephant.kitenet.net" Unstable "amd64"
, let ctx = Context "elephant.kitenet.net"
in standardSystem "elephant.kitenet.net" Unstable "amd64"
[ "Storage, big data, and backups, omnomnom!" ]
& ipv4 "193.234.225.114"
& Grub.chainPVGrub "hd0,0" "xen/xvda1" 30
& Hostname.sane
& Postfix.satellite
& Apt.unattendedUpgrades
& Ssh.hostKey SshDsa
& Ssh.hostKey SshRsa
& Ssh.hostKey SshEcdsa
& Ssh.keyImported SshRsa "joey"
-- PV-grub chaining
-- http://notes.pault.ag/linode-pv-grub-chainning/
-- (Adapted to use xvda1/hd0,0 instead of xvda/hd0)
& "/boot/grub/menu.lst" `File.hasContent`
[ "default 1"
, "timeout 30"
, ""
, "title grub-xen shim"
, "root (hd0,0)"
, "kernel /boot/xen-shim"
, "boot"
]
& "/boot/load.cf" `File.hasContent`
[ "configfile (xen/xvda1)/boot/grub/grub.cfg" ]
& Apt.installed ["grub-xen"]
& flagFile (scriptProperty ["update-grub; grub-mkimage --prefix '(xen/xvda1)/boot/grub' -c /boot/load.cf -O x86_64-xen /usr/lib/grub/x86_64-xen/*.mod > /boot/xen-shim"]) "/boot/xen-shim"
& Ssh.hostKeys ctx
& Ssh.keyImported SshRsa "joey" ctx
& Apt.serviceInstalledRunning "swapspace"
& alias "eubackup.kitenet.net"
& Apt.installed ["obnam", "sshfs", "rsync"]
@ -201,8 +168,43 @@ hosts = -- (o) `
& alias "podcatcher.kitenet.net"
& Apt.installed ["git-annex"]
& 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
& Docker.docked hosts "oldusenet-shellbox"
& 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.
& "/etc/ssh/sshd_config" `File.containsLine` "Port 80"
`onChange` Service.restarted "ssh"
-- temp
& Docker.docked hosts "amd64-git-annex-builder"
& Docker.docked hosts "i386-git-annex-builder"
& Docker.docked hosts "android-git-annex-builder"
--' __|II| ,.
---- __|II|II|__ ( \_,/\
@ -255,22 +257,25 @@ hosts = -- (o) `
-- temp for an acquantance
] ++ monsters
type Motd = [String]
-- This is my standard system setup.
standardSystem :: HostName -> DebianSuite -> Architecture -> Host
standardSystem hn suite arch = host hn
standardSystem :: HostName -> DebianSuite -> Architecture -> Motd -> Host
standardSystem hn suite arch motd = host hn
& os (System (Debian suite) arch)
& File.hasContent "/etc/motd" ("":motd++[""])
& Apt.stdSourcesList `onChange` Apt.upgrade
& Apt.cacheCleaned
& Apt.installed ["etckeeper"]
& Apt.installed ["ssh"]
& GitHome.installedFor "root"
& User.hasSomePassword "root"
& User.hasSomePassword "root" (Context hn)
-- Harden the system, but only once root's authorized_keys
-- is safely in place.
& check (Ssh.hasAuthorizedKeys "root")
(Ssh.passwordAuthentication False)
& User.accountFor "joey"
& User.hasSomePassword "joey"
& User.hasSomePassword "joey" (Context hn)
& Sudo.enabledFor "joey"
& GitHome.installedFor "joey"
& Apt.installed ["vim", "screen", "less"]
@ -309,14 +314,14 @@ branchableSecondary :: RevertableProperty
branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com"
-- Currently using diatom (ns2) as primary with secondaries
-- clam (ns9) and gandi.
-- elephant (ns3) and gandi.
-- kite handles all mail.
myDnsPrimary :: Domain -> [(BindDomain, Record)] -> RevertableProperty
myDnsPrimary domain extras = Dns.primary hosts domain
(Dns.mkSOA "ns2.kitenet.net" 100) $
[ (RootDomain, NS $ AbsDomain "ns2.kitenet.net")
, (RootDomain, NS $ AbsDomain "ns3.kitenet.net")
, (RootDomain, NS $ AbsDomain "ns6.gandi.net")
, (RootDomain, NS $ AbsDomain "ns9.kitenet.net")
, (RootDomain, MX 0 $ AbsDomain "kitenet.net")
, (RootDomain, TXT "v=spf1 a ?all")
] ++ extras
@ -350,7 +355,6 @@ monsters = -- but do want to track their public keys etc.
& ipv4 "80.68.85.49"
& ipv6 "2001:41c8:125:49::10"
& alias "kitenet.net"
& alias "kite.kitenet.net"
& alias "ns1.kitenet.net"
& alias "ftp.kitenet.net"
& alias "mail.kitenet.net"
@ -377,7 +381,7 @@ monsters = -- but do want to track their public keys etc.
- some static websites
- bitlbee
- prosody
- (used by anna and daddy's git-annex)
- (used by daddy's git-annex)
- named
- (branchable is still pushing to here
- (thinking it's ns2.branchable.com), but it's no

View File

@ -29,7 +29,7 @@ hosts =
& Apt.unattendedUpgrades
& Apt.installed ["etckeeper"]
& Apt.installed ["ssh"]
& User.hasSomePassword "root"
& User.hasSomePassword "root" (Context "mybox.example.com")
& Network.ipv6to4
& File.dirExists "/var/www"
& Docker.docked hosts "webserver"

36
debian/changelog vendored
View File

@ -1,3 +1,39 @@
propellor (0.8.1) unstable; urgency=medium
* Run apt-get update in initial bootstrap.
* --list-fields now includes a table of fields that are not currently set,
but would be used if they got set.
* Remove .gitignore from cabal file list, to avoid build failure on Debian.
Closes: #754334
-- Joey Hess <joeyh@debian.org> Wed, 09 Jul 2014 22:11:31 -0400
propellor (0.8.0) unstable; urgency=medium
* Completely reworked privdata storage. There is now a single file,
and each host is sent only the privdata that its Properties actually use.
To transition existing privdata, run propellor against a host and
watch out for the red failure messages, and run the suggested commands
to store the privdata using the new storage scheme. You may find
it useful to run the old version of propellor to extract data from the old
privdata files during this migration.
Several properties that use privdata now require a context to be
specified. If in doubt, you can use anyContext, or
Context "hostname.example.com"
* Add --edit to edit a privdata value in $EDITOR.
* Add --list-fields to list all currently set privdata fields, along with
the hosts that use them.
* Fix randomHostKeys property to run openssh-server's postinst in a
non-failing way.
* Hostname.sane now cleans up the 127.0.0.1 localhost line in /etc/hosts,
to avoid eg, apache complaining "Could not reliably determine the
server's fully qualified domain name".
-- Joey Hess <joeyh@debian.org> Sun, 06 Jul 2014 18:28:08 -0400
propellor (0.7.0) unstable; urgency=medium
* combineProperties no longer stops when a property fails; now it continues

View File

@ -1,8 +0,0 @@
propellor 0.5.0 released with [[!toggle text="these changes"]]
[[!toggleable text="""
* Removed root domain records from SOA. Instead, use RootDomain
when calling Dns.primary.
* Dns primary and secondary properties are now revertable.
* When unattendedUpgrades is enabled on an Unstable or Testing system,
configure it to allow the upgrades.
* New website, https://propellor.branchable.com/"""]]

View File

@ -1,8 +0,0 @@
propellor 0.5.1 released with [[!toggle text="these changes"]]
[[!toggleable text="""
* Primary DNS servers now have allow-transfer automatically populated
with the IP addresses of secondary dns servers. So, it's important
that all secondary DNS servers have an ipv4 (and/or ipv6) property
configured.
* Deal with old ssh connection caching sockets.
* Add missing build deps and deps. Closes: #[745459](http://bugs.debian.org/745459)"""]]

View File

@ -0,0 +1,9 @@
propellor 0.7.0 released with [[!toggle text="these changes"]]
[[!toggleable text="""
* combineProperties no longer stops when a property fails; now it continues
trying to satisfy all properties on the list before propigating the
failure.
* Attr is renamed to Info.
* Renamed wrapper to propellor to make cabal installation of propellor work.
* When git gpg signature of a fetched git branch cannot be verified,
propellor will now continue running, but without merging in that branch."""]]

View File

@ -0,0 +1,20 @@
propellor 0.8.0 released with [[!toggle text="these changes"]]
[[!toggleable text="""
* Completely reworked privdata storage. There is now a single file,
and each host is sent only the privdata that its Properties actually use.
To transition existing privdata, run propellor against a host and
watch out for the red failure messages, and run the suggested commands
to store the privdata using the new storage scheme. You may find
it useful to run the old version of propellor to extract data from the old
privdata files during this migration.
Several properties that use privdata now require a context to be
specified. If in doubt, you can use anyContext, or
Context "hostname.example.com"
* Add --edit to edit a privdata value in $EDITOR.
* Add --list-fields to list all currently set privdata fields, along with
the hosts that use them.
* Fix randomHostKeys property to run openssh-server's postinst in a
non-failing way.
* Hostname.sane now cleans up the 127.0.0.1 localhost line in /etc/hosts,
to avoid eg, apache complaining "Could not reliably determine the
server's fully qualified domain name"."""]]

View File

@ -27,10 +27,11 @@ Since the propoellor git repository is public, you can't store
in cleartext private data such as passwords, ssh private keys, etc.
Instead, `propellor --spin $host` looks for a
`~/.propellor/privdata/$host.gpg` file and if found decrypts it and sends
it to the remote host using ssh. This lets a remote host know its own
private data, without seeing all the rest.
`~/.propellor/privdata/privdata.gpg` file and if found decrypts it,
extracts the private that that the $host needs, and sends it to to the
$host using ssh. This lets a host know its own private data, without
seeing all the rest.
To securely store private data, use: `propellor --set $host $field`
The field name will be something like 'Password "root"'; see PrivData.hs
for available fields.
To securely store private data, use: `propellor --set $field $context`
Propellor will tell you the details when you use a Property that needs
PrivData.

View File

@ -0,0 +1,12 @@
It can be annoying to need to move privdata values around when moving
services between hosts, which is otherwise often just a cut-n-paste
of a line in config.hs.
It would be better if privdata were all stored in one Map, and the set of
privdata that a host's current properties need were sent to it
automatically, rather than the current 1-file-per-host separation.
For this to work though, each property that uses privdata would need to add
to the host's Info the privdata field it uses.
> [[done]]! --[[Joey]]

View File

@ -0,0 +1,28 @@
Currently, Info about a Host's Properties is manually gathered and
propigated. propertyList combines the Info of the Properties in the list.
Docker.docked extracts relevant Info from the Properties of the container
(but not al of it, intentionally!).
This works, but it's error-prone. Consider this example:
withOS desc $ \o -> case o of
(Just (System (Debian Unstable) _)) -> ensureProperty foo
_ -> ensureProperty bar
Here, the Info of `foo` is not propigated out. Nor is `bar`'s Info.
Of course, only one of them will be run, and only its info should be propigated
out..
One approach might be to make the Propellor monad be able to be run in two
modes. In one mode, it actually perform IO, etc. In the other mode, all
liftIO is a no-op, but all Info encountered is accumulated using a Reader
monad. This might need two separate monad definitions.
That is surely doable, but the withOS example above shows a problem with it --
the OS is itself part of a Host's info, so won't be known until all its
properties have been examined for info!
Perhaps that can be finessed. We don't really need to propigate out OS info.
Just DNS and PrivDataField Info. So info could be collected in 2 passes,
first as it's done now by static propertyInfo values. Then by running
the Properties in the Reader monad.

View File

@ -1,82 +0,0 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
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
=5rkr
-----END PGP MESSAGE-----

View File

@ -1,22 +0,0 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
hQIMA7ODiaEXBlRZAQ/9HdpfvTbfOnyqLlEK1WC9QO3HrF9w9yrEH8hCrVFJ/86r
xHK62+7I6wrV2W1UAHRx1b4H9qEkbD8+MAmjB2JYVmJUqvdzNv1jhsWwPpAcTQN1
RVWR95Auc2rjXXSiZRudLaWdxZdDBg5PWApH5+NW5grtNRKsTbYB1/No2iYJvDuv
WcbBkuFyEa0WbRiqUaUIyO9XAGyj4hqVDQSXH2Gzei8oB3PZh9+Lwv7i05lvSup+
dtbtEsEdDiJbCTzIakV6vEQT1BDVMpe6jRQbv7c+LXLeM65Tpl+2hnTPSTy1zcr0
bjfkFa6A75sHmIf0WGKAZj+jmNchp4AMdjmoMiXkHacDsBw623NgiMgzUnfWVkFm
BIrdk5AGBi50nqPxwtY7nWd0cbApvNvT1zlx8MlRBSZQ2zcijo5AjiCwb+eLLVhv
6oiKqpYGC1XpdNFFsaKHnHBCgsPIIetwx4ng0+lvRgBO+DEQ4RvvdKMhy/3nXrpz
NVdr/gG+HMBW1BjyCd9ArmTtSITQWDT8vnLmyFbc0aJ88c2rEjv2BpXmhKjxEoEn
IMxc3/9cLrVVRocnlq7YvKDZpfuwjgDs86D3e03Up7hQZhLU4+r8Wq7azxk3wE06
lAQIS0OwCe75EZvVWYHwhZ3vEoBE/TeqeaRyhKpofFS5GvtIJsZBjenmRcdOJTPS
wDQB/c3XkjuIrJErMBx/KrNQc2mAjcUpvW4+Ukj5vtpusi3qmSfsyaVJ4ZS9SwVv
7RPqLsH5Iz3Ga6u4of/mg+iG/wqJPJy2A9A/XOnsNVCVR3a+NxjPqevEjW1Pr6RL
SOMQSK6OuwuT1H13M1Z7R6dbg+pCcbc+hek9/6KzeZS9q4Di7aqq7+XeDr4c51+Q
2ojS4DG0/vAJmOO+E8ZatGiwdI8kmELrzAF8zzGz+ZujXSuiPXVd2kw/JdfUaTRq
KrtNhiGWWM44YWS43TYuYCoVgokrdVXzsZyKyhHzgXKCits3R5+QcUgUx2vESuOs
+FdM8fAd
=a0dr
-----END PGP MESSAGE-----

View File

@ -1,372 +0,0 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
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
7/HW/0mHEZlf846FaPssiNT+Ieyj9Q==
=lxmO
-----END PGP MESSAGE-----

View File

@ -1,111 +0,0 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
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
qQxw6B5ksDEcXeNKy5xa7gfOl5OJ+WxvbNHOy2s=
=oXYz
-----END PGP MESSAGE-----

View File

@ -1,57 +0,0 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
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
=ZBoU
-----END PGP MESSAGE-----

439
privdata/privdata.gpg Normal file
View File

@ -0,0 +1,439 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
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
7pa2HSH3ZFmSC8g5gt5ZA3TSQv8iY/7xD5cMsbk=
=6HOm
-----END PGP MESSAGE-----

View File

@ -1,5 +1,5 @@
Name: propellor
Version: 0.7.0
Version: 0.8.1
Cabal-Version: >= 1.6
License: BSD3
Maintainer: Joey Hess <joey@kitenet.net>
@ -25,7 +25,6 @@ Extra-Source-Files:
debian/copyright
debian/rules
debian/lintian-overrides
.gitignore
Synopsis: property-based host configuration management in haskell
Description:
Propellor enures that the system it's run in satisfies a list of
@ -81,6 +80,7 @@ Library
Propellor.Property.File
Propellor.Property.Git
Propellor.Property.Gpg
Propellor.Property.Grub
Propellor.Property.Network
Propellor.Property.Obnam
Propellor.Property.OpenId
@ -92,8 +92,9 @@ Library
Propellor.Property.Sudo
Propellor.Property.Tor
Propellor.Property.User
Propellor.Property.HostingProvider.DigitalOcean
Propellor.Property.HostingProvider.CloudAtCost
Propellor.Property.HostingProvider.DigitalOcean
Propellor.Property.HostingProvider.Linode
Propellor.Property.SiteSpecific.GitHome
Propellor.Property.SiteSpecific.JoeySites
Propellor.Property.SiteSpecific.GitAnnexBuilder
@ -105,6 +106,7 @@ Library
Propellor.Types
Propellor.Types.OS
Propellor.Types.Dns
Propellor.Types.PrivData
Other-Modules:
Propellor.Types.Info
Propellor.CmdLine
@ -126,6 +128,7 @@ Library
Utility.Process
Utility.SafeCommand
Utility.Scheduled
Utility.Table
Utility.ThreadScheduler
Utility.Tmp
Utility.UserInfo

View File

@ -26,9 +26,11 @@ usage = do
, " propellor"
, " propellor hostname"
, " propellor --spin hostname"
, " propellor --set hostname field"
, " propellor --dump hostname field"
, " propellor --add-key keyid"
, " propellor --set field context"
, " propellor --dump field context"
, " propellor --edit field context"
, " propellor --list-fields"
]
exitFailure
@ -39,8 +41,10 @@ processCmdLine = go =<< getArgs
go ("--spin":h:[]) = return $ Spin h
go ("--boot":h:[]) = return $ Boot h
go ("--add-key":k:[]) = return $ AddKey k
go ("--set":h:f:[]) = withprivfield f (return . Set h)
go ("--dump":h:f:[]) = withprivfield f (return . Dump h)
go ("--set":f:c:[]) = withprivfield f c Set
go ("--dump":f:c:[]) = withprivfield f c Dump
go ("--edit":f:c:[]) = withprivfield f c Edit
go ("--list-fields":[]) = return ListFields
go ("--continue":s:[]) = case readish s of
Just cmdline -> return $ Continue cmdline
Nothing -> errorMessage "--continue serialization failure"
@ -56,8 +60,8 @@ processCmdLine = go =<< getArgs
else return $ Run s
go _ = usage
withprivfield s f = case readish s of
Just pf -> f pf
withprivfield s c f = case readish s of
Just pf -> return $ f pf (Context c)
Nothing -> errorMessage $ "Unknown privdata field " ++ s
defaultMain :: [Host] -> IO ()
@ -69,8 +73,10 @@ defaultMain hostlist = do
go True cmdline
where
go _ (Continue cmdline) = go False cmdline
go _ (Set hn field) = setPrivData hn field
go _ (Dump hn field) = dumpPrivData hn field
go _ (Set field context) = setPrivData field context
go _ (Dump field context) = dumpPrivData field context
go _ (Edit field context) = editPrivData field context
go _ ListFields = listPrivDataFields hostlist
go _ (AddKey keyid) = addKey keyid
go _ (Chain hn) = withhost hn $ \h -> do
r <- runPropellor h $ ensureProperties $ hostProperties h
@ -78,7 +84,7 @@ defaultMain hostlist = do
go _ (Docker hn) = Docker.chain hn
go True cmdline@(Spin _) = buildFirst cmdline $ go False cmdline
go True cmdline = updateFirst cmdline $ go False cmdline
go False (Spin hn) = withhost hn $ const $ spin hn
go False (Spin hn) = withhost hn $ spin hn
go False (Run hn) = ifM ((==) 0 <$> getRealUserID)
( onlyProcess $ withhost hn mainProperties
, go True (Spin hn)
@ -86,7 +92,7 @@ defaultMain hostlist = do
go False (Boot hn) = onlyProcess $ withhost hn boot
withhost :: HostName -> (Host -> IO ()) -> IO ()
withhost hn a = maybe (unknownhost hn) a (findHost hostlist hn)
withhost hn a = maybe (unknownhost hn hostlist) a (findHost hostlist hn)
onlyProcess :: IO a -> IO a
onlyProcess a = bracket lock unlock (const a)
@ -100,11 +106,12 @@ onlyProcess a = bracket lock unlock (const a)
alreadyrunning = error "Propellor is already running on this host!"
lockfile = localdir </> ".lock"
unknownhost :: HostName -> IO a
unknownhost h = errorMessage $ unlines
unknownhost :: HostName -> [Host] -> IO a
unknownhost h hosts = errorMessage $ unlines
[ "Propellor does not know about host: " ++ h
, "(Perhaps you should specify the real hostname on the command line?)"
, "(Or, edit propellor's config.hs to configure this host)"
, "Known hosts: " ++ unwords (map hostName hosts)
]
buildFirst :: CmdLine -> IO () -> IO ()
@ -170,17 +177,19 @@ updateFirst cmdline next = do
getCurrentGitSha1 :: String -> IO String
getCurrentGitSha1 branchref = readProcess "git" ["show-ref", "--hash", branchref]
spin :: HostName -> IO ()
spin hn = do
spin :: HostName -> Host -> IO ()
spin hn hst = do
url <- getUrl
void $ gitCommit [Param "--allow-empty", Param "-a", Param "-m", Param "propellor spin"]
void $ boolSystem "git" [Param "push"]
cacheparams <- toCommand <$> sshCachingParams hn
go cacheparams url =<< gpgDecrypt (privDataFile hn)
go cacheparams url =<< hostprivdata
where
hostprivdata = show . filterPrivData hst <$> decryptPrivData
go cacheparams url privdata = withBothHandles createProcessSuccess (proc "ssh" $ cacheparams ++ [user, bootstrapcmd]) $ \(toh, fromh) -> do
let finish = do
senddata toh (privDataFile hn) privDataMarker privdata
senddata toh "privdata" privDataMarker privdata
hClose toh
-- Display remaining output.
@ -201,7 +210,8 @@ spin hn = do
bootstrapcmd = shellWrap $ intercalate " ; "
[ "if [ ! -d " ++ localdir ++ " ]"
, "then " ++ intercalate " && "
[ "apt-get --no-install-recommends --no-upgrade -y install git make"
[ "apt-get update"
, "apt-get --no-install-recommends --no-upgrade -y install git make"
, "echo " ++ toMarked statusMarker (show NeedGitClone)
]
, "else " ++ intercalate " && "
@ -222,8 +232,8 @@ spin hn = do
Just status -> return status
showremote s = putStrLn s
senddata toh f marker s = void $
actionMessage ("Sending " ++ f ++ " (" ++ show (length s) ++ " bytes) to " ++ hn) $ do
senddata toh desc marker s = void $
actionMessage ("Sending " ++ desc ++ " (" ++ show (length s) ++ " bytes) to " ++ hn) $ do
sendMarked toh marker s
return True

View File

@ -2,18 +2,23 @@
module Propellor.PrivData where
import qualified Data.Map as M
import Control.Applicative
import System.FilePath
import System.IO
import System.Directory
import Data.Maybe
import Data.Monoid
import Data.List
import Control.Monad
import Control.Monad.IfElse
import "mtl" Control.Monad.Reader
import qualified Data.Map as M
import qualified Data.Set as S
import Propellor.Types
import Propellor.Types.Info
import Propellor.Message
import Propellor.Info
import Utility.Monad
import Utility.PartialPrelude
import Utility.Exception
@ -21,53 +26,123 @@ import Utility.Process
import Utility.Tmp
import Utility.SafeCommand
import Utility.Misc
import Utility.FileMode
import Utility.Env
import Utility.Table
-- | When the specified PrivDataField is available on the host Propellor
-- is provisioning, it provies the data to the action. Otherwise, it prints
-- a message to help the user make the necessary private data available.
withPrivData :: PrivDataField -> (String -> Propellor Result) -> Propellor Result
withPrivData field a = maybe missing a =<< liftIO (getPrivData field)
-- | Allows a Property to access the value of a specific PrivDataField,
-- for use in a specific Context.
--
-- Example use:
--
-- > withPrivData (PrivFile pemfile) (Context "joeyh.name") $ \getdata ->
-- > property "joeyh.name ssl cert" $ getdata $ \privdata ->
-- > liftIO $ writeFile pemfile privdata
-- > where pemfile = "/etc/ssl/certs/web.pem"
--
-- Note that if the value is not available, the action is not run
-- and instead it prints a message to help the user make the necessary
-- private data available.
--
-- The resulting Property includes Info about the PrivDataField
-- being used, which is necessary to ensure that the privdata is sent to
-- the remote host by propellor.
withPrivData
:: PrivDataField
-> Context
-> (((PrivData -> Propellor Result) -> Propellor Result) -> Property)
-> Property
withPrivData field context@(Context cname) mkprop = addinfo $ mkprop $ \a ->
maybe missing a =<< liftIO (getLocalPrivData field context)
where
missing = do
host <- asks hostName
let host' = if ".docker" `isSuffixOf` host
then "$parent_host"
else host
liftIO $ do
warningMessage $ "Missing privdata " ++ show field
putStrLn $ "Fix this by running: propellor --set "++host'++" '" ++ show field ++ "'"
return FailedChange
missing = liftIO $ do
warningMessage $ "Missing privdata " ++ show field ++ " (for " ++ cname ++ ")"
putStrLn $ "Fix this by running: propellor --set '" ++ show field ++ "' '" ++ cname ++ "'"
return FailedChange
addinfo p = p { propertyInfo = propertyInfo p <> mempty { _privDataFields = S.singleton (field, context) } }
getPrivData :: PrivDataField -> IO (Maybe String)
getPrivData field = do
m <- catchDefaultIO Nothing $ readish <$> readFile privDataLocal
return $ maybe Nothing (M.lookup field) m
addPrivDataField :: (PrivDataField, Context) -> Property
addPrivDataField v = pureInfoProperty (show v) $
mempty { _privDataFields = S.singleton v }
setPrivData :: HostName -> PrivDataField -> IO ()
setPrivData host field = do
{- Gets the requested field's value, in the specified context if it's
- available, from the host's local privdata cache. -}
getLocalPrivData :: PrivDataField -> Context -> IO (Maybe PrivData)
getLocalPrivData field context =
getPrivData field context . fromMaybe M.empty <$> localcache
where
localcache = catchDefaultIO Nothing $ readish <$> readFile privDataLocal
type PrivMap = M.Map (PrivDataField, Context) PrivData
{- Get only the set of PrivData that the Host's Info says it uses. -}
filterPrivData :: Host -> PrivMap -> PrivMap
filterPrivData host = M.filterWithKey (\k _v -> S.member k used)
where
used = _privDataFields $ hostInfo host
getPrivData :: PrivDataField -> Context -> PrivMap -> Maybe PrivData
getPrivData field context = M.lookup (field, context)
setPrivData :: PrivDataField -> Context -> IO ()
setPrivData field context = do
putStrLn "Enter private data on stdin; ctrl-D when done:"
value <- chomp <$> hGetContentsStrict stdin
setPrivDataTo field context =<< hGetContentsStrict stdin
dumpPrivData :: PrivDataField -> Context -> IO ()
dumpPrivData field context =
maybe (error "Requested privdata is not set.") putStrLn
=<< (getPrivData field context <$> decryptPrivData)
editPrivData :: PrivDataField -> Context -> IO ()
editPrivData field context = do
v <- getPrivData field context <$> decryptPrivData
v' <- withTmpFile "propellorXXXX" $ \f h -> do
hClose h
maybe noop (writeFileProtected f) v
editor <- getEnvDefault "EDITOR" "vi"
unlessM (boolSystem editor [File f]) $
error "Editor failed; aborting."
readFile f
setPrivDataTo field context v'
listPrivDataFields :: [Host] -> IO ()
listPrivDataFields hosts = do
m <- decryptPrivData
showtable "Currently set data:" $
map mkrow (M.keys m)
showtable "Data that would be used if set:" $
map mkrow (M.keys $ M.difference wantedmap m)
where
header = ["Field", "Context", "Used by"]
mkrow k@(field, (Context context)) =
[ shellEscape $ show field
, shellEscape context
, intercalate ", " $ sort $ fromMaybe [] $ M.lookup k usedby
]
mkhostmap host = M.fromList $ map (\k -> (k, [hostName host])) $
S.toList $ _privDataFields $ hostInfo host
usedby = M.unionsWith (++) $ map mkhostmap hosts
wantedmap = M.fromList $ zip (M.keys usedby) (repeat "")
showtable desc rows = do
putStrLn $ "\n" ++ desc
putStr $ unlines $ formatTable $ tableWithHeader header rows
setPrivDataTo :: PrivDataField -> Context -> PrivData -> IO ()
setPrivDataTo field context value = do
makePrivDataDir
let f = privDataFile host
m <- decryptPrivData host
let m' = M.insert field value m
gpgEncrypt f (show m')
m <- decryptPrivData
let m' = M.insert (field, context) (chomp value) m
gpgEncrypt privDataFile (show m')
putStrLn "Private data set."
void $ boolSystem "git" [Param "add", File f]
void $ boolSystem "git" [Param "add", File privDataFile]
where
chomp s
| end s == "\n" = chomp (beginning s)
| otherwise = s
dumpPrivData :: HostName -> PrivDataField -> IO ()
dumpPrivData host field = go . M.lookup field =<< decryptPrivData host
where
go Nothing = error "Requested privdata is not set."
go (Just s) = putStrLn s
decryptPrivData :: HostName -> IO (M.Map PrivDataField String)
decryptPrivData host = fromMaybe M.empty . readish
<$> gpgDecrypt (privDataFile host)
decryptPrivData :: IO PrivMap
decryptPrivData = fromMaybe M.empty . readish <$> gpgDecrypt privDataFile
makePrivDataDir :: IO ()
makePrivDataDir = createDirectoryIfMissing False privDataDir
@ -75,8 +150,8 @@ makePrivDataDir = createDirectoryIfMissing False privDataDir
privDataDir :: FilePath
privDataDir = "privdata"
privDataFile :: HostName -> FilePath
privDataFile host = privDataDir </> host ++ ".gpg"
privDataFile :: FilePath
privDataFile = privDataDir </> "privdata.gpg"
privDataLocal :: FilePath
privDataLocal = privDataDir </> "local"

View File

@ -55,10 +55,11 @@ installed = Apt.installed ["docker.io"]
-- | Configures docker with an authentication file, so that images can be
-- pushed to index.docker.io. Optional.
configured :: Property
configured = property "docker configured" go `requires` installed
configured = prop `requires` installed
where
go = withPrivData DockerAuthentication $ \cfg -> ensureProperty $
"/root/.dockercfg" `File.hasContent` (lines cfg)
prop = withPrivData DockerAuthentication anyContext $ \getcfg ->
property "docker configured" $ getcfg $ \cfg -> ensureProperty $
"/root/.dockercfg" `File.hasContent` (lines cfg)
-- | A short descriptive name for a container.
-- Should not contain whitespace or other unusual characters,
@ -86,8 +87,8 @@ cn2hn cn = cn ++ ".docker"
-- The container has its own Properties which are handled by running
-- propellor inside the container.
--
-- Additionally, the container can have DNS info, such as a CNAME.
-- These become info of the host(s) it's docked in.
-- When the container's Properties include DNS info, such as a CNAME,
-- that is propigated to the Info of the host(s) it's docked in.
--
-- Reverting this property ensures that the container is stopped and
-- removed.
@ -96,7 +97,7 @@ docked
-> ContainerName
-> RevertableProperty
docked hosts cn = RevertableProperty
((maybe id exposeDnsInfos mhost) (go "docked" setup))
((maybe id propigateInfo mhost) (go "docked" setup))
(go "undocked" teardown)
where
go desc a = property (desc ++ " " ++ cn) $ do
@ -123,9 +124,12 @@ docked hosts cn = RevertableProperty
]
]
exposeDnsInfos :: Host -> Property -> Property
exposeDnsInfos (Host _ _ containerinfo) p = combineProperties (propertyDesc p) $
p : map addDNS (S.toList $ _dns containerinfo)
propigateInfo :: Host -> Property -> Property
propigateInfo (Host _ _ containerinfo) p =
combineProperties (propertyDesc p) $ p : dnsprops ++ privprops
where
dnsprops = map addDNS (S.toList $ _dns containerinfo)
privprops = map addPrivDataField (S.toList $ _privDataFields containerinfo)
findContainer
:: Maybe Host
@ -390,7 +394,7 @@ chain s = case toContainerId s of
-- being run. So, retry connections to the client for up to
-- 1 minute.
provisionContainer :: ContainerId -> Property
provisionContainer cid = containerDesc cid $ property "provision" $ liftIO $ do
provisionContainer cid = containerDesc cid $ property "provisioned" $ liftIO $ do
let shim = Shim.file (localdir </> "propellor") (localdir </> shimdir cid)
r <- simpleShClientRetry 60 (namedPipe cid) shim params (go Nothing)
when (r /= FailedChange) $

View File

@ -17,16 +17,17 @@ f `hasContent` newcontent = fileProperty ("replace " ++ f)
--
-- The file's permissions are preserved if the file already existed.
-- Otherwise, they're set to 600.
hasPrivContent :: FilePath -> Property
hasPrivContent f = property desc $ withPrivData (PrivFile f) $ \privcontent ->
ensureProperty $ fileProperty' writeFileProtected desc
(\_oldcontent -> lines privcontent) f
hasPrivContent :: FilePath -> Context -> Property
hasPrivContent f context = withPrivData (PrivFile f) context $ \getcontent ->
property desc $ getcontent $ \privcontent ->
ensureProperty $ fileProperty' writeFileProtected desc
(\_oldcontent -> lines privcontent) f
where
desc = "privcontent " ++ f
-- | Leaves the file world-readable.
hasPrivContentExposed :: FilePath -> Property
hasPrivContentExposed f = hasPrivContent f `onChange`
hasPrivContentExposed :: FilePath -> Context -> Property
hasPrivContentExposed f context = hasPrivContent f context `onChange`
mode f (combineModes (ownerWriteMode:readModes))
-- | Ensures that a line is present in a file, adding it to the end if not.

View File

@ -9,6 +9,8 @@ import System.PosixCompat
installed :: Property
installed = Apt.installed ["gnupg"]
type GpgKeyId = String
-- | Sets up a user with a gpg key from the privdata.
--
-- Note that if a secret key is exported using gpg -a --export-secret-key,
@ -21,19 +23,20 @@ installed = Apt.installed ["gnupg"]
-- The GpgKeyId does not have to be a numeric id; it can just as easily
-- be a description of the key.
keyImported :: GpgKeyId -> UserName -> Property
keyImported keyid user = flagFile' (property desc go) genflag
keyImported keyid user = flagFile' prop genflag
`requires` installed
where
desc = user ++ " has gpg key " ++ show keyid
genflag = do
d <- dotDir user
return $ d </> ".propellor-imported-keyid-" ++ keyid
go = withPrivData (GpgKey keyid) $ \key -> makeChange $
withHandle StdinHandle createProcessSuccess
(proc "su" ["-c", "gpg --import", user]) $ \h -> do
fileEncoding h
hPutStr h key
hClose h
prop = withPrivData GpgKey (Context keyid) $ \getkey ->
property desc $ getkey $ \key -> makeChange $
withHandle StdinHandle createProcessSuccess
(proc "su" ["-c", "gpg --import", user]) $ \h -> do
fileEncoding h
hPutStr h key
hClose h
dotDir :: UserName -> IO FilePath
dotDir user = do

View File

@ -0,0 +1,39 @@
module Propellor.Property.Grub where
import Propellor
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Apt as Apt
-- | Eg, hd0,0 or xen/xvda1
type GrubDevice = String
type TimeoutSecs = Int
-- | Use PV-grub chaining to boot
--
-- Useful when the VPS's pv-grub is too old to boot a modern kernel image.
--
-- http://notes.pault.ag/linode-pv-grub-chainning/
--
-- The rootdev should be in the form "hd0", while the bootdev is in the form
-- "xen/xvda".
chainPVGrub :: GrubDevice -> GrubDevice -> TimeoutSecs -> Property
chainPVGrub rootdev bootdev timeout = combineProperties desc
[ File.dirExists "/boot/grub"
, "/boot/grub/menu.lst" `File.hasContent`
[ "default 1"
, "timeout " ++ show timeout
, ""
, "title grub-xen shim"
, "root (" ++ rootdev ++ ")"
, "kernel /boot/xen-shim"
, "boot"
]
, "/boot/load.cf" `File.hasContent`
[ "configfile (" ++ bootdev ++ ")/boot/grub/grub.cfg" ]
, Apt.installed ["grub-xen"]
, flagFile (scriptProperty ["update-grub; grub-mkimage --prefix '(" ++ bootdev ++ ")/boot/grub' -c /boot/load.cf -O x86_64-xen /usr/lib/grub/x86_64-xen/*.mod > /boot/xen-shim"]) "/boot/xen-shim"
`describe` "/boot-xen-shim"
]
where
desc = "chain PV-grub"

View File

@ -0,0 +1,10 @@
module Propellor.Property.HostingProvider.Linode where
import Propellor
import qualified Propellor.Property.Grub as Grub
-- | Linode's pv-grub-x86_64 does not currently support booting recent
-- Debian kernels compressed with xz. This sets up pv-grub chaing to enable
-- it.
chainPVGrub :: Grub.TimeoutSecs -> Property
chainPVGrub = Grub.chainPVGrub "hd0" "xen/xvda"

View File

@ -3,11 +3,16 @@ module Propellor.Property.Hostname where
import Propellor
import qualified Propellor.Property.File as File
-- | Ensures that the hostname is set to the HostInfo value.
-- | Ensures that the hostname is set using best practices.
--
-- Configures /etc/hostname and the current hostname.
--
-- A FQDN also configures /etc/hosts, with an entry for 127.0.1.1, which is
-- standard at least on Debian to set the FDQN (127.0.0.1 is localhost).
-- /etc/hosts is also configured, with an entry for 127.0.1.1, which is
-- standard at least on Debian to set the FDQN.
--
-- Also, the /etc/hosts 127.0.0.1 line is set to localhost. Putting any
-- other hostnames there is not best practices and can lead to annoying
-- messages from eg, apache.
sane :: Property
sane = property ("sane hostname") (ensureProperty . setTo =<< asks hostName)
@ -21,13 +26,14 @@ setTo hn = combineProperties desc go
[ Just $ "/etc/hostname" `File.hasContent` [basehost]
, if null domain
then Nothing
else Just $ File.fileProperty desc
addhostline "/etc/hosts"
else Just $ trivial $ hostsline "127.0.1.1" [hn, basehost]
, Just $ trivial $ hostsline "127.0.0.1" ["localhost"]
, Just $ trivial $ cmdProperty "hostname" [basehost]
]
hostip = "127.0.1.1"
hostline = hostip ++ "\t" ++ hn ++ " " ++ basehost
addhostline ls = hostline : filter (not . hashostip) ls
hashostip l = headMaybe (words l) == Just hostip
hostsline ip names = File.fileProperty desc
(addhostsline ip names)
"/etc/hosts"
addhostsline ip names ls =
(ip ++ "\t" ++ (unwords names)) : filter (not . hasip ip) ls
hasip ip l = headMaybe (words l) == Just ip

View File

@ -25,5 +25,6 @@ providerFor users baseurl = propertyList desc $
-- the identitites directory controls access, so open up
-- file mode
identfile u = File.hasPrivContentExposed $
concat $ [ "/var/lib/simpleid/identities/", u, ".identity" ]
identfile u = File.hasPrivContentExposed
(concat [ "/var/lib/simpleid/identities/", u, ".identity" ])
(Context baseurl)

View File

@ -23,29 +23,25 @@ builddir = gitbuilderdir </> "build"
type TimeOut = String -- eg, 5h
autobuilder :: CronTimes -> TimeOut -> Bool -> Property
autobuilder crontimes timeout rsyncupload = combineProperties "gitannexbuilder"
autobuilder :: Architecture -> CronTimes -> TimeOut -> Property
autobuilder arch crontimes timeout = combineProperties "gitannexbuilder"
[ Apt.serviceInstalledRunning "cron"
, Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir $
"git pull ; timeout " ++ timeout ++ " ./autobuild"
-- The builduser account does not have a password set,
-- instead use the password privdata to hold the rsync server
-- password used to upload the built image.
, property "rsync password" $ do
let f = homedir </> "rsyncpassword"
if rsyncupload
then withPrivData (Password builduser) $ \p -> do
oldp <- liftIO $ catchDefaultIO "" $
readFileStrict f
if p /= oldp
then makeChange $ writeFile f p
else noChange
else do
ifM (liftIO $ doesFileExist f)
( noChange
, makeChange $ writeFile f "no password configured"
)
, withPrivData (Password builduser) context $ \getpw ->
property "rsync password" $ getpw $ \pw -> do
oldpw <- liftIO $ catchDefaultIO "" $
readFileStrict pwfile
if pw /= oldpw
then makeChange $ writeFile pwfile pw
else noChange
]
where
context = Context ("gitannexbuilder " ++ arch)
pwfile = homedir </> "rsyncpassword"
tree :: Architecture -> Property
tree buildarch = combineProperties "gitannexbuilder tree"
@ -101,13 +97,13 @@ standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.conta
& User.accountFor builduser
& tree arch
& buildDepsApt
& autobuilder (show buildminute ++ " * * * *") timeout True
& autobuilder arch (show buildminute ++ " * * * *") timeout
androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host
androidAutoBuilderContainer dockerImage crontimes timeout =
androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir
& Apt.unattendedUpgrades
& autobuilder crontimes timeout True
& autobuilder "android" crontimes timeout
-- Android is cross-built in a Debian i386 container, using the Android NDK.
androidContainer :: (System -> Docker.Image) -> Docker.ContainerName -> Property -> FilePath -> Host
@ -154,7 +150,7 @@ armelCompanionContainer dockerImage = Docker.container "armel-git-annex-builder-
-- The armel builder can ssh to this companion.
& Docker.expose "22"
& Apt.serviceInstalledRunning "ssh"
& Ssh.authorizedKeys builduser
& Ssh.authorizedKeys builduser (Context "armel-git-annex-builder")
armelAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host
armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder"
@ -172,9 +168,9 @@ armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "arme
-- git-annex/standalone/linux/install-haskell-packages
-- which is not fully automated.)
& buildDepsNoHaskellLibs
& autobuilder crontimes timeout True
& autobuilder "armel" crontimes timeout
`requires` tree "armel"
& Ssh.keyImported SshRsa builduser
& Ssh.keyImported SshRsa builduser (Context "armel-git-annex-builder")
& trivial writecompanionaddress
where
writecompanionaddress = scriptProperty

View File

@ -16,6 +16,7 @@ import qualified Propellor.Property.Obnam as Obnam
import qualified Propellor.Property.Apache as Apache
import Utility.SafeCommand
import Utility.FileMode
import Utility.Path
import Data.List
import System.Posix.Files
@ -28,7 +29,7 @@ oldUseNetServer hosts = propertyList ("olduse.net server")
[ "--repository=sftp://2318@usw-s002.rsync.net/~/olduse.net"
, "--client-name=spool"
] Obnam.OnlyClient
`requires` Ssh.keyImported SshRsa "root"
`requires` Ssh.keyImported SshRsa "root" (Context "olduse.net")
`requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root"
, check (not . isSymbolicLink <$> getSymbolicLinkStatus newsspool) $
property "olduse.net spool in place" $ makeChange $ do
@ -84,37 +85,44 @@ oldUseNetInstalled pkg = check (not <$> Apt.isInstalled pkg) $
, "dpkg -i ../" ++ pkg ++ "_*.deb || true"
, "apt-get -fy install" -- dependencies
, "rm -rf /root/tmp/oldusenet"
-- screen fails unless the directory has this mode.
-- not sure what's going on.
, "chmod 777 /var/run/screen"
] `describe` "olduse.net built"
]
kgbServer :: Property
kgbServer = withOS desc $ \o -> case o of
(Just (System (Debian Unstable) _)) ->
ensureProperty $ propertyList desc
[ Apt.serviceInstalledRunning "kgb-bot"
, File.hasPrivContent "/etc/kgb-bot/kgb.conf"
`onChange` Service.restarted "kgb-bot"
, "/etc/default/kgb-bot" `File.containsLine` "BOT_ENABLED=1"
`describe` "kgb bot enabled"
`onChange` Service.running "kgb-bot"
]
_ -> error "kgb server needs Debian unstable (for kgb-bot 1.31+)"
kgbServer = propertyList desc
[ withOS desc $ \o -> case o of
(Just (System (Debian Unstable) _)) ->
ensureProperty $ propertyList desc
[ Apt.serviceInstalledRunning "kgb-bot"
, "/etc/default/kgb-bot" `File.containsLine` "BOT_ENABLED=1"
`describe` "kgb bot enabled"
`onChange` Service.running "kgb-bot"
]
_ -> error "kgb server needs Debian unstable (for kgb-bot 1.31+)"
, File.hasPrivContent "/etc/kgb-bot/kgb.conf" anyContext
`onChange` Service.restarted "kgb-bot"
]
where
desc = "kgb.kitenet.net setup"
mumbleServer :: [Host] -> Property
mumbleServer hosts = combineProperties "mumble.debian.net"
mumbleServer hosts = combineProperties hn
[ Apt.serviceInstalledRunning "mumble-server"
, Obnam.latestVersion
, Obnam.backup "/var/lib/mumble-server" "55 5 * * *"
[ "--repository=sftp://joey@turtle.kitenet.net/~/lib/backup/mumble.debian.net.obnam"
[ "--repository=sftp://joey@turtle.kitenet.net/~/lib/backup/" ++ hn ++ ".obnam"
, "--client-name=mumble"
] Obnam.OnlyClient
`requires` Ssh.keyImported SshRsa "root"
`requires` Ssh.keyImported SshRsa "root" (Context hn)
`requires` Ssh.knownHost hosts "turtle.kitenet.net" "root"
, trivial $ cmdProperty "chown" ["-R", "mumble-server:mumble-server", "/var/lib/mumble-server"]
]
where
hn = "mumble.debian.net"
obnamLowMem :: Property
obnamLowMem = combineProperties "obnam tuned for low memory use"
@ -137,16 +145,16 @@ gitServer hosts = propertyList "git.kitenet.net setup"
, "--client-name=wren"
] Obnam.OnlyClient
`requires` Gpg.keyImported "1B169BE1" "root"
`requires` Ssh.keyImported SshRsa "root"
`requires` Ssh.keyImported SshRsa "root" (Context "git.kitenet.net")
`requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root"
`requires` Ssh.authorizedKeys "family"
`requires` Ssh.authorizedKeys "family" (Context "git.kitenet.net")
`requires` User.accountFor "family"
, Apt.installed ["git", "rsync", "gitweb"]
-- backport avoids channel flooding on branch merge
, Apt.installedBackport ["kgb-client"]
-- backport supports ssh event notification
, Apt.installedBackport ["git-annex"]
, File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf"
, File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" anyContext
, toProp $ Git.daemonRunning "/srv/git"
, "/etc/gitweb.conf" `File.containsLines`
[ "$projectroot = '/srv/git';"
@ -198,7 +206,7 @@ annexWebSite hosts origin hn uuid remotes = propertyList (hn ++" website using g
dir = "/srv/web/" ++ hn
postupdatehook = dir </> ".git/hooks/post-update"
setup = userScriptProperty "joey" setupscript
`requires` Ssh.keyImported SshRsa "joey"
`requires` Ssh.keyImported SshRsa "joey" (Context hn)
`requires` Ssh.knownHost hosts "turtle.kitenet.net" "joey"
setupscript =
[ "cd " ++ shellEscape dir
@ -266,9 +274,9 @@ mainhttpscert True =
gitAnnexDistributor :: Property
gitAnnexDistributor = combineProperties "git-annex distributor, including rsync server and signer"
[ Apt.installed ["rsync"]
, File.hasPrivContent "/etc/rsyncd.conf"
, File.hasPrivContent "/etc/rsyncd.conf" (Context "git-annex distributor")
`onChange` Service.restarted "rsync"
, File.hasPrivContent "/etc/rsyncd.secrets"
, File.hasPrivContent "/etc/rsyncd.secrets" (Context "git-annex distributor")
`onChange` Service.restarted "rsync"
, "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true"
`onChange` Service.running "rsync"
@ -310,10 +318,13 @@ ircBouncer :: Property
ircBouncer = propertyList "IRC bouncer"
[ Apt.installed ["znc"]
, User.accountFor "znc"
, File.hasPrivContent conf
, File.dirExists (parentDir conf)
, File.hasPrivContent conf anyContext
, File.ownerGroup conf "znc" "znc"
, Cron.job "znconboot" "@reboot" "znc" "~" "znc"
, Cron.job "zncrunning" "@hourly" "znc" "~" "znc || true"
-- ensure running if it was not already
, trivial $ userScriptProperty "znc" ["znc || true"]
`describe` "znc running"
]
where
conf = "/home/znc/.znc/configs/znc.conf"
@ -335,7 +346,7 @@ githubBackup :: Property
githubBackup = propertyList "github-backup box"
[ Apt.installed ["github-backup", "moreutils"]
, let f = "/home/joey/.github-keys"
in File.hasPrivContent f
in File.hasPrivContent f anyContext
`onChange` File.ownerGroup f "joey" "joey"
]

View File

@ -5,6 +5,7 @@ module Propellor.Property.Ssh (
hasAuthorizedKeys,
restartSshd,
randomHostKeys,
hostKeys,
hostKey,
keyImported,
knownHost,
@ -72,46 +73,54 @@ randomHostKeys = flagFile prop "/etc/ssh/.unique_host_keys"
[ Param "-c"
, Param "rm -f /etc/ssh/ssh_host_*"
]
ensureProperty $
cmdProperty "/var/lib/dpkg/info/openssh-server.postinst"
["configure"]
ensureProperty $ scriptProperty
[ "DPKG_MAINTSCRIPT_NAME=postinst DPKG_MAINTSCRIPT_PACKAGE=openssh-server /var/lib/dpkg/info/openssh-server.postinst configure" ]
-- | Sets ssh host keys from the site's PrivData.
--
-- (Uses a null username for host keys.)
hostKey :: SshKeyType -> Property
hostKey keytype = combineProperties desc
[ property desc (install writeFile (SshPubKey keytype "") ".pub")
, property desc (install writeFileProtected (SshPrivKey keytype "") "")
-- | Sets all types of ssh host keys from the privdata.
hostKeys :: Context -> Property
hostKeys ctx = propertyList "known ssh host keys"
[ hostKey SshDsa ctx
, hostKey SshRsa ctx
, hostKey SshEcdsa ctx
]
-- | Sets a single ssh host key from the privdata.
hostKey :: SshKeyType -> Context -> Property
hostKey keytype context = combineProperties desc
[ installkey (SshPubKey keytype "") (install writeFile ".pub")
, installkey (SshPrivKey keytype "") (install writeFileProtected "")
]
`onChange` restartSshd
where
desc = "known ssh host key (" ++ fromKeyType keytype ++ ")"
install writer p ext = withPrivData p $ \key -> do
installkey p a = withPrivData p context $ \getkey ->
property desc $ getkey a
install writer ext key = do
let f = "/etc/ssh/ssh_host_" ++ fromKeyType keytype ++ "_key" ++ ext
s <- liftIO $ readFileStrict f
if s == key
then noChange
else makeChange $ writer f key
-- | Sets up a user with a ssh private key and public key pair
-- from the site's PrivData.
keyImported :: SshKeyType -> UserName -> Property
keyImported keytype user = combineProperties desc
[ property desc (install writeFile (SshPubKey keytype user) ".pub")
, property desc (install writeFileProtected (SshPrivKey keytype user) "")
-- | Sets up a user with a ssh private key and public key pair from the
-- PrivData.
keyImported :: SshKeyType -> UserName -> Context -> Property
keyImported keytype user context = combineProperties desc
[ installkey (SshPubKey keytype user) (install writeFile ".pub")
, installkey (SshPrivKey keytype user) (install writeFileProtected "")
]
where
desc = user ++ " has ssh key (" ++ fromKeyType keytype ++ ")"
install writer p ext = do
installkey p a = withPrivData p context $ \getkey ->
property desc $ getkey a
install writer ext key = do
f <- liftIO $ keyfile ext
ifM (liftIO $ doesFileExist f)
( noChange
, ensureProperties
[ property desc $
withPrivData p $ \key -> makeChange $ do
createDirectoryIfMissing True (takeDirectory f)
writer f key
[ property desc $ makeChange $ do
createDirectoryIfMissing True (takeDirectory f)
writer f key
, File.ownerGroup f user user
, File.ownerGroup (takeDirectory f) user user
]
@ -144,9 +153,9 @@ knownHost hosts hn user = property desc $
return FailedChange
-- | Makes a user have authorized_keys from the PrivData
authorizedKeys :: UserName -> Property
authorizedKeys user = property (user ++ " has authorized_keys") $
withPrivData (SshAuthorizedKeys user) $ \v -> do
authorizedKeys :: UserName -> Context -> Property
authorizedKeys user context = withPrivData (SshAuthorizedKeys user) context $ \get ->
property (user ++ " has authorized_keys") $ get $ \v -> do
f <- liftIO $ dotFile "authorized_keys" user
liftIO $ do
createDirectoryIfMissing True (takeDirectory f)

View File

@ -24,17 +24,18 @@ nuked user _ = check (isJust <$> catchMaybeIO (homedir user)) $ cmdProperty "use
-- | Only ensures that the user has some password set. It may or may
-- not be the password from the PrivData.
hasSomePassword :: UserName -> Property
hasSomePassword user = check ((/= HasPassword) <$> getPasswordStatus user) $
hasPassword user
hasSomePassword :: UserName -> Context -> Property
hasSomePassword user context = check ((/= HasPassword) <$> getPasswordStatus user) $
hasPassword user context
hasPassword :: UserName -> Property
hasPassword user = property (user ++ " has password") $
withPrivData (Password user) $ \password -> makeChange $
withHandle StdinHandle createProcessSuccess
(proc "chpasswd" []) $ \h -> do
hPutStrLn h $ user ++ ":" ++ password
hClose h
hasPassword :: UserName -> Context -> Property
hasPassword user context = withPrivData (Password user) context $ \getpassword ->
property (user ++ " has password") $
getpassword $ \password -> makeChange $
withHandle StdinHandle createProcessSuccess
(proc "chpasswd" []) $ \h -> do
hPutStrLn h $ user ++ ":" ++ password
hClose h
lockedPassword :: UserName -> Property
lockedPassword user = check (not <$> isLockedPassword user) $ cmdProperty "passwd"

View File

@ -17,7 +17,9 @@ module Propellor.Types
, ActionResult(..)
, CmdLine(..)
, PrivDataField(..)
, GpgKeyId
, PrivData
, Context(..)
, anyContext
, SshKeyType(..)
, module Propellor.Types.OS
, module Propellor.Types.Dns
@ -32,6 +34,7 @@ import "MonadCatchIO-transformers" Control.Monad.CatchIO
import Propellor.Types.Info
import Propellor.Types.OS
import Propellor.Types.Dns
import Propellor.Types.PrivData
-- | Everything Propellor knows about a system: Its hostname,
-- properties and other info.
@ -135,28 +138,12 @@ data CmdLine
= Run HostName
| Spin HostName
| Boot HostName
| Set HostName PrivDataField
| Dump HostName PrivDataField
| Set PrivDataField Context
| Dump PrivDataField Context
| Edit PrivDataField Context
| ListFields
| AddKey String
| Continue CmdLine
| Chain HostName
| Docker HostName
deriving (Read, Show, Eq)
-- | Note that removing or changing field names will break the
-- serialized privdata files, so don't do that!
-- It's fine to add new fields.
data PrivDataField
= DockerAuthentication
| SshPubKey SshKeyType UserName
| SshPrivKey SshKeyType UserName
| SshAuthorizedKeys UserName
| Password UserName
| PrivFile FilePath
| GpgKey GpgKeyId
deriving (Read, Show, Ord, Eq)
type GpgKeyId = String
data SshKeyType = SshRsa | SshDsa | SshEcdsa | SshEd25519
deriving (Read, Show, Ord, Eq)

View File

@ -1,6 +1,7 @@
module Propellor.Types.Info where
import Propellor.Types.OS
import Propellor.Types.PrivData
import qualified Propellor.Types.Dns as Dns
import qualified Data.Set as S
@ -9,6 +10,7 @@ import Data.Monoid
-- | Information about a host.
data Info = Info
{ _os :: Val System
, _privDataFields :: S.Set (PrivDataField, Context)
, _sshPubKey :: Val String
, _dns :: S.Set Dns.Record
, _namedconf :: Dns.NamedConfMap
@ -17,9 +19,10 @@ data Info = Info
deriving (Eq, Show)
instance Monoid Info where
mempty = Info mempty mempty mempty mempty mempty
mempty = Info mempty mempty mempty mempty mempty mempty
mappend old new = Info
{ _os = _os old <> _os new
, _privDataFields = _privDataFields old <> _privDataFields new
, _sshPubKey = _sshPubKey old <> _sshPubKey new
, _dns = _dns old <> _dns new
, _namedconf = _namedconf old <> _namedconf new

View File

@ -0,0 +1,34 @@
module Propellor.Types.PrivData where
import Propellor.Types.OS
-- | Note that removing or changing field names will break the
-- serialized privdata files, so don't do that!
-- It's fine to add new fields.
data PrivDataField
= DockerAuthentication
| SshPubKey SshKeyType UserName
| SshPrivKey SshKeyType UserName
| SshAuthorizedKeys UserName
| Password UserName
| PrivFile FilePath
| GpgKey
deriving (Read, Show, Ord, Eq)
-- | Context in which a PrivDataField is used.
--
-- Often this will be a domain name. For example,
-- Context "www.example.com" could be used for the SSL cert
-- for the web server serving that domain. Multiple hosts might
-- use that privdata.
newtype Context = Context String
deriving (Read, Show, Ord, Eq)
-- | Use when a PrivDataField is not dependent on any paricular context.
anyContext :: Context
anyContext = Context "any"
type PrivData = String
data SshKeyType = SshRsa | SshDsa | SshEcdsa | SshEd25519
deriving (Read, Show, Ord, Eq)

28
src/Utility/Table.hs Normal file
View File

@ -0,0 +1,28 @@
{- text based table generation
-
- Copyright 2014 Joey Hess <joey@kitenet.net>
-
- License: BSD-2-clause
-}
module Utility.Table where
type Table = [[String]]
-- | A table with a header that is set off with lines under each
-- header item.
tableWithHeader :: [String] -> [[String]] -> Table
tableWithHeader header rows = header : map linesep header : rows
where
linesep = map (const '-')
-- | Formats a table to lines, automatically padding rows to the same size.
formatTable :: Table -> [String]
formatTable table = map (\r -> unwords (map pad (zip r rowsizes))) table
where
pad (cell, size) = cell ++ take (size - length cell) padding
padding = repeat ' '
rowsizes = sumrows (map (map length) table)
sumrows [] = repeat 0
sumrows [r] = r
sumrows (r1:r2:rs) = sumrows $ map (uncurry max) (zip r1 r2) : rs