diff options
| -rw-r--r-- | debian/changelog | 3 | ||||
| -rw-r--r-- | doc/usage.mdwn | 17 | ||||
| -rw-r--r-- | src/wrapper.hs | 43 |
3 files changed, 54 insertions, 9 deletions
diff --git a/debian/changelog b/debian/changelog index 509734dd..f3442116 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,9 @@ propellor (3.2.3) UNRELEASED; urgency=medium * Improve extraction of gpg secret key id list, to work with gpg 2.1. + * The propellor wrapper checks if ./config.hs exists; if so it runs + using the configuration in the current directory, rather than + ~/.propellor/config.hs -- Joey Hess <id@joeyh.name> Fri, 11 Nov 2016 19:32:54 -0400 diff --git a/doc/usage.mdwn b/doc/usage.mdwn index 02686d5f..ac23799e 100644 --- a/doc/usage.mdwn +++ b/doc/usage.mdwn @@ -24,8 +24,8 @@ and configured in haskell. Once propellor is configured, running it without any options will take action as needed to satisfy the configured properties of the local host. - If there's a central git repository, it will first fetch from the - repository, check the gpg signature and merge, and rebuild propellor, + If there's a central git repository, it will first fetch from it, + check the gpg signature and merge, and rebuild propellor, so that any configuration changes will immediately take effect. If propellor is run by a non-root user without any options, this is @@ -116,6 +116,19 @@ and configured in haskell. This is useful when the local host doesn't yet have its hostname set correctly. +# FILES + +* ~/.propellor/config.hs + + This is the default config file used by propellor. + +* ./config.hs + + If propellor is run in a directory containing a config.hs, it + assumes that the current directory is a propellor repository, and + uses the configuration from the current directory, rather tnan + ~/.propellor/ + # ENVIRONMENT Set `PROPELLOR_DEBUG=1` to make propellor output each command it runs and diff --git a/src/wrapper.hs b/src/wrapper.hs index dab77358..6b24a368 100644 --- a/src/wrapper.hs +++ b/src/wrapper.hs @@ -6,6 +6,9 @@ -- 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, it instead builds and runs in the +-- current working directory. module Main where @@ -14,31 +17,57 @@ import Propellor.Message import Propellor.Bootstrap import Utility.Monad import Utility.Directory +import Utility.FileMode import Utility.Process import Utility.Process.NonConcurrent import System.Environment (getArgs) import System.Exit -import System.Posix.Directory +import System.Posix import Control.Monad.IfElse main :: IO () main = withConcurrentOutput $ go =<< getArgs where go ["--init"] = interactiveInit - go args = ifM (doesDirectoryExist =<< dotPropellor) - ( do - checkRepoUpToDate - buildRunConfig args - , error "Seems that ~/.propellor/ does not exist. To set it up, run: propellor --init" + 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 - changeWorkingDirectory =<< dotPropellor 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 return True + , return False + ) + where + unsafe s = error $ "Not using ./config.hs because " ++ s ++ ". This seems unsafe." |
