propellor spin

This commit is contained in:
Joey Hess 2014-03-30 21:01:18 -04:00
parent 409cb20373
commit cc16366ff2
7 changed files with 45 additions and 24 deletions

View File

@ -11,7 +11,7 @@ data CmdLine
= Run HostName = Run HostName
| Spin HostName | Spin HostName
| Boot HostName | Boot HostName
| Set HostName PrivDataField String | Set HostName PrivDataField
processCmdLine :: IO CmdLine processCmdLine :: IO CmdLine
processCmdLine = go =<< getArgs processCmdLine = go =<< getArgs
@ -19,8 +19,8 @@ processCmdLine = go =<< getArgs
go ("--help":_) = usage go ("--help":_) = usage
go ("--spin":h:[]) = return $ Spin h go ("--spin":h:[]) = return $ Spin h
go ("--boot":h:[]) = return $ Boot h go ("--boot":h:[]) = return $ Boot h
go ("--set":h:f:v:[]) = case readish f of go ("--set":h:f:[]) = case readish f of
Just pf -> return $ Set h pf v Just pf -> return $ Set h pf
Nothing -> error $ "Unknown privdata field " ++ f Nothing -> error $ "Unknown privdata field " ++ f
go (h:[]) = return $ Run h go (h:[]) = return $ Run h
go [] = do go [] = do
@ -37,7 +37,7 @@ usage = do
, " propellor" , " propellor"
, " propellor hostname" , " propellor hostname"
, " propellor --spin hostname" , " propellor --spin hostname"
, " propellor --set hostname field value" , " propellor --set hostname field"
] ]
exitFailure exitFailure
@ -47,7 +47,7 @@ defaultMain getprops = go =<< processCmdLine
go (Run host) = ensureProperties (getprops host) go (Run host) = ensureProperties (getprops host)
go (Spin host) = spin host go (Spin host) = spin host
go (Boot host) = boot (getprops host) go (Boot host) = boot (getprops host)
go (Set host field val) = setPrivData host field val go (Set host field) = setPrivData host field
spin :: HostName -> IO () spin :: HostName -> IO ()
spin host = do spin host = do

View File

@ -19,3 +19,4 @@ import System.FilePath as X
import Data.Maybe as X import Data.Maybe as X
import Data.Either as X import Data.Either as X
import Utility.Monad as X import Utility.Monad as X
import Utility.Misc as X

View File

