2013-11-24 20:03:03 +00:00
|
|
|
{- git-annex program path
|
|
|
|
-
|
2022-10-26 19:44:06 +00:00
|
|
|
- Copyright 2013-2022 Joey Hess <id@joeyh.name>
|
2013-11-24 20:03:03 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2013-11-24 20:03:03 +00:00
|
|
|
-}
|
|
|
|
|
2021-05-12 19:08:03 +00:00
|
|
|
module Annex.Path (
|
|
|
|
programPath,
|
|
|
|
readProgramFile,
|
|
|
|
gitAnnexChildProcess,
|
|
|
|
gitAnnexChildProcessParams,
|
|
|
|
gitAnnexDaemonizeParams,
|
2022-10-26 19:44:06 +00:00
|
|
|
cleanStandaloneEnvironment,
|
2021-05-12 19:08:03 +00:00
|
|
|
) where
|
2013-11-24 20:03:03 +00:00
|
|
|
|
2020-08-25 18:57:25 +00:00
|
|
|
import Annex.Common
|
2013-11-24 20:03:03 +00:00
|
|
|
import Config.Files
|
2015-03-27 16:55:18 +00:00
|
|
|
import Utility.Env
|
2020-08-26 16:20:56 +00:00
|
|
|
import Annex.PidLock
|
2020-12-15 14:44:36 +00:00
|
|
|
import qualified Annex
|
2015-03-27 16:55:18 +00:00
|
|
|
|
2022-10-26 19:44:06 +00:00
|
|
|
import System.Environment (getExecutablePath, getArgs, getProgName)
|
2013-11-24 20:03:03 +00:00
|
|
|
|
|
|
|
{- A fully qualified path to the currently running git-annex program.
|
|
|
|
-
|
2017-12-14 17:45:50 +00:00
|
|
|
- getExecutablePath is used when possible. On OSs it supports
|
2013-11-24 20:03:03 +00:00
|
|
|
- well, it returns the complete path to the program. But, on other OSs,
|
2015-02-28 20:59:52 +00:00
|
|
|
- it might return just the basename. Fall back to reading the programFile,
|
|
|
|
- or searching for the command name in PATH.
|
2015-03-27 16:55:18 +00:00
|
|
|
-
|
|
|
|
- The standalone build runs git-annex via ld.so, and defeats
|
2022-10-26 19:44:06 +00:00
|
|
|
- getExecutablePath. It sets GIT_ANNEX_DIR to the location of the
|
|
|
|
- standalone build directory, and there are wrapper scripts for git-annex
|
|
|
|
- and git-annex-shell in that directory.
|
2013-11-24 20:03:03 +00:00
|
|
|
-}
|
2015-02-28 20:59:52 +00:00
|
|
|
programPath :: IO FilePath
|
2022-10-26 19:44:06 +00:00
|
|
|
programPath = go =<< getEnv "GIT_ANNEX_DIR"
|
2015-03-27 16:55:18 +00:00
|
|
|
where
|
2022-10-26 19:44:06 +00:00
|
|
|
go (Just dir) = do
|
|
|
|
name <- getProgName
|
|
|
|
return (dir </> name)
|
2015-03-27 16:55:18 +00:00
|
|
|
go Nothing = do
|
|
|
|
exe <- getExecutablePath
|
|
|
|
p <- if isAbsolute exe
|
|
|
|
then return exe
|
2020-04-15 20:46:34 +00:00
|
|
|
else fromMaybe exe <$> readProgramFile
|
2015-03-27 16:55:18 +00:00
|
|
|
maybe cannotFindProgram return =<< searchPath p
|
2020-03-30 20:03:44 +00:00
|
|
|
|
|
|
|
{- Returns the path for git-annex that is recorded in the programFile. -}
|
2020-04-15 20:46:34 +00:00
|
|
|
readProgramFile :: IO (Maybe FilePath)
|
2020-03-30 20:03:44 +00:00
|
|
|
readProgramFile = do
|
|
|
|
programfile <- programFile
|
2020-04-15 20:46:34 +00:00
|
|
|
headMaybe . lines <$> readFile programfile
|
2020-03-30 20:03:44 +00:00
|
|
|
|
|
|
|
cannotFindProgram :: IO a
|
|
|
|
cannotFindProgram = do
|
|
|
|
f <- programFile
|
|
|
|
giveup $ "cannot find git-annex program in PATH or in " ++ f
|
2020-08-25 18:57:25 +00:00
|
|
|
|
|
|
|
{- Runs a git-annex child process.
|
|
|
|
-
|
|
|
|
- Like runsGitAnnexChildProcessViaGit, when pid locking is in use,
|
|
|
|
- this takes the pid lock, while running it, and sets an env var
|
|
|
|
- that prevents the child process trying to take the pid lock,
|
|
|
|
- to avoid it deadlocking.
|
|
|
|
-}
|
|
|
|
gitAnnexChildProcess
|
2020-12-15 14:44:36 +00:00
|
|
|
:: String
|
propagate git-annex -c on to transferrer child process
git -c was already propagated via environment, but need this for
consistency.
Also, notice it does not use gitAnnexChildProcess to run the
transferrer. So nothing is done about avoid it taking the
pid lock. It's possible that the caller is already doing something that
took the pid lock, and if so, the transferrer will certianly fail,
since it needs to take the pid lock too. This may prevent combining
annex.stalldetection with annex.pidlock, but I have not verified it's
really a problem. If it was, it seems git-annex would have to take
the pid lock when starting a transferrer, and hold it until shutdown,
or would need to take pid lock when starting to use a transferrer,
and hold it until done with a transfer and then drop it. The latter
would require starting the transferrer with pid locking disabled for the
child process, so assumes that the transferrer does not do anyting that
needs locking when not running a transfer.
2020-12-15 15:36:25 +00:00
|
|
|
-> [CommandParam]
|
2020-08-25 18:57:25 +00:00
|
|
|
-> (CreateProcess -> CreateProcess)
|
|
|
|
-> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
|
|
|
|
-> Annex a
|
2020-12-15 14:44:36 +00:00
|
|
|
gitAnnexChildProcess subcmd ps f a = do
|
2020-08-25 18:57:25 +00:00
|
|
|
cmd <- liftIO programPath
|
propagate git-annex -c on to transferrer child process
git -c was already propagated via environment, but need this for
consistency.
Also, notice it does not use gitAnnexChildProcess to run the
transferrer. So nothing is done about avoid it taking the
pid lock. It's possible that the caller is already doing something that
took the pid lock, and if so, the transferrer will certianly fail,
since it needs to take the pid lock too. This may prevent combining
annex.stalldetection with annex.pidlock, but I have not verified it's
really a problem. If it was, it seems git-annex would have to take
the pid lock when starting a transferrer, and hold it until shutdown,
or would need to take pid lock when starting to use a transferrer,
and hold it until done with a transfer and then drop it. The latter
would require starting the transferrer with pid locking disabled for the
child process, so assumes that the transferrer does not do anyting that
needs locking when not running a transfer.
2020-12-15 15:36:25 +00:00
|
|
|
ps' <- gitAnnexChildProcessParams subcmd ps
|
|
|
|
pidLockChildProcess cmd ps' f a
|
|
|
|
|
|
|
|
{- Parameters to pass to a git-annex child process to run a subcommand
|
|
|
|
- with some parameters.
|
|
|
|
-
|
2021-03-22 18:25:28 +00:00
|
|
|
- Includes -c values that were passed on the git-annex command line
|
2021-05-12 19:08:03 +00:00
|
|
|
- or due to options like --debug being enabled.
|
propagate git-annex -c on to transferrer child process
git -c was already propagated via environment, but need this for
consistency.
Also, notice it does not use gitAnnexChildProcess to run the
transferrer. So nothing is done about avoid it taking the
pid lock. It's possible that the caller is already doing something that
took the pid lock, and if so, the transferrer will certianly fail,
since it needs to take the pid lock too. This may prevent combining
annex.stalldetection with annex.pidlock, but I have not verified it's
really a problem. If it was, it seems git-annex would have to take
the pid lock when starting a transferrer, and hold it until shutdown,
or would need to take pid lock when starting to use a transferrer,
and hold it until done with a transfer and then drop it. The latter
would require starting the transferrer with pid locking disabled for the
child process, so assumes that the transferrer does not do anyting that
needs locking when not running a transfer.
2020-12-15 15:36:25 +00:00
|
|
|
-}
|
|
|
|
gitAnnexChildProcessParams :: String -> [CommandParam] -> Annex [CommandParam]
|
|
|
|
gitAnnexChildProcessParams subcmd ps = do
|
2021-05-12 19:08:03 +00:00
|
|
|
cps <- gitAnnexGitConfigOverrides
|
propagate git-annex -c on to transferrer child process
git -c was already propagated via environment, but need this for
consistency.
Also, notice it does not use gitAnnexChildProcess to run the
transferrer. So nothing is done about avoid it taking the
pid lock. It's possible that the caller is already doing something that
took the pid lock, and if so, the transferrer will certianly fail,
since it needs to take the pid lock too. This may prevent combining
annex.stalldetection with annex.pidlock, but I have not verified it's
really a problem. If it was, it seems git-annex would have to take
the pid lock when starting a transferrer, and hold it until shutdown,
or would need to take pid lock when starting to use a transferrer,
and hold it until done with a transfer and then drop it. The latter
would require starting the transferrer with pid locking disabled for the
child process, so assumes that the transferrer does not do anyting that
needs locking when not running a transfer.
2020-12-15 15:36:25 +00:00
|
|
|
return (Param subcmd : cps ++ ps)
|
2021-05-12 19:08:03 +00:00
|
|
|
|
|
|
|
gitAnnexGitConfigOverrides :: Annex [CommandParam]
|
|
|
|
gitAnnexGitConfigOverrides = concatMap (\c -> [Param "-c", Param c])
|
|
|
|
<$> Annex.getGitConfigOverrides
|
|
|
|
|
|
|
|
{- Parameters to pass to git-annex when re-running the current command
|
|
|
|
- to daemonize it. Used with Utility.Daemon.daemonize. -}
|
|
|
|
gitAnnexDaemonizeParams :: Annex [CommandParam]
|
|
|
|
gitAnnexDaemonizeParams = do
|
2023-03-14 02:39:16 +00:00
|
|
|
-- This includes -c parameters passed to git, as well as ones
|
2021-05-12 19:08:03 +00:00
|
|
|
-- passed to git-annex.
|
|
|
|
cps <- gitAnnexGitConfigOverrides
|
|
|
|
-- Get every parameter git-annex was run with.
|
|
|
|
ps <- liftIO getArgs
|
|
|
|
return (map Param ps ++ cps)
|
2022-10-26 19:44:06 +00:00
|
|
|
|
|
|
|
{- Returns a cleaned up environment that lacks path and other settings
|
|
|
|
- used to make the standalone builds use their bundled libraries and programs.
|
|
|
|
- Useful when calling programs not included in the standalone builds.
|
|
|
|
-
|
|
|
|
- For a non-standalone build, returns Nothing.
|
|
|
|
-}
|
|
|
|
cleanStandaloneEnvironment :: IO (Maybe [(String, String)])
|
|
|
|
cleanStandaloneEnvironment = clean <$> getEnvironment
|
|
|
|
where
|
|
|
|
clean environ
|
|
|
|
| null vars = Nothing
|
|
|
|
| otherwise = Just $ catMaybes $ map (restoreorig environ) environ
|
|
|
|
where
|
|
|
|
vars = words $ fromMaybe "" $
|
|
|
|
lookup "GIT_ANNEX_STANDLONE_ENV" environ
|
|
|
|
restoreorig oldenviron p@(k, _v)
|
|
|
|
| k `elem` vars = case lookup ("ORIG_" ++ k) oldenviron of
|
|
|
|
(Just v')
|
|
|
|
| not (null v') -> Just (k, v')
|
|
|
|
_ -> Nothing
|
|
|
|
| otherwise = Just p
|