2012-06-22 17:04:03 +00:00
|
|
|
{- git-annex assistant
|
|
|
|
-
|
2017-02-07 17:31:45 +00:00
|
|
|
- Copyright 2012-2017 Joey Hess <id@joeyh.name>
|
2012-06-22 17:04:03 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2012-06-22 17:04:03 +00:00
|
|
|
-}
|
|
|
|
|
|
|
|
module Command.Assistant where
|
|
|
|
|
|
|
|
import Command
|
|
|
|
import qualified Command.Watch
|
2014-01-26 20:36:31 +00:00
|
|
|
import Annex.Init
|
2015-02-28 21:23:13 +00:00
|
|
|
import Annex.Path
|
2013-04-23 15:38:52 +00:00
|
|
|
import Config.Files
|
2017-12-14 16:46:57 +00:00
|
|
|
import qualified BuildInfo
|
2013-10-26 16:42:58 +00:00
|
|
|
import Utility.HumanTime
|
2014-06-30 21:13:08 +00:00
|
|
|
import Assistant.Install
|
2012-08-02 04:42:33 +00:00
|
|
|
|
2017-02-07 17:31:45 +00:00
|
|
|
import Control.Concurrent.Async
|
|
|
|
|
2015-07-08 16:33:27 +00:00
|
|
|
cmd :: Command
|
2015-07-13 15:42:42 +00:00
|
|
|
cmd = dontCheck repoExists $ notBareRepo $
|
|
|
|
noRepo (startNoRepo <$$> optParser) $
|
2015-07-08 19:39:05 +00:00
|
|
|
command "assistant" SectionCommon
|
|
|
|
"automatically sync changes"
|
2015-07-13 15:42:42 +00:00
|
|
|
paramNothing (seek <$$> optParser)
|
2012-08-02 04:42:33 +00:00
|
|
|
|
2015-07-13 15:42:42 +00:00
|
|
|
data AssistantOptions = AssistantOptions
|
|
|
|
{ daemonOptions :: DaemonOptions
|
|
|
|
, autoStartOption :: Bool
|
|
|
|
, startDelayOption :: Maybe Duration
|
|
|
|
, autoStopOption :: Bool
|
|
|
|
}
|
2015-05-01 17:53:45 +00:00
|
|
|
|
2015-07-13 15:42:42 +00:00
|
|
|
optParser :: CmdParamsDesc -> Parser AssistantOptions
|
|
|
|
optParser _ = AssistantOptions
|
2019-09-30 18:40:46 +00:00
|
|
|
<$> parseDaemonOptions True
|
2015-07-13 15:42:42 +00:00
|
|
|
<*> switch
|
|
|
|
( long "autostart"
|
|
|
|
<> help "start in known repositories"
|
|
|
|
)
|
2020-08-15 19:53:35 +00:00
|
|
|
<*> optional (option (eitherReader parseDuration)
|
2015-07-13 15:42:42 +00:00
|
|
|
( long "startdelay" <> metavar paramNumber
|
|
|
|
<> help "delay before running startup scan"
|
|
|
|
))
|
|
|
|
<*> switch
|
|
|
|
( long "autostop"
|
|
|
|
<> help "stop in known repositories"
|
|
|
|
)
|
2013-10-26 16:42:58 +00:00
|
|
|
|
2015-07-13 15:42:42 +00:00
|
|
|
seek :: AssistantOptions -> CommandSeek
|
|
|
|
seek = commandAction . start
|
2012-08-02 04:42:33 +00:00
|
|
|
|
2015-07-13 15:42:42 +00:00
|
|
|
start :: AssistantOptions -> CommandStart
|
|
|
|
start o
|
|
|
|
| autoStartOption o = do
|
|
|
|
liftIO $ autoStart o
|
2012-08-02 04:42:33 +00:00
|
|
|
stop
|
2015-07-13 15:42:42 +00:00
|
|
|
| autoStopOption o = do
|
2015-05-01 17:53:45 +00:00
|
|
|
liftIO autoStop
|
|
|
|
stop
|
2012-08-02 04:42:33 +00:00
|
|
|
| otherwise = do
|
2014-06-30 21:13:08 +00:00
|
|
|
liftIO ensureInstalled
|
2012-08-02 04:42:33 +00:00
|
|
|
ensureInitialized
|
2015-07-13 15:42:42 +00:00
|
|
|
Command.Watch.start True (daemonOptions o) (startDelayOption o)
|
2012-08-02 04:42:33 +00:00
|
|
|
|
2015-07-13 15:42:42 +00:00
|
|
|
startNoRepo :: AssistantOptions -> IO ()
|
|
|
|
startNoRepo o
|
|
|
|
| autoStartOption o = autoStart o
|
|
|
|
| autoStopOption o = autoStop
|
2016-11-16 01:29:54 +00:00
|
|
|
| otherwise = giveup "Not in a git repository."
|
2012-08-02 04:42:33 +00:00
|
|
|
|
2017-02-07 17:31:45 +00:00
|
|
|
-- Does not return
|
2015-07-13 15:42:42 +00:00
|
|
|
autoStart :: AssistantOptions -> IO ()
|
|
|
|
autoStart o = do
|
2013-03-03 21:07:27 +00:00
|
|
|
dirs <- liftIO readAutoStartFile
|
|
|
|
when (null dirs) $ do
|
|
|
|
f <- autoStartFile
|
2016-11-16 01:29:54 +00:00
|
|
|
giveup $ "Nothing listed in " ++ f
|
2015-02-28 21:23:13 +00:00
|
|
|
program <- programPath
|
2017-12-14 16:46:57 +00:00
|
|
|
haveionice <- pure BuildInfo.ionice <&&> inPath "ionice"
|
2017-02-07 17:31:45 +00:00
|
|
|
pids <- forM dirs $ \d -> do
|
2013-03-03 21:07:27 +00:00
|
|
|
putStrLn $ "git-annex autostart in " ++ d
|
2017-02-07 17:31:45 +00:00
|
|
|
mpid <- catchMaybeIO $ go haveionice program d
|
|
|
|
if foregroundDaemonOption (daemonOptions o)
|
|
|
|
then return mpid
|
|
|
|
else do
|
|
|
|
case mpid of
|
|
|
|
Nothing -> putStrLn "failed"
|
|
|
|
Just pid -> ifM (checkSuccessProcess pid)
|
|
|
|
( putStrLn "ok"
|
|
|
|
, putStrLn "failed"
|
|
|
|
)
|
|
|
|
return Nothing
|
|
|
|
-- Wait for any foreground jobs to finish and propigate exit status.
|
|
|
|
ifM (all (== True) <$> mapConcurrently checkSuccessProcess (catMaybes pids))
|
|
|
|
( exitSuccess
|
|
|
|
, exitFailure
|
|
|
|
)
|
2012-11-12 05:05:04 +00:00
|
|
|
where
|
2013-06-21 17:23:20 +00:00
|
|
|
go haveionice program dir = do
|
2013-05-11 23:14:30 +00:00
|
|
|
setCurrentDirectory dir
|
2015-07-02 18:16:53 +00:00
|
|
|
-- First stop any old daemon running in this directory, which
|
|
|
|
-- might be a leftover from an old login session. Such a
|
|
|
|
-- leftover might be left in an environment where it is
|
2017-02-07 17:31:45 +00:00
|
|
|
-- unable to use the ssh agent or other login session
|
2015-07-02 18:16:53 +00:00
|
|
|
-- resources.
|
|
|
|
void $ boolSystem program [Param "assistant", Param "--stop"]
|
2017-02-07 17:31:45 +00:00
|
|
|
(Nothing, Nothing, Nothing, pid) <- createProcess p
|
|
|
|
return pid
|
2013-10-26 16:42:58 +00:00
|
|
|
where
|
2017-02-07 17:31:45 +00:00
|
|
|
p
|
|
|
|
| haveionice = proc "ionice"
|
|
|
|
(toCommand $ Param "-c3" : Param program : baseparams)
|
|
|
|
| otherwise = proc program
|
|
|
|
(toCommand baseparams)
|
|
|
|
baseparams = catMaybes
|
|
|
|
[ Just $ Param "assistant"
|
|
|
|
, Just $ Param $ "--startdelay=" ++ fromDuration (fromMaybe (Duration 5) (startDelayOption o))
|
|
|
|
, if foregroundDaemonOption (daemonOptions o)
|
|
|
|
then Just $ Param "--foreground"
|
|
|
|
else Nothing
|
2013-10-26 16:42:58 +00:00
|
|
|
]
|
2015-05-01 17:53:45 +00:00
|
|
|
|
|
|
|
autoStop :: IO ()
|
|
|
|
autoStop = do
|
|
|
|
dirs <- liftIO readAutoStartFile
|
|
|
|
program <- programPath
|
|
|
|
forM_ dirs $ \d -> do
|
|
|
|
putStrLn $ "git-annex autostop in " ++ d
|
|
|
|
setCurrentDirectory d
|
|
|
|
ifM (boolSystem program [Param "assistant", Param "--stop"])
|
|
|
|
( putStrLn "ok"
|
|
|
|
, putStrLn "failed"
|
|
|
|
)
|