Merge branch 'joeyconfig'
This commit is contained in:
commit
ac41f8b07b
|
@ -7,3 +7,4 @@ Setup
|
||||||
Setup.hi
|
Setup.hi
|
||||||
Setup.o
|
Setup.o
|
||||||
docker
|
docker
|
||||||
|
propellor.1
|
||||||
|
|
|
@ -26,6 +26,7 @@ import qualified Propellor.Property.Obnam as Obnam
|
||||||
import qualified Propellor.Property.Gpg as Gpg
|
import qualified Propellor.Property.Gpg as Gpg
|
||||||
import qualified Propellor.Property.Chroot as Chroot
|
import qualified Propellor.Property.Chroot as Chroot
|
||||||
import qualified Propellor.Property.Systemd as Systemd
|
import qualified Propellor.Property.Systemd as Systemd
|
||||||
|
import qualified Propellor.Property.Debootstrap as Debootstrap
|
||||||
import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean
|
import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean
|
||||||
import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost
|
import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost
|
||||||
import qualified Propellor.Property.HostingProvider.Linode as Linode
|
import qualified Propellor.Property.HostingProvider.Linode as Linode
|
||||||
|
@ -46,6 +47,7 @@ hosts = -- (o) `
|
||||||
, kite
|
, kite
|
||||||
, diatom
|
, diatom
|
||||||
, elephant
|
, elephant
|
||||||
|
, alien
|
||||||
] ++ monsters
|
] ++ monsters
|
||||||
|
|
||||||
darkstar :: Host
|
darkstar :: Host
|
||||||
|
@ -81,18 +83,21 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64"
|
||||||
! Ssh.listenPort 80
|
! Ssh.listenPort 80
|
||||||
! Ssh.listenPort 443
|
! Ssh.listenPort 443
|
||||||
|
|
||||||
! Chroot.provisioned testChroot
|
|
||||||
& Systemd.persistentJournal
|
& Systemd.persistentJournal
|
||||||
& Systemd.nspawned meow
|
! Systemd.nspawned meow
|
||||||
|
|
||||||
meow :: Systemd.Container
|
meow :: Systemd.Container
|
||||||
meow = Systemd.container "meow" (Chroot.debootstrapped (System (Debian Unstable) "amd64") mempty)
|
meow = Systemd.container "meow" (Chroot.debootstrapped (System (Debian Unstable) "amd64") mempty)
|
||||||
& Apt.serviceInstalledRunning "uptimed"
|
& Apt.serviceInstalledRunning "uptimed"
|
||||||
& alias "meow.kitenet.net"
|
& alias "meow.kitenet.net"
|
||||||
|
|
||||||
testChroot :: Chroot.Chroot
|
alien :: Host
|
||||||
testChroot = Chroot.debootstrapped (System (Debian Unstable) "amd64") mempty "/tmp/chroot"
|
alien = host "alientest.kitenet.net"
|
||||||
& File.hasContent "/foo" ["hello"]
|
& ipv4 "104.131.106.199"
|
||||||
|
& Chroot.provisioned
|
||||||
|
( Chroot.debootstrapped (System (Debian Unstable) "amd64") Debootstrap.MinBase "/debian"
|
||||||
|
& Apt.serviceInstalledRunning "uptimed"
|
||||||
|
)
|
||||||
|
|
||||||
orca :: Host
|
orca :: Host
|
||||||
orca = standardSystem "orca.kitenet.net" Unstable "amd64"
|
orca = standardSystem "orca.kitenet.net" Unstable "amd64"
|
||||||
|
|
|
@ -3,8 +3,13 @@ propellor (1.0.1) UNRELEASED; urgency=medium
|
||||||
* propellor --spin can now deploy propellor to hosts that do not have
|
* propellor --spin can now deploy propellor to hosts that do not have
|
||||||
git, ghc, or apt-get. This is accomplished by uploading a fairly
|
git, ghc, or apt-get. This is accomplished by uploading a fairly
|
||||||
portable precompiled tarball of propellor.
|
portable precompiled tarball of propellor.
|
||||||
* --spin host --via host causes propellor to bounce through an intermediate
|
* --spin target --via relay causes propellor to bounce through an
|
||||||
host, which handles any necessary provisioning of the host being spun.
|
intermediate relay host, which handles any necessary uploads
|
||||||
|
when provisioning the target host.
|
||||||
|
* Hostname parameters not containing dots are looked up in the DNS to
|
||||||
|
find the full hostname.
|
||||||
|
* Added group-related properties. Thanks, Félix Sipma.
|
||||||
|
* Added Git.barerepo. Thanks, Félix Sipma.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Sat, 22 Nov 2014 00:12:35 -0400
|
-- Joey Hess <joeyh@debian.org> Sat, 22 Nov 2014 00:12:35 -0400
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,18 @@ action as needed to satisfy the configured properties of the local host.
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
|
|
||||||
* --spin hostname
|
* --spin targethost [--via relayhost]
|
||||||
|
|
||||||
Causes propellor to automatically install itself on the specified host,
|
Causes propellor to automatically install itself on the specified target
|
||||||
or if it's already installed there, push any updates. Propellor is then
|
host, or if it's already installed there, push any updates. Propellor is
|
||||||
run on the host, to satisfy its configured properties.
|
then run on the target host, to satisfy its configured properties.
|
||||||
|
|
||||||
|
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
|
||||||
|
is done between relay host and target host. Note that propellor
|
||||||
|
uses ssh agent forwarding to make this work, and the relay host
|
||||||
|
sees any privdata belonging to the target host.
|
||||||
|
|
||||||
* --add-key keyid
|
* --add-key keyid
|
||||||
|
|
||||||
|
@ -52,6 +59,13 @@ action as needed to satisfy the configured properties of the local host.
|
||||||
|
|
||||||
Opens $EDITOR on the privdata value.
|
Opens $EDITOR on the privdata value.
|
||||||
|
|
||||||
|
* hostname
|
||||||
|
|
||||||
|
When run with a hostname and no other options, propellor will
|
||||||
|
provision the local host with the configuration of that hostname.
|
||||||
|
This is useful when the local host doesn't yet have its hostname set
|
||||||
|
correctly.
|
||||||
|
|
||||||
# ENVIRONMENT
|
# ENVIRONMENT
|
||||||
|
|
||||||
Set `PROPELLOR_DEBUG=1` to make propellor output each command it runs and
|
Set `PROPELLOR_DEBUG=1` to make propellor output each command it runs and
|
||||||
|
|
|
@ -83,6 +83,7 @@ Library
|
||||||
Propellor.Property.Firewall
|
Propellor.Property.Firewall
|
||||||
Propellor.Property.Git
|
Propellor.Property.Git
|
||||||
Propellor.Property.Gpg
|
Propellor.Property.Gpg
|
||||||
|
Propellor.Property.Group
|
||||||
Propellor.Property.Grub
|
Propellor.Property.Grub
|
||||||
Propellor.Property.Network
|
Propellor.Property.Network
|
||||||
Propellor.Property.Nginx
|
Propellor.Property.Nginx
|
||||||
|
@ -121,11 +122,12 @@ Library
|
||||||
Other-Modules:
|
Other-Modules:
|
||||||
Propellor.Git
|
Propellor.Git
|
||||||
Propellor.Gpg
|
Propellor.Gpg
|
||||||
Propellor.Server
|
Propellor.Spin
|
||||||
Propellor.Ssh
|
Propellor.Ssh
|
||||||
Propellor.PrivData.Paths
|
Propellor.PrivData.Paths
|
||||||
Propellor.Protocol
|
Propellor.Protocol
|
||||||
Propellor.Shim
|
Propellor.Shim
|
||||||
|
Propellor.Property.Chroot.Util
|
||||||
Utility.Applicative
|
Utility.Applicative
|
||||||
Utility.Data
|
Utility.Data
|
||||||
Utility.Directory
|
Utility.Directory
|
||||||
|
|
|
@ -7,13 +7,12 @@ import System.Environment (getArgs)
|
||||||
import Data.List
|
import Data.List
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import System.PosixCompat
|
import System.PosixCompat
|
||||||
|
import qualified Network.BSD
|
||||||
|
|
||||||
import Propellor
|
import Propellor
|
||||||
import Propellor.Protocol
|
|
||||||
import Propellor.Gpg
|
import Propellor.Gpg
|
||||||
import Propellor.Git
|
import Propellor.Git
|
||||||
import Propellor.Ssh
|
import Propellor.Spin
|
||||||
import Propellor.Server
|
|
||||||
import qualified Propellor.Property.Docker as Docker
|
import qualified Propellor.Property.Docker as Docker
|
||||||
import qualified Propellor.Property.Chroot as Chroot
|
import qualified Propellor.Property.Chroot as Chroot
|
||||||
import qualified Propellor.Shim as Shim
|
import qualified Propellor.Shim as Shim
|
||||||
|
@ -24,7 +23,7 @@ usage h = hPutStrLn h $ unlines
|
||||||
[ "Usage:"
|
[ "Usage:"
|
||||||
, " propellor"
|
, " propellor"
|
||||||
, " propellor hostname"
|
, " propellor hostname"
|
||||||
, " propellor --spin hostname"
|
, " propellor --spin targethost [--via relayhost]"
|
||||||
, " propellor --add-key keyid"
|
, " propellor --add-key keyid"
|
||||||
, " propellor --set field context"
|
, " propellor --set field context"
|
||||||
, " propellor --dump field context"
|
, " propellor --dump field context"
|
||||||
|
@ -40,8 +39,8 @@ usageError ps = do
|
||||||
processCmdLine :: IO CmdLine
|
processCmdLine :: IO CmdLine
|
||||||
processCmdLine = go =<< getArgs
|
processCmdLine = go =<< getArgs
|
||||||
where
|
where
|
||||||
go ("--run":h:[]) = return $ Run h
|
go ("--spin":h:[]) = Spin <$> hostname h <*> pure Nothing
|
||||||
go ("--spin":h:[]) = return $ Spin h
|
go ("--spin":h:"--via":r:[]) = Spin <$> hostname h <*> pure (Just r)
|
||||||
go ("--add-key":k:[]) = return $ AddKey k
|
go ("--add-key":k:[]) = return $ AddKey k
|
||||||
go ("--set":f:c:[]) = withprivfield f c Set
|
go ("--set":f:c:[]) = withprivfield f c Set
|
||||||
go ("--dump":f:c:[]) = withprivfield f c Dump
|
go ("--dump":f:c:[]) = withprivfield f c Dump
|
||||||
|
@ -50,15 +49,15 @@ processCmdLine = go =<< getArgs
|
||||||
go ("--help":_) = do
|
go ("--help":_) = do
|
||||||
usage stdout
|
usage stdout
|
||||||
exitFailure
|
exitFailure
|
||||||
go ("--update":h:[]) = return $ Update h
|
go ("--update":_:[]) = return $ Update Nothing
|
||||||
go ("--boot":h:[]) = return $ Update h -- for back-compat
|
go ("--boot":_:[]) = return $ Update Nothing -- for back-compat
|
||||||
go ("--continue":s:[]) = case readish s of
|
go ("--serialized":s:[]) = serialized Serialized s
|
||||||
Just cmdline -> return $ Continue cmdline
|
go ("--continue":s:[]) = serialized Continue s
|
||||||
Nothing -> errorMessage $ "--continue serialization failure (" ++ s ++ ")"
|
|
||||||
go ("--gitpush":fin:fout:_) = return $ GitPush (Prelude.read fin) (Prelude.read fout)
|
go ("--gitpush":fin:fout:_) = return $ GitPush (Prelude.read fin) (Prelude.read fout)
|
||||||
|
go ("--run":h:[]) = go [h]
|
||||||
go (h:[])
|
go (h:[])
|
||||||
| "--" `isPrefixOf` h = usageError [h]
|
| "--" `isPrefixOf` h = usageError [h]
|
||||||
| otherwise = return $ Run h
|
| otherwise = Run <$> hostname h
|
||||||
go [] = do
|
go [] = do
|
||||||
s <- takeWhile (/= '\n') <$> readProcess "hostname" ["-f"]
|
s <- takeWhile (/= '\n') <$> readProcess "hostname" ["-f"]
|
||||||
if null s
|
if null s
|
||||||
|
@ -70,6 +69,10 @@ processCmdLine = go =<< getArgs
|
||||||
Just pf -> return $ f pf (Context c)
|
Just pf -> return $ f pf (Context c)
|
||||||
Nothing -> errorMessage $ "Unknown privdata field " ++ s
|
Nothing -> errorMessage $ "Unknown privdata field " ++ s
|
||||||
|
|
||||||
|
serialized mk s = case readish s of
|
||||||
|
Just cmdline -> return $ mk cmdline
|
||||||
|
Nothing -> errorMessage $ "serialization failure (" ++ s ++ ")"
|
||||||
|
|
||||||
-- | Runs propellor on hosts, as controlled by command-line options.
|
-- | Runs propellor on hosts, as controlled by command-line options.
|
||||||
defaultMain :: [Host] -> IO ()
|
defaultMain :: [Host] -> IO ()
|
||||||
defaultMain hostlist = do
|
defaultMain hostlist = do
|
||||||
|
@ -79,6 +82,7 @@ defaultMain hostlist = do
|
||||||
debug ["command line: ", show cmdline]
|
debug ["command line: ", show cmdline]
|
||||||
go True cmdline
|
go True cmdline
|
||||||
where
|
where
|
||||||
|
go _ (Serialized cmdline) = go True cmdline
|
||||||
go _ (Continue cmdline) = go False cmdline
|
go _ (Continue cmdline) = go False cmdline
|
||||||
go _ (Set field context) = setPrivData field context
|
go _ (Set field context) = setPrivData field context
|
||||||
go _ (Dump field context) = dumpPrivData field context
|
go _ (Dump field context) = dumpPrivData field context
|
||||||
|
@ -89,15 +93,16 @@ defaultMain hostlist = do
|
||||||
go _ (DockerChain hn cid) = Docker.chain hostlist hn cid
|
go _ (DockerChain hn cid) = Docker.chain hostlist hn cid
|
||||||
go _ (DockerInit hn) = Docker.init hn
|
go _ (DockerInit hn) = Docker.init hn
|
||||||
go _ (GitPush fin fout) = gitPushHelper fin fout
|
go _ (GitPush fin fout) = gitPushHelper fin fout
|
||||||
go _ (Update _) = forceConsole >> fetchFirst (onlyprocess update)
|
go _ (Update Nothing) = forceConsole >> fetchFirst (onlyprocess (update Nothing))
|
||||||
go True cmdline@(Spin _) = buildFirst cmdline $ go False cmdline
|
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 True cmdline = updateFirst cmdline $ go False cmdline
|
||||||
go False (Spin hn) = withhost hn $ spin hn
|
go False (Spin hn r) = withhost hn $ spin hn r
|
||||||
go False cmdline@(SimpleRun hn) = buildFirst cmdline $
|
go False cmdline@(SimpleRun hn) = buildFirst cmdline $
|
||||||
go False (Run hn)
|
go False (Run hn)
|
||||||
go False (Run hn) = ifM ((==) 0 <$> getRealUserID)
|
go False (Run hn) = ifM ((==) 0 <$> getRealUserID)
|
||||||
( onlyprocess $ withhost hn mainProperties
|
( onlyprocess $ withhost hn mainProperties
|
||||||
, go True (Spin hn)
|
, go True (Spin hn Nothing)
|
||||||
)
|
)
|
||||||
|
|
||||||
withhost :: HostName -> (Host -> IO ()) -> IO ()
|
withhost :: HostName -> (Host -> IO ()) -> IO ()
|
||||||
|
@ -148,45 +153,9 @@ updateFirst' cmdline next = ifM fetchOrigin
|
||||||
, next
|
, next
|
||||||
)
|
)
|
||||||
|
|
||||||
spin :: HostName -> Host -> IO ()
|
hostname :: String -> IO HostName
|
||||||
spin hn hst = do
|
hostname s
|
||||||
void $ actionMessage "Git commit" $
|
| "." `isInfixOf` s = pure s
|
||||||
gitCommit [Param "--allow-empty", Param "-a", Param "-m", Param "propellor spin"]
|
| otherwise = do
|
||||||
-- Push to central origin repo first, if possible.
|
h <- Network.BSD.getHostByName s
|
||||||
-- The remote propellor will pull from there, which avoids
|
return (Network.BSD.hostName h)
|
||||||
-- us needing to send stuff directly to the remote host.
|
|
||||||
whenM hasOrigin $
|
|
||||||
void $ actionMessage "Push to central git repository" $
|
|
||||||
boolSystem "git" [Param "push"]
|
|
||||||
|
|
||||||
cacheparams <- toCommand <$> sshCachingParams hn
|
|
||||||
|
|
||||||
-- Install, or update the remote propellor.
|
|
||||||
updateServer hn hst $ withBothHandles createProcessSuccess
|
|
||||||
(proc "ssh" $ cacheparams ++ [user, updatecmd])
|
|
||||||
|
|
||||||
-- And now we can run it.
|
|
||||||
unlessM (boolSystem "ssh" (map Param $ cacheparams ++ ["-t", user, runcmd])) $
|
|
||||||
error $ "remote propellor failed"
|
|
||||||
where
|
|
||||||
user = "root@"++hn
|
|
||||||
|
|
||||||
mkcmd = shellWrap . intercalate " ; "
|
|
||||||
|
|
||||||
updatecmd = mkcmd
|
|
||||||
[ "if [ ! -d " ++ localdir ++ " ]"
|
|
||||||
, "then (" ++ intercalate " && "
|
|
||||||
[ "apt-get update"
|
|
||||||
, "apt-get --no-install-recommends --no-upgrade -y install git make"
|
|
||||||
, "echo " ++ toMarked statusMarker (show NeedGitClone)
|
|
||||||
] ++ ") || echo " ++ toMarked statusMarker (show NeedPrecompiled)
|
|
||||||
, "else " ++ intercalate " && "
|
|
||||||
[ "cd " ++ localdir
|
|
||||||
, "if ! test -x ./propellor; then make deps build; fi"
|
|
||||||
, "./propellor --boot " ++ hn
|
|
||||||
]
|
|
||||||
, "fi"
|
|
||||||
]
|
|
||||||
|
|
||||||
runcmd = mkcmd
|
|
||||||
[ "cd " ++ localdir ++ " && ./propellor --continue " ++ shellEscape (show (SimpleRun hn)) ]
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import "mtl" Control.Monad.Reader
|
||||||
import Control.Exception (bracket)
|
import Control.Exception (bracket)
|
||||||
import System.PosixCompat
|
import System.PosixCompat
|
||||||
import System.Posix.IO
|
import System.Posix.IO
|
||||||
|
import System.FilePath
|
||||||
|
import System.Directory
|
||||||
|
|
||||||
import Propellor.Types
|
import Propellor.Types
|
||||||
import Propellor.Message
|
import Propellor.Message
|
||||||
|
@ -60,6 +62,7 @@ onlyProcess :: FilePath -> IO a -> IO a
|
||||||
onlyProcess lockfile a = bracket lock unlock (const a)
|
onlyProcess lockfile a = bracket lock unlock (const a)
|
||||||
where
|
where
|
||||||
lock = do
|
lock = do
|
||||||
|
createDirectoryIfMissing True (takeDirectory lockfile)
|
||||||
l <- createFile lockfile stdFileMode
|
l <- createFile lockfile stdFileMode
|
||||||
setLock l (WriteLock, AbsoluteSeek, 0, 0)
|
setLock l (WriteLock, AbsoluteSeek, 0, 0)
|
||||||
`catchIO` const alreadyrunning
|
`catchIO` const alreadyrunning
|
||||||
|
|
|
@ -42,6 +42,9 @@ hasOrigin = catchDefaultIO False $ do
|
||||||
rs <- lines <$> readProcess "git" ["remote"]
|
rs <- lines <$> readProcess "git" ["remote"]
|
||||||
return $ "origin" `elem` rs
|
return $ "origin" `elem` rs
|
||||||
|
|
||||||
|
hasGitRepo :: IO Bool
|
||||||
|
hasGitRepo = doesFileExist ".git/HEAD"
|
||||||
|
|
||||||
{- To verify origin branch commit's signature, have to convince gpg
|
{- To verify origin branch commit's signature, have to convince gpg
|
||||||
- to use our keyring.
|
- to use our keyring.
|
||||||
- While running git log. Which has no way to pass options to gpg.
|
- While running git log. Which has no way to pass options to gpg.
|
||||||
|
|
|
@ -10,3 +10,6 @@ privDataFile = privDataDir </> "privdata.gpg"
|
||||||
|
|
||||||
privDataLocal :: FilePath
|
privDataLocal :: FilePath
|
||||||
privDataLocal = privDataDir </> "local"
|
privDataLocal = privDataDir </> "local"
|
||||||
|
|
||||||
|
privDataRelay :: String -> FilePath
|
||||||
|
privDataRelay host = privDataDir </> "relay" </> host
|
||||||
|
|
|
@ -11,6 +11,7 @@ module Propellor.Property.Chroot (
|
||||||
|
|
||||||
import Propellor
|
import Propellor
|
||||||
import Propellor.Types.Chroot
|
import Propellor.Types.Chroot
|
||||||
|
import Propellor.Property.Chroot.Util
|
||||||
import qualified Propellor.Property.Debootstrap as Debootstrap
|
import qualified Propellor.Property.Debootstrap as Debootstrap
|
||||||
import qualified Propellor.Property.Systemd.Core as Systemd
|
import qualified Propellor.Property.Systemd.Core as Systemd
|
||||||
import qualified Propellor.Shim as Shim
|
import qualified Propellor.Shim as Shim
|
||||||
|
@ -88,7 +89,7 @@ propellChroot c@(Chroot loc _ _ _) mkproc systemdonly = property (chrootDesc c "
|
||||||
let me = localdir </> "propellor"
|
let me = localdir </> "propellor"
|
||||||
shim <- liftIO $ ifM (doesDirectoryExist d)
|
shim <- liftIO $ ifM (doesDirectoryExist d)
|
||||||
( pure (Shim.file me d)
|
( pure (Shim.file me d)
|
||||||
, Shim.setup me d
|
, Shim.setup me Nothing d
|
||||||
)
|
)
|
||||||
ifM (liftIO $ bindmount shim)
|
ifM (liftIO $ bindmount shim)
|
||||||
( chainprovision shim
|
( chainprovision shim
|
||||||
|
@ -109,12 +110,14 @@ propellChroot c@(Chroot loc _ _ _) mkproc systemdonly = property (chrootDesc c "
|
||||||
chainprovision shim = do
|
chainprovision shim = do
|
||||||
parenthost <- asks hostName
|
parenthost <- asks hostName
|
||||||
cmd <- liftIO $ toChain parenthost c systemdonly
|
cmd <- liftIO $ toChain parenthost c systemdonly
|
||||||
|
pe <- liftIO standardPathEnv
|
||||||
let p = mkproc
|
let p = mkproc
|
||||||
[ shim
|
[ shim
|
||||||
, "--continue"
|
, "--continue"
|
||||||
, show cmd
|
, show cmd
|
||||||
]
|
]
|
||||||
liftIO $ withHandle StdoutHandle createProcessSuccess p
|
let p' = p { env = Just pe }
|
||||||
|
liftIO $ withHandle StdoutHandle createProcessSuccess p'
|
||||||
processChainOutput
|
processChainOutput
|
||||||
|
|
||||||
toChain :: HostName -> Chroot -> Bool -> IO CmdLine
|
toChain :: HostName -> Chroot -> Bool -> IO CmdLine
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
module Propellor.Property.Chroot.Util where
|
||||||
|
|
||||||
|
import Utility.Env
|
||||||
|
import Control.Applicative
|
||||||
|
|
||||||
|
-- When chrooting, it's useful to ensure that PATH has all the standard
|
||||||
|
-- directories in it. This adds those directories to whatever PATH is
|
||||||
|
-- already set.
|
||||||
|
standardPathEnv :: IO [(String, String)]
|
||||||
|
standardPathEnv = do
|
||||||
|
path <- getEnvDefault "PATH" "/bin"
|
||||||
|
addEntry "PATH" (path ++ std)
|
||||||
|
<$> getEnvironment
|
||||||
|
where
|
||||||
|
std = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
@ -8,6 +8,7 @@ module Propellor.Property.Debootstrap (
|
||||||
|
|
||||||
import Propellor
|
import Propellor
|
||||||
import qualified Propellor.Property.Apt as Apt
|
import qualified Propellor.Property.Apt as Apt
|
||||||
|
import Propellor.Property.Chroot.Util
|
||||||
import Utility.Path
|
import Utility.Path
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
import Utility.FileMode
|
import Utility.FileMode
|
||||||
|
@ -78,7 +79,8 @@ built target system@(System _ arch) config =
|
||||||
, Param target
|
, Param target
|
||||||
]
|
]
|
||||||
cmd <- fromMaybe "debootstrap" <$> programPath
|
cmd <- fromMaybe "debootstrap" <$> programPath
|
||||||
ifM (boolSystem cmd params)
|
de <- standardPathEnv
|
||||||
|
ifM (boolSystemEnv cmd params (Just de))
|
||||||
( do
|
( do
|
||||||
fixForeignDev target
|
fixForeignDev target
|
||||||
return MadeChange
|
return MadeChange
|
||||||
|
@ -141,8 +143,26 @@ installed = RevertableProperty install remove
|
||||||
aptremove = Apt.removed ["debootstrap"]
|
aptremove = Apt.removed ["debootstrap"]
|
||||||
|
|
||||||
sourceInstall :: Property
|
sourceInstall :: Property
|
||||||
sourceInstall = property "debootstrap installed from source"
|
sourceInstall = property "debootstrap installed from source" (liftIO sourceInstall')
|
||||||
(liftIO sourceInstall')
|
`requires` perlInstalled
|
||||||
|
`requires` arInstalled
|
||||||
|
|
||||||
|
perlInstalled :: Property
|
||||||
|
perlInstalled = check (not <$> inPath "perl") $ property "perl installed" $ do
|
||||||
|
v <- liftIO $ firstM id
|
||||||
|
[ yumInstall "perl"
|
||||||
|
]
|
||||||
|
if isJust v then return MadeChange else return FailedChange
|
||||||
|
|
||||||
|
arInstalled :: Property
|
||||||
|
arInstalled = check (not <$> inPath "ar") $ property "ar installed" $ do
|
||||||
|
v <- liftIO $ firstM id
|
||||||
|
[ yumInstall "binutils"
|
||||||
|
]
|
||||||
|
if isJust v then return MadeChange else return FailedChange
|
||||||
|
|
||||||
|
yumInstall :: String -> IO Bool
|
||||||
|
yumInstall p = boolSystem "yum" [Param "-y", Param "install", Param p]
|
||||||
|
|
||||||
sourceInstall' :: IO Result
|
sourceInstall' :: IO Result
|
||||||
sourceInstall' = withTmpDir "debootstrap" $ \tmpd -> do
|
sourceInstall' = withTmpDir "debootstrap" $ \tmpd -> do
|
||||||
|
@ -228,18 +248,23 @@ makeDevicesTarball = do
|
||||||
tarcmd = "(cd / && tar cf - dev) | gzip > devices.tar.gz"
|
tarcmd = "(cd / && tar cf - dev) | gzip > devices.tar.gz"
|
||||||
|
|
||||||
fixForeignDev :: FilePath -> IO ()
|
fixForeignDev :: FilePath -> IO ()
|
||||||
fixForeignDev target = whenM (doesFileExist (target ++ foreignDevFlag)) $
|
fixForeignDev target = whenM (doesFileExist (target ++ foreignDevFlag)) $ do
|
||||||
void $ boolSystem "chroot"
|
de <- standardPathEnv
|
||||||
|
void $ boolSystemEnv "chroot"
|
||||||
[ File target
|
[ File target
|
||||||
, Param "sh"
|
, Param "sh"
|
||||||
, Param "-c"
|
, Param "-c"
|
||||||
, Param $ intercalate " && "
|
, Param $ intercalate " && "
|
||||||
[ "rm -rf /dev"
|
[ "apt-get update"
|
||||||
|
, "apt-get -y install makedev"
|
||||||
|
, "rm -rf /dev"
|
||||||
, "mkdir /dev"
|
, "mkdir /dev"
|
||||||
, "cd /dev"
|
, "cd /dev"
|
||||||
|
, "mount -t proc proc /proc"
|
||||||
, "/sbin/MAKEDEV std ptmx fd consoleonly"
|
, "/sbin/MAKEDEV std ptmx fd consoleonly"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
(Just de)
|
||||||
|
|
||||||
foreignDevFlag :: FilePath
|
foreignDevFlag :: FilePath
|
||||||
foreignDevFlag = "/dev/.propellor-foreign-dev"
|
foreignDevFlag = "/dev/.propellor-foreign-dev"
|
||||||
|
|
|
@ -377,7 +377,7 @@ runningContainer cid@(ContainerId hn cn) image runps = containerDesc cid $ prope
|
||||||
liftIO $ do
|
liftIO $ do
|
||||||
clearProvisionedFlag cid
|
clearProvisionedFlag cid
|
||||||
createDirectoryIfMissing True (takeDirectory $ identFile cid)
|
createDirectoryIfMissing True (takeDirectory $ identFile cid)
|
||||||
shim <- liftIO $ Shim.setup (localdir </> "propellor") (localdir </> shimdir cid)
|
shim <- liftIO $ Shim.setup (localdir </> "propellor") Nothing (localdir </> shimdir cid)
|
||||||
liftIO $ writeFile (identFile cid) (show ident)
|
liftIO $ writeFile (identFile cid) (show ident)
|
||||||
ensureProperty $ boolProperty "run" $ runContainer img
|
ensureProperty $ boolProperty "run" $ runContainer img
|
||||||
(runps ++ ["-i", "-d", "-t"])
|
(runps ++ ["-i", "-d", "-t"])
|
||||||
|
|
|
@ -57,8 +57,9 @@ type Branch = String
|
||||||
|
|
||||||
-- | Specified git repository is cloned to the specified directory.
|
-- | Specified git repository is cloned to the specified directory.
|
||||||
--
|
--
|
||||||
-- If the firectory exists with some other content, it will be recursively
|
-- If the directory exists with some other content (either a non-git
|
||||||
-- deleted.
|
-- repository, or a git repository cloned from some other location),
|
||||||
|
-- it will be recursively deleted first.
|
||||||
--
|
--
|
||||||
-- A branch can be specified, to check out.
|
-- A branch can be specified, to check out.
|
||||||
cloned :: UserName -> RepoUrl -> FilePath -> Maybe Branch -> Property
|
cloned :: UserName -> RepoUrl -> FilePath -> Maybe Branch -> Property
|
||||||
|
@ -94,3 +95,23 @@ cloned owner url dir mbranch = check originurl (property desc checkout)
|
||||||
|
|
||||||
isGitDir :: FilePath -> IO Bool
|
isGitDir :: FilePath -> IO Bool
|
||||||
isGitDir dir = isNothing <$> catchMaybeIO (readProcess "git" ["rev-parse", "--resolve-git-dir", dir])
|
isGitDir dir = isNothing <$> catchMaybeIO (readProcess "git" ["rev-parse", "--resolve-git-dir", dir])
|
||||||
|
|
||||||
|
data GitShared = Shared GroupName | SharedAll | NotShared
|
||||||
|
|
||||||
|
bareRepo :: FilePath -> UserName -> GitShared -> Property
|
||||||
|
bareRepo repo user gitshared = check (isRepo repo) $ propertyList ("git repo: " ++ repo) $
|
||||||
|
dirExists repo : case gitshared of
|
||||||
|
NotShared ->
|
||||||
|
[ ownerGroup repo user user
|
||||||
|
, userScriptProperty user ["git", "init", "--bare", "--shared=false", repo]
|
||||||
|
]
|
||||||
|
SharedAll ->
|
||||||
|
[ ownerGroup repo user user
|
||||||
|
, userScriptProperty user ["git", "init", "--bare", "--shared=all", repo]
|
||||||
|
]
|
||||||
|
Shared group' ->
|
||||||
|
[ ownerGroup repo user group'
|
||||||
|
, userScriptProperty user ["git", "init", "--bare", "--shared=group", repo]
|
||||||
|
]
|
||||||
|
where
|
||||||
|
isRepo repo' = isNothing <$> catchMaybeIO (readProcess "git" ["rev-parse", "--resolve-git-dir", repo'])
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
module Propellor.Property.Group where
|
||||||
|
|
||||||
|
import Propellor
|
||||||
|
|
||||||
|
type GID = Int
|
||||||
|
|
||||||
|
exists :: GroupName -> Maybe GID -> Property
|
||||||
|
exists group' mgid = check test (cmdProperty "addgroup" $ args mgid)
|
||||||
|
`describe` unwords ["group", group']
|
||||||
|
where
|
||||||
|
groupFile = "/etc/group"
|
||||||
|
test = not <$> elem group' <$> words <$> readProcess "cut" ["-d:", "-f1", groupFile]
|
||||||
|
args Nothing = [group']
|
||||||
|
args (Just gid) = ["--gid", show gid, group']
|
|
@ -30,7 +30,7 @@ hasSomePassword user context = check ((/= HasPassword) <$> getPasswordStatus use
|
||||||
|
|
||||||
hasPassword :: UserName -> Context -> Property
|
hasPassword :: UserName -> Context -> Property
|
||||||
hasPassword user context = withPrivData (Password user) context $ \getpassword ->
|
hasPassword user context = withPrivData (Password user) context $ \getpassword ->
|
||||||
property (user ++ " has password") $
|
property (user ++ " has password") $
|
||||||
getpassword $ \password -> makeChange $
|
getpassword $ \password -> makeChange $
|
||||||
withHandle StdinHandle createProcessSuccess
|
withHandle StdinHandle createProcessSuccess
|
||||||
(proc "chpasswd" []) $ \h -> do
|
(proc "chpasswd" []) $ \h -> do
|
||||||
|
@ -60,3 +60,12 @@ isLockedPassword user = (== LockedPassword) <$> getPasswordStatus user
|
||||||
|
|
||||||
homedir :: UserName -> IO FilePath
|
homedir :: UserName -> IO FilePath
|
||||||
homedir user = homeDirectory <$> getUserEntryForName user
|
homedir user = homeDirectory <$> getUserEntryForName user
|
||||||
|
|
||||||
|
hasGroup :: UserName -> GroupName -> Property
|
||||||
|
hasGroup user group' = check test $ cmdProperty "adduser"
|
||||||
|
[ user
|
||||||
|
, group'
|
||||||
|
]
|
||||||
|
`describe` unwords ["user", user, "in group", group']
|
||||||
|
where
|
||||||
|
test = not . elem group' . words <$> readProcess "groups" [user]
|
||||||
|
|
|
@ -11,14 +11,18 @@ import Utility.LinuxMkLibs
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
import Utility.Path
|
import Utility.Path
|
||||||
import Utility.FileMode
|
import Utility.FileMode
|
||||||
|
import Utility.FileSystemEncoding
|
||||||
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import System.Posix.Files
|
import System.Posix.Files
|
||||||
|
|
||||||
-- | Sets up a shimmed version of the program, in a directory, and
|
-- | Sets up a shimmed version of the program, in a directory, and
|
||||||
-- returns its path.
|
-- returns its path.
|
||||||
setup :: FilePath -> FilePath -> IO FilePath
|
--
|
||||||
setup propellorbin dest = do
|
-- Propellor may be running from an existing shim, in which case it's
|
||||||
|
-- simply reused.
|
||||||
|
setup :: FilePath -> Maybe FilePath -> FilePath -> IO FilePath
|
||||||
|
setup propellorbin propellorbinpath dest = checkAlreadyShimmed propellorbin $ do
|
||||||
createDirectoryIfMissing True dest
|
createDirectoryIfMissing True dest
|
||||||
|
|
||||||
libs <- parseLdd <$> readProcess "ldd" [propellorbin]
|
libs <- parseLdd <$> readProcess "ldd" [propellorbin]
|
||||||
|
@ -36,15 +40,26 @@ setup propellorbin dest = do
|
||||||
let linkerparams = ["--library-path", intercalate ":" libdirs ]
|
let linkerparams = ["--library-path", intercalate ":" libdirs ]
|
||||||
let shim = file propellorbin dest
|
let shim = file propellorbin dest
|
||||||
writeFile shim $ unlines
|
writeFile shim $ unlines
|
||||||
[ "#!/bin/sh"
|
[ shebang
|
||||||
, "GCONV_PATH=" ++ shellEscape gconvdir
|
, "GCONV_PATH=" ++ shellEscape gconvdir
|
||||||
, "export GCONV_PATH"
|
, "export GCONV_PATH"
|
||||||
, "exec " ++ unwords (map shellEscape $ linker : linkerparams) ++
|
, "exec " ++ unwords (map shellEscape $ linker : linkerparams) ++
|
||||||
" " ++ shellEscape propellorbin ++ " \"$@\""
|
" " ++ shellEscape (fromMaybe propellorbin propellorbinpath) ++ " \"$@\""
|
||||||
]
|
]
|
||||||
modifyFileMode shim (addModes executeModes)
|
modifyFileMode shim (addModes executeModes)
|
||||||
return shim
|
return shim
|
||||||
|
|
||||||
|
shebang :: String
|
||||||
|
shebang = "#!/bin/sh"
|
||||||
|
|
||||||
|
checkAlreadyShimmed :: FilePath -> IO FilePath -> IO FilePath
|
||||||
|
checkAlreadyShimmed f nope = withFile f ReadMode $ \h -> do
|
||||||
|
fileEncoding h
|
||||||
|
s <- hGetLine h
|
||||||
|
if s == shebang
|
||||||
|
then return f
|
||||||
|
else nope
|
||||||
|
|
||||||
-- Called when the shimmed propellor is running, so that commands it runs
|
-- Called when the shimmed propellor is running, so that commands it runs
|
||||||
-- don't see it.
|
-- don't see it.
|
||||||
cleanEnv :: IO ()
|
cleanEnv :: IO ()
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
-- When propellor --spin is running, the local host acts as a server,
|
module Propellor.Spin (
|
||||||
-- which connects to the remote host's propellor and responds to its
|
spin,
|
||||||
-- requests.
|
|
||||||
|
|
||||||
module Propellor.Server (
|
|
||||||
update,
|
update,
|
||||||
updateServer,
|
|
||||||
gitPushHelper
|
gitPushHelper
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
@ -22,21 +18,83 @@ import Propellor.Protocol
|
||||||
import Propellor.PrivData.Paths
|
import Propellor.PrivData.Paths
|
||||||
import Propellor.Git
|
import Propellor.Git
|
||||||
import Propellor.Ssh
|
import Propellor.Ssh
|
||||||
|
import Propellor.Gpg
|
||||||
import qualified Propellor.Shim as Shim
|
import qualified Propellor.Shim as Shim
|
||||||
import Utility.FileMode
|
import Utility.FileMode
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
|
|
||||||
|
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
|
||||||
|
when viarelay $
|
||||||
|
void $ boolSystem "ssh-add" []
|
||||||
|
|
||||||
|
-- Install, or update the remote propellor.
|
||||||
|
updateServer target relay hst
|
||||||
|
(proc "ssh" $ cacheparams ++ [user, shellWrap probecmd])
|
||||||
|
(proc "ssh" $ cacheparams ++ [user, shellWrap updatecmd])
|
||||||
|
|
||||||
|
-- And now we can run it.
|
||||||
|
unlessM (boolSystem "ssh" (map Param $ cacheparams ++ ["-t", user, shellWrap runcmd])) $
|
||||||
|
error $ "remote propellor failed"
|
||||||
|
where
|
||||||
|
hn = fromMaybe target relay
|
||||||
|
user = "root@"++hn
|
||||||
|
|
||||||
|
relaying = relay == Just target
|
||||||
|
viarelay = isJust relay && not relaying
|
||||||
|
|
||||||
|
probecmd = intercalate " ; "
|
||||||
|
[ "if [ ! -d " ++ localdir ++ "/.git ]"
|
||||||
|
, "then (" ++ intercalate " && "
|
||||||
|
[ "if ! git --version || ! make --version; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git make; fi"
|
||||||
|
, "echo " ++ toMarked statusMarker (show NeedGitClone)
|
||||||
|
] ++ ") || echo " ++ toMarked statusMarker (show NeedPrecompiled)
|
||||||
|
, "else " ++ updatecmd
|
||||||
|
, "fi"
|
||||||
|
]
|
||||||
|
|
||||||
|
updatecmd = intercalate " && "
|
||||||
|
[ "cd " ++ localdir
|
||||||
|
, "if ! test -x ./propellor; then make deps build; fi"
|
||||||
|
, if viarelay
|
||||||
|
then "./propellor --continue " ++
|
||||||
|
shellEscape (show (Update (Just target)))
|
||||||
|
-- Still using --boot for back-compat...
|
||||||
|
else "./propellor --boot " ++ target
|
||||||
|
]
|
||||||
|
|
||||||
|
runcmd = "cd " ++ localdir ++ " && ./propellor " ++ cmd
|
||||||
|
cmd = if viarelay
|
||||||
|
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
|
-- Update the privdata, repo url, and git repo over the ssh
|
||||||
-- connection, talking to the user's local propellor instance which is
|
-- connection, talking to the user's local propellor instance which is
|
||||||
-- running the updateServer
|
-- running the updateServer
|
||||||
update :: IO ()
|
update :: Maybe HostName -> IO ()
|
||||||
update = do
|
update forhost = do
|
||||||
whenM hasOrigin $
|
whenM hasGitRepo $
|
||||||
req NeedRepoUrl repoUrlMarker setRepoUrl
|
req NeedRepoUrl repoUrlMarker setRepoUrl
|
||||||
|
|
||||||
makePrivDataDir
|
makePrivDataDir
|
||||||
|
createDirectoryIfMissing True (takeDirectory privfile)
|
||||||
req NeedPrivData privDataMarker $
|
req NeedPrivData privDataMarker $
|
||||||
writeFileProtected privDataLocal
|
writeFileProtected privfile
|
||||||
whenM hasOrigin $
|
|
||||||
|
whenM hasGitRepo $
|
||||||
req NeedGitPush gitPushMarker $ \_ -> do
|
req NeedGitPush gitPushMarker $ \_ -> do
|
||||||
hin <- dup stdInput
|
hin <- dup stdInput
|
||||||
hout <- dup stdOutput
|
hout <- dup stdOutput
|
||||||
|
@ -52,48 +110,70 @@ update = do
|
||||||
, Param $ "./propellor --gitpush " ++ show hin ++ " " ++ show hout
|
, Param $ "./propellor --gitpush " ++ show hin ++ " " ++ show hout
|
||||||
, Param "."
|
, Param "."
|
||||||
]
|
]
|
||||||
|
|
||||||
|
-- When --spin --relay is run, get a privdata file
|
||||||
|
-- to be relayed to the target host.
|
||||||
|
privfile = maybe privDataLocal privDataRelay forhost
|
||||||
|
|
||||||
-- The connect action should ssh to the remote host and run the provided
|
updateServer
|
||||||
-- calback action.
|
:: HostName
|
||||||
updateServer :: HostName -> Host -> (((Handle, Handle) -> IO ()) -> IO ()) -> IO ()
|
-> Maybe HostName
|
||||||
updateServer hn hst connect = connect go
|
-> Host
|
||||||
|
-> CreateProcess
|
||||||
|
-> CreateProcess
|
||||||
|
-> IO ()
|
||||||
|
updateServer target relay hst connect haveprecompiled =
|
||||||
|
withBothHandles createProcessSuccess connect go
|
||||||
where
|
where
|
||||||
|
hn = fromMaybe target relay
|
||||||
|
relaying = relay == Just target
|
||||||
|
|
||||||
go (toh, fromh) = do
|
go (toh, fromh) = do
|
||||||
let loop = go (toh, fromh)
|
let loop = go (toh, fromh)
|
||||||
|
let restart = updateServer hn relay hst connect haveprecompiled
|
||||||
|
let done = return ()
|
||||||
v <- (maybe Nothing readish <$> getMarked fromh statusMarker)
|
v <- (maybe Nothing readish <$> getMarked fromh statusMarker)
|
||||||
case v of
|
case v of
|
||||||
(Just NeedRepoUrl) -> do
|
(Just NeedRepoUrl) -> do
|
||||||
sendRepoUrl toh
|
sendRepoUrl toh
|
||||||
loop
|
loop
|
||||||
(Just NeedPrivData) -> do
|
(Just NeedPrivData) -> do
|
||||||
sendPrivData hn hst toh
|
sendPrivData hn hst toh relaying
|
||||||
loop
|
loop
|
||||||
(Just NeedGitPush) -> do
|
|
||||||
sendGitUpdate hn fromh toh
|
|
||||||
-- no more protocol possible after git push
|
|
||||||
hClose fromh
|
|
||||||
hClose toh
|
|
||||||
(Just NeedGitClone) -> do
|
(Just NeedGitClone) -> do
|
||||||
hClose toh
|
hClose toh
|
||||||
hClose fromh
|
hClose fromh
|
||||||
sendGitClone hn
|
sendGitClone hn
|
||||||
updateServer hn hst connect
|
restart
|
||||||
(Just NeedPrecompiled) -> do
|
(Just NeedPrecompiled) -> do
|
||||||
hClose toh
|
hClose toh
|
||||||
hClose fromh
|
hClose fromh
|
||||||
sendPrecompiled hn
|
sendPrecompiled hn
|
||||||
updateServer hn hst connect
|
updateServer hn relay hst haveprecompiled (error "loop")
|
||||||
Nothing -> return ()
|
(Just NeedGitPush) -> do
|
||||||
|
sendGitUpdate hn fromh toh
|
||||||
|
hClose fromh
|
||||||
|
hClose toh
|
||||||
|
done
|
||||||
|
Nothing -> done
|
||||||
|
|
||||||
sendRepoUrl :: Handle -> IO ()
|
sendRepoUrl :: Handle -> IO ()
|
||||||
sendRepoUrl toh = sendMarked toh repoUrlMarker =<< (fromMaybe "" <$> getRepoUrl)
|
sendRepoUrl toh = sendMarked toh repoUrlMarker =<< (fromMaybe "" <$> getRepoUrl)
|
||||||
|
|
||||||
sendPrivData :: HostName -> Host -> Handle -> IO ()
|
sendPrivData :: HostName -> Host -> Handle -> Bool -> IO ()
|
||||||
sendPrivData hn hst toh = do
|
sendPrivData hn hst toh relaying = do
|
||||||
privdata <- show . filterPrivData hst <$> decryptPrivData
|
privdata <- getdata
|
||||||
void $ actionMessage ("Sending privdata (" ++ show (length privdata) ++ " bytes) to " ++ hn) $ do
|
void $ actionMessage ("Sending privdata (" ++ show (length privdata) ++ " bytes) to " ++ hn) $ do
|
||||||
sendMarked toh privDataMarker privdata
|
sendMarked toh privDataMarker privdata
|
||||||
return True
|
return True
|
||||||
|
where
|
||||||
|
getdata
|
||||||
|
| relaying = do
|
||||||
|
let f = privDataRelay hn
|
||||||
|
d <- readFileStrictAnyEncoding f
|
||||||
|
nukeFile f
|
||||||
|
return d
|
||||||
|
| otherwise = show . filterPrivData hst <$> decryptPrivData
|
||||||
|
|
||||||
sendGitUpdate :: HostName -> Handle -> Handle -> IO ()
|
sendGitUpdate :: HostName -> Handle -> Handle -> IO ()
|
||||||
sendGitUpdate hn fromh toh =
|
sendGitUpdate hn fromh toh =
|
||||||
|
@ -141,9 +221,12 @@ sendPrecompiled hn = void $ actionMessage ("Uploading locally compiled propellor
|
||||||
createDirectoryIfMissing True (tmpdir </> shimdir)
|
createDirectoryIfMissing True (tmpdir </> shimdir)
|
||||||
changeWorkingDirectory (tmpdir </> shimdir)
|
changeWorkingDirectory (tmpdir </> shimdir)
|
||||||
me <- readSymbolicLink "/proc/self/exe"
|
me <- readSymbolicLink "/proc/self/exe"
|
||||||
shim <- Shim.setup me "."
|
createDirectoryIfMissing True "bin"
|
||||||
when (shim /= "propellor") $
|
unlessM (boolSystem "cp" [File me, File "bin/propellor"]) $
|
||||||
renameFile shim "propellor"
|
errorMessage "failed copying in propellor"
|
||||||
|
let bin = "bin/propellor"
|
||||||
|
let binpath = Just $ localdir </> bin
|
||||||
|
void $ Shim.setup bin binpath "."
|
||||||
changeWorkingDirectory tmpdir
|
changeWorkingDirectory tmpdir
|
||||||
withTmpFile "propellor.tar." $ \tarball _ -> allM id
|
withTmpFile "propellor.tar." $ \tarball _ -> allM id
|
||||||
[ boolSystem "strip" [File me]
|
[ boolSystem "strip" [File me]
|
|
@ -20,8 +20,9 @@ sshCachingParams hn = do
|
||||||
let cachedir = home </> ".ssh" </> "propellor"
|
let cachedir = home </> ".ssh" </> "propellor"
|
||||||
createDirectoryIfMissing False cachedir
|
createDirectoryIfMissing False cachedir
|
||||||
let socketfile = cachedir </> hn ++ ".sock"
|
let socketfile = cachedir </> hn ++ ".sock"
|
||||||
let ps =
|
let ps =
|
||||||
[ Param "-o", Param ("ControlPath=" ++ socketfile)
|
[ Param "-o"
|
||||||
|
, Param ("ControlPath=" ++ socketfile)
|
||||||
, Params "-o ControlMaster=auto -o ControlPersist=yes"
|
, Params "-o ControlMaster=auto -o ControlPersist=yes"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -142,15 +142,16 @@ instance ActionResult Result where
|
||||||
|
|
||||||
data CmdLine
|
data CmdLine
|
||||||
= Run HostName
|
= Run HostName
|
||||||
| Spin HostName
|
| Spin HostName (Maybe HostName)
|
||||||
| SimpleRun HostName
|
| SimpleRun HostName
|
||||||
| Set PrivDataField Context
|
| Set PrivDataField Context
|
||||||
| Dump PrivDataField Context
|
| Dump PrivDataField Context
|
||||||
| Edit PrivDataField Context
|
| Edit PrivDataField Context
|
||||||
| ListFields
|
| ListFields
|
||||||
| AddKey String
|
| AddKey String
|
||||||
|
| Serialized CmdLine
|
||||||
| Continue CmdLine
|
| Continue CmdLine
|
||||||
| Update HostName
|
| Update (Maybe HostName)
|
||||||
| DockerInit HostName
|
| DockerInit HostName
|
||||||
| DockerChain HostName String
|
| DockerChain HostName String
|
||||||
| ChrootChain HostName FilePath Bool Bool
|
| ChrootChain HostName FilePath Bool Bool
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
module Propellor.Types.OS where
|
module Propellor.Types.OS (
|
||||||
|
HostName,
|
||||||
|
UserName,
|
||||||
|
GroupName,
|
||||||
|
System(..),
|
||||||
|
Distribution(..),
|
||||||
|
DebianSuite(..),
|
||||||
|
isStable,
|
||||||
|
Release,
|
||||||
|
Architecture,
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Network.BSD (HostName)
|
||||||
|
|
||||||
type HostName = String
|
|
||||||
type UserName = String
|
type UserName = String
|
||||||
type GroupName = String
|
type GroupName = String
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue