2024-09-04 19:10:39 +00:00
|
|
|
{- git-annex command
|
|
|
|
-
|
|
|
|
- Copyright 2024 Joey Hess <id@joeyh.name>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
2024-09-11 14:32:04 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
2024-09-04 19:10:39 +00:00
|
|
|
module Command.Sim where
|
|
|
|
|
|
|
|
import Command
|
|
|
|
import Annex.Sim
|
2024-09-11 15:53:25 +00:00
|
|
|
import Annex.Sim.File
|
2024-09-12 20:07:44 +00:00
|
|
|
import Annex.Perms
|
|
|
|
import Utility.Env
|
2024-09-09 14:59:01 +00:00
|
|
|
|
|
|
|
import System.Random
|
2024-09-12 20:07:44 +00:00
|
|
|
import qualified Data.Map as M
|
2024-09-04 19:10:39 +00:00
|
|
|
|
|
|
|
cmd :: Command
|
|
|
|
cmd = command "sim" SectionTesting
|
|
|
|
"simulate a network of repositories"
|
|
|
|
paramCommand (withParams seek)
|
|
|
|
|
|
|
|
seek :: CmdParams -> CommandSeek
|
2024-09-12 20:07:44 +00:00
|
|
|
seek ("start":[]) = start Nothing
|
|
|
|
seek ("start":simfile:[]) = start (Just simfile)
|
|
|
|
seek ("end":[]) = do
|
2024-09-12 20:39:44 +00:00
|
|
|
simdir <- fromRawFilePath <$> fromRepo gitAnnexSimDir
|
|
|
|
whenM (liftIO $ doesDirectoryExist simdir) $ do
|
|
|
|
liftIO $ removeDirectoryRecursive simdir
|
2024-09-12 20:07:44 +00:00
|
|
|
seek ("visit":reponame:[]) = do
|
|
|
|
simdir <- fromRepo gitAnnexSimDir
|
|
|
|
liftIO (restoreSim simdir) >>= \case
|
|
|
|
Left err -> giveup err
|
|
|
|
Right st -> case M.lookup (RepoName reponame) (simRepos st) of
|
|
|
|
Just u -> do
|
|
|
|
let dir = simRepoDirectory st u
|
|
|
|
unlessM (liftIO $ doesDirectoryExist dir) $
|
|
|
|
giveup "Simulated repository unavailable."
|
|
|
|
showLongNote "Starting a shell in the simulated repository."
|
|
|
|
shellcmd <- liftIO $ fromMaybe "sh" <$> getEnv "SHELL"
|
|
|
|
exitcode <- liftIO $
|
|
|
|
safeSystem' shellcmd []
|
|
|
|
(\p -> p { cwd = Just dir })
|
|
|
|
showLongNote "Finished visit to simulated repository."
|
|
|
|
liftIO $ exitWith exitcode
|
|
|
|
Nothing -> giveup $ unwords
|
|
|
|
[ "There is no simulated repository with that name."
|
|
|
|
, "Choose from:"
|
|
|
|
, unwords $ map fromRepoName $ M.keys (simRepos st)
|
|
|
|
]
|
|
|
|
seek ps = case parseSimCommand ps of
|
|
|
|
Left err -> giveup err
|
|
|
|
Right simcmd -> do
|
|
|
|
repobyname <- mkGetExistingRepoByName
|
|
|
|
simdir <- fromRepo gitAnnexSimDir
|
|
|
|
liftIO (restoreSim simdir) >>= \case
|
|
|
|
Left err -> giveup err
|
|
|
|
Right st ->
|
|
|
|
runSimCommand simcmd repobyname st
|
|
|
|
>>= liftIO . saveState
|
2024-09-09 14:59:01 +00:00
|
|
|
|
2024-09-12 20:07:44 +00:00
|
|
|
start :: Maybe FilePath -> CommandSeek
|
|
|
|
start simfile = do
|
|
|
|
simdir <- fromRawFilePath <$> fromRepo gitAnnexSimDir
|
|
|
|
whenM (liftIO $ doesDirectoryExist simdir) $
|
|
|
|
giveup "A sim was previously started. Use `git-annex sim end` to stop it before starting a new one."
|
|
|
|
|
|
|
|
let simlogfile = case simfile of
|
|
|
|
Nothing -> simdir </> "log.sim"
|
|
|
|
Just f -> simdir </> takeFileName f
|
|
|
|
|
|
|
|
rng <- fst . random <$> initStdGen
|
|
|
|
let st = (emptySimState rng simdir)
|
|
|
|
{ simFile = Just simlogfile }
|
|
|
|
case simfile of
|
|
|
|
Nothing -> startup simdir st []
|
2024-09-12 20:39:44 +00:00
|
|
|
Just f -> liftIO (readFile f) >>= \c ->
|
|
|
|
case parseSimFile c of
|
|
|
|
Left err -> giveup err
|
|
|
|
Right cs -> startup simdir st cs
|
2024-09-12 20:07:44 +00:00
|
|
|
showLongNote $ UnquotedString "Sim started, logging to sim file "
|
|
|
|
<> QuotedPath (toRawFilePath simlogfile)
|
|
|
|
where
|
|
|
|
startup simdir st cs = do
|
|
|
|
repobyname <- mkGetExistingRepoByName
|
|
|
|
createAnnexDirectory (toRawFilePath simdir)
|
|
|
|
st' <- go st repobyname cs
|
|
|
|
liftIO $ saveState st'
|
|
|
|
|
|
|
|
go st _ [] = return st
|
|
|
|
go st repobyname (c:cs) = do
|
|
|
|
st' <- runSimCommand c repobyname st
|
|
|
|
go st' repobyname cs
|
|
|
|
|
|
|
|
saveState :: SimState SimRepo -> IO ()
|
|
|
|
saveState st = do
|
|
|
|
suspendSim st
|
|
|
|
case simFile st of
|
|
|
|
Just f -> writeFile f $ generateSimFile $ reverse $ simHistory st
|
|
|
|
Nothing -> noop
|