propellor 5.2.0 → 5.3.0
raw patch · 20 files changed
+1522/−82 lines, 20 filesdep ~base
Dependency ranges changed: base
Files
- CHANGELOG +19/−0
- config.hs +644/−15
- debian/changelog +19/−0
- joeyconfig.hs +18/−1
- propellor.cabal +2/−1
- src/Propellor/DotDir.hs +16/−12
- src/Propellor/Git.hs +5/−2
- src/Propellor/Property.hs +3/−1
- src/Propellor/Property/Cmd.hs +2/−1
- src/Propellor/Property/DiskImage.hs +1/−1
- src/Propellor/Property/DiskImage/PartSpec.hs +7/−2
- src/Propellor/Property/FlashKernel.hs +6/−1
- src/Propellor/Property/Gpg.hs +3/−3
- src/Propellor/Property/Grub.hs +65/−0
- src/Propellor/Property/Installer/Target.hs +17/−7
- src/Propellor/Property/Laptop.hs +28/−0
- src/Propellor/Property/Parted.hs +10/−8
- src/Propellor/Property/Parted/Types.hs +4/−3
- src/Propellor/Property/SiteSpecific/JoeySites.hs +9/−9
- src/propellor-config.hs +644/−15
CHANGELOG view
@@ -1,3 +1,22 @@+propellor (5.3.0) unstable; urgency=medium++ * Avoid bogus warning about new upstream version when /usr/bin/propellor+ is run on a Debian system, but ~/.propellor was not cloned from the+ Debian git bundle.+ * Parted: Allow partitions to have no filesystem, for eg, GPT BIOS boot+ partitions. (API change)+ * Added rawPartition to PartSpec, for specifying partitions with no+ filesystem.+ * Added BiosGrubFlag to PartFlag.+ * Add HasCallStack constraint to pickOS and unsupportedOS, so the+ call stack includes the caller.+ * Run su with --login, to avoid inheriting some problematic environment+ variables, such as TMP, from the caller.+ * Grub: Added properties to configure /etc/default/grub.+ * Laptop: New module, starting with powertopAutoTuneOnBoot.++ -- Joey Hess <id@joeyh.name> Thu, 01 Feb 2018 12:27:01 -0400+ propellor (5.2.0) unstable; urgency=medium [ Joey Hess ]
config.hs view
@@ -1,29 +1,658 @@--- This is the main configuration file for Propellor, and is used to build--- the propellor program.+-- This is the live config file used by propellor's author.+-- https://propellor.branchable.com/+module Main where import Propellor+import Propellor.Property.Scheduled+import Propellor.Property.DiskImage+import Propellor.Property.Chroot+import Propellor.Property.Machine+import Propellor.Property.Bootstrap 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.Cron as Cron+import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User+import qualified Propellor.Property.Hostname as Hostname+import qualified Propellor.Property.Fstab as Fstab+import qualified Propellor.Property.Tor as Tor+import qualified Propellor.Property.Dns as Dns+import qualified Propellor.Property.OpenId as OpenId+import qualified Propellor.Property.Git as Git+import qualified Propellor.Property.Postfix as Postfix+import qualified Propellor.Property.Apache as Apache+import qualified Propellor.Property.LetsEncrypt as LetsEncrypt+import qualified Propellor.Property.Locale as Locale+import qualified Propellor.Property.Grub as Grub+import qualified Propellor.Property.FlashKernel as FlashKernel+import qualified Propellor.Property.Borg as Borg+import qualified Propellor.Property.Gpg as Gpg+import qualified Propellor.Property.Systemd as Systemd+import qualified Propellor.Property.Journald as Journald+import qualified Propellor.Property.Fail2Ban as Fail2Ban+import qualified Propellor.Property.Laptop as Laptop+import qualified Propellor.Property.OS as OS+import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost+import qualified Propellor.Property.HostingProvider.Linode as Linode+import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean+import qualified Propellor.Property.SiteSpecific.GitHome as GitHome+import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder+import qualified Propellor.Property.SiteSpecific.Branchable as Branchable+import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites -main :: IO ()-main = defaultMain hosts+main :: IO () -- _ ______`| ,-.__+main = defaultMain hosts -- / \___-=O`/|O`/__| (____.'+ {- Propellor -- \ / | / ) _.-"-._+ Deployed -} -- `/-==__ _/__|/__=-| ( \_+hosts :: [Host] -- * \ | | '--------'+hosts = -- (o) `+ [ darkstar+ , gnu+ , dragon+ , clam+ , orca+ , baleen+ , honeybee+ , kite+ , elephant+ , beaver+ , mouse+ , peregrine+ , pell+ , keysafe+ ] ++ monsters --- The hosts propellor knows about.-hosts :: [Host]-hosts =- [ mybox- ]+testvm :: Host+testvm = host "testvm.kitenet.net" $ props+ & osDebian Unstable X86_64+ & OS.cleanInstallOnce (OS.Confirmed "testvm.kitenet.net")+ `onChange` postinstall+ & Hostname.sane+ & Hostname.searchDomain+ & Apt.installed ["linux-image-amd64"]+ & Apt.installed ["ssh"]+ & User.hasPassword (User "root")+ where+ postinstall :: Property (HasInfo + DebianLike)+ postinstall = propertyList "fixing up after clean install" $ props+ & OS.preserveRootSshAuthorized+ & OS.preserveResolvConf+ & Apt.update+ & Grub.boots "/dev/sda"+ `requires` Grub.installed Grub.PC --- An example host.-mybox :: Host-mybox = host "mybox.example.com" $ props+darkstar :: Host+darkstar = host "darkstar.kitenet.net" $ props & osDebian Unstable X86_64- & Apt.stdSourcesList+ & ipv6 "2001:4830:1600:187::2"+ & Hostname.sane+ & Apt.serviceInstalledRunning "swapspace"+ & Laptop.powertopAutoTuneOnBoot+ & Grub.cmdline_Linux_default "i915.enable_psr=1"+ ! Grub.cmdline_Linux_default "quiet"++ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient+ -- & JoeySites.alarmClock "*-*-* 7:30" (User "joey")+ -- "/usr/bin/timeout 45m /home/joey/bin/goodmorning"+ & JoeySites.laptopSoftware+ & JoeySites.userDirHtml+ & Ssh.userKeys (User "joey") hostContext+ [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1YoyHxZwG5Eg0yiMTJLSWJ/+dMM6zZkZiR4JJ0iUfP+tT2bm/lxYompbSqBeiCq+PYcSC67mALxp1vfmdOV//LWlbXfotpxtyxbdTcQbHhdz4num9rJQz1tjsOsxTEheX5jKirFNC5OiKhqwIuNydKWDS9qHGqsKcZQ8p+n1g9Lr3nJVGY7eRRXzw/HopTpwmGmAmb9IXY6DC2k91KReRZAlOrk0287LaK3eCe1z0bu7LYzqqS+w99iXZ/Qs0m9OqAPnHZjWQQ0fN4xn5JQpZSJ7sqO38TBAimM+IHPmy2FTNVVn9zGM+vN1O2xr3l796QmaUG1+XLL0shfR/OZbb joey@darkstar")+ ]+ -- & imageBuiltFor honeybee+ -- (RawDiskImage "/srv/honeybee.img")+ -- (Debootstrapped mempty)++gnu :: Host+gnu = host "gnu.kitenet.net" $ props+ & Postfix.satellite++dragon :: Host+dragon = host "dragon.kitenet.net" $ props+ & ipv6 "2001:4830:1600:187::2"+ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient++clam :: Host+clam = host "clam.kitenet.net" $ props+ & standardSystem Unstable X86_64+ ["Unreliable server. Anything here may be lost at any time!" ]+ & ipv4 "45.62.211.94"++ & CloudAtCost.decruft+ & Ssh.hostKeys hostContext+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAI3WUq0RaigLlcUivgNG4sXpso2ORZkMvfqKz6zkc60L6dpxvWDNmZVEH8hEjxRSYG07NehcuOgQqeyFnS++xw1hdeGjf37JqCUH49i02lra3Zxv8oPpRxyeqe5MmuzUJhlWvBdlc3O/nqZ4bTUfnxMzSYWyy6++s/BpSHttZplNAAAAFQC1DE0vzgVeNAv9smHLObQWZFe2VQAAAIBECtpJry3GC8NVTFsTHDGWksluoFPIbKiZUFFztZGdM0AO2VwAbiJ6Au6M3VddGFANgTlni6d2/9yS919zO90TaFoIjywZeXhxE2CSuRfU7sx2hqDBk73jlycem/ER0sanFhzpHVpwmLfWneTXImWyq37vhAxatJANOtbj81vQ3AAAAIBV3lcyTT9xWg1Q4vERJbvyF8mCliwZmnIPa7ohveKkxlcgUk5d6dnaqFfjVaiXBPN3Qd08WXoQ/a9k3chBPT9nW2vWgzzM8l36j2MbHLmaxGwevAc9+vx4MXqvnGHzd2ex950mC33ct3j0fzMZlO6vqEsgD4CYmiASxhfefj+JCQ==")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJybAjUPUWIhvVMmer8K5ZgdfI54DM6vc8Mzw+5KmVKL0TwkvzbR1HAB4heyMGtN1F8YzkWhsI3/Txh+MQUJ+i4u8SvSYc6D1q3j3ZyCi06wZ3DJS25tZrOM/thOOA1DFA4Hhb0uI/1Kg8PguNNNSMXn8F7q3F6cFQizYgszs6z6ktiST/BTC+IXWovhcnn2vQXXU8FTcTsqBFqA5dEjZbp1WDzqp3km84ZyXGmoVlpqzXeMvlkWTIshYiQjXIwPOkALzlGYjp1lw1OaxPVI1IGFcgCbIWQQWoCReb+genX2VaR+odAYXjaOdRx0lQj7UCPTBCpqMyzBMLtT5Yiaqh")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPhfvcOuw0Yt+MnsFc4TI2gWkKi62Eajxz+TgbHMO/uRTYF8c5V8fOI3o+J/3m5+lT0S5o8j8a7xIC3COvi+AVw=")+ ] & Apt.unattendedUpgrades- & Apt.installed ["etckeeper"]+ & Systemd.persistentJournal+ & Journald.systemMaxUse "50MiB"+ & Apt.serviceInstalledRunning "swapspace"++ & Tor.isRelay+ & Tor.named "kite1"+ & Tor.bandwidthRate (Tor.PerMonth "400 GB")++ & Systemd.nspawned oldusenetShellBox++ & JoeySites.scrollBox+ & alias "scroll.joeyh.name"+ & alias "us.scroll.joeyh.name"++baleen :: Host+baleen = host "baleen.kitenet.net" $ props+ & standardSystem Unstable X86_64 [ "New git-annex build box." ]++ -- Not on public network; ssh access via bounce host.+ & ipv4 "138.38.77.40"+ + -- The root filesystem content may be lost if the VM is resized.+ -- /dev/vdb contains persistent storage.+ & Fstab.mounted "auto" "/dev/vdb" "/var/lib/container" mempty+ + & Apt.unattendedUpgrades+ & Postfix.satellite+ & Apt.serviceInstalledRunning "ntp"+ & Systemd.persistentJournal++orca :: Host+orca = host "orca.kitenet.net" $ props+ & standardSystem Unstable X86_64 [ "Main git-annex build box." ]+ & ipv4 "138.38.108.179"++ & Apt.unattendedUpgrades+ & Postfix.satellite+ & Apt.serviceInstalledRunning "ntp"+ & Systemd.persistentJournal++ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_64 Nothing (Cron.Times "15 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_32 Nothing (Cron.Times "30 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.stackAutoBuilder+ (Stable "jessie") X86_32 (Just "ancient") (Cron.Times "45 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.androidAutoBuilderContainer+ (Cron.Times "1 1 * * *") "3h")++honeybee :: Host+honeybee = host "honeybee.kitenet.net" $ props+ & standardSystem Testing ARMHF+ [ "Home router and arm git-annex build box." ]+ + & cubietech_Cubietruck+ & hasPartition+ ( partition EXT4+ `mountedAt` "/"+ `setSize` MegaBytes 8000+ )+ & File.hasPrivContentExposed "/etc/flash-kernel/dtbs/sun7i-a20-cubietruck.dtb"+ (Context "cubietruck gpio")+ `onChange` FlashKernel.flashKernel+ + & Apt.installed ["firmware-brcm80211"]+ -- Workaround for https://bugs.debian.org/844056+ `requires` File.hasPrivContent "/lib/firmware/brcm/brcmfmac43362-sdio.txt" anyContext+ `requires` File.dirExists "/lib/firmware/brcm"+ & "/etc/default/rcS" `File.containsLine` "FSCKFIX=yes"+ & Apt.serviceInstalledRunning "ntp" -- no hardware clock+ & bootstrappedFrom GitRepoOutsideChroot+ & Ssh.hostKeys hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIS/hDYq1MAxfOBf49htym3BOYlx4Gk9SDpiHjv7u6IC")+ ]++ & JoeySites.homePowerMonitor+ (User "joey")+ hosts+ (Context "homepower.joeyh.name")+ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMAmVYddg/RgCbIj+cLcEiddeFXaYFnbEJ3uGj9G/EyV joey@honeybee")+ & JoeySites.homeRouter+ & Apt.installed ["mtr-tiny", "iftop", "screen"]+ & Postfix.satellite++ & check (not <$> inChroot) (setupRevertableProperty autobuilder)+ -- In case compiler needs more than available ram+ & Apt.serviceInstalledRunning "swapspace"+ where+ autobuilder = Systemd.nspawned $ GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.armAutoBuilder+ Unstable ARMEL Nothing (Cron.Times "15 10 * * *") "10h"++-- 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 = host "kite.kitenet.net" $ props+ & standardSystemUnhardened Testing X86_64 [ "Welcome to kite!" ]+ & ipv4 "66.228.36.95"+ & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2"+ & alias "kitenet.net"+ & alias "wren.kitenet.net" -- temporary+ & Ssh.hostKeys (Context "kitenet.net")+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAO9tnPUT4p+9z7K6/OYuiBNHaij4Nzv5YVBih1vMl+ALz0gYAj8RWJzXmqp5buFAyfgOoLw+H9s1bBS01Sy3i07Dm6cx1fWG4RXL/E/3w1tavX99GD2bBxDBu890ebA5Tp+eFRJkS9+JwSvFiF6CP7NbVjifCagoUO56Ig048RwDAAAAFQDPY2xM3q6KwsVQliel23nrd0rV2QAAAIEAga3hj1hL00rYPNnAUzT8GAaSP62S4W68lusErH+KPbsMwFBFY/Ib1FVf8k6Zn6dZLh/HH/RtJi0JwdzPI1IFW+lwVbKfwBvhQ1lw9cH2rs1UIVgi7Wxdgfy8gEWxf+QIqn62wG+Ulf/HkWGvTrRpoJqlYRNS/gnOWj9Z/4s99koAAACBAM/uJIo2I0nK15wXiTYs/NYUZA7wcErugFn70TRbSgduIFH6U/CQa3rgHJw9DCPCQJLq7pwCnFH7too/qaK+czDk04PsgqV0+Jc7957gU5miPg50d60eJMctHV4eQ1FpwmGGfXxRBR9k2ZvikWYatYir3L6/x1ir7M0bA9IzNU45")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA2QAJEuvbTmaN9ex9i9bjPhMGj+PHUYq2keIiaIImJ+8mo+yKSaGUxebG4tpuDPx6KZjdycyJt74IXfn1voGUrfzwaEY9NkqOP3v6OWTC3QeUGqDCeJ2ipslbEd9Ep9XBp+/ldDQm60D0XsIZdmDeN6MrHSbKF4fXv1bqpUoUILk=")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLF+dzqBJZix+CWUkAd3Bd3cofFCKwHMNRIfwx1G7dL4XFe6fMKxmrNetQcodo2edyufwoPmCPr3NmnwON9vyh0=")+ , (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFZftKMnH/zH29BHMKbcBO4QsgTrstYFVhbrzrlRzBO3")+ ]++ & Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile+ & Apt.installed ["linux-image-amd64"]+ & Linode.serialGrub+ & Linode.mlocateEnabled+ & Apt.unattendedUpgrades+ & Systemd.installed+ & Systemd.persistentJournal+ & Journald.systemMaxUse "500MiB"+ & Ssh.passwordAuthentication True+ & Fail2Ban.installed -- since ssh password authentication is allowed+ -- Allow ssh -R to forward ports via kite+ & Ssh.setSshdConfig "GatewayPorts" "clientspecified"+ & Apt.serviceInstalledRunning "ntp"+ & "/etc/timezone" `File.hasContent` ["US/Eastern"]+ + & Borg.backup "/" (Borg.BorgRepo "joey@eubackup.kitenet.net:/home/joey/lib/backup/kite/kite.borg") Cron.Daily+ [ "--exclude=/proc/*"+ , "--exclude=/sys/*"+ , "--exclude=/run/*"+ , "--exclude=/tmp/*"+ , "--exclude=/var/tmp/*"+ , "--exclude=/var/cache/*"+ , "--exclude=/home/joey/lib"+ -- These directories are backed up and restored separately.+ , "--exclude=/srv/git"+ , "--exclude=/var/spool/oldusenet"+ ]+ [ Borg.KeepDays 7+ , Borg.KeepWeeks 4+ , Borg.KeepMonths 6+ ]+ `requires` Ssh.knownHost hosts "eubackup.kitenet.net" (User "root")+ `requires` Ssh.userKeys (User "root")+ (Context "kite.kitenet.net")+ [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5Gza2sNqSKfNtUN4dN/Z3rlqw18nijmXFx6df2GtBoZbkIak73uQfDuZLP+AXlyfHocwdkdHEf/zrxgXS4EokQMGLZhJ37Pr3edrEn/NEnqroiffw7kyd7EqaziA6UOezcLTjWGv+Zqg9JhitYs4WWTpNzrPH3yQf1V9FunZnkzb4gJGndts13wGmPEwSuf+QHbgQvjMOMCJwWSNcJGdhDR66hFlxfG26xx50uIczXYAbgLfHp5W6WuR/lcaS9J6i7HAPwcsPDA04XDinrcpl29QwsMW1HyGS/4FSCgrDqNZ2jzP49Bka78iCLRqfl1efyYas/Zo1jQ0x+pxq2RMr root@kite")+ ]++ & alias "smtp.kitenet.net"+ & alias "imap.kitenet.net"+ & alias "pop.kitenet.net"+ & alias "mail.kitenet.net"+ & JoeySites.kiteMailServer++ & JoeySites.legacyWebSites+ & File.ownerGroup "/srv/web" (User "joey") (Group "joey")+ & Apt.installed ["analog"]++ & alias "git.kitenet.net"+ & alias "git.joeyh.name"+ & JoeySites.gitServer hosts++ & JoeySites.downloads hosts+ & JoeySites.gitAnnexDistributor+ & JoeySites.tmp++ & 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"++ & Apt.installed+ [ "git-annex", "myrepos"+ , "build-essential", "make"+ , "rss2email", "archivemail"+ , "devscripts"+ -- Some users have zsh as their login shell.+ , "zsh"+ ]++ & alias "nntp.olduse.net"+ & JoeySites.oldUseNetServer hosts++ & alias "ns4.kitenet.net"+ & myDnsPrimary True "kitenet.net"+ [ (RelDomain "mouse-onion", CNAME $ AbsDomain "htieo6yu2qtcn2j3.onion")+ , (RelDomain "beaver-onion", CNAME $ AbsDomain "tl4xsvaxryjylgxs.onion")+ , (RelDomain "peregrine-onion", CNAME $ AbsDomain "ahw47zqw6qszoufl.onion")+ ]+ & myDnsPrimary True "joeyh.name" []+ & myDnsPrimary True "ikiwiki.info" []+ & myDnsPrimary True "olduse.net"+ [ (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk")+ ]+ & alias "ns4.branchable.com"+ & branchableSecondary+ & Dns.secondaryFor ["animx"] hosts "animx.eu.org"+ -- Use its own name server (amoung other things this avoids+ -- spamassassin URIBL_BLOCKED.+ & "/etc/resolv.conf" `File.hasContent`+ [ "nameserver 127.0.0.1"+ , "domain kitenet.net"+ , "search kitenet.net"+ ]+ & alias "debug-me.joeyh.name"+ -- debug-me installed manually until package is available+ & Systemd.enabled "debug-me"++ -- testing+ & Apache.httpsVirtualHost "letsencrypt.joeyh.name" "/var/www/html"+ (LetsEncrypt.AgreeTOS (Just "id@joeyh.name"))+ & alias "letsencrypt.joeyh.name"+ where++elephant :: Host+elephant = host "elephant.kitenet.net" $ props+ & standardSystem Unstable X86_64+ [ "Storage, big data, and backups, omnomnom!"+ , "(Encrypt all data stored here.)"+ ]+ & ipv4 "193.234.225.114"+ & Ssh.hostKeys hostContext+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBANxXGWac0Yz58akI3UbLkphAa8VPDCGswTS0CT3D5xWyL9OeArISAi/OKRIvxA4c+9XnWtNXS7nYVFDJmzzg8v3ZMx543AxXK82kXCfvTOc/nAlVz9YKJAA+FmCloxpmOGrdiTx1k36FE+uQgorslGW/QTxnOcO03fDZej/ppJifAAAAFQCnenyJIw6iJB1+zuF/1TSLT8UAeQAAAIEA1WDrI8rKnxnh2rGaQ0nk+lOcVMLEr7AxParnZjgC4wt2mm/BmkF/feI1Fjft2z4D+V1W7MJHOqshliuproxhFUNGgX9fTbstFJf66p7h7OLAlwK8ZkpRk/uV3h5cIUPel6aCwjL5M2gN6/yq+gcCTXeHLq9OPyUTmlN77SBL71UAAACBAJJiCHWxPAGooe7Vv3W7EIBbsDyf7b2kDH3bsIlo+XFcKIN6jysBu4kn9utjFlrlPeHUDzGQHe+DmSqTUQQ0JPCRGcAcuJL8XUqhJi6A6ye51M9hVt51cJMXmERx9TjLOP/adkEuxpv3Fj20FxRUr1HOmvRvewSHrJ1GeA1bjbYL")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrEQ7aNmRYyLKY7xHILQsyV/w0B3++D98vn5IvjHkDnitrUWjB+vPxlS7LYKLzN9Jx7Hb14R2lg7+wdgtFMxLZZukA8b0tqFpTdRFBvBYGh8IM8Id1iE/6io/NZl+hTQEDp0LJP+RljH1CLfz7J3qtc+v6NbfTP5cOgH104mWYoLWzJGaZ4p53jz6THRWnVXy5nPO3dSBr2f/SQgRuJQWHNIh0jicRGD8H2kzOQzilpo+Y46PWtkufl3Yu3UsP5UMAyLRIXwZ6nNRZqRiVWrX44hoNfDbooTdFobbHlqMl+y6291bOXaOA6PACk8B4IVcC89/gmc9Oe4EaDuszU5kD")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJkoPRhUGT8EId6m37uBdYEtq42VNwslKnc9mmO+89ody066q6seHKeFY6ImfwjcyIjM30RTzEwftuVNQnbEB0=")+ , (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6VtXi0uygxZeCo26n6PuCTlSFCBcwRifv6N8HdWh2Z")+ ]++ & Grub.chainPVGrub "hd0,0" "xen/xvda1" 30+ & Postfix.satellite+ & Apt.unattendedUpgrades+ & Systemd.installed+ & Systemd.persistentJournal+ & Ssh.userKeys (User "joey") hostContext+ [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4wJuQEGno+nJvtE75IKL6JQ08sJHZ9Bzs9Dvu0zuxSEZE30MWK98/twNwCH9PVf2N9m4apfN7f9GHgHTUongfo8xnLAk4PuBSTV74YgKyOCvNYqANuKKa+76PsS/vFf/or3ct++uTEWsRyYD29cQndufwKA4rthAqHG+fifbLDC53AjcldI0zI1RckpPzT+AMazlnSBFMlpKvGD2uzSXALVRXa3vSqWkWd0z7qmIkpmpq0AAgbDLwrGBcUGV/h0rOa2s8zSeirA0tLmHNROl4cZsX0T/6VBGfBRkrHSxL67xJziATw4WPq6spYlxg84pC/5qJVr9SC5HosppbDqgj joey@elephant")+ ]+ & Apt.serviceInstalledRunning "swapspace"++ & alias "eubackup.kitenet.net"+ & Apt.installed ["sshfs", "rsync", "borgbackup"]+ & JoeySites.githubBackup+ & JoeySites.rsyncNetBackup hosts++ & alias "podcatcher.kitenet.net"+ & JoeySites.podcatcher++ & alias "znc.kitenet.net"+ & JoeySites.ircBouncer+ & alias "kgb.kitenet.net"+ & JoeySites.kgbServer++ & alias "ns3.kitenet.net"+ & myDnsSecondary++ & Systemd.nspawned oldusenetShellBox+ & Systemd.nspawned ancientKitenet+ & Systemd.nspawned openidProvider+ `requires` Apt.serviceInstalledRunning "ntp"++ & JoeySites.scrollBox+ & alias "scroll.joeyh.name"+ & alias "eu.scroll.joeyh.name"++ -- For https port 443, shellinabox with ssh login to+ -- kitenet.net+ & alias "shell.kitenet.net"+ & Systemd.nspawned kiteShellBox+ -- Nothing is using http port 80, so listen on+ -- that port for ssh, for traveling on bad networks that+ -- block 22.+ & Ssh.listenPort (Port 80)++beaver :: Host+beaver = host "beaver.kitenet.net" $ props+ & ipv6 "2001:4830:1600:195::2" & Apt.installed ["ssh"]+ & Ssh.hostPubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)+ & alias "usbackup.kitenet.net"+ & JoeySites.backupsBackedupFrom hosts "eubackup.kitenet.net" "/home/joey/lib/backup"+ & Apt.serviceInstalledRunning "anacron"+ & Cron.niceJob "system disk backed up" Cron.Weekly (User "root") "/"+ "rsync -a -x / /home/joey/lib/backup/beaver.kitenet.net/"++mouse :: Host+mouse = host "mouse.kitenet.net" $ props+ & ipv4 "67.223.19.96"+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++peregrine :: Host+peregrine = host "peregrine.kitenet.net" $ props+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++-- Branchable is not completely deployed with propellor yet.+pell :: Host+pell = host "pell.branchable.com" $ props+ & alias "branchable.com"+ & ipv4 "66.228.46.55"+ & ipv6 "2600:3c03::f03c:91ff:fedf:c0e5"++ -- All the websites I host at branchable that don't use+ -- branchable.com dns.+ & alias "olduse.net"+ & alias "www.olduse.net"+ & alias "www.kitenet.net"+ & alias "joeyh.name"+ & alias "www.joeyh.name"+ & alias "campaign.joeyh.name"+ & alias "ikiwiki.info"+ & alias "www.ikiwiki.info"+ & alias "git.ikiwiki.info"+ & alias "l10n.ikiwiki.info"+ & alias "dist-bugs.kitenet.net"+ & alias "family.kitenet.net"++ & osDebian (Stable "stretch") X86_64+ & Apt.installed ["linux-image-686-pae"]+ & Apt.unattendedUpgrades+ & Branchable.server hosts+ & Linode.serialGrub++-- See https://joeyh.name/code/keysafe/servers/ for requirements.+keysafe :: Host+keysafe = host "keysafe.joeyh.name" $ props+ & ipv4 "139.59.17.168"+ & Hostname.sane+ & osDebian (Stable "stretch") X86_64+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & DigitalOcean.distroKernel+ -- This is a 500 mb VM, so need more ram to build propellor.+ & Apt.serviceInstalledRunning "swapspace"+ & Cron.runPropellor (Cron.Times "30 * * * *")+ & Apt.installed ["etckeeper", "sudo"]+ & Apt.removed ["nfs-common", "exim4", "exim4-base", "exim4-daemon-light", "rsyslog", "acpid", "rpcbind", "at"]+ & User.hasSomePassword (User "root")- & File.dirExists "/var/www"+ & User.accountFor (User "joey")+ & User.hasSomePassword (User "joey")+ & Sudo.enabledFor (User "joey")++ & Ssh.installed+ & Ssh.randomHostKeys+ & User "root" `Ssh.authorizedKeysFrom` (User "joey", darkstar)+ & User "joey" `Ssh.authorizedKeysFrom` (User "joey", darkstar)+ & Ssh.noPasswords++ & Tor.installed+ & Tor.hiddenServiceAvailable "keysafe" (Port 4242)+ `requires` Tor.hiddenServiceData "keysafe" hostContext+ & Tor.bandwidthRate (Tor.PerMonth "750 GB")++ -- keysafe installed manually until package is available+ & Systemd.enabled "keysafe"++ & Gpg.keyImported (Gpg.GpgKeyId "CECE11AE") (User "root")+ & Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")+ & Ssh.userKeys (User "root")+ (Context "keysafe.joeyh.name")+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEx8bK9ZbXVEgEvxQeXLjnr9cGa/QvoB459aglP529My root@keysafe")+ ]+ -- Note that this is not an incremental backup; it uploads the+ -- whole content every time. So, only run weekly.+ & Cron.niceJob "keysafe backup" Cron.Weekly (User "root") "/" backupcmd+ `requires` Apt.installed ["rsync"]+ where+ datadir = "/var/lib/keysafe"+ backupdir = "/var/backups/keysafe"+ rsyncnetbackup = "2318@usw-s002.rsync.net:keysafe"+ backupcmd = unwords+ [ "keysafe --store-directory", datadir, "--backup-server", backupdir+ , "&& rsync -a --delete --max-delete 3 ", backupdir , rsyncnetbackup+ ]++ --' __|II| ,.+ ---- __|II|II|__ ( \_,/\+--'-------'\o/-'-.-'-.-'-.- __|II|II|II|II|___/ __/ -'-.-'-.-'-.-'-.-'-.-'-+-------------------------- | [Containers] / --------------------------+-------------------------- : / ---------------------------+--------------------------- \____, o ,' ----------------------------+---------------------------- '--,___________,' -----------------------------++-- My own openid provider. Uses php, so containerized for security+-- and administrative sanity.+openidProvider :: Systemd.Container+openidProvider = Systemd.debContainer "openid-provider" $ props+ & standardContainer (Stable "stretch")+ & alias hn+ & OpenId.providerFor [User "joey", User "liw"] hn (Just (Port 8081))+ where+ hn = "openid.kitenet.net"++-- Exhibit: kite's 90's website on port 1994.+ancientKitenet :: Systemd.Container+ancientKitenet = Systemd.debContainer "ancient-kitenet" $ props+ & standardContainer (Stable "stretch")+ & alias hn+ & Git.cloned (User "root") "git://kitenet-net.branchable.com/" "/var/www/html"+ (Just "remotes/origin/old-kitenet.net")+ & Apache.installed+ & Apache.listenPorts [p]+ & Apache.virtualHost hn p "/var/www/html"+ & Apache.siteDisabled "000-default"+ where+ p = Port 1994+ hn = "ancient.kitenet.net"++oldusenetShellBox :: Systemd.Container+oldusenetShellBox = Systemd.debContainer "oldusenet-shellbox" $ props+ & standardContainer (Stable "stretch")+ & alias "shell.olduse.net"+ & JoeySites.oldUseNetShellBox++kiteShellBox :: Systemd.Container+kiteShellBox = Systemd.debContainer "kiteshellbox" $ props+ & standardContainer (Stable "stretch")+ & JoeySites.kiteShellBox++type Motd = [String]++-- This is my standard system setup.+standardSystem :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystem suite arch motd =+ standardSystemUnhardened suite arch motd+ `before` Ssh.noPasswords++standardSystemUnhardened :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystemUnhardened suite arch motd = propertyList "standard system" $ props+ & osDebian suite arch+ & Hostname.sane+ & Hostname.searchDomain+ & Locale.available "en_US.UTF-8"+ & File.hasContent "/etc/motd" ("":motd++[""])+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.cacheCleaned+ & Apt.installed ["etckeeper"]+ & Apt.installed ["ssh", "mosh"]+ & GitHome.installedFor (User "root")+ & User.hasSomePassword (User "root")+ & User.accountFor (User "joey")+ & User.hasSomePassword (User "joey")+ & Sudo.enabledFor (User "joey")+ & GitHome.installedFor (User "joey")+ & Apt.installed ["vim", "screen", "less"] & Cron.runPropellor (Cron.Times "30 * * * *")+ -- I use postfix, or no MTA.+ & Apt.removed ["exim4", "exim4-daemon-light", "exim4-config", "exim4-base"]+ `onChange` Apt.autoRemove+ -- At least until system integration catches up, revert+ -- systemd 230's behavior of enabling this property by default.+ ! Systemd.killUserProcesses++-- This is my standard container setup, Featuring automatic upgrades.+standardContainer :: DebianSuite -> Property (HasInfo + Debian)+standardContainer suite = propertyList "standard container" $ props+ & osDebian suite X86_64+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & Apt.cacheCleaned++myDnsSecondary :: Property (HasInfo + DebianLike)+myDnsSecondary = propertyList "dns secondary for all my domains" $ props+ & Dns.secondary hosts "kitenet.net"+ & Dns.secondary hosts "joeyh.name"+ & Dns.secondary hosts "ikiwiki.info"+ & Dns.secondary hosts "olduse.net"++branchableSecondary :: RevertableProperty (HasInfo + DebianLike) DebianLike+branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com"++-- Currently using kite (ns4) as primary with secondaries+-- elephant (ns3) and gandi.+-- kite handles all mail.+myDnsPrimary :: Bool -> Domain -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike+myDnsPrimary dnssec domain extras = (if dnssec then Dns.signedPrimary (Weekly Nothing) else Dns.primary) hosts domain+ (Dns.mkSOA "ns4.kitenet.net" 100) $+ [ (RootDomain, NS $ AbsDomain "ns4.kitenet.net")+ , (RootDomain, NS $ AbsDomain "ns3.kitenet.net")+ , (RootDomain, NS $ AbsDomain "ns6.gandi.net")+ , (RootDomain, MX 0 $ AbsDomain "kitenet.net")+ , (RootDomain, TXT "v=spf1 a a:kitenet.net ~all")+ , JoeySites.domainKey+ ] ++ extras+++monsters :: [Host] -- Systems I don't manage with propellor,+monsters = -- but do want to track their public keys etc.+ [ host "usw-s002.rsync.net" $ props+ & Ssh.hostPubKey SshEd25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7yTEBGfQYdwG/oeL+U9XPMIh/dW7XNs9T+M79YIOrd"+ , host "github.com" $ props+ & Ssh.hostPubKey SshRsa "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="+ , host "gitlab.com" $ props+ & Ssh.hostPubKey SshEcdsa "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY="+ , host "ns6.gandi.net" $ props+ & ipv4 "217.70.177.40"+ , host "animx" $ props+ & ipv4 "76.7.162.186"+ & ipv4 "76.7.162.187"+ ]++++ -- o+ -- ___ o o+ {-----\ / o \ ___o o+ { \ __ \ / _ (X___>-- __o+ _____________________{ ______\___ \__/ | \__/ \____ |X__>+ < \___//|\\___/\ \____________ _+ \ ___/ | \___ # # \ (-)+ \ O O O # | \ # >=)+ \______________________________# # / #__________________/ (-}++
debian/changelog view
@@ -1,3 +1,22 @@+propellor (5.3.0) unstable; urgency=medium++ * Avoid bogus warning about new upstream version when /usr/bin/propellor+ is run on a Debian system, but ~/.propellor was not cloned from the+ Debian git bundle.+ * Parted: Allow partitions to have no filesystem, for eg, GPT BIOS boot+ partitions. (API change)+ * Added rawPartition to PartSpec, for specifying partitions with no+ filesystem.+ * Added BiosGrubFlag to PartFlag.+ * Add HasCallStack constraint to pickOS and unsupportedOS, so the+ call stack includes the caller.+ * Run su with --login, to avoid inheriting some problematic environment+ variables, such as TMP, from the caller.+ * Grub: Added properties to configure /etc/default/grub.+ * Laptop: New module, starting with powertopAutoTuneOnBoot.++ -- Joey Hess <id@joeyh.name> Thu, 01 Feb 2018 12:27:01 -0400+ propellor (5.2.0) unstable; urgency=medium [ Joey Hess ]
joeyconfig.hs view
@@ -27,11 +27,13 @@ import qualified Propellor.Property.LetsEncrypt as LetsEncrypt import qualified Propellor.Property.Locale as Locale import qualified Propellor.Property.Grub as Grub+import qualified Propellor.Property.FlashKernel as FlashKernel import qualified Propellor.Property.Borg as Borg import qualified Propellor.Property.Gpg as Gpg import qualified Propellor.Property.Systemd as Systemd import qualified Propellor.Property.Journald as Journald import qualified Propellor.Property.Fail2Ban as Fail2Ban+import qualified Propellor.Property.Laptop as Laptop import qualified Propellor.Property.OS as OS import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost import qualified Propellor.Property.HostingProvider.Linode as Linode@@ -58,6 +60,7 @@ , elephant , beaver , mouse+ , peregrine , pell , keysafe ] ++ monsters@@ -87,12 +90,16 @@ & ipv6 "2001:4830:1600:187::2" & Hostname.sane & Apt.serviceInstalledRunning "swapspace"+ & Laptop.powertopAutoTuneOnBoot+ & Grub.cmdline_Linux_default "i915.enable_psr=1"+ ! Grub.cmdline_Linux_default "quiet" & JoeySites.dkimMilter & JoeySites.postfixSaslPasswordClient -- & JoeySites.alarmClock "*-*-* 7:30" (User "joey") -- "/usr/bin/timeout 45m /home/joey/bin/goodmorning" & JoeySites.laptopSoftware+ & JoeySites.userDirHtml & Ssh.userKeys (User "joey") hostContext [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1YoyHxZwG5Eg0yiMTJLSWJ/+dMM6zZkZiR4JJ0iUfP+tT2bm/lxYompbSqBeiCq+PYcSC67mALxp1vfmdOV//LWlbXfotpxtyxbdTcQbHhdz4num9rJQz1tjsOsxTEheX5jKirFNC5OiKhqwIuNydKWDS9qHGqsKcZQ8p+n1g9Lr3nJVGY7eRRXzw/HopTpwmGmAmb9IXY6DC2k91KReRZAlOrk0287LaK3eCe1z0bu7LYzqqS+w99iXZ/Qs0m9OqAPnHZjWQQ0fN4xn5JQpZSJ7sqO38TBAimM+IHPmy2FTNVVn9zGM+vN1O2xr3l796QmaUG1+XLL0shfR/OZbb joey@darkstar") ]@@ -114,7 +121,7 @@ clam = host "clam.kitenet.net" $ props & standardSystem Unstable X86_64 ["Unreliable server. Anything here may be lost at any time!" ]- & ipv4 "45.62.211.6"+ & ipv4 "45.62.211.94" & CloudAtCost.decruft & Ssh.hostKeys hostContext@@ -186,6 +193,9 @@ `mountedAt` "/" `setSize` MegaBytes 8000 )+ & File.hasPrivContentExposed "/etc/flash-kernel/dtbs/sun7i-a20-cubietruck.dtb"+ (Context "cubietruck gpio")+ `onChange` FlashKernel.flashKernel & Apt.installed ["firmware-brcm80211"] -- Workaround for https://bugs.debian.org/844056@@ -315,6 +325,7 @@ & myDnsPrimary True "kitenet.net" [ (RelDomain "mouse-onion", CNAME $ AbsDomain "htieo6yu2qtcn2j3.onion") , (RelDomain "beaver-onion", CNAME $ AbsDomain "tl4xsvaxryjylgxs.onion")+ , (RelDomain "peregrine-onion", CNAME $ AbsDomain "ahw47zqw6qszoufl.onion") ] & myDnsPrimary True "joeyh.name" [] & myDnsPrimary True "ikiwiki.info" []@@ -415,6 +426,12 @@ mouse :: Host mouse = host "mouse.kitenet.net" $ props & ipv4 "67.223.19.96"+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++peregrine :: Host+peregrine = host "peregrine.kitenet.net" $ props & Apt.installed ["ssh"] & Tor.installed & Tor.hiddenServiceAvailable "ssh" (Port 22)
propellor.cabal view
@@ -1,5 +1,5 @@ Name: propellor-Version: 5.2.0+Version: 5.3.0 Cabal-Version: >= 1.20 License: BSD2 Maintainer: Joey Hess <id@joeyh.name>@@ -126,6 +126,7 @@ Propellor.Property.Installer.Target Propellor.Property.Journald Propellor.Property.Kerberos+ Propellor.Property.Laptop Propellor.Property.LetsEncrypt Propellor.Property.List Propellor.Property.LightDM
src/Propellor/DotDir.hs view
@@ -358,7 +358,7 @@ withQuietOutput createProcessSuccess $ proc "git" ["log", headrev] if (headknown == Nothing)- then setupUpstreamMaster headrev+ then updateUpstreamMaster headrev else do theirhead <- getCurrentGitSha1 =<< getCurrentBranchRef when (theirhead /= headrev) $ do@@ -372,26 +372,30 @@ d <- dotPropellor doesFileExist (d </> "propellor.cabal") --- Makes upstream/master in dotPropellor be a usefully mergeable branch.+-- Updates upstream/master in dotPropellor so merging from it will update+-- to the latest distrepo. ----- We cannot just use origin/master, because in the case of a distrepo,--- it only contains 1 commit. So, trying to merge with it will result--- in lots of merge conflicts, since git cannot find a common parent--- commit.+-- We cannot just fetch the distrepo because the distrepo contains only +-- 1 commit. So, trying to merge with it will result in lots of merge+-- conflicts, since git cannot find a common parent commit. ----- Instead, the upstream/master branch is created by taking the--- upstream/master branch (which must be an old version of propellor,+-- Instead, the new upstream/master branch is updated by taking the+-- current upstream/master branch (which must be an old version of propellor, -- as distributed), and diffing from it to the current origin/master, -- and committing the result. This is done in a temporary clone of the -- repository, giving it a new master branch. That new branch is fetched -- into the user's repository, as if fetching from a upstream remote, -- yielding a new upstream/master branch.-setupUpstreamMaster :: String -> IO ()-setupUpstreamMaster newref = do+--+-- If there's no upstream/master, the user is not using the distrepo,+-- so do nothing. And, if there's a remote named "upstream", the user+-- must have set that up is not using the distrepo, so do nothing.+updateUpstreamMaster :: String -> IO ()+updateUpstreamMaster newref = unlessM (hasRemote "upstream") $ do changeWorkingDirectory =<< dotPropellor go =<< catchMaybeIO getoldrev where- go Nothing = warnoutofdate False+ go Nothing = return () go (Just oldref) = do let tmprepo = ".git/propellordisttmp" let cleantmprepo = void $ catchMaybeIO $ removeDirectoryRecursive tmprepo@@ -427,7 +431,7 @@ warnoutofdate :: Bool -> IO () warnoutofdate havebranch = do warningMessage ("** Your ~/.propellor/ is out of date..")- let also s = hPutStrLn stderr (" " ++ s)+ let also s = infoMessage [" " ++ s] also ("A newer upstream version is available in " ++ distrepo) if havebranch then also ("To merge it, run: git merge " ++ upstreambranch)
src/Propellor/Git.hs view
@@ -23,9 +23,12 @@ <$> readProcess "git" ["show-ref", "--hash", branchref] hasOrigin :: IO Bool-hasOrigin = catchDefaultIO False $ do+hasOrigin = hasRemote "origin"++hasRemote :: String -> IO Bool+hasRemote remotename = catchDefaultIO False $ do rs <- lines <$> readProcess "git" ["remote"]- return $ "origin" `elem` rs+ return $ remotename `elem` rs hasGitRepo :: IO Bool hasGitRepo = doesFileExist ".git/HEAD"
src/Propellor/Property.hs view
@@ -55,6 +55,7 @@ import Data.List import Data.Hashable import Control.Applicative+import GHC.Stack import Prelude import Propellor.Types@@ -283,6 +284,7 @@ -- fail that way. pickOS ::+ HasCallStack => ( SingKind ('KProxy :: KProxy ka) , SingKind ('KProxy :: KProxy kb) , DemoteRep ('KProxy :: KProxy ka) ~ [MetaType]@@ -344,7 +346,7 @@ -- | Throws an error, for use in `withOS` when a property is lacking -- support for an OS.-unsupportedOS' :: Propellor Result+unsupportedOS' :: HasCallStack => Propellor Result unsupportedOS' = go =<< getOS where go Nothing = error "Unknown host OS is not supported by this property."
src/Propellor/Property/Cmd.hs view
@@ -94,6 +94,7 @@ -- | A property that can satisfied by running a script -- as user (cd'd to their home directory). userScriptProperty :: User -> Script -> UncheckedProperty UnixLike-userScriptProperty (User user) script = cmdProperty "su" ["--shell", "/bin/sh", "-c", shellcmd, user]+userScriptProperty (User user) script = cmdProperty "su"+ ["--login", "--shell", "/bin/sh", "-c", shellcmd, user] where shellcmd = intercalate " ; " ("set -e" : "cd" : script)
src/Propellor/Property/DiskImage.hs view
@@ -420,7 +420,7 @@ orderedmntsdevs = sortBy (compare `on` fst) $ zip mnts (zip mntopts devs) swaps = map (SwapPartition . partitionLoopDev . snd) $- filter ((== LinuxSwap) . partFs . fst) $+ filter ((== Just LinuxSwap) . partFs . fst) $ zip parts devs mountall top = forM_ orderedmntsdevs $ \(mp, (mopts, loopdev)) -> case mp of
src/Propellor/Property/DiskImage/PartSpec.hs view
@@ -9,6 +9,7 @@ partition, -- * PartSpec combinators swapPartition,+ rawPartition, mountedAt, addFreeSpace, setSize,@@ -48,11 +49,15 @@ -- The partition is not mounted anywhere by default; use the combinators -- below to configure it. partition :: Monoid t => Fs -> PartSpec t-partition fs = (Nothing, mempty, mkPartition fs, mempty)+partition fs = (Nothing, mempty, mkPartition (Just fs), mempty) -- | Specifies a swap partition of a given size. swapPartition :: Monoid t => PartSize -> PartSpec t-swapPartition sz = (Nothing, mempty, const (mkPartition LinuxSwap sz), mempty)+swapPartition sz = (Nothing, mempty, const (mkPartition (Just LinuxSwap) sz), mempty)++-- | Specifies a partition without any filesystem, of a given size.+rawPartition :: Monoid t => PartSize -> PartSpec t+rawPartition sz = (Nothing, mempty, const (mkPartition Nothing sz), mempty) -- | Specifies where to mount a partition. mountedAt :: PartSpec t -> MountPoint -> PartSpec t
src/Propellor/Property/FlashKernel.hs view
@@ -23,9 +23,14 @@ installed machine = setInfoProperty go (toInfo [FlashKernelInstalled]) where go = "/etc/flash-kernel/machine" `File.hasContent` [machine]- `onChange` (cmdProperty "flash-kernel" [] `assume` MadeChange)+ `onChange` flashKernel `requires` File.dirExists "/etc/flash-kernel" `requires` Apt.installed ["flash-kernel"]++-- | Runs flash-kernel with whatever machine `installed` configured.+flashKernel :: Property DebianLike+flashKernel = tightenTargets $+ cmdProperty "flash-kernel" [] `assume` MadeChange -- | Runs flash-kernel in the system mounted at a particular directory. flashKernelMounted :: FilePath -> Property Linux
src/Propellor/Property/Gpg.hs view
@@ -33,7 +33,7 @@ ifM (liftIO $ hasGpgKey (parse keylines)) ( return NoChange , makeChange $ withHandle StdinHandle createProcessSuccess- (proc "su" ["-c", "gpg --import", u]) $ \h -> do+ (proc "su" ["--login", "-c", "gpg --import", u]) $ \h -> do hPutStr h (unlines keylines) hClose h )@@ -49,11 +49,11 @@ hasPrivKey :: GpgKeyId -> User -> IO Bool hasPrivKey (GpgKeyId keyid) (User u) = catchBoolIO $- snd <$> processTranscript "su" ["-c", "gpg --list-secret-keys " ++ shellEscape keyid, u] Nothing+ snd <$> processTranscript "su" ["--login", "-c", "gpg --list-secret-keys " ++ shellEscape keyid, u] Nothing hasPubKey :: GpgKeyId -> User -> IO Bool hasPubKey (GpgKeyId keyid) (User u) = catchBoolIO $- snd <$> processTranscript "su" ["-c", "gpg --list-public-keys " ++ shellEscape keyid, u] Nothing+ snd <$> processTranscript "su" ["--login", "-c", "gpg --list-public-keys " ++ shellEscape keyid, u] Nothing dotDir :: User -> IO FilePath dotDir (User u) = do
src/Propellor/Property/Grub.hs view
@@ -5,6 +5,8 @@ installed, mkConfig, installed',+ configured,+ cmdline_Linux_default, boots, bootsMounted, TimeoutSecs,@@ -13,12 +15,16 @@ import Propellor.Base import qualified Propellor.Property.File as File+import qualified Propellor.Property.ConfFile as ConfFile import qualified Propellor.Property.Apt as Apt import Propellor.Property.Mount import Propellor.Property.Chroot (inChroot) import Propellor.Types.Info import Propellor.Types.Bootloader+import Utility.SafeCommand +import Data.List+ -- | Eg, \"hd0,0\" or \"xen/xvda1\" type GrubDevice = String @@ -52,6 +58,65 @@ EFI32 -> "grub-efi-ia32" Coreboot -> "grub-coreboot" Xen -> "grub-xen"++-- | Sets a simple confguration value, using grub-mkconfig to update+-- the grub boot menu accordingly. On Debian, these are written to+-- </etc/default/grub>+--+-- Example:+--+-- > & Grub.configured "GRUB_TIMEOUT" "10"+-- > & Grub.configured "GRUB_TERMINAL_INPUT" "console serial"+configured :: String -> String -> Property DebianLike+configured k v = ConfFile.adjustSection + ("grub configured with " ++ k ++ "=" ++ v)+ isline+ (not . isline)+ (const [l])+ (const [l])+ simpleConfigFile+ `onChange` mkConfig+ where+ isline s = (k ++ "=") `isPrefixOf` s+ l = k ++ "=" ++ shellEscape v++simpleConfigFile :: FilePath+simpleConfigFile = "/etc/default/grub"++-- | Adds a word to the default linux command line.+-- Any other words in the command line will be left unchanged.+--+-- Example:+--+-- > & Grub.cmdline_Linux_default "i915.enable_psr=1"+-- > ! Grub.cmdline_Linux_default "quiet"+cmdline_Linux_default :: String -> RevertableProperty DebianLike DebianLike+cmdline_Linux_default w = setup <!> undo+ where+ setup = ConfFile.adjustSection+ ("linux command line includes " ++ w)+ isline+ (not . isline)+ (map (mkline . addw . getws))+ (++ [mkline [w]])+ simpleConfigFile+ `onChange` mkConfig+ undo = ConfFile.adjustSection+ ("linux command line does not include " ++ w)+ isline+ (not . isline)+ (map (mkline . rmw . getws))+ (++ [mkline [""]])+ simpleConfigFile+ `onChange` mkConfig+ k = "GRUB_CMDLINE_LINUX_DEFAULT"+ isline s = (k ++ "=") `isPrefixOf` s+ mkline ws = k ++ "=" ++ shellEscape (unwords ws)+ getws = concatMap words . shellUnEscape . drop 1 . dropWhile (/= '=')+ addw ws+ | w `elem` ws = ws+ | otherwise = ws ++ [w]+ rmw = filter (/= w) -- | Installs grub onto a device's boot loader, -- so the system can boot from that device.
src/Propellor/Property/Installer/Target.hs view
@@ -68,15 +68,19 @@ -- see <https://git.joeyh.name/index.cgi/secret-project.git/> module Propellor.Property.Installer.Target (+ -- * Main interface TargetPartTable(..), targetInstalled,- mountTarget, fstabLists,+ -- * Additional properties+ mountTarget, targetBootable, partitionTargetDisk,+ -- * Utility functions targetDir, probeDisk, findDiskDevices,+ -- * Installation progress tracking TargetFilled, TargetFilledHandle, prepTargetFilled,@@ -110,6 +114,7 @@ import Data.Ratio import System.Process (readProcess) +-- | Partition table for the target disk. data TargetPartTable = TargetPartTable TableType [PartSpec DiskPart] -- | Property that installs the target system to the TargetDiskDevice@@ -179,6 +184,7 @@ umountaside = cmdProperty "umount" ["-l", "/mnt"] `assume` MadeChange +-- | Gets the target mounted. mountTarget :: UserInput i => i@@ -240,10 +246,10 @@ partitions = map (\(mp, _, mkpart, _) -> (mp, mkpart mempty)) partspecs mnts = mapMaybe fst $- filter (\(_, p) -> partFs p /= LinuxSwap) partitions+ filter (\(_, p) -> partFs p /= Just LinuxSwap && partFs p /= Nothing) partitions swaps targetdev = map (Fstab.SwapPartition . diskPartition targetdev . snd) $- filter (\((_, p), _) -> partFs p == LinuxSwap)+ filter (\((_, p), _) -> partFs p == Just LinuxSwap) (zip partitions partNums) -- | Make the target bootable using whatever bootloader is installed on it.@@ -271,6 +277,7 @@ warningMessage $ "don't know how to enable bootloader(s) " ++ show l return FailedChange +-- | Partitions the target disk. partitionTargetDisk :: UserInput i => i@@ -424,10 +431,10 @@ parse _ = Nothing -- | How much of the target disks are used, compared with the size of the--- installer's root device. Since the main part of an installation --- is rsyncing the latter to the former, this allows roughly estimating--- the percent done while an install is running, and can be used in some--- sort of progress display.+-- installer's root device. Since the main part of an installation+-- is `targetInstalled` rsyncing the latter to the former, this allows+-- roughly estimating the percent done while an install is running,+-- and can be used in some sort of progress display. data TargetFilled = TargetFilled (Ratio Integer) deriving (Show, Eq) @@ -437,6 +444,7 @@ newtype TargetFilledHandle = TargetFilledHandle Integer +-- | Prepare for getting `TargetFilled`. prepTargetFilled :: IO TargetFilledHandle prepTargetFilled = go =<< getMountSource "/" where@@ -446,6 +454,8 @@ return (TargetFilledHandle sz) go Nothing = return (TargetFilledHandle 0) +-- | Get the current `TargetFilled` value. This is fast enough to be run+-- multiple times per second without using much CPU. checkTargetFilled :: TargetFilledHandle -> IO TargetFilled checkTargetFilled (TargetFilledHandle installsz) = do targetsz <- sum . map snd . filter (isTargetMountPoint . fst)
+ src/Propellor/Property/Laptop.hs view
@@ -0,0 +1,28 @@+module Propellor.Property.Laptop where++import Propellor.Base+import qualified Propellor.Property.File as File+import qualified Propellor.Property.Apt as Apt+import qualified Propellor.Property.Systemd as Systemd++-- | Makes powertop auto-tune the system for optimal power consumption on+-- boot.+powertopAutoTuneOnBoot :: RevertableProperty DebianLike DebianLike+powertopAutoTuneOnBoot = setup <!> undo+ `describe` "powertop auto-tune on boot"+ where+ setup = Systemd.enabled "powertop"+ `requires` Apt.installed ["powertop"]+ `requires` File.hasContent servicefile+ [ "[Unit]"+ , "Description=Powertop tunings"+ , "[Service]"+ , "ExecStart=/usr/sbin/powertop --auto-tune"+ , "RemainAfterExit=true"+ , "[Install]"+ , "WantedBy=multi-user.target"+ ]+ undo = tightenTargets $ File.notPresent servicefile+ `requires` check (doesFileExist servicefile)+ (Systemd.disabled "powertop")+ servicefile = "/etc/systemd/system/powertop.service"
src/Propellor/Property/Parted.hs view
@@ -62,8 +62,10 @@ where desc = disk ++ " partitioned" formatl devs = combineProperties desc (toProps $ map format (zip parts devs))- format (p, dev) = Partition.formatted' (partMkFsOpts p)- Partition.YesReallyFormatPartition (partFs p) dev+ format (p, dev) = case partFs p of+ Just fs -> Partition.formatted' (partMkFsOpts p)+ Partition.YesReallyFormatPartition fs dev+ Nothing -> doNothing -- | Gets the total size of the disk specified by the partition table. partTableSize :: PartTable -> ByteSize@@ -81,12 +83,12 @@ , pval f , pval b ]- mkpart partnum startpos endpos p =- [ "mkpart"- , pval (partType p)- , pval (partFs p)- , partposexact startpos- , partposfuzzy endpos+ mkpart partnum startpos endpos p = catMaybes+ [ Just "mkpart"+ , Just $ pval (partType p)+ , fmap pval (partFs p)+ , Just $ partposexact startpos+ , Just $ partposfuzzy endpos ] ++ case partName p of Just n -> ["name", show partnum, n] Nothing -> []
src/Propellor/Property/Parted/Types.hs view
@@ -31,7 +31,7 @@ data Partition = Partition { partType :: PartType , partSize :: PartSize- , partFs :: Partition.Fs+ , partFs :: Maybe Partition.Fs , partMkFsOpts :: Partition.MkfsOpts , partFlags :: [(PartFlag, Bool)] -- ^ flags can be set or unset (parted may set some flags by default) , partName :: Maybe String -- ^ optional name for partition (only works for GPT, PC98, MAC)@@ -39,7 +39,7 @@ deriving (Show) -- | Makes a Partition with defaults for non-important values.-mkPartition :: Partition.Fs -> PartSize -> Partition+mkPartition :: Maybe Partition.Fs -> PartSize -> Partition mkPartition fs sz = Partition { partType = Primary , partSize = sz@@ -105,7 +105,7 @@ fromAlignment (Alignment n) = n -- | Flags that can be set on a partition.-data PartFlag = BootFlag | RootFlag | SwapFlag | HiddenFlag | RaidFlag | LvmFlag | LbaFlag | LegacyBootFlag | IrstFlag | EspFlag | PaloFlag+data PartFlag = BootFlag | RootFlag | SwapFlag | HiddenFlag | RaidFlag | LvmFlag | LbaFlag | LegacyBootFlag | IrstFlag | EspFlag | PaloFlag | BiosGrubFlag deriving (Show) instance PartedVal PartFlag where@@ -120,6 +120,7 @@ pval IrstFlag = "irst" pval EspFlag = "esp" pval PaloFlag = "palo"+ pval BiosGrubFlag = "bios_grub" instance PartedVal Bool where pval True = "on"
src/Propellor/Property/SiteSpecific/JoeySites.hs view
@@ -948,10 +948,9 @@ , "[Install]" , "WantedBy=multi-user.target" ]- -- Only upload when eth0 is up; eg the satellite internet is up. -- Any changes to the rsync command will need my .authorized_keys -- rsync server command to be updated too.- rsynccommand = "if ip route | grep '^default' | grep -q eth0; then rsync -e 'ssh -i" ++ sshkeyfile ++ "' -avz rrds/recent/ joey@kitenet.net:/srv/web/homepower.joeyh.name/rrds/recent/; fi"+ rsynccommand = "rsync -e 'ssh -i" ++ sshkeyfile ++ "' -avz rrds/recent/ joey@kitenet.net:/srv/web/homepower.joeyh.name/rrds/recent/" -- My home router, running hostapd and dnsmasq for wlan0, -- with eth0 connected to a satellite modem, and a fallback ppp connection.@@ -998,7 +997,7 @@ & Apt.installed ["ppp"] `before` File.hasContent "/etc/ppp/peers/provider" [ "user \"joeyh@arczip.com\""- , "connect \"/usr/sbin/chat -v -f /etc/chatscripts/pap -T 9734111\""+ , "connect \"/usr/sbin/chat -v -f /etc/chatscripts/pap -T 3825441\"" , "/dev/ttyACM0" , "115200" , "noipdefault"@@ -1037,23 +1036,25 @@ laptopSoftware :: Property DebianLike laptopSoftware = Apt.installed- [ "procmeter3", "xfce4", "procmeter3", "unclutter"+ [ "intel-microcode"+ , "procmeter3", "xfce4", "procmeter3", "unclutter" , "mplayer", "fbreader", "firefox", "chromium" , "libdatetime-event-sunrise-perl", "libtime-duration-perl"- , "iftop", "network-manager", "gtk-redshift", "powertop"+ , "network-manager", "gtk-redshift", "powertop" , "gimp", "gthumb", "inkscape", "sozi", "xzgv", "hugin" , "mpc", "mpd", "ncmpc", "sonata", "mpdtoys"- , "bsdgames", "nethack"+ , "bsdgames", "nethack-console" , "xmonad", "libghc-xmonad-dev", "libghc-xmonad-contrib-dev" , "ttf-bitstream-vera" , "mairix", "offlineimap", "mutt"- , "nmap"+ , "nmap", "whois", "wireshark", "tcpdump", "iftop" , "udevil", "pmount" , "arbtt", "hledger", "bc" , "apache2", "ikiwiki", "libhighlight-perl" , "pal" , "yeahconsole", "xkbset", "xinput"- , "assword", "pumpa", "vorbis-tools"+ , "assword", "pumpa"+ , "vorbis-tools", "audacity" , "xul-ext-ublock-origin", "xul-ext-pdf.js", "xul-ext-status4evar" , "vim-syntastic", "vim-fugitive" , "adb", "gthumb"@@ -1076,5 +1077,4 @@ , "hothasktags", "hdevtools", "hlint" , "gdb", "dpkg-repack", "lintian" , "pristine-tar", "github-backup"- , "kvm" ]
src/propellor-config.hs view
@@ -1,29 +1,658 @@--- This is the main configuration file for Propellor, and is used to build--- the propellor program.+-- This is the live config file used by propellor's author.+-- https://propellor.branchable.com/+module Main where import Propellor+import Propellor.Property.Scheduled+import Propellor.Property.DiskImage+import Propellor.Property.Chroot+import Propellor.Property.Machine+import Propellor.Property.Bootstrap 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.Cron as Cron+import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User+import qualified Propellor.Property.Hostname as Hostname+import qualified Propellor.Property.Fstab as Fstab+import qualified Propellor.Property.Tor as Tor+import qualified Propellor.Property.Dns as Dns+import qualified Propellor.Property.OpenId as OpenId+import qualified Propellor.Property.Git as Git+import qualified Propellor.Property.Postfix as Postfix+import qualified Propellor.Property.Apache as Apache+import qualified Propellor.Property.LetsEncrypt as LetsEncrypt+import qualified Propellor.Property.Locale as Locale+import qualified Propellor.Property.Grub as Grub+import qualified Propellor.Property.FlashKernel as FlashKernel+import qualified Propellor.Property.Borg as Borg+import qualified Propellor.Property.Gpg as Gpg+import qualified Propellor.Property.Systemd as Systemd+import qualified Propellor.Property.Journald as Journald+import qualified Propellor.Property.Fail2Ban as Fail2Ban+import qualified Propellor.Property.Laptop as Laptop+import qualified Propellor.Property.OS as OS+import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost+import qualified Propellor.Property.HostingProvider.Linode as Linode+import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean+import qualified Propellor.Property.SiteSpecific.GitHome as GitHome+import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder+import qualified Propellor.Property.SiteSpecific.Branchable as Branchable+import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites -main :: IO ()-main = defaultMain hosts+main :: IO () -- _ ______`| ,-.__+main = defaultMain hosts -- / \___-=O`/|O`/__| (____.'+ {- Propellor -- \ / | / ) _.-"-._+ Deployed -} -- `/-==__ _/__|/__=-| ( \_+hosts :: [Host] -- * \ | | '--------'+hosts = -- (o) `+ [ darkstar+ , gnu+ , dragon+ , clam+ , orca+ , baleen+ , honeybee+ , kite+ , elephant+ , beaver+ , mouse+ , peregrine+ , pell+ , keysafe+ ] ++ monsters --- The hosts propellor knows about.-hosts :: [Host]-hosts =- [ mybox- ]+testvm :: Host+testvm = host "testvm.kitenet.net" $ props+ & osDebian Unstable X86_64+ & OS.cleanInstallOnce (OS.Confirmed "testvm.kitenet.net")+ `onChange` postinstall+ & Hostname.sane+ & Hostname.searchDomain+ & Apt.installed ["linux-image-amd64"]+ & Apt.installed ["ssh"]+ & User.hasPassword (User "root")+ where+ postinstall :: Property (HasInfo + DebianLike)+ postinstall = propertyList "fixing up after clean install" $ props+ & OS.preserveRootSshAuthorized+ & OS.preserveResolvConf+ & Apt.update+ & Grub.boots "/dev/sda"+ `requires` Grub.installed Grub.PC --- An example host.-mybox :: Host-mybox = host "mybox.example.com" $ props+darkstar :: Host+darkstar = host "darkstar.kitenet.net" $ props & osDebian Unstable X86_64- & Apt.stdSourcesList+ & ipv6 "2001:4830:1600:187::2"+ & Hostname.sane+ & Apt.serviceInstalledRunning "swapspace"+ & Laptop.powertopAutoTuneOnBoot+ & Grub.cmdline_Linux_default "i915.enable_psr=1"+ ! Grub.cmdline_Linux_default "quiet"++ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient+ -- & JoeySites.alarmClock "*-*-* 7:30" (User "joey")+ -- "/usr/bin/timeout 45m /home/joey/bin/goodmorning"+ & JoeySites.laptopSoftware+ & JoeySites.userDirHtml+ & Ssh.userKeys (User "joey") hostContext+ [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1YoyHxZwG5Eg0yiMTJLSWJ/+dMM6zZkZiR4JJ0iUfP+tT2bm/lxYompbSqBeiCq+PYcSC67mALxp1vfmdOV//LWlbXfotpxtyxbdTcQbHhdz4num9rJQz1tjsOsxTEheX5jKirFNC5OiKhqwIuNydKWDS9qHGqsKcZQ8p+n1g9Lr3nJVGY7eRRXzw/HopTpwmGmAmb9IXY6DC2k91KReRZAlOrk0287LaK3eCe1z0bu7LYzqqS+w99iXZ/Qs0m9OqAPnHZjWQQ0fN4xn5JQpZSJ7sqO38TBAimM+IHPmy2FTNVVn9zGM+vN1O2xr3l796QmaUG1+XLL0shfR/OZbb joey@darkstar")+ ]+ -- & imageBuiltFor honeybee+ -- (RawDiskImage "/srv/honeybee.img")+ -- (Debootstrapped mempty)++gnu :: Host+gnu = host "gnu.kitenet.net" $ props+ & Postfix.satellite++dragon :: Host+dragon = host "dragon.kitenet.net" $ props+ & ipv6 "2001:4830:1600:187::2"+ & JoeySites.dkimMilter+ & JoeySites.postfixSaslPasswordClient++clam :: Host+clam = host "clam.kitenet.net" $ props+ & standardSystem Unstable X86_64+ ["Unreliable server. Anything here may be lost at any time!" ]+ & ipv4 "45.62.211.94"++ & CloudAtCost.decruft+ & Ssh.hostKeys hostContext+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAI3WUq0RaigLlcUivgNG4sXpso2ORZkMvfqKz6zkc60L6dpxvWDNmZVEH8hEjxRSYG07NehcuOgQqeyFnS++xw1hdeGjf37JqCUH49i02lra3Zxv8oPpRxyeqe5MmuzUJhlWvBdlc3O/nqZ4bTUfnxMzSYWyy6++s/BpSHttZplNAAAAFQC1DE0vzgVeNAv9smHLObQWZFe2VQAAAIBECtpJry3GC8NVTFsTHDGWksluoFPIbKiZUFFztZGdM0AO2VwAbiJ6Au6M3VddGFANgTlni6d2/9yS919zO90TaFoIjywZeXhxE2CSuRfU7sx2hqDBk73jlycem/ER0sanFhzpHVpwmLfWneTXImWyq37vhAxatJANOtbj81vQ3AAAAIBV3lcyTT9xWg1Q4vERJbvyF8mCliwZmnIPa7ohveKkxlcgUk5d6dnaqFfjVaiXBPN3Qd08WXoQ/a9k3chBPT9nW2vWgzzM8l36j2MbHLmaxGwevAc9+vx4MXqvnGHzd2ex950mC33ct3j0fzMZlO6vqEsgD4CYmiASxhfefj+JCQ==")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJybAjUPUWIhvVMmer8K5ZgdfI54DM6vc8Mzw+5KmVKL0TwkvzbR1HAB4heyMGtN1F8YzkWhsI3/Txh+MQUJ+i4u8SvSYc6D1q3j3ZyCi06wZ3DJS25tZrOM/thOOA1DFA4Hhb0uI/1Kg8PguNNNSMXn8F7q3F6cFQizYgszs6z6ktiST/BTC+IXWovhcnn2vQXXU8FTcTsqBFqA5dEjZbp1WDzqp3km84ZyXGmoVlpqzXeMvlkWTIshYiQjXIwPOkALzlGYjp1lw1OaxPVI1IGFcgCbIWQQWoCReb+genX2VaR+odAYXjaOdRx0lQj7UCPTBCpqMyzBMLtT5Yiaqh")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPhfvcOuw0Yt+MnsFc4TI2gWkKi62Eajxz+TgbHMO/uRTYF8c5V8fOI3o+J/3m5+lT0S5o8j8a7xIC3COvi+AVw=")+ ] & Apt.unattendedUpgrades- & Apt.installed ["etckeeper"]+ & Systemd.persistentJournal+ & Journald.systemMaxUse "50MiB"+ & Apt.serviceInstalledRunning "swapspace"++ & Tor.isRelay+ & Tor.named "kite1"+ & Tor.bandwidthRate (Tor.PerMonth "400 GB")++ & Systemd.nspawned oldusenetShellBox++ & JoeySites.scrollBox+ & alias "scroll.joeyh.name"+ & alias "us.scroll.joeyh.name"++baleen :: Host+baleen = host "baleen.kitenet.net" $ props+ & standardSystem Unstable X86_64 [ "New git-annex build box." ]++ -- Not on public network; ssh access via bounce host.+ & ipv4 "138.38.77.40"+ + -- The root filesystem content may be lost if the VM is resized.+ -- /dev/vdb contains persistent storage.+ & Fstab.mounted "auto" "/dev/vdb" "/var/lib/container" mempty+ + & Apt.unattendedUpgrades+ & Postfix.satellite+ & Apt.serviceInstalledRunning "ntp"+ & Systemd.persistentJournal++orca :: Host+orca = host "orca.kitenet.net" $ props+ & standardSystem Unstable X86_64 [ "Main git-annex build box." ]+ & ipv4 "138.38.108.179"++ & Apt.unattendedUpgrades+ & Postfix.satellite+ & Apt.serviceInstalledRunning "ntp"+ & Systemd.persistentJournal++ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_64 Nothing (Cron.Times "15 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.standardAutoBuilder+ Unstable X86_32 Nothing (Cron.Times "30 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.stackAutoBuilder+ (Stable "jessie") X86_32 (Just "ancient") (Cron.Times "45 * * * *") "2h")+ & Systemd.nspawned (GitAnnexBuilder.androidAutoBuilderContainer+ (Cron.Times "1 1 * * *") "3h")++honeybee :: Host+honeybee = host "honeybee.kitenet.net" $ props+ & standardSystem Testing ARMHF+ [ "Home router and arm git-annex build box." ]+ + & cubietech_Cubietruck+ & hasPartition+ ( partition EXT4+ `mountedAt` "/"+ `setSize` MegaBytes 8000+ )+ & File.hasPrivContentExposed "/etc/flash-kernel/dtbs/sun7i-a20-cubietruck.dtb"+ (Context "cubietruck gpio")+ `onChange` FlashKernel.flashKernel+ + & Apt.installed ["firmware-brcm80211"]+ -- Workaround for https://bugs.debian.org/844056+ `requires` File.hasPrivContent "/lib/firmware/brcm/brcmfmac43362-sdio.txt" anyContext+ `requires` File.dirExists "/lib/firmware/brcm"+ & "/etc/default/rcS" `File.containsLine` "FSCKFIX=yes"+ & Apt.serviceInstalledRunning "ntp" -- no hardware clock+ & bootstrappedFrom GitRepoOutsideChroot+ & Ssh.hostKeys hostContext+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIS/hDYq1MAxfOBf49htym3BOYlx4Gk9SDpiHjv7u6IC")+ ]++ & JoeySites.homePowerMonitor+ (User "joey")+ hosts+ (Context "homepower.joeyh.name")+ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMAmVYddg/RgCbIj+cLcEiddeFXaYFnbEJ3uGj9G/EyV joey@honeybee")+ & JoeySites.homeRouter+ & Apt.installed ["mtr-tiny", "iftop", "screen"]+ & Postfix.satellite++ & check (not <$> inChroot) (setupRevertableProperty autobuilder)+ -- In case compiler needs more than available ram+ & Apt.serviceInstalledRunning "swapspace"+ where+ autobuilder = Systemd.nspawned $ GitAnnexBuilder.autoBuilderContainer+ GitAnnexBuilder.armAutoBuilder+ Unstable ARMEL Nothing (Cron.Times "15 10 * * *") "10h"++-- 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 = host "kite.kitenet.net" $ props+ & standardSystemUnhardened Testing X86_64 [ "Welcome to kite!" ]+ & ipv4 "66.228.36.95"+ & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2"+ & alias "kitenet.net"+ & alias "wren.kitenet.net" -- temporary+ & Ssh.hostKeys (Context "kitenet.net")+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAO9tnPUT4p+9z7K6/OYuiBNHaij4Nzv5YVBih1vMl+ALz0gYAj8RWJzXmqp5buFAyfgOoLw+H9s1bBS01Sy3i07Dm6cx1fWG4RXL/E/3w1tavX99GD2bBxDBu890ebA5Tp+eFRJkS9+JwSvFiF6CP7NbVjifCagoUO56Ig048RwDAAAAFQDPY2xM3q6KwsVQliel23nrd0rV2QAAAIEAga3hj1hL00rYPNnAUzT8GAaSP62S4W68lusErH+KPbsMwFBFY/Ib1FVf8k6Zn6dZLh/HH/RtJi0JwdzPI1IFW+lwVbKfwBvhQ1lw9cH2rs1UIVgi7Wxdgfy8gEWxf+QIqn62wG+Ulf/HkWGvTrRpoJqlYRNS/gnOWj9Z/4s99koAAACBAM/uJIo2I0nK15wXiTYs/NYUZA7wcErugFn70TRbSgduIFH6U/CQa3rgHJw9DCPCQJLq7pwCnFH7too/qaK+czDk04PsgqV0+Jc7957gU5miPg50d60eJMctHV4eQ1FpwmGGfXxRBR9k2ZvikWYatYir3L6/x1ir7M0bA9IzNU45")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA2QAJEuvbTmaN9ex9i9bjPhMGj+PHUYq2keIiaIImJ+8mo+yKSaGUxebG4tpuDPx6KZjdycyJt74IXfn1voGUrfzwaEY9NkqOP3v6OWTC3QeUGqDCeJ2ipslbEd9Ep9XBp+/ldDQm60D0XsIZdmDeN6MrHSbKF4fXv1bqpUoUILk=")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLF+dzqBJZix+CWUkAd3Bd3cofFCKwHMNRIfwx1G7dL4XFe6fMKxmrNetQcodo2edyufwoPmCPr3NmnwON9vyh0=")+ , (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFZftKMnH/zH29BHMKbcBO4QsgTrstYFVhbrzrlRzBO3")+ ]++ & Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile+ & Apt.installed ["linux-image-amd64"]+ & Linode.serialGrub+ & Linode.mlocateEnabled+ & Apt.unattendedUpgrades+ & Systemd.installed+ & Systemd.persistentJournal+ & Journald.systemMaxUse "500MiB"+ & Ssh.passwordAuthentication True+ & Fail2Ban.installed -- since ssh password authentication is allowed+ -- Allow ssh -R to forward ports via kite+ & Ssh.setSshdConfig "GatewayPorts" "clientspecified"+ & Apt.serviceInstalledRunning "ntp"+ & "/etc/timezone" `File.hasContent` ["US/Eastern"]+ + & Borg.backup "/" (Borg.BorgRepo "joey@eubackup.kitenet.net:/home/joey/lib/backup/kite/kite.borg") Cron.Daily+ [ "--exclude=/proc/*"+ , "--exclude=/sys/*"+ , "--exclude=/run/*"+ , "--exclude=/tmp/*"+ , "--exclude=/var/tmp/*"+ , "--exclude=/var/cache/*"+ , "--exclude=/home/joey/lib"+ -- These directories are backed up and restored separately.+ , "--exclude=/srv/git"+ , "--exclude=/var/spool/oldusenet"+ ]+ [ Borg.KeepDays 7+ , Borg.KeepWeeks 4+ , Borg.KeepMonths 6+ ]+ `requires` Ssh.knownHost hosts "eubackup.kitenet.net" (User "root")+ `requires` Ssh.userKeys (User "root")+ (Context "kite.kitenet.net")+ [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5Gza2sNqSKfNtUN4dN/Z3rlqw18nijmXFx6df2GtBoZbkIak73uQfDuZLP+AXlyfHocwdkdHEf/zrxgXS4EokQMGLZhJ37Pr3edrEn/NEnqroiffw7kyd7EqaziA6UOezcLTjWGv+Zqg9JhitYs4WWTpNzrPH3yQf1V9FunZnkzb4gJGndts13wGmPEwSuf+QHbgQvjMOMCJwWSNcJGdhDR66hFlxfG26xx50uIczXYAbgLfHp5W6WuR/lcaS9J6i7HAPwcsPDA04XDinrcpl29QwsMW1HyGS/4FSCgrDqNZ2jzP49Bka78iCLRqfl1efyYas/Zo1jQ0x+pxq2RMr root@kite")+ ]++ & alias "smtp.kitenet.net"+ & alias "imap.kitenet.net"+ & alias "pop.kitenet.net"+ & alias "mail.kitenet.net"+ & JoeySites.kiteMailServer++ & JoeySites.legacyWebSites+ & File.ownerGroup "/srv/web" (User "joey") (Group "joey")+ & Apt.installed ["analog"]++ & alias "git.kitenet.net"+ & alias "git.joeyh.name"+ & JoeySites.gitServer hosts++ & JoeySites.downloads hosts+ & JoeySites.gitAnnexDistributor+ & JoeySites.tmp++ & 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"++ & Apt.installed+ [ "git-annex", "myrepos"+ , "build-essential", "make"+ , "rss2email", "archivemail"+ , "devscripts"+ -- Some users have zsh as their login shell.+ , "zsh"+ ]++ & alias "nntp.olduse.net"+ & JoeySites.oldUseNetServer hosts++ & alias "ns4.kitenet.net"+ & myDnsPrimary True "kitenet.net"+ [ (RelDomain "mouse-onion", CNAME $ AbsDomain "htieo6yu2qtcn2j3.onion")+ , (RelDomain "beaver-onion", CNAME $ AbsDomain "tl4xsvaxryjylgxs.onion")+ , (RelDomain "peregrine-onion", CNAME $ AbsDomain "ahw47zqw6qszoufl.onion")+ ]+ & myDnsPrimary True "joeyh.name" []+ & myDnsPrimary True "ikiwiki.info" []+ & myDnsPrimary True "olduse.net"+ [ (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk")+ ]+ & alias "ns4.branchable.com"+ & branchableSecondary+ & Dns.secondaryFor ["animx"] hosts "animx.eu.org"+ -- Use its own name server (amoung other things this avoids+ -- spamassassin URIBL_BLOCKED.+ & "/etc/resolv.conf" `File.hasContent`+ [ "nameserver 127.0.0.1"+ , "domain kitenet.net"+ , "search kitenet.net"+ ]+ & alias "debug-me.joeyh.name"+ -- debug-me installed manually until package is available+ & Systemd.enabled "debug-me"++ -- testing+ & Apache.httpsVirtualHost "letsencrypt.joeyh.name" "/var/www/html"+ (LetsEncrypt.AgreeTOS (Just "id@joeyh.name"))+ & alias "letsencrypt.joeyh.name"+ where++elephant :: Host+elephant = host "elephant.kitenet.net" $ props+ & standardSystem Unstable X86_64+ [ "Storage, big data, and backups, omnomnom!"+ , "(Encrypt all data stored here.)"+ ]+ & ipv4 "193.234.225.114"+ & Ssh.hostKeys hostContext+ [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBANxXGWac0Yz58akI3UbLkphAa8VPDCGswTS0CT3D5xWyL9OeArISAi/OKRIvxA4c+9XnWtNXS7nYVFDJmzzg8v3ZMx543AxXK82kXCfvTOc/nAlVz9YKJAA+FmCloxpmOGrdiTx1k36FE+uQgorslGW/QTxnOcO03fDZej/ppJifAAAAFQCnenyJIw6iJB1+zuF/1TSLT8UAeQAAAIEA1WDrI8rKnxnh2rGaQ0nk+lOcVMLEr7AxParnZjgC4wt2mm/BmkF/feI1Fjft2z4D+V1W7MJHOqshliuproxhFUNGgX9fTbstFJf66p7h7OLAlwK8ZkpRk/uV3h5cIUPel6aCwjL5M2gN6/yq+gcCTXeHLq9OPyUTmlN77SBL71UAAACBAJJiCHWxPAGooe7Vv3W7EIBbsDyf7b2kDH3bsIlo+XFcKIN6jysBu4kn9utjFlrlPeHUDzGQHe+DmSqTUQQ0JPCRGcAcuJL8XUqhJi6A6ye51M9hVt51cJMXmERx9TjLOP/adkEuxpv3Fj20FxRUr1HOmvRvewSHrJ1GeA1bjbYL")+ , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrEQ7aNmRYyLKY7xHILQsyV/w0B3++D98vn5IvjHkDnitrUWjB+vPxlS7LYKLzN9Jx7Hb14R2lg7+wdgtFMxLZZukA8b0tqFpTdRFBvBYGh8IM8Id1iE/6io/NZl+hTQEDp0LJP+RljH1CLfz7J3qtc+v6NbfTP5cOgH104mWYoLWzJGaZ4p53jz6THRWnVXy5nPO3dSBr2f/SQgRuJQWHNIh0jicRGD8H2kzOQzilpo+Y46PWtkufl3Yu3UsP5UMAyLRIXwZ6nNRZqRiVWrX44hoNfDbooTdFobbHlqMl+y6291bOXaOA6PACk8B4IVcC89/gmc9Oe4EaDuszU5kD")+ , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJkoPRhUGT8EId6m37uBdYEtq42VNwslKnc9mmO+89ody066q6seHKeFY6ImfwjcyIjM30RTzEwftuVNQnbEB0=")+ , (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6VtXi0uygxZeCo26n6PuCTlSFCBcwRifv6N8HdWh2Z")+ ]++ & Grub.chainPVGrub "hd0,0" "xen/xvda1" 30+ & Postfix.satellite+ & Apt.unattendedUpgrades+ & Systemd.installed+ & Systemd.persistentJournal+ & Ssh.userKeys (User "joey") hostContext+ [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4wJuQEGno+nJvtE75IKL6JQ08sJHZ9Bzs9Dvu0zuxSEZE30MWK98/twNwCH9PVf2N9m4apfN7f9GHgHTUongfo8xnLAk4PuBSTV74YgKyOCvNYqANuKKa+76PsS/vFf/or3ct++uTEWsRyYD29cQndufwKA4rthAqHG+fifbLDC53AjcldI0zI1RckpPzT+AMazlnSBFMlpKvGD2uzSXALVRXa3vSqWkWd0z7qmIkpmpq0AAgbDLwrGBcUGV/h0rOa2s8zSeirA0tLmHNROl4cZsX0T/6VBGfBRkrHSxL67xJziATw4WPq6spYlxg84pC/5qJVr9SC5HosppbDqgj joey@elephant")+ ]+ & Apt.serviceInstalledRunning "swapspace"++ & alias "eubackup.kitenet.net"+ & Apt.installed ["sshfs", "rsync", "borgbackup"]+ & JoeySites.githubBackup+ & JoeySites.rsyncNetBackup hosts++ & alias "podcatcher.kitenet.net"+ & JoeySites.podcatcher++ & alias "znc.kitenet.net"+ & JoeySites.ircBouncer+ & alias "kgb.kitenet.net"+ & JoeySites.kgbServer++ & alias "ns3.kitenet.net"+ & myDnsSecondary++ & Systemd.nspawned oldusenetShellBox+ & Systemd.nspawned ancientKitenet+ & Systemd.nspawned openidProvider+ `requires` Apt.serviceInstalledRunning "ntp"++ & JoeySites.scrollBox+ & alias "scroll.joeyh.name"+ & alias "eu.scroll.joeyh.name"++ -- For https port 443, shellinabox with ssh login to+ -- kitenet.net+ & alias "shell.kitenet.net"+ & Systemd.nspawned kiteShellBox+ -- Nothing is using http port 80, so listen on+ -- that port for ssh, for traveling on bad networks that+ -- block 22.+ & Ssh.listenPort (Port 80)++beaver :: Host+beaver = host "beaver.kitenet.net" $ props+ & ipv6 "2001:4830:1600:195::2" & Apt.installed ["ssh"]+ & Ssh.hostPubKey SshDsa "ssh-dss AAAAB3NzaC1kc3MAAACBAIrLX260fY0Jjj/p0syNhX8OyR8hcr6feDPGOj87bMad0k/w/taDSOzpXe0Wet7rvUTbxUjH+Q5wPd4R9zkaSDiR/tCb45OdG6JsaIkmqncwe8yrU+pqSRCxttwbcFe+UU+4AAcinjVedZjVRDj2rRaFPc9BXkPt7ffk8GwEJ31/AAAAFQCG/gOjObsr86vvldUZHCteaJttNQAAAIB5nomvcqOk/TD07DLaWKyG7gAcW5WnfY3WtnvLRAFk09aq1EuiJ6Yba99Zkb+bsxXv89FWjWDg/Z3Psa22JMyi0HEDVsOevy/1sEQ96AGH5ijLzFInfXAM7gaJKXASD7hPbVdjySbgRCdwu0dzmQWHtH+8i1CMVmA2/a5Y/wtlJAAAAIAUZj2US2D378jBwyX1Py7e4sJfea3WSGYZjn4DLlsLGsB88POuh32aOChd1yzF6r6C2sdoPBHQcWBgNGXcx4gF0B5UmyVHg3lIX2NVSG1ZmfuLNJs9iKNu4cHXUmqBbwFYQJBvB69EEtrOw4jSbiTKwHFmqdA/mw1VsMB+khUaVw=="+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)+ & alias "usbackup.kitenet.net"+ & JoeySites.backupsBackedupFrom hosts "eubackup.kitenet.net" "/home/joey/lib/backup"+ & Apt.serviceInstalledRunning "anacron"+ & Cron.niceJob "system disk backed up" Cron.Weekly (User "root") "/"+ "rsync -a -x / /home/joey/lib/backup/beaver.kitenet.net/"++mouse :: Host+mouse = host "mouse.kitenet.net" $ props+ & ipv4 "67.223.19.96"+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++peregrine :: Host+peregrine = host "peregrine.kitenet.net" $ props+ & Apt.installed ["ssh"]+ & Tor.installed+ & Tor.hiddenServiceAvailable "ssh" (Port 22)++-- Branchable is not completely deployed with propellor yet.+pell :: Host+pell = host "pell.branchable.com" $ props+ & alias "branchable.com"+ & ipv4 "66.228.46.55"+ & ipv6 "2600:3c03::f03c:91ff:fedf:c0e5"++ -- All the websites I host at branchable that don't use+ -- branchable.com dns.+ & alias "olduse.net"+ & alias "www.olduse.net"+ & alias "www.kitenet.net"+ & alias "joeyh.name"+ & alias "www.joeyh.name"+ & alias "campaign.joeyh.name"+ & alias "ikiwiki.info"+ & alias "www.ikiwiki.info"+ & alias "git.ikiwiki.info"+ & alias "l10n.ikiwiki.info"+ & alias "dist-bugs.kitenet.net"+ & alias "family.kitenet.net"++ & osDebian (Stable "stretch") X86_64+ & Apt.installed ["linux-image-686-pae"]+ & Apt.unattendedUpgrades+ & Branchable.server hosts+ & Linode.serialGrub++-- See https://joeyh.name/code/keysafe/servers/ for requirements.+keysafe :: Host+keysafe = host "keysafe.joeyh.name" $ props+ & ipv4 "139.59.17.168"+ & Hostname.sane+ & osDebian (Stable "stretch") X86_64+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & DigitalOcean.distroKernel+ -- This is a 500 mb VM, so need more ram to build propellor.+ & Apt.serviceInstalledRunning "swapspace"+ & Cron.runPropellor (Cron.Times "30 * * * *")+ & Apt.installed ["etckeeper", "sudo"]+ & Apt.removed ["nfs-common", "exim4", "exim4-base", "exim4-daemon-light", "rsyslog", "acpid", "rpcbind", "at"]+ & User.hasSomePassword (User "root")- & File.dirExists "/var/www"+ & User.accountFor (User "joey")+ & User.hasSomePassword (User "joey")+ & Sudo.enabledFor (User "joey")++ & Ssh.installed+ & Ssh.randomHostKeys+ & User "root" `Ssh.authorizedKeysFrom` (User "joey", darkstar)+ & User "joey" `Ssh.authorizedKeysFrom` (User "joey", darkstar)+ & Ssh.noPasswords++ & Tor.installed+ & Tor.hiddenServiceAvailable "keysafe" (Port 4242)+ `requires` Tor.hiddenServiceData "keysafe" hostContext+ & Tor.bandwidthRate (Tor.PerMonth "750 GB")++ -- keysafe installed manually until package is available+ & Systemd.enabled "keysafe"++ & Gpg.keyImported (Gpg.GpgKeyId "CECE11AE") (User "root")+ & Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")+ & Ssh.userKeys (User "root")+ (Context "keysafe.joeyh.name")+ [ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEx8bK9ZbXVEgEvxQeXLjnr9cGa/QvoB459aglP529My root@keysafe")+ ]+ -- Note that this is not an incremental backup; it uploads the+ -- whole content every time. So, only run weekly.+ & Cron.niceJob "keysafe backup" Cron.Weekly (User "root") "/" backupcmd+ `requires` Apt.installed ["rsync"]+ where+ datadir = "/var/lib/keysafe"+ backupdir = "/var/backups/keysafe"+ rsyncnetbackup = "2318@usw-s002.rsync.net:keysafe"+ backupcmd = unwords+ [ "keysafe --store-directory", datadir, "--backup-server", backupdir+ , "&& rsync -a --delete --max-delete 3 ", backupdir , rsyncnetbackup+ ]++ --' __|II| ,.+ ---- __|II|II|__ ( \_,/\+--'-------'\o/-'-.-'-.-'-.- __|II|II|II|II|___/ __/ -'-.-'-.-'-.-'-.-'-.-'-+-------------------------- | [Containers] / --------------------------+-------------------------- : / ---------------------------+--------------------------- \____, o ,' ----------------------------+---------------------------- '--,___________,' -----------------------------++-- My own openid provider. Uses php, so containerized for security+-- and administrative sanity.+openidProvider :: Systemd.Container+openidProvider = Systemd.debContainer "openid-provider" $ props+ & standardContainer (Stable "stretch")+ & alias hn+ & OpenId.providerFor [User "joey", User "liw"] hn (Just (Port 8081))+ where+ hn = "openid.kitenet.net"++-- Exhibit: kite's 90's website on port 1994.+ancientKitenet :: Systemd.Container+ancientKitenet = Systemd.debContainer "ancient-kitenet" $ props+ & standardContainer (Stable "stretch")+ & alias hn+ & Git.cloned (User "root") "git://kitenet-net.branchable.com/" "/var/www/html"+ (Just "remotes/origin/old-kitenet.net")+ & Apache.installed+ & Apache.listenPorts [p]+ & Apache.virtualHost hn p "/var/www/html"+ & Apache.siteDisabled "000-default"+ where+ p = Port 1994+ hn = "ancient.kitenet.net"++oldusenetShellBox :: Systemd.Container+oldusenetShellBox = Systemd.debContainer "oldusenet-shellbox" $ props+ & standardContainer (Stable "stretch")+ & alias "shell.olduse.net"+ & JoeySites.oldUseNetShellBox++kiteShellBox :: Systemd.Container+kiteShellBox = Systemd.debContainer "kiteshellbox" $ props+ & standardContainer (Stable "stretch")+ & JoeySites.kiteShellBox++type Motd = [String]++-- This is my standard system setup.+standardSystem :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystem suite arch motd =+ standardSystemUnhardened suite arch motd+ `before` Ssh.noPasswords++standardSystemUnhardened :: DebianSuite -> Architecture -> Motd -> Property (HasInfo + Debian)+standardSystemUnhardened suite arch motd = propertyList "standard system" $ props+ & osDebian suite arch+ & Hostname.sane+ & Hostname.searchDomain+ & Locale.available "en_US.UTF-8"+ & File.hasContent "/etc/motd" ("":motd++[""])+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.cacheCleaned+ & Apt.installed ["etckeeper"]+ & Apt.installed ["ssh", "mosh"]+ & GitHome.installedFor (User "root")+ & User.hasSomePassword (User "root")+ & User.accountFor (User "joey")+ & User.hasSomePassword (User "joey")+ & Sudo.enabledFor (User "joey")+ & GitHome.installedFor (User "joey")+ & Apt.installed ["vim", "screen", "less"] & Cron.runPropellor (Cron.Times "30 * * * *")+ -- I use postfix, or no MTA.+ & Apt.removed ["exim4", "exim4-daemon-light", "exim4-config", "exim4-base"]+ `onChange` Apt.autoRemove+ -- At least until system integration catches up, revert+ -- systemd 230's behavior of enabling this property by default.+ ! Systemd.killUserProcesses++-- This is my standard container setup, Featuring automatic upgrades.+standardContainer :: DebianSuite -> Property (HasInfo + Debian)+standardContainer suite = propertyList "standard container" $ props+ & osDebian suite X86_64+ & Apt.stdSourcesList `onChange` Apt.upgrade+ & Apt.unattendedUpgrades+ & Apt.cacheCleaned++myDnsSecondary :: Property (HasInfo + DebianLike)+myDnsSecondary = propertyList "dns secondary for all my domains" $ props+ & Dns.secondary hosts "kitenet.net"+ & Dns.secondary hosts "joeyh.name"+ & Dns.secondary hosts "ikiwiki.info"+ & Dns.secondary hosts "olduse.net"++branchableSecondary :: RevertableProperty (HasInfo + DebianLike) DebianLike+branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com"++-- Currently using kite (ns4) as primary with secondaries+-- elephant (ns3) and gandi.+-- kite handles all mail.+myDnsPrimary :: Bool -> Domain -> [(BindDomain, Record)] -> RevertableProperty (HasInfo + DebianLike) DebianLike+myDnsPrimary dnssec domain extras = (if dnssec then Dns.signedPrimary (Weekly Nothing) else Dns.primary) hosts domain+ (Dns.mkSOA "ns4.kitenet.net" 100) $+ [ (RootDomain, NS $ AbsDomain "ns4.kitenet.net")+ , (RootDomain, NS $ AbsDomain "ns3.kitenet.net")+ , (RootDomain, NS $ AbsDomain "ns6.gandi.net")+ , (RootDomain, MX 0 $ AbsDomain "kitenet.net")+ , (RootDomain, TXT "v=spf1 a a:kitenet.net ~all")+ , JoeySites.domainKey+ ] ++ extras+++monsters :: [Host] -- Systems I don't manage with propellor,+monsters = -- but do want to track their public keys etc.+ [ host "usw-s002.rsync.net" $ props+ & Ssh.hostPubKey SshEd25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB7yTEBGfQYdwG/oeL+U9XPMIh/dW7XNs9T+M79YIOrd"+ , host "github.com" $ props+ & Ssh.hostPubKey SshRsa "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="+ , host "gitlab.com" $ props+ & Ssh.hostPubKey SshEcdsa "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY="+ , host "ns6.gandi.net" $ props+ & ipv4 "217.70.177.40"+ , host "animx" $ props+ & ipv4 "76.7.162.186"+ & ipv4 "76.7.162.187"+ ]++++ -- o+ -- ___ o o+ {-----\ / o \ ___o o+ { \ __ \ / _ (X___>-- __o+ _____________________{ ______\___ \__/ | \__/ \____ |X__>+ < \___//|\\___/\ \____________ _+ \ ___/ | \___ # # \ (-)+ \ O O O # | \ # >=)+ \______________________________# # / #__________________/ (-}++