extend manifest with keys to be deleted
This will eventually be used to recover from an interrupted fullPush and drop the old bundle keys it was unable to delete. Sponsored-by: Luke T. Shumaker on Patreon
This commit is contained in:
parent
1f62bc861a
commit
97b309b56e
3 changed files with 31 additions and 7 deletions
|
@ -40,6 +40,7 @@ import Utility.Env
|
||||||
import Utility.Metered
|
import Utility.Metered
|
||||||
|
|
||||||
import Network.URI
|
import Network.URI
|
||||||
|
import Data.Either
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Char8 as B8
|
import qualified Data.ByteString.Char8 as B8
|
||||||
import qualified Data.Map.Strict as M
|
import qualified Data.Map.Strict as M
|
||||||
|
@ -265,7 +266,7 @@ fullPush st rmt refs = guardPush st $ do
|
||||||
oldmanifest <- maybe (downloadManifest rmt) pure (manifestCache st)
|
oldmanifest <- maybe (downloadManifest rmt) pure (manifestCache st)
|
||||||
let bs = map Git.Bundle.fullBundleSpec refs
|
let bs = map Git.Bundle.fullBundleSpec refs
|
||||||
bundlekey <- generateAndUploadGitBundle rmt bs oldmanifest
|
bundlekey <- generateAndUploadGitBundle rmt bs oldmanifest
|
||||||
uploadManifest rmt (Manifest [bundlekey])
|
uploadManifest rmt (Manifest [bundlekey] [])
|
||||||
ok <- allM (dropKey rmt) $
|
ok <- allM (dropKey rmt) $
|
||||||
filter (/= bundlekey) (inManifest oldmanifest)
|
filter (/= bundlekey) (inManifest oldmanifest)
|
||||||
return (ok, st { manifestCache = Nothing })
|
return (ok, st { manifestCache = Nothing })
|
||||||
|
@ -285,7 +286,7 @@ incrementalPush st rmt oldtrackingrefs newtrackingrefs = guardPush st $ do
|
||||||
bs <- calc [] (M.toList newtrackingrefs)
|
bs <- calc [] (M.toList newtrackingrefs)
|
||||||
oldmanifest <- maybe (downloadManifest rmt) pure (manifestCache st)
|
oldmanifest <- maybe (downloadManifest rmt) pure (manifestCache st)
|
||||||
bundlekey <- generateAndUploadGitBundle rmt bs oldmanifest
|
bundlekey <- generateAndUploadGitBundle rmt bs oldmanifest
|
||||||
uploadManifest rmt (Manifest [bundlekey])
|
uploadManifest rmt (Manifest [bundlekey] [])
|
||||||
return (True, st { manifestCache = Nothing })
|
return (True, st { manifestCache = Nothing })
|
||||||
where
|
where
|
||||||
calc c [] = return (reverse c)
|
calc c [] = return (reverse c)
|
||||||
|
@ -355,7 +356,7 @@ incrementalPush st rmt oldtrackingrefs newtrackingrefs = guardPush st $ do
|
||||||
pushEmpty :: State -> Remote -> Annex (Bool, State)
|
pushEmpty :: State -> Remote -> Annex (Bool, State)
|
||||||
pushEmpty st rmt = do
|
pushEmpty st rmt = do
|
||||||
manifest <- maybe (downloadManifest rmt) pure (manifestCache st)
|
manifest <- maybe (downloadManifest rmt) pure (manifestCache st)
|
||||||
uploadManifest rmt (Manifest [])
|
uploadManifest rmt (Manifest [] [])
|
||||||
ok <- allM (dropKey rmt)
|
ok <- allM (dropKey rmt)
|
||||||
(genManifestKey (Remote.uuid rmt) : inManifest manifest)
|
(genManifestKey (Remote.uuid rmt) : inManifest manifest)
|
||||||
return (ok, st { manifestCache = Nothing })
|
return (ok, st { manifestCache = Nothing })
|
||||||
|
@ -533,7 +534,14 @@ checkSpecialRemoteProblems rmt
|
||||||
| otherwise = Nothing
|
| otherwise = Nothing
|
||||||
|
|
||||||
-- The manifest contains an ordered list of git bundle keys.
|
-- The manifest contains an ordered list of git bundle keys.
|
||||||
newtype Manifest = Manifest { inManifest :: [Key] }
|
--
|
||||||
|
-- There is a second list of git bundle keys that are no longer
|
||||||
|
-- used and should be deleted.
|
||||||
|
data Manifest =
|
||||||
|
Manifest
|
||||||
|
{ inManifest :: [Key]
|
||||||
|
, outManifest :: [Key]
|
||||||
|
}
|
||||||
|
|
||||||
-- Downloads the Manifest, or if it does not exist, returns an empty
|
-- Downloads the Manifest, or if it does not exist, returns an empty
|
||||||
-- Manifest.
|
-- Manifest.
|
||||||
|
@ -551,9 +559,12 @@ downloadManifest rmt = ifM (Remote.checkPresent rmt mk)
|
||||||
_ <- Remote.retrieveKeyFile rmt mk
|
_ <- Remote.retrieveKeyFile rmt mk
|
||||||
(AssociatedFile Nothing) tmp
|
(AssociatedFile Nothing) tmp
|
||||||
nullMeterUpdate Remote.NoVerify
|
nullMeterUpdate Remote.NoVerify
|
||||||
ks <- map deserializeKey' . B8.lines <$> liftIO (B.readFile tmp)
|
(outks, inks) <- partitionEithers . map parseline . B8.lines
|
||||||
Manifest <$> checkvalid [] ks
|
<$> liftIO (B.readFile tmp)
|
||||||
, return (Manifest [])
|
Manifest
|
||||||
|
<$> checkvalid [] inks
|
||||||
|
<*> checkvalid [] (filter (`notElem` inks) outks)
|
||||||
|
, return (Manifest [] [])
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
mk = genManifestKey (Remote.uuid rmt)
|
mk = genManifestKey (Remote.uuid rmt)
|
||||||
|
@ -565,6 +576,12 @@ downloadManifest rmt = ifM (Remote.checkPresent rmt mk)
|
||||||
checkvalid _ (Nothing:_) =
|
checkvalid _ (Nothing:_) =
|
||||||
giveup $ "Error parsing manifest " ++ serializeKey mk
|
giveup $ "Error parsing manifest " ++ serializeKey mk
|
||||||
|
|
||||||
|
parseline l
|
||||||
|
| "-" `B.isPrefixOf` l =
|
||||||
|
Left $ deserializeKey' $ B.drop 1 l
|
||||||
|
| otherwise =
|
||||||
|
Right $ deserializeKey' l
|
||||||
|
|
||||||
-- Uploads the Manifest to the remote.
|
-- Uploads the Manifest to the remote.
|
||||||
--
|
--
|
||||||
-- Throws errors if the remote cannot be accessed or the upload fails.
|
-- Throws errors if the remote cannot be accessed or the upload fails.
|
||||||
|
|
|
@ -12,6 +12,10 @@ GITBUNDLE--$UUID-sha256 is a git bundle.
|
||||||
|
|
||||||
An ordered list of bundle keys, one per line.
|
An ordered list of bundle keys, one per line.
|
||||||
|
|
||||||
|
Additionally, there may be bundle keys that are prefixed with "-".
|
||||||
|
These keys are not part of the current content of the git remote
|
||||||
|
and are in the process of being deleted.
|
||||||
|
|
||||||
(Lines end with unix `"\n"`, not `"\r\n"`.)
|
(Lines end with unix `"\n"`, not `"\r\n"`.)
|
||||||
|
|
||||||
# multiple GITMANIFEST files
|
# multiple GITMANIFEST files
|
||||||
|
|
|
@ -33,6 +33,9 @@ This is implememented and working. Remaining todo list for it:
|
||||||
to clone from a wrong url, since it fails to download
|
to clone from a wrong url, since it fails to download
|
||||||
a manifest and so appears as if the remote is empty.
|
a manifest and so appears as if the remote is empty.
|
||||||
|
|
||||||
|
* Improve recovery from interrupted push by using outManifest to clean up
|
||||||
|
after it. (Requires populating outManifest.)
|
||||||
|
|
||||||
* See XXX in uploadManifest about recovering from a situation
|
* See XXX in uploadManifest about recovering from a situation
|
||||||
where the remote is left with a deleted manifest when a push
|
where the remote is left with a deleted manifest when a push
|
||||||
is interrupted part way through. This should be recoverable
|
is interrupted part way through. This should be recoverable
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue