sim visit as first-class command

Allows using it in a sim file.
This commit is contained in:
Joey Hess 2024-09-23 13:09:35 -04:00
parent 6cf9a101b8
commit 7bc8c2bfeb
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 48 additions and 34 deletions

View file

@ -35,6 +35,7 @@ import Logs.MaxSize
import Logs.Difference
import Logs.UUID
import Logs.Location
import Utility.Env
import qualified Annex
import qualified Remote
import qualified Git.Construct
@ -222,6 +223,7 @@ data SimCommand
| CommandGroupWanted Group PreferredContentExpression
| CommandMaxSize RepoName MaxSize
| CommandRebalance Bool
| CommandVisit RepoName [String]
| CommandComment String
| CommandBlank
deriving (Show, Read)
@ -278,6 +280,32 @@ applySimCommand (CommandNotPresent repo file) st _ = checkKnownRepo repo st $ \u
present = Left $ "Expected " ++ fromRawFilePath file
++ " not to be present in "
++ fromRepoName repo ++ ", but it is present."
applySimCommand c@(CommandVisit repo cmdparams) st _ =
checkKnownRepo repo st $ \u -> Right $ Left $ do
st' <- liftIO $ updateSimRepos st
let dir = simRepoDirectory st' u
unlessM (liftIO $ doesDirectoryExist dir) $
giveup "Simulated repository unavailable."
(cmd, params) <- case cmdparams of
(cmd:params) -> return (cmd, params)
[] -> do
showLongNote "Starting a shell in the simulated repository."
shellcmd <- liftIO $ fromMaybe "sh" <$> getEnv "SHELL"
return (shellcmd, [])
exitcode <- liftIO $
safeSystem' cmd (map Param params)
(\p -> p { cwd = Just dir })
when (null cmdparams) $
showLongNote "Finished visit to simulated repository."
if null cmdparams
then return st'
else if exitcode == ExitSuccess
then return $ addHistory st' c
else do
showLongNote $ UnquotedString $
"Command " ++ unwords cmdparams ++
" exited nonzero."
liftIO $ exitWith exitcode
applySimCommand cmd st repobyname =
let st' = flip addHistory cmd $ st
{ simVectorClock =
@ -455,6 +483,7 @@ applySimCommand' (CommandRebalance b) st _ =
}
applySimCommand' (CommandComment _) st _ = Right $ Right st
applySimCommand' CommandBlank st _ = Right $ Right st
applySimCommand' (CommandVisit _ _) _ _ = error "applySimCommand' CommandVisit"
applySimCommand' (CommandPresent _ _) _ _ = error "applySimCommand' CommandPresent"
applySimCommand' (CommandNotPresent _ _) _ _ = error "applySimCommand' CommandNotPresent"
@ -716,7 +745,8 @@ checkKnownRepo :: RepoName -> SimState SimRepo -> (UUID -> Either String a) -> E
checkKnownRepo reponame st a = case M.lookup reponame (simRepos st) of
Just u -> a u
Nothing -> Left $ "No repository in the simulation is named \""
++ fromRepoName reponame ++ "\"."
++ fromRepoName reponame ++ "\". Choose from: "
++ unwords (map fromRepoName $ M.keys (simRepos st))
checkKnownRemote :: RemoteName -> RepoName -> UUID -> SimState SimRepo -> (UUID -> Either String a) -> Either String a
checkKnownRemote remotename reponame u st a =

View file

@ -80,6 +80,8 @@ generateSimFile = unlines . map unwords . go
["maxsize", repo, showsize (fromMaxSize maxsize)] : go rest
go (CommandRebalance b : rest) =
["rebalance", if b then "on" else "off"] : go rest
go (CommandVisit (RepoName repo) cmdparams : rest) =
(["visit", repo] ++ cmdparams) : go rest
go (CommandComment s : rest) =
[s] : go rest
go (CommandBlank : rest) =
@ -184,6 +186,8 @@ parseSimCommand ("maxsize":repo:size:[]) =
parseSimCommand ("rebalance":onoff:[]) = case isTrueFalse onoff of
Just b -> Right $ CommandRebalance b
Nothing -> Left $ "Unable to parse rebalance value \"" ++ onoff ++ "\""
parseSimCommand ("visit":repo:cmdparams) =
Right $ CommandVisit (RepoName repo) cmdparams
parseSimCommand ws = parseError ws
parseSimAction :: [String] -> Either String SimAction

View file

@ -13,10 +13,8 @@ import Command
import Annex.Sim
import Annex.Sim.File
import Annex.Perms
import Utility.Env
import System.Random
import qualified Data.Map as M
cmd :: Command
cmd = command "sim" SectionTesting
@ -31,27 +29,6 @@ seek ("end":[]) = do
whenM (liftIO $ doesDirectoryExist simdir) $ do
liftIO $ removeDirectoryRecursive simdir
showLongNote $ UnquotedString "Sim ended."
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 ("show":[]) = do
simdir <- fromRepo gitAnnexSimDir
liftIO (restoreSim simdir) >>= \case

View file

@ -8,8 +8,6 @@ git annex sim start [my.sim]
git annex sim command
git annex sim visit repo
git annex sim show
git annex sim end
@ -32,14 +30,6 @@ simulation, and the results of the simulation. Use "git-annex sim show"
to display the log. This allows re-running the same simulation later,
as well as analyzing the results of the simulation.
While a simulation is running, the command "git annex sim visit repo", where
"repo" is the name of one of the repositories in the simulation, will spawn
a subshell in a git repository whose git-annex branch contains the state of
that simulated repository. This allows running any git-annex command, such
as `git-annex whereis` to examine the state of the simulation.
You should avoid making any changes to git-annex state.
Exit the subshell to end the visit.
Use "git annex sim end" to finish the simulation, and clean up.
# THE SIM FILE
@ -109,6 +99,19 @@ as passed to "git annex sim" while a simulation is running.
The repository to use can be specified by remote name, uuid, etc.
Example: "use myrepo here"
* `visit repo [command]`
Runs the specified shell command inside the simulated repository,
and waits for it to exit.
When no shell command is specified, it runs an interactive shell.
The command is run in a git repository whosegit-annex branch contains
the state of that simulated repository. This allows running any
git-annex commands, such as `git-annex whereis` to examine the
state of the simulation. You should avoid making any changes to
git-annex state.
* `connect repo [<-|->|<->] repo [...]`
Add a connection between two or more repositories. The arrow indicates