add VerifiedCopy data type
There should be no behavior changes in this commit, it just adds a more expressive data type and adjusts code that had been passing around a [UUID] or sometimes a Maybe Remote to instead use [VerifiedCopy]. Although, since some functions were taking two different [UUID] lists, there's some potential for me to have gotten it horribly wrong.
This commit is contained in:
parent
b1abe59193
commit
90f7c4b6a2
16 changed files with 107 additions and 60 deletions
|
@ -67,6 +67,8 @@ import Messages.Progress
|
||||||
import qualified Types.Remote
|
import qualified Types.Remote
|
||||||
import qualified Types.Backend
|
import qualified Types.Backend
|
||||||
import qualified Backend
|
import qualified Backend
|
||||||
|
import Types.NumCopies
|
||||||
|
import Annex.UUID
|
||||||
|
|
||||||
{- Checks if a given key's content is currently present. -}
|
{- Checks if a given key's content is currently present. -}
|
||||||
inAnnex :: Key -> Annex Bool
|
inAnnex :: Key -> Annex Bool
|
||||||
|
@ -178,8 +180,10 @@ contentLockFile key = Just <$> calcRepo (gitAnnexContentLock key)
|
||||||
- Note that, in direct mode, nothing prevents the user from directly
|
- Note that, in direct mode, nothing prevents the user from directly
|
||||||
- editing or removing the content, even while it's locked by this.
|
- editing or removing the content, even while it's locked by this.
|
||||||
-}
|
-}
|
||||||
lockContentShared :: Key -> Annex a -> Annex a
|
lockContentShared :: Key -> (VerifiedCopy -> Annex a) -> Annex a
|
||||||
lockContentShared = lockContentUsing lock
|
lockContentShared key a = lockContentUsing lock key $ do
|
||||||
|
u <- getUUID
|
||||||
|
a (VerifiedCopyLock u (return ()))
|
||||||
where
|
where
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
lock contentfile Nothing = liftIO $ tryLockShared Nothing contentfile
|
lock contentfile Nothing = liftIO $ tryLockShared Nothing contentfile
|
||||||
|
@ -195,7 +199,7 @@ newtype ContentLockExclusive = ContentLockExclusive Key
|
||||||
-}
|
-}
|
||||||
lockContentExclusive :: Key -> (ContentLockExclusive -> Annex a) -> Annex a
|
lockContentExclusive :: Key -> (ContentLockExclusive -> Annex a) -> Annex a
|
||||||
lockContentExclusive key a = lockContentUsing lock key $
|
lockContentExclusive key a = lockContentUsing lock key $
|
||||||
a $ ContentLockExclusive key
|
a (ContentLockExclusive key)
|
||||||
where
|
where
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
{- Since content files are stored with the write bit disabled, have
|
{- Since content files are stored with the write bit disabled, have
|
||||||
|
@ -238,7 +242,7 @@ lockContentUsing locker key a = do
|
||||||
bracket
|
bracket
|
||||||
(lock contentfile lockfile)
|
(lock contentfile lockfile)
|
||||||
(unlock lockfile)
|
(unlock lockfile)
|
||||||
(const $ a)
|
(const a)
|
||||||
where
|
where
|
||||||
alreadylocked = error "content is locked"
|
alreadylocked = error "content is locked"
|
||||||
failedtolock e = error $ "failed to lock content: " ++ show e
|
failedtolock e = error $ "failed to lock content: " ++ show e
|
||||||
|
|
|
@ -32,9 +32,8 @@ type Reason = String
|
||||||
- only ones that match the UUIDs will be dropped from.
|
- only ones that match the UUIDs will be dropped from.
|
||||||
- If allowed to drop fromhere, that drop will be tried first.
|
- If allowed to drop fromhere, that drop will be tried first.
|
||||||
-
|
-
|
||||||
- A remote can be specified that is known to have the key. This can be
|
- A VerifiedCopy can be provided as an optimisation when eg, a key
|
||||||
- used an an optimisation when eg, a key has just been uploaded to a
|
- has just been uploaded to a remote.
|
||||||
- remote.
|
|
||||||
-
|
-
|
||||||
- In direct mode, all associated files are checked, and only if all
|
- In direct mode, all associated files are checked, and only if all
|
||||||
- of them are unwanted are they dropped.
|
- of them are unwanted are they dropped.
|
||||||
|
@ -42,8 +41,8 @@ type Reason = String
|
||||||
- The runner is used to run commands, and so can be either callCommand
|
- The runner is used to run commands, and so can be either callCommand
|
||||||
- or commandAction.
|
- or commandAction.
|
||||||
-}
|
-}
|
||||||
handleDropsFrom :: [UUID] -> [Remote] -> Reason -> Bool -> Key -> AssociatedFile -> Maybe Remote -> (CommandStart -> CommandCleanup) -> Annex ()
|
handleDropsFrom :: [UUID] -> [Remote] -> Reason -> Bool -> Key -> AssociatedFile -> [VerifiedCopy] -> (CommandStart -> CommandCleanup) -> Annex ()
|
||||||
handleDropsFrom locs rs reason fromhere key afile knownpresentremote runner = do
|
handleDropsFrom locs rs reason fromhere key afile preverified runner = do
|
||||||
fs <- ifM isDirect
|
fs <- ifM isDirect
|
||||||
( do
|
( do
|
||||||
l <- associatedFilesRelative key
|
l <- associatedFilesRelative key
|
||||||
|
@ -112,7 +111,7 @@ handleDropsFrom locs rs reason fromhere key afile knownpresentremote runner = do
|
||||||
)
|
)
|
||||||
|
|
||||||
dropl fs n = checkdrop fs n Nothing $ \numcopies ->
|
dropl fs n = checkdrop fs n Nothing $ \numcopies ->
|
||||||
Command.Drop.startLocal afile numcopies key knownpresentremote
|
Command.Drop.startLocal afile numcopies key preverified
|
||||||
|
|
||||||
dropr fs r n = checkdrop fs n (Just $ Remote.uuid r) $ \numcopies ->
|
dropr fs r n = checkdrop fs n (Just $ Remote.uuid r) $ \numcopies ->
|
||||||
Command.Drop.startRemote afile numcopies key r
|
Command.Drop.startRemote afile numcopies key r
|
||||||
|
|
|
@ -96,11 +96,11 @@ verifyEnoughCopies
|
||||||
-> Key
|
-> Key
|
||||||
-> NumCopies
|
-> NumCopies
|
||||||
-> [UUID] -- repos to skip considering (generally untrusted remotes)
|
-> [UUID] -- repos to skip considering (generally untrusted remotes)
|
||||||
-> [UUID] -- repos that are trusted or already verified to have it
|
-> [VerifiedCopy] -- already known verifications
|
||||||
-> [Remote] -- remotes to check to see if they have it
|
-> [Remote] -- remotes to check to see if they have it
|
||||||
-> Annex Bool
|
-> Annex Bool
|
||||||
verifyEnoughCopies nolocmsg key need skip trusted tocheck =
|
verifyEnoughCopies nolocmsg key need skip preverified tocheck =
|
||||||
helper [] [] (nub trusted) (nub tocheck)
|
helper [] [] (deDupVerifiedCopies preverified) (nub tocheck)
|
||||||
where
|
where
|
||||||
helper bad missing have []
|
helper bad missing have []
|
||||||
| NumCopies (length have) >= need = return True
|
| NumCopies (length have) >= need = return True
|
||||||
|
@ -109,17 +109,17 @@ verifyEnoughCopies nolocmsg key need skip trusted tocheck =
|
||||||
return False
|
return False
|
||||||
helper bad missing have (r:rs)
|
helper bad missing have (r:rs)
|
||||||
| NumCopies (length have) >= need = return True
|
| NumCopies (length have) >= need = return True
|
||||||
|
| any (== u) (map toUUID have) = helper bad missing have rs
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
let u = Remote.uuid r
|
|
||||||
let duplicate = u `elem` have
|
|
||||||
haskey <- Remote.hasKey r key
|
haskey <- Remote.hasKey r key
|
||||||
case (duplicate, haskey) of
|
case haskey of
|
||||||
(False, Right True) -> helper bad missing (u:have) rs
|
Right True -> helper bad missing (VerifiedCopy u:have) rs
|
||||||
(False, Left _) -> helper (r:bad) missing have rs
|
Left _ -> helper (r:bad) missing have rs
|
||||||
(False, Right False) -> helper bad (u:missing) have rs
|
Right False -> helper bad (u:missing) have rs
|
||||||
_ -> helper bad missing have rs
|
where
|
||||||
|
u = Remote.uuid r
|
||||||
|
|
||||||
notEnoughCopies :: Key -> NumCopies -> [UUID] -> [UUID] -> [Remote] -> String -> Annex ()
|
notEnoughCopies :: Key -> NumCopies -> [VerifiedCopy] -> [UUID] -> [Remote] -> String -> Annex ()
|
||||||
notEnoughCopies key need have skip bad nolocmsg = do
|
notEnoughCopies key need have skip bad nolocmsg = do
|
||||||
showNote "unsafe"
|
showNote "unsafe"
|
||||||
showLongNote $
|
showLongNote $
|
||||||
|
@ -127,7 +127,7 @@ notEnoughCopies key need have skip bad nolocmsg = do
|
||||||
show (length have) ++ " out of " ++ show (fromNumCopies need) ++
|
show (length have) ++ " out of " ++ show (fromNumCopies need) ++
|
||||||
" necessary copies"
|
" necessary copies"
|
||||||
Remote.showTriedRemotes bad
|
Remote.showTriedRemotes bad
|
||||||
Remote.showLocations True key (have++skip) nolocmsg
|
Remote.showLocations True key (map toUUID have++skip) nolocmsg
|
||||||
|
|
||||||
{- Cost ordered lists of remotes that the location log indicates
|
{- Cost ordered lists of remotes that the location log indicates
|
||||||
- may have a key.
|
- may have a key.
|
||||||
|
|
|
@ -15,11 +15,12 @@ import Assistant.DaemonStatus
|
||||||
import Annex.Drop (handleDropsFrom, Reason)
|
import Annex.Drop (handleDropsFrom, Reason)
|
||||||
import Logs.Location
|
import Logs.Location
|
||||||
import CmdLine.Action
|
import CmdLine.Action
|
||||||
|
import Types.NumCopies
|
||||||
|
|
||||||
{- Drop from local and/or remote when allowed by the preferred content and
|
{- Drop from local and/or remote when allowed by the preferred content and
|
||||||
- numcopies settings. -}
|
- numcopies settings. -}
|
||||||
handleDrops :: Reason -> Bool -> Key -> AssociatedFile -> Maybe Remote -> Assistant ()
|
handleDrops :: Reason -> Bool -> Key -> AssociatedFile -> [VerifiedCopy] -> Assistant ()
|
||||||
handleDrops reason fromhere key f knownpresentremote = do
|
handleDrops reason fromhere key f preverified = do
|
||||||
syncrs <- syncDataRemotes <$> getDaemonStatus
|
syncrs <- syncDataRemotes <$> getDaemonStatus
|
||||||
locs <- liftAnnex $ loggedLocations key
|
locs <- liftAnnex $ loggedLocations key
|
||||||
liftAnnex $ handleDropsFrom locs syncrs reason fromhere key f knownpresentremote callCommandAction
|
liftAnnex $ handleDropsFrom locs syncrs reason fromhere key f preverified callCommandAction
|
||||||
|
|
|
@ -479,7 +479,7 @@ checkChangeContent change@(Change { changeInfo = i }) =
|
||||||
void $ if present
|
void $ if present
|
||||||
then queueTransfers "new file created" Next k (Just f) Upload
|
then queueTransfers "new file created" Next k (Just f) Upload
|
||||||
else queueTransfers "new or renamed file wanted" Next k (Just f) Download
|
else queueTransfers "new or renamed file wanted" Next k (Just f) Download
|
||||||
handleDrops "file renamed" present k (Just f) Nothing
|
handleDrops "file renamed" present k (Just f) []
|
||||||
where
|
where
|
||||||
f = changeFile change
|
f = changeFile change
|
||||||
checkChangeContent _ = noop
|
checkChangeContent _ = noop
|
||||||
|
|
|
@ -191,7 +191,7 @@ dailyCheck urlrenderer = do
|
||||||
void $ liftAnnex $ setUnusedKeys unused
|
void $ liftAnnex $ setUnusedKeys unused
|
||||||
forM_ unused $ \k -> do
|
forM_ unused $ \k -> do
|
||||||
unlessM (queueTransfers "unused" Later k Nothing Upload) $
|
unlessM (queueTransfers "unused" Later k Nothing Upload) $
|
||||||
handleDrops "unused" True k Nothing Nothing
|
handleDrops "unused" True k Nothing []
|
||||||
|
|
||||||
return True
|
return True
|
||||||
where
|
where
|
||||||
|
|
|
@ -157,7 +157,7 @@ expensiveScan urlrenderer rs = batch <~> do
|
||||||
present <- liftAnnex $ inAnnex key
|
present <- liftAnnex $ inAnnex key
|
||||||
liftAnnex $ handleDropsFrom locs syncrs
|
liftAnnex $ handleDropsFrom locs syncrs
|
||||||
"expensive scan found too many copies of object"
|
"expensive scan found too many copies of object"
|
||||||
present key (Just f) Nothing callCommandAction
|
present key (Just f) [] callCommandAction
|
||||||
liftAnnex $ do
|
liftAnnex $ do
|
||||||
let slocs = S.fromList locs
|
let slocs = S.fromList locs
|
||||||
let use a = return $ mapMaybe (a key slocs) syncrs
|
let use a = return $ mapMaybe (a key slocs) syncrs
|
||||||
|
|
|
@ -30,6 +30,7 @@ import Annex.Content
|
||||||
import Annex.Wanted
|
import Annex.Wanted
|
||||||
import Annex.Path
|
import Annex.Path
|
||||||
import Utility.Batch
|
import Utility.Batch
|
||||||
|
import Types.NumCopies
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Control.Exception as E
|
import qualified Control.Exception as E
|
||||||
|
@ -160,7 +161,7 @@ genTransfer t info = case transferRemote info of
|
||||||
("object uploaded to " ++ show remote)
|
("object uploaded to " ++ show remote)
|
||||||
True (transferKey t)
|
True (transferKey t)
|
||||||
(associatedFile info)
|
(associatedFile info)
|
||||||
(Just remote)
|
[VerifiedCopy (Remote.uuid remote)]
|
||||||
void recordCommit
|
void recordCommit
|
||||||
, whenM (liftAnnex $ isNothing <$> checkTransfer t) $
|
, whenM (liftAnnex $ isNothing <$> checkTransfer t) $
|
||||||
void $ removeTransfer t
|
void $ removeTransfer t
|
||||||
|
@ -225,7 +226,7 @@ finishedTransfer t (Just info)
|
||||||
where
|
where
|
||||||
dodrops fromhere = handleDrops
|
dodrops fromhere = handleDrops
|
||||||
("drop wanted after " ++ describeTransfer t info)
|
("drop wanted after " ++ describeTransfer t info)
|
||||||
fromhere (transferKey t) (associatedFile info) Nothing
|
fromhere (transferKey t) (associatedFile info) []
|
||||||
finishedTransfer _ _ = noop
|
finishedTransfer _ _ = noop
|
||||||
|
|
||||||
{- Pause a running transfer. -}
|
{- Pause a running transfer. -}
|
||||||
|
|
|
@ -64,11 +64,11 @@ start' o key afile = do
|
||||||
checkDropAuto (autoMode o) from afile key $ \numcopies ->
|
checkDropAuto (autoMode o) from afile key $ \numcopies ->
|
||||||
stopUnless (want from) $
|
stopUnless (want from) $
|
||||||
case from of
|
case from of
|
||||||
Nothing -> startLocal afile numcopies key Nothing
|
Nothing -> startLocal afile numcopies key []
|
||||||
Just remote -> do
|
Just remote -> do
|
||||||
u <- getUUID
|
u <- getUUID
|
||||||
if Remote.uuid remote == u
|
if Remote.uuid remote == u
|
||||||
then startLocal afile numcopies key Nothing
|
then startLocal afile numcopies key []
|
||||||
else startRemote afile numcopies key remote
|
else startRemote afile numcopies key remote
|
||||||
where
|
where
|
||||||
want from
|
want from
|
||||||
|
@ -78,10 +78,10 @@ start' o key afile = do
|
||||||
startKeys :: DropOptions -> Key -> CommandStart
|
startKeys :: DropOptions -> Key -> CommandStart
|
||||||
startKeys o key = start' o key Nothing
|
startKeys o key = start' o key Nothing
|
||||||
|
|
||||||
startLocal :: AssociatedFile -> NumCopies -> Key -> Maybe Remote -> CommandStart
|
startLocal :: AssociatedFile -> NumCopies -> Key -> [VerifiedCopy] -> CommandStart
|
||||||
startLocal afile numcopies key knownpresentremote = stopUnless (inAnnex key) $ do
|
startLocal afile numcopies key preverified = stopUnless (inAnnex key) $ do
|
||||||
showStart' "drop" key afile
|
showStart' "drop" key afile
|
||||||
next $ performLocal key afile numcopies knownpresentremote
|
next $ performLocal key afile numcopies preverified
|
||||||
|
|
||||||
startRemote :: AssociatedFile -> NumCopies -> Key -> Remote -> CommandStart
|
startRemote :: AssociatedFile -> NumCopies -> Key -> Remote -> CommandStart
|
||||||
startRemote afile numcopies key remote = do
|
startRemote afile numcopies key remote = do
|
||||||
|
@ -92,16 +92,14 @@ startRemote afile numcopies key remote = do
|
||||||
-- present on enough remotes to allow removal. This avoids a scenario where two
|
-- present on enough remotes to allow removal. This avoids a scenario where two
|
||||||
-- or more remotes are trying to remove a key at the same time, and each
|
-- or more remotes are trying to remove a key at the same time, and each
|
||||||
-- sees the key is present on the other.
|
-- sees the key is present on the other.
|
||||||
performLocal :: Key -> AssociatedFile -> NumCopies -> Maybe Remote -> CommandPerform
|
performLocal :: Key -> AssociatedFile -> NumCopies -> [VerifiedCopy] -> CommandPerform
|
||||||
performLocal key afile numcopies knownpresentremote = lockContentExclusive key $ \contentlock -> do
|
performLocal key afile numcopies preverified = lockContentExclusive key $ \contentlock -> do
|
||||||
(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key
|
(remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key
|
||||||
let trusteduuids' = case knownpresentremote of
|
let preverified' = preverified ++ map TrustedCopy trusteduuids
|
||||||
Nothing -> trusteduuids
|
|
||||||
Just r -> Remote.uuid r:trusteduuids
|
|
||||||
untrusteduuids <- trustGet UnTrusted
|
untrusteduuids <- trustGet UnTrusted
|
||||||
let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids'++untrusteduuids)
|
let tocheck = Remote.remotesWithoutUUID remotes (map toUUID preverified'++untrusteduuids)
|
||||||
u <- getUUID
|
u <- getUUID
|
||||||
ifM (canDrop u key afile numcopies trusteduuids' tocheck [])
|
ifM (canDrop u key afile numcopies [] preverified' tocheck)
|
||||||
( do
|
( do
|
||||||
removeAnnex contentlock
|
removeAnnex contentlock
|
||||||
notifyDrop afile True
|
notifyDrop afile True
|
||||||
|
@ -118,11 +116,11 @@ performRemote key afile numcopies remote = do
|
||||||
-- When the local repo has the key, that's one additional copy,
|
-- When the local repo has the key, that's one additional copy,
|
||||||
-- as long as the local repo is not untrusted.
|
-- as long as the local repo is not untrusted.
|
||||||
(remotes, trusteduuids) <- knownCopies key
|
(remotes, trusteduuids) <- knownCopies key
|
||||||
let have = filter (/= uuid) trusteduuids
|
let trusted = filter (/= uuid) trusteduuids
|
||||||
untrusteduuids <- trustGet UnTrusted
|
untrusteduuids <- trustGet UnTrusted
|
||||||
let tocheck = filter (/= remote) $
|
let tocheck = filter (/= remote) $
|
||||||
Remote.remotesWithoutUUID remotes (have++untrusteduuids)
|
Remote.remotesWithoutUUID remotes (trusted++untrusteduuids)
|
||||||
stopUnless (canDrop uuid key afile numcopies have tocheck [uuid]) $ do
|
stopUnless (canDrop uuid key afile numcopies [uuid] (map TrustedCopy trusted) tocheck) $ do
|
||||||
ok <- Remote.removeKey remote key
|
ok <- Remote.removeKey remote key
|
||||||
next $ cleanupRemote key remote ok
|
next $ cleanupRemote key remote ok
|
||||||
where
|
where
|
||||||
|
@ -140,19 +138,18 @@ cleanupRemote key remote ok = do
|
||||||
return ok
|
return ok
|
||||||
|
|
||||||
{- Checks specified remotes to verify that enough copies of a key exist to
|
{- Checks specified remotes to verify that enough copies of a key exist to
|
||||||
- allow it to be safely removed (with no data loss). Can be provided with
|
- allow it to be safely removed (with no data loss).
|
||||||
- some locations where the key is known/assumed to be present.
|
|
||||||
-
|
-
|
||||||
- Also checks if it's required content, and refuses to drop if so.
|
- Also checks if it's required content, and refuses to drop if so.
|
||||||
-
|
-
|
||||||
- --force overrides and always allows dropping.
|
- --force overrides and always allows dropping.
|
||||||
-}
|
-}
|
||||||
canDrop :: UUID -> Key -> AssociatedFile -> NumCopies -> [UUID] -> [Remote] -> [UUID] -> Annex Bool
|
canDrop :: UUID -> Key -> AssociatedFile -> NumCopies -> [UUID] -> [VerifiedCopy] -> [Remote] -> Annex Bool
|
||||||
canDrop dropfrom key afile numcopies have check skip =
|
canDrop dropfrom key afile numcopies skip preverified check =
|
||||||
ifM (Annex.getState Annex.force)
|
ifM (Annex.getState Annex.force)
|
||||||
( return True
|
( return True
|
||||||
, ifM (checkRequiredContent dropfrom key afile
|
, ifM (checkRequiredContent dropfrom key afile
|
||||||
<&&> verifyEnoughCopies nolocmsg key numcopies skip have check
|
<&&> verifyEnoughCopies nolocmsg key numcopies skip preverified check
|
||||||
)
|
)
|
||||||
( return True
|
( return True
|
||||||
, do
|
, do
|
||||||
|
|
|
@ -44,7 +44,7 @@ perform from numcopies key = case from of
|
||||||
Just r -> do
|
Just r -> do
|
||||||
showAction $ "from " ++ Remote.name r
|
showAction $ "from " ++ Remote.name r
|
||||||
Command.Drop.performRemote key Nothing numcopies r
|
Command.Drop.performRemote key Nothing numcopies r
|
||||||
Nothing -> Command.Drop.performLocal key Nothing numcopies Nothing
|
Nothing -> Command.Drop.performLocal key Nothing numcopies []
|
||||||
|
|
||||||
performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
|
performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
|
||||||
performOther filespec key = do
|
performOther filespec key = do
|
||||||
|
|
|
@ -143,4 +143,4 @@ verifiedExisting key destfile = do
|
||||||
(remotes, trusteduuids) <- knownCopies key
|
(remotes, trusteduuids) <- knownCopies key
|
||||||
untrusteduuids <- trustGet UnTrusted
|
untrusteduuids <- trustGet UnTrusted
|
||||||
let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids++untrusteduuids)
|
let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids++untrusteduuids)
|
||||||
verifyEnoughCopies [] key need [] trusteduuids tocheck
|
verifyEnoughCopies [] key need [] (map TrustedCopy trusteduuids) tocheck
|
||||||
|
|
|
@ -27,7 +27,7 @@ seek = withWords start
|
||||||
-- dropping the lock.
|
-- dropping the lock.
|
||||||
start :: [String] -> CommandStart
|
start :: [String] -> CommandStart
|
||||||
start [ks] = do
|
start [ks] = do
|
||||||
ok <- lockContentShared k locksuccess
|
ok <- lockContentShared k (const locksuccess)
|
||||||
`catchNonAsync` (const $ return False)
|
`catchNonAsync` (const $ return False)
|
||||||
liftIO $ if ok
|
liftIO $ if ok
|
||||||
then exitSuccess
|
then exitSuccess
|
||||||
|
|
|
@ -65,7 +65,7 @@ startKey o afile key = case fromToOptions o of
|
||||||
Right False -> ifM (inAnnex key)
|
Right False -> ifM (inAnnex key)
|
||||||
( do
|
( do
|
||||||
numcopies <- getnumcopies
|
numcopies <- getnumcopies
|
||||||
Command.Drop.startLocal afile numcopies key Nothing
|
Command.Drop.startLocal afile numcopies key []
|
||||||
, stop
|
, stop
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
|
@ -460,8 +460,8 @@ syncFile ebloom rs af k = do
|
||||||
-- includeCommandAction for drops,
|
-- includeCommandAction for drops,
|
||||||
-- because a failure to drop does not mean
|
-- because a failure to drop does not mean
|
||||||
-- the sync failed.
|
-- the sync failed.
|
||||||
handleDropsFrom locs' rs "unwanted" True k af
|
handleDropsFrom locs' rs "unwanted" True k af []
|
||||||
Nothing callCommandAction
|
callCommandAction
|
||||||
|
|
||||||
return (got || not (null putrs))
|
return (got || not (null putrs))
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{- git-annex numcopies type
|
{- git-annex numcopies types
|
||||||
-
|
-
|
||||||
- Copyright 2014 Joey Hess <id@joeyh.name>
|
- Copyright 2014 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
|
@ -7,8 +7,48 @@
|
||||||
|
|
||||||
module Types.NumCopies where
|
module Types.NumCopies where
|
||||||
|
|
||||||
|
import Types.UUID
|
||||||
|
|
||||||
|
import qualified Data.Map as M
|
||||||
|
|
||||||
newtype NumCopies = NumCopies Int
|
newtype NumCopies = NumCopies Int
|
||||||
deriving (Ord, Eq)
|
deriving (Ord, Eq)
|
||||||
|
|
||||||
fromNumCopies :: NumCopies -> Int
|
fromNumCopies :: NumCopies -> Int
|
||||||
fromNumCopies (NumCopies n) = n
|
fromNumCopies (NumCopies n) = n
|
||||||
|
|
||||||
|
data VerifiedCopy
|
||||||
|
{- Use when a repository cannot be accessed, but it's
|
||||||
|
- a trusted repository, which is presumably not going to
|
||||||
|
- lose a copy. This is the weakest level of verification. -}
|
||||||
|
= TrustedCopy UUID
|
||||||
|
{- Represents a recent verification that a copy of an
|
||||||
|
- object exists in a repository with the given UUID. -}
|
||||||
|
| VerifiedCopy UUID
|
||||||
|
{- The strongest proof of the existence of a copy.
|
||||||
|
- Until its associated action is called to unlock it,
|
||||||
|
- the copy is locked in the repository and is guaranteed
|
||||||
|
- not to be dropped by any git-annex process. -}
|
||||||
|
| VerifiedCopyLock UUID (IO ())
|
||||||
|
|
||||||
|
instance ToUUID VerifiedCopy where
|
||||||
|
toUUID (VerifiedCopy u) = u
|
||||||
|
toUUID (VerifiedCopyLock u _) = u
|
||||||
|
toUUID (TrustedCopy u) = u
|
||||||
|
|
||||||
|
instance Show VerifiedCopy where
|
||||||
|
show (TrustedCopy u) = "TrustedCopy " ++ show u
|
||||||
|
show (VerifiedCopy u) = "VerifiedCopy " ++ show u
|
||||||
|
show (VerifiedCopyLock u _) = "VerifiedCopyLock " ++ show u
|
||||||
|
|
||||||
|
strongestVerifiedCopy :: VerifiedCopy -> VerifiedCopy -> VerifiedCopy
|
||||||
|
strongestVerifiedCopy a@(VerifiedCopyLock _ _) _ = a
|
||||||
|
strongestVerifiedCopy _ b@(VerifiedCopyLock _ _) = b
|
||||||
|
strongestVerifiedCopy a@(VerifiedCopy _) _ = a
|
||||||
|
strongestVerifiedCopy _ b@(VerifiedCopy _) = b
|
||||||
|
strongestVerifiedCopy a@(TrustedCopy _) _ = a
|
||||||
|
|
||||||
|
-- Retains stronger verifications over weaker for the same uuid.
|
||||||
|
deDupVerifiedCopies :: [VerifiedCopy] -> [VerifiedCopy]
|
||||||
|
deDupVerifiedCopies l = M.elems $
|
||||||
|
M.fromListWith strongestVerifiedCopy (zip (map toUUID l) l)
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
|
||||||
|
|
||||||
module Types.UUID where
|
module Types.UUID where
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
@ -19,7 +21,10 @@ fromUUID :: UUID -> String
|
||||||
fromUUID (UUID u) = u
|
fromUUID (UUID u) = u
|
||||||
fromUUID NoUUID = ""
|
fromUUID NoUUID = ""
|
||||||
|
|
||||||
toUUID :: String -> UUID
|
class ToUUID a where
|
||||||
|
toUUID :: a -> UUID
|
||||||
|
|
||||||
|
instance ToUUID String where
|
||||||
toUUID [] = NoUUID
|
toUUID [] = NoUUID
|
||||||
toUUID s = UUID s
|
toUUID s = UUID s
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue