From 0ea0f7f4dee7f0e0835a82814fa89af6ce1756a1 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 23 Nov 2014 15:17:57 -0400 Subject: [PATCH] --spin can be passed multiple hosts, and it will provision each host in turn. Note that if it fails to spin a host, it will stop. I think this is better than continuing to the next, because there might be a reason to spin hosts in some specific order (ie, update dns first and then use it). --- debian/changelog | 2 ++ doc/usage.mdwn | 8 +++++++- src/Propellor/CmdLine.hs | 13 +++++++++---- src/Propellor/Spin.hs | 24 +++++++++++++----------- src/Propellor/Types.hs | 2 +- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2c3baf8..6a1d60d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ propellor (1.0.1) UNRELEASED; urgency=medium * --spin target --via relay causes propellor to bounce through an intermediate relay host, which handles any necessary uploads when provisioning the target host. + * --spin can be passed multiple hosts, and it will provision each host + in turn. * Hostname parameters not containing dots are looked up in the DNS to find the full hostname. * Added group-related properties. Thanks, FĂ©lix Sipma. diff --git a/doc/usage.mdwn b/doc/usage.mdwn index 6646ab1..1678832 100644 --- a/doc/usage.mdwn +++ b/doc/usage.mdwn @@ -20,12 +20,18 @@ action as needed to satisfy the configured properties of the local host. # OPTIONS -* --spin targethost [--via relayhost] +* --spin targethost [targethost ...] [--via relayhost] Causes propellor to automatically install itself on the specified target host, or if it's already installed there, push any updates. Propellor is then run on the target host, to satisfy its configured properties. + A signed git commit is made by --spin, so that any changes you have made + get propigated to the target host. + + Multiple target hosts can be specified; propellor will run on each of + them in sequence. + When run with --via, propellor sshes to the relay host and runs `propellor --spin hostname` from there. This can be useful when propellor is installing itself, since most of the data transfer diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index f5cfc78..4a0ac61 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -39,8 +39,11 @@ usageError ps = do processCmdLine :: IO CmdLine processCmdLine = go =<< getArgs where - go ("--spin":h:[]) = Spin <$> hostname h <*> pure Nothing - go ("--spin":h:"--via":r:[]) = Spin <$> hostname h <*> pure (Just r) + go ("--spin":ps) = case reverse ps of + (r:"--via":hs) -> Spin + <$> mapM hostname (reverse hs) + <*> pure (Just r) + _ -> Spin <$> mapM hostname ps <*> pure Nothing go ("--add-key":k:[]) = return $ AddKey k go ("--set":f:c:[]) = withprivfield f c Set go ("--dump":f:c:[]) = withprivfield f c Dump @@ -97,12 +100,14 @@ defaultMain hostlist = do go _ (Update (Just h)) = forceConsole >> fetchFirst (update (Just h)) go True cmdline@(Spin _ _) = buildFirst cmdline $ go False cmdline go True cmdline = updateFirst cmdline $ go False cmdline - go False (Spin hn r) = withhost hn $ spin hn r + go False (Spin hs r) = do + commitSpin + forM_ hs $ \hn -> withhost hn $ spin hn r go False cmdline@(SimpleRun hn) = buildFirst cmdline $ go False (Run hn) go False (Run hn) = ifM ((==) 0 <$> getRealUserID) ( onlyprocess $ withhost hn mainProperties - , go True (Spin hn Nothing) + , go True (Spin [hn] Nothing) ) withhost :: HostName -> (Host -> IO ()) -> IO () diff --git a/src/Propellor/Spin.hs b/src/Propellor/Spin.hs index 06bac33..8606013 100644 --- a/src/Propellor/Spin.hs +++ b/src/Propellor/Spin.hs @@ -1,4 +1,5 @@ module Propellor.Spin ( + commitSpin, spin, update, gitPushHelper @@ -23,18 +24,19 @@ import qualified Propellor.Shim as Shim import Utility.FileMode import Utility.SafeCommand +commitSpin :: IO () +commitSpin = do + void $ actionMessage "Git commit" $ + gitCommit [Param "--allow-empty", Param "-a", Param "-m", Param "propellor spin"] + -- Push to central origin repo first, if possible. + -- The remote propellor will pull from there, which avoids + -- us needing to send stuff directly to the remote host. + whenM hasOrigin $ + void $ actionMessage "Push to central git repository" $ + boolSystem "git" [Param "push"] + spin :: HostName -> Maybe HostName -> Host -> IO () spin target relay hst = do - unless relaying $ do - void $ actionMessage "Git commit" $ - gitCommit [Param "--allow-empty", Param "-a", Param "-m", Param "propellor spin"] - -- Push to central origin repo first, if possible. - -- The remote propellor will pull from there, which avoids - -- us needing to send stuff directly to the remote host. - whenM hasOrigin $ - void $ actionMessage "Push to central git repository" $ - boolSystem "git" [Param "push"] - cacheparams <- if viarelay then pure ["-A"] else toCommand <$> sshCachingParams hn @@ -78,7 +80,7 @@ spin target relay hst = do runcmd = "cd " ++ localdir ++ " && ./propellor " ++ cmd cmd = if viarelay - then "--serialized " ++ shellEscape (show (Spin target (Just target))) + then "--serialized " ++ shellEscape (show (Spin [target] (Just target))) else "--continue " ++ shellEscape (show (SimpleRun target)) -- Update the privdata, repo url, and git repo over the ssh diff --git a/src/Propellor/Types.hs b/src/Propellor/Types.hs index 949ce4b..92b18cd 100644 --- a/src/Propellor/Types.hs +++ b/src/Propellor/Types.hs @@ -142,7 +142,7 @@ instance ActionResult Result where data CmdLine = Run HostName - | Spin HostName (Maybe HostName) + | Spin [HostName] (Maybe HostName) | SimpleRun HostName | Set PrivDataField Context | Dump PrivDataField Context