annex.addunlocked support for git-annex compute
And for git-annex recompute, add the file unlocked when the original is unlocked.
This commit is contained in:
parent
de6e9f5beb
commit
23538ea17b
3 changed files with 58 additions and 42 deletions
|
@ -24,11 +24,13 @@ import Annex.UUID
|
||||||
import Annex.GitShaKey
|
import Annex.GitShaKey
|
||||||
import Types.KeySource
|
import Types.KeySource
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
import Annex.FileMatcher
|
||||||
import Messages.Progress
|
import Messages.Progress
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import Logs.EquivilantKeys
|
import Logs.EquivilantKeys
|
||||||
import Utility.Metered
|
import Utility.Metered
|
||||||
import Backend.URL (fromUrl)
|
import Backend.URL (fromUrl)
|
||||||
|
import Git.FilePath
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Time.Clock
|
import Data.Time.Clock
|
||||||
|
@ -73,20 +75,21 @@ seek o = startConcurrency commandStages (seek' o)
|
||||||
|
|
||||||
seek' :: AddComputedOptions -> CommandSeek
|
seek' :: AddComputedOptions -> CommandSeek
|
||||||
seek' o = do
|
seek' o = do
|
||||||
|
addunlockedmatcher <- addUnlockedMatcher
|
||||||
r <- getParsed (computeRemote o)
|
r <- getParsed (computeRemote o)
|
||||||
unless (Remote.Compute.isComputeRemote r) $
|
unless (Remote.Compute.isComputeRemote r) $
|
||||||
giveup "That is not a compute remote."
|
giveup "That is not a compute remote."
|
||||||
|
|
||||||
commandAction $ start o r
|
commandAction $ start o r addunlockedmatcher
|
||||||
|
|
||||||
start :: AddComputedOptions -> Remote -> CommandStart
|
start :: AddComputedOptions -> Remote -> AddUnlockedMatcher -> CommandStart
|
||||||
start o r = starting "addcomputed" ai si $ perform o r
|
start o r = starting "addcomputed" ai si . perform o r
|
||||||
where
|
where
|
||||||
ai = ActionItemUUID (Remote.uuid r) (UnquotedString (Remote.name r))
|
ai = ActionItemUUID (Remote.uuid r) (UnquotedString (Remote.name r))
|
||||||
si = SeekInput (computeParams o)
|
si = SeekInput (computeParams o)
|
||||||
|
|
||||||
perform :: AddComputedOptions -> Remote -> CommandPerform
|
perform :: AddComputedOptions -> Remote -> AddUnlockedMatcher -> CommandPerform
|
||||||
perform o r = do
|
perform o r addunlockedmatcher = do
|
||||||
program <- Remote.Compute.getComputeProgram r
|
program <- Remote.Compute.getComputeProgram r
|
||||||
repopath <- fromRepo Git.repoPath
|
repopath <- fromRepo Git.repoPath
|
||||||
subdir <- liftIO $ relPathDirToFile repopath (literalOsPath ".")
|
subdir <- liftIO $ relPathDirToFile repopath (literalOsPath ".")
|
||||||
|
@ -102,8 +105,11 @@ perform o r = do
|
||||||
(Remote.Compute.ImmutableState False)
|
(Remote.Compute.ImmutableState False)
|
||||||
(getInputContent fast)
|
(getInputContent fast)
|
||||||
Nothing
|
Nothing
|
||||||
(addComputed (Just "adding") r (reproducible o) chooseBackend Just fast)
|
(go fast)
|
||||||
next $ return True
|
next $ return True
|
||||||
|
where
|
||||||
|
go fast = addComputed (Just "adding") r (reproducible o)
|
||||||
|
chooseBackend Just fast (Right addunlockedmatcher)
|
||||||
|
|
||||||
addComputed
|
addComputed
|
||||||
:: Maybe StringContainingQuotedPath
|
:: Maybe StringContainingQuotedPath
|
||||||
|
@ -112,11 +118,12 @@ addComputed
|
||||||
-> (OsPath -> Annex Backend)
|
-> (OsPath -> Annex Backend)
|
||||||
-> (OsPath -> Maybe OsPath)
|
-> (OsPath -> Maybe OsPath)
|
||||||
-> Bool
|
-> Bool
|
||||||
|
-> Either Bool AddUnlockedMatcher
|
||||||
-> Remote.Compute.ComputeProgramResult
|
-> Remote.Compute.ComputeProgramResult
|
||||||
-> OsPath
|
-> OsPath
|
||||||
-> NominalDiffTime
|
-> NominalDiffTime
|
||||||
-> Annex ()
|
-> Annex ()
|
||||||
addComputed maddaction r reproducibleconfig choosebackend destfile fast result tmpdir ts = do
|
addComputed maddaction r reproducibleconfig choosebackend destfile fast addunlockedmatcher result tmpdir ts = do
|
||||||
when (M.null outputs) $
|
when (M.null outputs) $
|
||||||
giveup "The computation succeeded, but it did not generate any files."
|
giveup "The computation succeeded, but it did not generate any files."
|
||||||
oks <- forM (M.keys outputs) $ \outputfile -> do
|
oks <- forM (M.keys outputs) $ \outputfile -> do
|
||||||
|
@ -163,19 +170,43 @@ addComputed maddaction r reproducibleconfig choosebackend destfile fast result t
|
||||||
stateurl = Remote.Compute.computeStateUrl r state outputfile
|
stateurl = Remote.Compute.computeStateUrl r state outputfile
|
||||||
stateurlk = fromUrl stateurl Nothing True
|
stateurlk = fromUrl stateurl Nothing True
|
||||||
outputfile' = tmpdir </> outputfile
|
outputfile' = tmpdir </> outputfile
|
||||||
ld f = LockedDown ldc (ks f)
|
|
||||||
ks f = KeySource
|
|
||||||
{ keyFilename = f
|
|
||||||
, contentLocation = outputfile'
|
|
||||||
, inodeCache = Nothing
|
|
||||||
}
|
|
||||||
genkey f p = do
|
genkey f p = do
|
||||||
backend <- choosebackend outputfile
|
backend <- choosebackend outputfile
|
||||||
fst <$> genKey (ks f) p backend
|
let ks = KeySource
|
||||||
ingesthelper f p mk =
|
{ keyFilename = f
|
||||||
ingestwith $ do
|
, contentLocation = outputfile'
|
||||||
k <- maybe (genkey f p) return mk
|
, inodeCache = Nothing
|
||||||
ingestAdd' p (Just (ld f)) (Just k)
|
}
|
||||||
|
fst <$> genKey ks p backend
|
||||||
|
ingesthelper f p mk = ingestwith $ do
|
||||||
|
k <- maybe (genkey f p) return mk
|
||||||
|
topf <- inRepo $ toTopFilePath f
|
||||||
|
let fi = FileInfo
|
||||||
|
{ contentFile = outputfile'
|
||||||
|
, matchFile = getTopFilePath topf
|
||||||
|
, matchKey = Just k
|
||||||
|
}
|
||||||
|
lockingfile <- case addunlockedmatcher of
|
||||||
|
Right addunlockedmatcher' ->
|
||||||
|
not <$> addUnlocked addunlockedmatcher'
|
||||||
|
(MatchingFile fi)
|
||||||
|
(not fast)
|
||||||
|
Left v -> pure v
|
||||||
|
let ldc = LockDownConfig
|
||||||
|
{ lockingFile = lockingfile
|
||||||
|
, hardlinkFileTmpDir = Nothing
|
||||||
|
, checkWritePerms = True
|
||||||
|
}
|
||||||
|
liftIO $ createDirectoryIfMissing True $
|
||||||
|
takeDirectory f
|
||||||
|
liftIO $ moveFile outputfile' f
|
||||||
|
let ks = KeySource
|
||||||
|
{ keyFilename = f
|
||||||
|
, contentLocation = f
|
||||||
|
, inodeCache = Nothing
|
||||||
|
}
|
||||||
|
let ld = LockedDown ldc ks
|
||||||
|
ingestAdd' p (Just ld) (Just k)
|
||||||
ingestwith a = a >>= \case
|
ingestwith a = a >>= \case
|
||||||
Nothing -> giveup "ingestion failed"
|
Nothing -> giveup "ingestion failed"
|
||||||
Just k -> do
|
Just k -> do
|
||||||
|
@ -188,12 +219,6 @@ addComputed maddaction r reproducibleconfig choosebackend destfile fast result t
|
||||||
=<< calcRepo (gitAnnexLocation k)
|
=<< calcRepo (gitAnnexLocation k)
|
||||||
return k
|
return k
|
||||||
|
|
||||||
ldc = LockDownConfig
|
|
||||||
{ lockingFile = True
|
|
||||||
, hardlinkFileTmpDir = Nothing
|
|
||||||
, checkWritePerms = True
|
|
||||||
}
|
|
||||||
|
|
||||||
isreproducible = case reproducibleconfig of
|
isreproducible = case reproducibleconfig of
|
||||||
Just v -> isReproducible v
|
Just v -> isReproducible v
|
||||||
Nothing -> Remote.Compute.computeReproducible result
|
Nothing -> Remote.Compute.computeReproducible result
|
||||||
|
|
|
@ -23,8 +23,10 @@ import Logs.Location
|
||||||
import Command.AddComputed (Reproducible(..), parseReproducible, getInputContent, getInputContent', addComputed)
|
import Command.AddComputed (Reproducible(..), parseReproducible, getInputContent, getInputContent', addComputed)
|
||||||
import Backend (maybeLookupBackendVariety, unknownBackendVarietyMessage, chooseBackend)
|
import Backend (maybeLookupBackendVariety, unknownBackendVarietyMessage, chooseBackend)
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
import qualified Utility.RawFilePath as R
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
import System.PosixCompat.Files (isSymbolicLink)
|
||||||
|
|
||||||
cmd :: Command
|
cmd :: Command
|
||||||
cmd = notBareRepo $
|
cmd = notBareRepo $
|
||||||
|
@ -126,19 +128,22 @@ perform :: RecomputeOptions -> Remote -> OsPath -> Key -> Remote.Compute.Compute
|
||||||
perform o r file origkey origstate = do
|
perform o r file origkey origstate = do
|
||||||
program <- Remote.Compute.getComputeProgram r
|
program <- Remote.Compute.getComputeProgram r
|
||||||
reproducibleconfig <- getreproducibleconfig
|
reproducibleconfig <- getreproducibleconfig
|
||||||
|
originallocked <- liftIO $ isSymbolicLink
|
||||||
|
<$> R.getSymbolicLinkStatus (fromOsPath file)
|
||||||
showOutput
|
showOutput
|
||||||
Remote.Compute.runComputeProgram program origstate
|
Remote.Compute.runComputeProgram program origstate
|
||||||
(Remote.Compute.ImmutableState False)
|
(Remote.Compute.ImmutableState False)
|
||||||
(getinputcontent program)
|
(getinputcontent program)
|
||||||
Nothing
|
Nothing
|
||||||
(go program reproducibleconfig)
|
(go program reproducibleconfig originallocked)
|
||||||
next cleanup
|
next cleanup
|
||||||
where
|
where
|
||||||
go program reproducibleconfig result tmpdir ts = do
|
go program reproducibleconfig originallocked result tmpdir ts = do
|
||||||
checkbehaviorchange program
|
checkbehaviorchange program
|
||||||
(Remote.Compute.computeState result)
|
(Remote.Compute.computeState result)
|
||||||
addComputed Nothing r reproducibleconfig
|
addComputed Nothing r reproducibleconfig
|
||||||
choosebackend destfile False result tmpdir ts
|
choosebackend destfile False (Left originallocked)
|
||||||
|
result tmpdir ts
|
||||||
|
|
||||||
checkbehaviorchange program state = do
|
checkbehaviorchange program state = do
|
||||||
let check s w a b = forM_ (M.keys (w a)) $ \f ->
|
let check s w a b = forM_ (M.keys (w a)) $ \f ->
|
||||||
|
|
|
@ -29,21 +29,6 @@ compute special remote. --[[Joey]]
|
||||||
* allow git-annex enableremote with program= explicitly specified,
|
* allow git-annex enableremote with program= explicitly specified,
|
||||||
without checking annex.security.allowed-compute-programs
|
without checking annex.security.allowed-compute-programs
|
||||||
|
|
||||||
* addcomputed should honor annex.addunlocked.
|
|
||||||
|
|
||||||
What about recompute? It seems it should either write the new version of
|
|
||||||
the file as an unlocked file when the old version was unlocked, or also
|
|
||||||
honor annex.addunlocked.
|
|
||||||
|
|
||||||
Problem: Since recompute does not stage the file, it would have to write
|
|
||||||
the content to the working tree. And then the user would need to
|
|
||||||
git-annex add. But then, if the key was a VURL key, it would add it with
|
|
||||||
the default backend instead, and the file would no longer use a computed
|
|
||||||
key.
|
|
||||||
|
|
||||||
So it, seems that, for this to be done, recompute would need to stage the
|
|
||||||
pointer file.
|
|
||||||
|
|
||||||
* recompute could ingest keys for other files than the one being
|
* recompute could ingest keys for other files than the one being
|
||||||
recomputed, and remember them. Then recomputing those files could just
|
recomputed, and remember them. Then recomputing those files could just
|
||||||
use those keys, without re-running a computation. (Better than --others
|
use those keys, without re-running a computation. (Better than --others
|
||||||
|
@ -68,3 +53,4 @@ compute special remote. --[[Joey]]
|
||||||
that recompute should also support recomputing non-annexed files.
|
that recompute should also support recomputing non-annexed files.
|
||||||
Otherwise, adding a file and then recomputing it would vary in
|
Otherwise, adding a file and then recomputing it would vary in
|
||||||
what the content of the file is, depending on annex.smallfiles setting.
|
what the content of the file is, depending on annex.smallfiles setting.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue