packages feed

propellor 5.3.4 → 5.3.5

raw patch · 14 files changed

+219/−184 lines, 14 filesdep +propellordep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: propellor

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Propellor.DotDir: checkRepoUpToDate :: IO ()
+ Propellor.DotDir: distrepo :: FilePath
+ Propellor.DotDir: dotPropellor :: IO FilePath
+ Propellor.DotDir: interactiveInit :: IO ()
+ Propellor.Wrapper: runWrapper :: IO ()
- Propellor.Property.Scheduled: period :: (IsProp (Property i)) => Property i -> Recurrance -> Property i
+ Propellor.Property.Scheduled: period :: Property i -> Recurrance -> Property i
- Propellor.Property.Scheduled: periodParse :: (IsProp (Property i)) => Property i -> String -> Property i
+ Propellor.Property.Scheduled: periodParse :: Property i -> String -> Property i

Files

CHANGELOG view
@@ -1,3 +1,13 @@+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.++ -- Joey Hess <id@joeyh.name>  Sun, 22 Apr 2018 12:27:45 -0400+ propellor (5.3.4) unstable; urgency=medium    * Apt.trustsKey: Use apt-key to add key rather than manually driving gpg,
debian/changelog view
@@ -1,3 +1,13 @@+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.++ -- Joey Hess <id@joeyh.name>  Sun, 22 Apr 2018 12:27:45 -0400+ propellor (5.3.4) unstable; urgency=medium    * Apt.trustsKey: Use apt-key to add key rather than manually driving gpg,
+ executables/propellor-config.hs view
@@ -0,0 +1,29 @@+-- This is the main configuration file for Propellor, and is used to build+-- the propellor program.++import Propellor+import qualified Propellor.Property.File as File+import qualified Propellor.Property.Apt as Apt+import qualified Propellor.Property.Cron as Cron+import qualified Propellor.Property.User as User++main :: IO ()+main = defaultMain hosts++-- The hosts propellor knows about.+hosts :: [Host]+hosts =+	[ mybox+	]++-- An example host.+mybox :: Host+mybox = host "mybox.example.com" $ props+	& osDebian Unstable X86_64+	& Apt.stdSourcesList+	& Apt.unattendedUpgrades+	& Apt.installed ["etckeeper"]+	& Apt.installed ["ssh"]+	& User.hasSomePassword (User "root")+	& File.dirExists "/var/www"+	& Cron.runPropellor (Cron.Times "30 * * * *")
+ executables/wrapper.hs view
@@ -0,0 +1,6 @@+module Main where++import Propellor.Wrapper++main :: IO ()+main = runWrapper
joeyconfig.hs view
@@ -33,7 +33,6 @@ 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 @@ hosts :: [Host]          --   *             \ | |           '--------' hosts =                 --                  (o)  ` 	[ darkstar-	, gnu 	, dragon 	, clam 	, orca@@ -64,25 +62,6 @@ 	, 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 @@ 	-- & 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 @@ 	& 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 @@ 	& 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 @@  	& Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile 	& Apt.installed ["linux-image-amd64"]+	& Apt.serviceInstalledRunning "swapspace" 	& Linode.serialGrub 	& Linode.mlocateEnabled 	& Apt.unattendedUpgrades@@ -341,7 +330,7 @@ 		, "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 @@ 	, 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" 	]  
propellor.cabal view
@@ -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 @@  .  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 @@   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 @@   Exposed-Modules:     Propellor     Propellor.Base+    Propellor.DotDir     Propellor.Location     Propellor.Property     Propellor.Property.Aiccu@@ -211,6 +182,7 @@     Propellor.Types.ResultCheck     Propellor.Types.Singletons     Propellor.Types.ZFS+    Propellor.Wrapper   Other-Modules:     Propellor.Bootstrap     Propellor.Git@@ -254,6 +226,23 @@     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
src/Propellor/Property/Apt.hs view
@@ -88,6 +88,8 @@ binandsrc url suite = catMaybes 	[ Just l 	, Just $ srcLine l+	, sul+	, srcLine <$> sul 	, bl 	, srcLine <$> bl 	]@@ -96,6 +98,10 @@ 	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
src/Propellor/Property/Machine.hs view
@@ -48,10 +48,10 @@ 	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,
src/Propellor/Property/Scheduled.hs view
@@ -21,7 +21,7 @@ -- -- 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 @@ 	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
src/Propellor/Property/SiteSpecific/JoeySites.hs view
@@ -15,6 +15,7 @@ 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 @@ 	& 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 @@ 		, "[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 @@ 		, "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 @@  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 @@ 	, "pmount", "tree", "pv" 	, "arbtt", "hledger", "bc" 	, "apache2", "ikiwiki", "libhighlight-perl"+	, "avahi-daemon", "avahi-discover" 	, "pal" 	, "yeahconsole", "xkbset", "xinput" 	, "assword", "pumpa"@@ -1096,13 +1121,13 @@ 		["--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 @@ 		, "" 		, "&pio {" 		, "\tmy_w1_pin: my_w1_pin@0 {"-		, "\t\tallwinner,pins = \"PG8\";"+		, "\t\tallwinner,pins = \"PC21\";" 		, "\t\tallwinner,function = \"gpio_in\";" 		, "\t};" 		, "};"
src/Propellor/Property/Systemd.hs view
@@ -217,7 +217,7 @@ -- 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 @@ -- to bootstrap. -- -- > debContainer "webserver" $ props--- >	& osDebian Unstable X86_64+-- >    & osDebian Unstable X86_64 -- >    & Apt.installedRunning "apache2" -- >    & ... debContainer :: MachineName -> Props metatypes -> Container
+ src/Propellor/Wrapper.hs view
@@ -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"
− src/propellor-config.hs
@@ -1,29 +0,0 @@--- This is the main configuration file for Propellor, and is used to build--- the propellor program.--import Propellor-import qualified Propellor.Property.File as File-import qualified Propellor.Property.Apt as Apt-import qualified Propellor.Property.Cron as Cron-import qualified Propellor.Property.User as User--main :: IO ()-main = defaultMain hosts---- The hosts propellor knows about.-hosts :: [Host]-hosts =-	[ mybox-	]---- An example host.-mybox :: Host-mybox = host "mybox.example.com" $ props-	& osDebian Unstable X86_64-	& Apt.stdSourcesList-	& Apt.unattendedUpgrades-	& Apt.installed ["etckeeper"]-	& Apt.installed ["ssh"]-	& User.hasSomePassword (User "root")-	& File.dirExists "/var/www"-	& Cron.runPropellor (Cron.Times "30 * * * *")
− src/wrapper.hs
@@ -1,84 +0,0 @@--- | 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 Main 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--main :: IO ()-main = 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"