@ -16,6 +16,7 @@ import Utility.Exception
import Utility.Process import Utility.Process
import Utility.Tmp import Utility.Tmp
import Utility.SafeCommand import Utility.SafeCommand
import Utility.Misc
{- Note that removing or changing field names will break the {- Note that removing or changing field names will break the
- serialized privdata files, so don't do that! - serialized privdata files, so don't do that!
@ -38,13 +39,16 @@ getPrivData field = do
m <- catchDefaultIO Nothing $ readish <$> readFile privDataLocal m <- catchDefaultIO Nothing $ readish <$> readFile privDataLocal
return $ maybe Nothing (M.lookup field) m return $ maybe Nothing (M.lookup field) m
setPrivData :: HostName -> PrivDataField -> String -> IO () setPrivData :: HostName -> PrivDataField -> IO ()
setPrivData host field value = do setPrivData host field = do
putStrLn "Enter private data on stdin; ctrl-D when done:"
value <- hGetContentsStrict stdin
makePrivDataDir makePrivDataDir
let f = privDataFile host let f = privDataFile host
m <- fromMaybe M.empty . readish <$> gpgDecrypt f m <- fromMaybe M.empty . readish <$> gpgDecrypt f
let m' = M.insert field value m let m' = M.insert field value m
gpgEncrypt f (show m') gpgEncrypt f (show m')
putStrLn "Private data set."
void $ boolSystem "git" [Param "add", File f] void $ boolSystem "git" [Param "add", File f]
makePrivDataDir :: IO () makePrivDataDir :: IO ()

View File

@ -8,6 +8,7 @@ import qualified Property.User as User
import qualified Property.Hostname as Hostname import qualified Property.Hostname as Hostname
import qualified Property.Reboot as Reboot import qualified Property.Reboot as Reboot
import qualified Property.Tor as Tor import qualified Property.Tor as Tor
import qualified Property.Docker as Docker
import qualified Property.GitHome as GitHome import qualified Property.GitHome as GitHome
main :: IO () main :: IO ()
@ -22,7 +23,9 @@ getProperties hostname@"clam.kitenet.net" =
, standardSystem Apt.Unstable , standardSystem Apt.Unstable
-- Clam is a tor bridge. -- Clam is a tor bridge.
, Tor.isBridge , Tor.isBridge
-- I play with docker on clam.
, Apt.installed ["docker.io"] , Apt.installed ["docker.io"]
, Docker.configured
-- This is not an important system so I don't want to need to -- This is not an important system so I don't want to need to
-- manually upgrade it. -- manually upgrade it.
, Apt.unattendedUpgrades True , Apt.unattendedUpgrades True

11
Property/Docker.hs Normal file
View File

@ -0,0 +1,11 @@
module Property.Docker where
import Common
import qualified Property.File as File
{- Configures docker with an authentication file, so that images can be
- pushed to index.docker.io. -}
configured :: Property
configured = Property "docker configured" $
withPrivData DockerAuthentication $ \cfg ->
ensureProperty $ "/root/.dockercfg" `File.hasContent` (lines cfg)

2
README
View File

@ -35,7 +35,7 @@ for each host and be annoying.
Instead, propellor --spin $host looks for a privdata/$host.gpg file and Instead, propellor --spin $host looks for a privdata/$host.gpg file and
if found decrypts it and sends it to the host using ssh. To set a field if found decrypts it and sends it to the host using ssh. To set a field
in such a file, use: propellor --set $host $field $value in such a file, use: propellor --set $host $field
The field name is will be something like 'Password "root"'; see PrivData.hs The field name is will be something like 'Password "root"'; see PrivData.hs
for available fields. for available fields.

View File

@ -1,20 +1,22 @@
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
Version: GnuPG v1 Version: GnuPG v1
hQIMA7ODiaEXBlRZAQ//SyRFzPr0cVNc0QXGb2fqCEVBuwKPhAyVnkR7exaV8QQ5 hQIMA7ODiaEXBlRZAQ//fmOcGRNxe/ooyFebOl54oFJtUvmWclBN8ycWb+1FEiED
PG16euIse608lLcR6TnnQ5BHB2d7FuSM3czbFX7qUFlJJU87wgw9ApiGXwfMmdmM 4293/YYL13OXStSDCMc1o0Rq6SxRpkD/xavcc2wqBa4rTEvOzU/YdhXRLOCr2QwQ
MquAPOgsaxTOlQFY4DPulOCAXXZW61BI+S0O//ajn+wnzJ4Jr1SQ58bzTE3DqmHb Mhn4vtLmQqaQwYz5tzPkfRwtB/Wx/R4dJBfNF5vp+nl788fF+cdgLLSihY+TEPSk
eSClkbO0oH21ARqYeQ77Vs7VJTlGloT5f+xXMp4d/RxsKVyo8jkry30NDcqklzBQ +Wo2PZ0jNvCSpVR99Rh3o3ut57shsVGGa4Z4uaXfLVOu118Z00iyKZ9pHFa7gLH4
tXgTb38JQRvVdPjI4AQhi+LYjLrl+XCxQjMSktXC8MqXr7c+yuzu8ovE+tTa4xO6 nU1Y8N8JPg0Z+zJvTbJGU66k5LMZx9a/cu/+dwk2KPm3uldld4dwFk9zkmnzsIzS
OOhYN48K6AnyrY6kQAbQeuEk6VY7VFpuc+eirugvV5h+8rH8wvST2/xsC1t/Y1yJ UhWWsuea4OGanjDsPZzECkLY/AOWxRL7+4qC6c9vsFagktJezRNqNImeSkYi9fR5
NVp5zY7qzMv410dNm7hO7JFiaZmmMc0UcEYRNIIBvy51MJMmSP7KlzLNn4engFM1 xw4VnhL5JwC2RF3gMC8XHYSx5C1ByGIq0gaklJjdPRn3Kj7/zSOefgNZC/O+wSfG
xcfVVYSG1W053jY0AlOpa+8kZPhM9zBFASfUBqEOxUJ4RQE+MGdK8QrdOIl5OevJ V5W7kW7x6vvMv9og3k4BBpD4p2s94O8xtztLE+wOXxJclFen37FNhwuJyp7PiBN6
aZzYr/eFm/01n1ciz/JlNP4QgNBfNgwTAgNbGpcQGCdlp/s2HlgXm0IMLDQuFm6j T4PgekpqPfX9Xp4M1tgyUVV9m8Jeof0TtS/YsKeYqaGk1ZKPOJvqXnZTL5LOkaqE
N9V9tK35AELdoFeLlsoriwL3OA8CcMpeF3RLLAIpwXhXgAHxuhzsEwzvmx3DaUTK KTWYnWdBROwNXhsaIUnu8YHqf2mRA5VlCl1Uspd3SIyU1Xh0LL9stPnxdyJGghrG
2iV7z8qOeghRgx86pefaBmH4TDMEe6ZeSKWcoDB5lff8+DssIisniiQrDyV6PdzS RTmTJsEkzPAxnjSop72sEkKjqwkHxNbEkXg690QEPon+m/FAg083yTtKH/whbQ7S
lQGVy7VgTe35k2t8CZpbLzklS72QcEASxUISroC++YTVYejlkEHwd0axY47B8cc2 wFIBtEWDmBQyFmc1fvi1IouM9fUij6AwtJx2JrWE2d68BqE1moFGGiRSnf7itNc0
9P/ujFFco+IyU8a1b80f6QXbVE7zeS263cTCwMwhO7SBEDYA9FVTZ18eaRvSi05b YFashaGMSRZAzlx6quMJtg3sE/Xw4zra1b8SkvmH6FoQnQ2rXriG5U4Hc6bW0jIX
GtCEdu5BuNOkO0XyOSyHuCaVAJN14rH1yJXPwqfUacRxCwlaJK3YH+cTgmeKhYWp 48O96/NbIwabZiwC5BKGmSPpQBDnyzruWR/Qsnw6uar5/ZKsIOvPhICCvChO03So
zmqe4fA2 6C6WLHFb9trLqpB+r8BOMjUG/FPqZ4lRanQ3Xn///lLD2uuhH27Pmt/XDpwRJgsz
=kIsE V+uM6TVQMBe5XyE3LOk7Yn0oosohYF0LFFzQH0mO5cykx+Ctjt1muxKoUmcN99ms
j99fwMhrk1qlzlu2Yoe5caph4M44TXbQRGhPX7jXDJzYbRdS
=GYf9
-----END PGP MESSAGE----- -----END PGP MESSAGE-----