migrate --update fully working
authorJoey Hess <joeyh@joeyh.name>
Thu, 7 Dec 2023 21:26:12 +0000 (17:26 -0400)
committerJoey Hess <joeyh@joeyh.name>
Thu, 7 Dec 2023 21:27:51 +0000 (17:27 -0400)
Could use some more testing.

When the old key is not present, Command.ReKey.linkKey' will return
False, so this handles that case ok.

But, I do wonder if distributed migration may need to deal with the old
key getting copied into the repository later. In that situation,
re-running migrate --update won't link it to the new key. It may be that
some users will need that. They can delete .git/annex/migrate.log and
run it again, but that is not a good user interface. Maybe either have
a way to re-run all distributed migrations, or record migrations
in a database and scan the db to find migrations to do in a future run?

Sponsored-by: Kevin Mueller on Patreon
Command/Migrate.hs
Command/ReKey.hs

index 614eab858ac0484542b27d91e0e236929d526da6..188dd03532dcf00c963afc17cc2c741df1206052 100644 (file)
@@ -18,6 +18,7 @@ import qualified Annex
 import Logs.Migrate
 import Logs.MetaData
 import Logs.Web
+import Logs.Location
 import Utility.Metered
 
 cmd :: Command
@@ -144,7 +145,8 @@ perform onlyremovesize o file oldkey oldkeyrec oldbackend newbackend = go =<< ge
 
 update :: CommandStart
 update = starting "migrate" (ActionItemOther Nothing) (SeekInput []) $ do
-       streamNewDistributedMigrations $ \oldkey newkey -> do
-               liftIO $ print ("migrate", oldkey, newkey)
+       streamNewDistributedMigrations $ \oldkey newkey ->
+               unlessM (inAnnex newkey) $
+                       whenM (Command.ReKey.linkKey' oldkey newkey) $
+                               logStatus newkey InfoPresent
        next $ return True
-
index dc19b1e7ca54f6bc182c02470ec42aefacdd8cd3..001ed2d130a4e122221c8fbd19c370d3b52f4dcb 100644 (file)
@@ -95,14 +95,7 @@ perform file oldkey newkey = do
  - to avoid wasting disk space. -}
 linkKey :: RawFilePath -> Key -> Key -> Annex Bool
 linkKey file oldkey newkey = ifM (isJust <$> isAnnexLink file)
-       {- If the object file is already hardlinked to elsewhere, a hard
-        - link won't be made by getViaTmpFromDisk, but a copy instead.
-        - This avoids hard linking to content linked to an
-        - unlocked file, which would leave the new key unlocked
-        - and vulnerable to corruption. -}
-       ( getViaTmpFromDisk RetrievalAllKeysSecure DefaultVerify newkey (AssociatedFile Nothing) $ \tmp -> unVerified $ do
-               oldobj <- calcRepo (gitAnnexLocation oldkey)
-               isJust <$> linkOrCopy' (return True) newkey oldobj tmp Nothing
+       ( linkKey' oldkey newkey
        , do
                {- The file being rekeyed is itself an unlocked file; if
                 - it's hard linked to the old key, that link must be broken. -}
@@ -128,6 +121,17 @@ linkKey file oldkey newkey = ifM (isJust <$> isAnnexLink file)
                                        LinkAnnexNoop -> True
        )
 
+ {- If the object file is already hardlinked to elsewhere, a hard
+ - link won't be made by getViaTmpFromDisk, but a copy instead.
+ - This avoids hard linking to content linked to an
+ - unlocked file, which would leave the new key unlocked
+ - and vulnerable to corruption. -}
+linkKey' :: Key -> Key -> Annex Bool
+linkKey' oldkey newkey =
+       getViaTmpFromDisk RetrievalAllKeysSecure DefaultVerify newkey (AssociatedFile Nothing) $ \tmp -> unVerified $ do
+               oldobj <- calcRepo (gitAnnexLocation oldkey)
+               isJust <$> linkOrCopy' (return True) newkey oldobj tmp Nothing
+
 cleanup :: RawFilePath -> Key -> (MigrationRecord -> Annex ()) -> CommandCleanup
 cleanup file newkey a = do
        newkeyrec <- ifM (isJust <$> isAnnexLink file)