propellor

propellor config for hosts.
git clone git://git.ricketyspace.net/propellor.git
Log | Files | Refs | LICENSE

commit 0828ef397e76e2f53c5f0c3597e09c7194aaf17e
parent afe8674f63af32cb76c8104b9f9a7a5fb3b01138
Author: rsiddharth <s@ricketyspace.net>
Date:   Mon, 30 Apr 2018 06:10:18 +0000

Merge remote-tracking branch 'upstream/master'

Diffstat:
debian/changelog | 17+++++++++++++----
executables/propellor-config.hs | 2++
executables/wrapper.hs | 6++++++
joeyconfig.hs | 46+++++++++++++++++-----------------------------
propellor.cabal | 55++++++++++++++++++++++---------------------------------
src/Propellor/Property/Apt.hs | 6++++++
src/Propellor/Property/Machine.hs | 2+-
src/Propellor/Property/Scheduled.hs | 4++--
src/Propellor/Property/SiteSpecific/JoeySites.hs | 33+++++++++++++++++++++++++++++----
src/Propellor/Property/Systemd.hs | 4++--
src/Propellor/Wrapper.hs | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 185 insertions(+), 75 deletions(-)

diff --git a/debian/changelog b/debian/changelog @@ -1,9 +1,18 @@ -propellor (5.3.4-1+b1) sid; urgency=low, binary-only=yes +propellor (5.3.5-1) unstable; urgency=medium - * Binary-only non-maintainer upload for amd64; no source changes. - * ifelse-0.85.0.0.1 changed from eac11 to caa14, ansi-terminal changed from 0.6.3.1 to 0.8.0.2, async-2.1.1.1 changed from a35d4 to 3e78d, base changed from 4.9.1.0 to 4.10.1.0, bytestring changed from 0.10.8.1 to 0.10.8.2, containers changed from 0.5.7.1 to 0.5.10.2, directory changed from 1.3.0.0 to 1.3.0.2, exceptions-0.8.3 changed from 5fa88 to 23c90, filepath changed from 1.4.1.1 to 1.4.1.2, hashable changed from 1.2.6.1 to 1.2.7.0, hslogger-1.2.10 changed from 41a68 to db2a6, mtl changed from 2.2.1 to 2.2.2, network changed from 2.6.3.2 to 2.6.3.5, process changed from 1.4.3.0 to 1.6.1.0, split changed from 0.2.3.2 to 0.2.3.3, stm changed from 2.4.4.1 to 2.4.5.0, text changed from 1.2.2.2 to 1.2.3.0, time changed from 1.6.0.1 to 1.8.0.2, transformers-0.5.2.0 changed from 1d020 to e0457, unix changed from 2.7.2.1 to 2.7.2.2, unix-compat changed from 0.4.3.1 to 0.5.0.1 + * New upstream release. + + -- Sean Whitton <spwhitton@spwhitton.name> Sat, 28 Apr 2018 13:03:55 -0700 + +propellor (5.3.5) unstable; urgency=medium + + * Apt.stdSourcesList now adds stable-updates suite + Thanks, Sean Whitton + * Significantly increased propellor build speed when your config.hs + is in a fork of the propellor repository, by avoiding redundant builds + of propellor library. - -- amd64 / i386 Build Daemon (x86-ubc-01) <buildd_amd64-x86-ubc-01@buildd.debian.org> Mon, 16 Apr 2018 15:59:41 +0000 + -- Joey Hess <id@joeyh.name> Sun, 22 Apr 2018 12:27:45 -0400 propellor (5.3.4-1) unstable; urgency=medium diff --git a/executables/propellor-config.hs b/executables/propellor-config.hs @@ -0,0 +1 @@ +../config.hs+ \ No newline at end of file diff --git a/executables/wrapper.hs b/executables/wrapper.hs @@ -0,0 +1,6 @@ +module Main where + +import Propellor.Wrapper + +main :: IO () +main = runWrapper diff --git a/joeyconfig.hs b/joeyconfig.hs @@ -33,7 +33,6 @@ 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 @@ -49,7 +48,6 @@ main = defaultMain hosts -- / \___-=O`/|O`/__| (____.' hosts :: [Host] -- * \ | | '--------' hosts = -- (o) ` [ darkstar - , gnu , dragon , clam , orca @@ -64,25 +62,6 @@ hosts = -- (o) ` , keysafe ] ++ monsters -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 - darkstar :: Host darkstar = host "darkstar.kitenet.net" $ props & osDebian Unstable X86_64 @@ -106,10 +85,9 @@ darkstar = host "darkstar.kitenet.net" $ props -- & imageBuiltFor honeybee -- (RawDiskImage "/srv/honeybee.img") -- (Debootstrapped mempty) - -gnu :: Host -gnu = host "gnu.kitenet.net" $ props - & Postfix.satellite + & imageBuiltFor banana + (RawDiskImage "/srv/banana.img") + (Debootstrapped mempty) dragon :: Host dragon = host "dragon.kitenet.net" $ props @@ -182,6 +160,17 @@ orca = host "orca.kitenet.net" $ props & Systemd.nspawned (GitAnnexBuilder.androidAutoBuilderContainer (Cron.Times "1 1 * * *") "3h") +banana :: Host +banana = host "banana.kitenet.net" $ props + & lemaker_Banana_Pi + & hasPartition + ( partition EXT4 + `mountedAt` "/" + `setSize` MegaBytes 950 + ) + & osDebian Testing ARMHF + & User.hasInsecurePassword (User "root") "root" + honeybee :: Host honeybee = host "honeybee.kitenet.net" $ props & standardSystem Testing ARMHF @@ -232,7 +221,6 @@ kite = host "kite.kitenet.net" $ props & 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=") @@ -242,6 +230,7 @@ kite = host "kite.kitenet.net" $ props & Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile & Apt.installed ["linux-image-amd64"] + & Apt.serviceInstalledRunning "swapspace" & Linode.serialGrub & Linode.mlocateEnabled & Apt.unattendedUpgrades @@ -341,7 +330,7 @@ kite = host "kite.kitenet.net" $ props , "search kitenet.net" ] & alias "debug-me.joeyh.name" - -- debug-me installed manually until package is available + & Apt.installed ["debug-me"] & Systemd.enabled "debug-me" -- testing @@ -637,8 +626,7 @@ monsters = -- but do want to track their public keys etc. , host "ns6.gandi.net" $ props & ipv4 "217.70.177.40" , host "animx" $ props - & ipv4 "76.7.162.186" - & ipv4 "76.7.162.187" + & ipv4 "76.7.174.49" ] diff --git a/propellor.cabal b/propellor.cabal @@ -1,5 +1,5 @@ Name: propellor -Version: 5.3.4 +Version: 5.3.5 Cabal-Version: >= 1.20 License: BSD2 Maintainer: Joey Hess <id@joeyh.name> @@ -35,38 +35,6 @@ Description: . It is configured using haskell. -Executable propellor - Default-Language: Haskell98 - Main-Is: wrapper.hs - GHC-Options: -threaded -Wall -fno-warn-tabs -O0 - if impl(ghc >= 8.0) - GHC-Options: -fno-warn-redundant-constraints - Default-Extensions: TypeOperators - Hs-Source-Dirs: src - Build-Depends: - -- propellor needs to support the ghc shipped in Debian stable, - -- and also only depends on packages in Debian stable. - base >= 4.5, base < 5, - directory, filepath, IfElse, process, bytestring, hslogger, split, - unix, unix-compat, ansi-terminal, containers (>= 0.5), network, async, - time, mtl, transformers, exceptions (>= 0.6), stm, text, hashable - Other-Modules: - Propellor.DotDir - -Executable propellor-config - Default-Language: Haskell98 - Main-Is: propellor-config.hs - GHC-Options: -threaded -Wall -fno-warn-tabs -O0 - if impl(ghc >= 8.0) - GHC-Options: -fno-warn-redundant-constraints - Default-Extensions: TypeOperators - Hs-Source-Dirs: src - Build-Depends: - base >= 4.5, base < 5, - directory, filepath, IfElse, process, bytestring, hslogger, split, - unix, unix-compat, ansi-terminal, containers (>= 0.5), network, async, - time, mtl, transformers, exceptions (>= 0.6), stm, text, hashable - Library Default-Language: Haskell98 GHC-Options: -Wall -fno-warn-tabs -O0 @@ -75,6 +43,8 @@ Library Default-Extensions: TypeOperators Hs-Source-Dirs: src Build-Depends: + -- propellor needs to support the ghc shipped in Debian stable, + -- and also only depends on packages in Debian stable. base >= 4.5, base < 5, directory, filepath, IfElse, process, bytestring, hslogger, split, unix, unix-compat, ansi-terminal, containers (>= 0.5), network, async, @@ -83,6 +53,7 @@ Library Exposed-Modules: Propellor Propellor.Base + Propellor.DotDir Propellor.Location Propellor.Property Propellor.Property.Aiccu @@ -211,6 +182,7 @@ Library Propellor.Types.ResultCheck Propellor.Types.Singletons Propellor.Types.ZFS + Propellor.Wrapper Other-Modules: Propellor.Bootstrap Propellor.Git @@ -254,6 +226,23 @@ Library System.Console.Concurrent System.Console.Concurrent.Internal System.Process.Concurrent + Paths_propellor + +Executable propellor-config + Default-Language: Haskell98 + Hs-Source-Dirs: executables + Main-Is: propellor-config.hs + GHC-Options: -threaded -Wall -fno-warn-tabs -O0 + if impl(ghc >= 8.0) + GHC-Options: -fno-warn-redundant-constraints + Default-Extensions: TypeOperators + Build-Depends: propellor, base + +Executable propellor + Default-Language: Haskell98 + Hs-Source-Dirs: executables + Main-Is: wrapper.hs + Build-Depends: propellor, base source-repository head type: git diff --git a/src/Propellor/Property/Apt.hs b/src/Propellor/Property/Apt.hs @@ -88,6 +88,8 @@ binandsrc :: String -> SourcesGenerator binandsrc url suite = catMaybes [ Just l , Just $ srcLine l + , sul + , srcLine <$> sul , bl , srcLine <$> bl ] @@ -96,6 +98,10 @@ binandsrc url suite = catMaybes bl = do bs <- backportSuite suite return $ debLine bs url stdSections + -- formerly known as 'volatile' + sul = do + sus <- stableUpdatesSuite suite + return $ debLine sus url stdSections stdArchiveLines :: Propellor SourcesGenerator stdArchiveLines = return . binandsrc =<< getMirror diff --git a/src/Propellor/Property/Machine.hs b/src/Propellor/Property/Machine.hs @@ -48,10 +48,10 @@ module Propellor.Property.Machine ( marvell_SheevaPlug, cubietech_Cubietruck, olimex_A10_OLinuXino_LIME, + lemaker_Banana_Pi, -- * ARM boards (untested) cubietech_Cubieboard, cubietech_Cubieboard2, - lemaker_Banana_Pi, lemaker_Banana_Pro, olimex_A10s_OLinuXino_Micro, olimex_A20_OLinuXino_LIME, diff --git a/src/Propellor/Property/Scheduled.hs b/src/Propellor/Property/Scheduled.hs @@ -21,7 +21,7 @@ import qualified Data.Map as M -- -- This uses the description of the Property to keep track of when it was -- last run. -period :: (IsProp (Property i)) => Property i -> Recurrance -> Property i +period :: Property i -> Recurrance -> Property i period prop recurrance = flip describe desc $ adjustPropertySatisfy prop $ \satisfy -> do lasttime <- liftIO $ getLastChecked (getDesc prop) nexttime <- liftIO $ fmap startTime <$> nextTime schedule lasttime @@ -37,7 +37,7 @@ period prop recurrance = flip describe desc $ adjustPropertySatisfy prop $ \sati desc = getDesc prop ++ " (period " ++ fromRecurrance recurrance ++ ")" -- | Like period, but parse a human-friendly string. -periodParse :: (IsProp (Property i)) => Property i -> String -> Property i +periodParse :: Property i -> String -> Property i periodParse prop s = case toRecurrance s of Just recurrance -> period prop recurrance Nothing -> adjustPropertySatisfy prop $ \_ -> do diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -15,6 +15,7 @@ import qualified Propellor.Property.Git as Git import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.Service as Service import qualified Propellor.Property.User as User +import qualified Propellor.Property.Group as Group import qualified Propellor.Property.Borg as Borg import qualified Propellor.Property.Apache as Apache import qualified Propellor.Property.Postfix as Postfix @@ -916,10 +917,15 @@ homePowerMonitor user hosts ctx sshkey = propertyList "home power monitor" $ pro & File.ownerGroup "/var/www/html" user (userGroup user) & Git.cloned user "git://git.kitenet.net/joey/homepower" d Nothing & buildpoller + & Systemd.enabled setupservicename + `requires` setupserviceinstalled + `onChange` Systemd.started setupservicename & Systemd.enabled servicename `requires` serviceinstalled `onChange` Systemd.started servicename & User.hasGroup user (Group "dialout") + & Group.exists (Group "gpio") Nothing + & User.hasGroup user (Group "gpio") & Cron.niceJob "homepower upload" (Cron.Times "1 * * * *") user d rsynccommand `requires` Ssh.userKeyAt (Just sshkeyfile) user ctx sshkey @@ -951,6 +957,23 @@ homePowerMonitor user hosts ctx sshkey = propertyList "home power monitor" $ pro , "[Install]" , "WantedBy=multi-user.target" ] + setupservicename = "homepower-setup" + setupservicefile = "/etc/systemd/system/" ++ setupservicename ++ ".service" + setupserviceinstalled = setupservicefile `File.hasContent` + [ "[Unit]" + , "Description=home power monitor setup" + , "" + , "[Service]" + , "ExecStart=" ++ d ++ "/setup" + , "WorkingDirectory=" ++ d + , "User=root" + , "Group=root" + , "Type=oneshot" + , "" + , "[Install]" + , "WantedBy=multi-user.target" + , "WantedBy=homepower.target" + ] -- Any changes to the rsync command will need my .authorized_keys -- rsync server command to be updated too. rsynccommand = "rsync -e 'ssh -i" ++ sshkeyfile ++ "' -avz rrds/recent/ joey@kitenet.net:/srv/web/homepower.joeyh.name/rrds/recent/" @@ -987,6 +1010,7 @@ homeRouter = propertyList "home router" $ props , "dhcp-range=10.1.1.100,10.1.1.150,24h" , "no-hosts" , "address=/honeybee.kitenet.net/10.1.1.1" + , "address=/house.kitenet.net/10.1.1.1" ] `onChange` Service.restarted "dnsmasq" & ipmasq "wlan0" @@ -1040,7 +1064,7 @@ ipmasq intif = File.hasContent ifupscript laptopSoftware :: Property DebianLike laptopSoftware = Apt.installed - [ "intel-microcode" + [ "intel-microcode", "acpi" , "procmeter3", "xfce4", "procmeter3", "unclutter" , "mplayer", "fbreader", "firefox", "chromium" , "libdatetime-event-sunrise-perl", "libtime-duration-perl" @@ -1055,6 +1079,7 @@ laptopSoftware = Apt.installed , "pmount", "tree", "pv" , "arbtt", "hledger", "bc" , "apache2", "ikiwiki", "libhighlight-perl" + , "avahi-daemon", "avahi-discover" , "pal" , "yeahconsole", "xkbset", "xinput" , "assword", "pumpa" @@ -1096,13 +1121,13 @@ cubieTruckOneWire = ["--debian", "sun7i-a20-cubietruck"] `assume` MadeChange mydts = - [ "/* Device tree addition enabling onewire sensors on CubieTruck GPIO pin PG8 */" + [ "/* Device tree addition enabling onewire sensors on CubieTruck GPIO pin PC21 */" , "#include <dt-bindings/gpio/gpio.h>" , "" , "/ {" , "\tonewire_device {" , "\t\tcompatible = \"w1-gpio\";" - , "\t\tgpios = <&pio 6 8 GPIO_ACTIVE_HIGH>; /* PG8 */" + , "\t\tgpios = <&pio 2 21 GPIO_ACTIVE_HIGH>; /* PC21 */" , "\t\tpinctrl-names = \"default\";" , "\t\tpinctrl-0 = <&my_w1_pin>;" , "\t};" @@ -1110,7 +1135,7 @@ cubieTruckOneWire = , "" , "&pio {" , "\tmy_w1_pin: my_w1_pin@0 {" - , "\t\tallwinner,pins = \"PG8\";" + , "\t\tallwinner,pins = \"PC21\";" , "\t\tallwinner,function = \"gpio_in\";" , "\t};" , "};" diff --git a/src/Propellor/Property/Systemd.hs b/src/Propellor/Property/Systemd.hs @@ -217,7 +217,7 @@ machined = withOS "machined installed" $ \w o -> -- to bootstrap. -- -- > container "webserver" $ \d -> Chroot.debootstrapped mempty d $ props --- > & osDebian Unstable X86_64 +-- > & osDebian Unstable X86_64 -- > & Apt.installedRunning "apache2" -- > & ... container :: MachineName -> (FilePath -> Chroot.Chroot) -> Container @@ -238,7 +238,7 @@ container name mkchroot = -- to bootstrap. -- -- > debContainer "webserver" $ props --- > & osDebian Unstable X86_64 +-- > & osDebian Unstable X86_64 -- > & Apt.installedRunning "apache2" -- > & ... debContainer :: MachineName -> Props metatypes -> Container diff --git a/src/Propellor/Wrapper.hs b/src/Propellor/Wrapper.hs @@ -0,0 +1,85 @@ +-- | This module is used to implement a wrapper program for propellor +-- distribution. +-- +-- Distributions should install this program into PATH. +-- (Cabal builds it as dist/build/propellor/propellor). +-- +-- This is not the propellor main program (that's config.hs). +-- This bootstraps ~/.propellor/config.hs, builds it if +-- it's not already built, and runs it. +-- +-- If ./config.hs exists and looks like a propellor config file, +-- it instead builds and runs in the current working directory. + +module Propellor.Wrapper (runWrapper) where + +import Propellor.DotDir +import Propellor.Message +import Propellor.Bootstrap +import Utility.Monad +import Utility.Directory +import Utility.FileMode +import Utility.Process +import Utility.Process.NonConcurrent +import Utility.FileSystemEncoding + +import System.Environment (getArgs) +import System.Exit +import System.Posix +import Data.List +import Control.Monad.IfElse +import Control.Applicative +import Prelude + +runWrapper :: IO () +runWrapper = withConcurrentOutput $ do + useFileSystemEncoding + go =<< getArgs + where + go ["--init"] = interactiveInit + go args = ifM configInCurrentWorkingDirectory + ( buildRunConfig args + , ifM (doesDirectoryExist =<< dotPropellor) + ( do + checkRepoUpToDate + changeWorkingDirectory =<< dotPropellor + buildRunConfig args + , error "Seems that ~/.propellor/ does not exist. To set it up, run: propellor --init" + ) + ) + +buildRunConfig :: [String] -> IO () +buildRunConfig args = do + unlessM (doesFileExist "propellor") $ do + buildPropellor Nothing + putStrLn "" + putStrLn "" + (_, _, _, pid) <- createProcessNonConcurrent (proc "./propellor" args) + exitWith =<< waitForProcessNonConcurrent pid + +configInCurrentWorkingDirectory :: IO Bool +configInCurrentWorkingDirectory = ifM (doesFileExist "config.hs") + ( do + -- This is a security check to avoid using the current + -- working directory as the propellor configuration + -- if it's not owned by the user, or is world-writable, + -- or group writable. (Some umasks may make directories + -- group writable, but typical ones do not.) + s <- getFileStatus "." + uid <- getRealUserID + if fileOwner s /= uid + then unsafe "you don't own the current directory" + else if checkMode groupWriteMode (fileMode s) + then unsafe "the current directory is group writable" + else if checkMode otherWriteMode (fileMode s) + then unsafe "the current directory is world-writable" + else ifM mentionspropellor + ( return True + , notusing "it does not seem to be a propellor config file" + ) + , return False + ) + where + unsafe s = notusing (s ++ ". This seems unsafe.") + notusing s = error $ "Not using ./config.hs because " ++ s + mentionspropellor = ("Propellor" `isInfixOf`) <$> readFile "config.hs"