2011-01-08 19:54:14 +00:00
|
|
|
{- git-annex command
|
|
|
|
-
|
2015-01-21 16:50:09 +00:00
|
|
|
- Copyright 2011 Joey Hess <id@joeyh.name>
|
2011-01-08 19:54:14 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2011-01-08 19:54:14 +00:00
|
|
|
-}
|
|
|
|
|
|
|
|
module Command.Migrate where
|
|
|
|
|
|
|
|
import Command
|
2012-06-05 23:51:03 +00:00
|
|
|
import Backend
|
2014-07-10 21:06:04 +00:00
|
|
|
import Types.Backend (canUpgradeKey, fastMigrate)
|
2012-06-20 20:07:14 +00:00
|
|
|
import Types.KeySource
|
2011-10-04 04:40:47 +00:00
|
|
|
import Annex.Content
|
2012-02-17 02:36:56 +00:00
|
|
|
import qualified Command.ReKey
|
2012-09-14 04:18:18 +00:00
|
|
|
import qualified Command.Fsck
|
2015-03-23 16:11:16 +00:00
|
|
|
import qualified Annex
|
2016-01-07 18:21:12 +00:00
|
|
|
import Logs.MetaData
|
2016-01-07 22:06:20 +00:00
|
|
|
import Logs.Web
|
2019-06-25 15:37:52 +00:00
|
|
|
import Utility.Metered
|
2011-01-08 19:54:14 +00:00
|
|
|
|
2015-07-08 16:33:27 +00:00
|
|
|
cmd :: Command
|
2022-06-29 17:28:08 +00:00
|
|
|
cmd = withAnnexOptions [backendOption, annexedMatchingOptions] $
|
2015-07-08 19:08:02 +00:00
|
|
|
command "migrate" SectionUtility
|
|
|
|
"switch data to different backend"
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
paramPaths (seek <$$> optParser)
|
2011-01-08 19:54:14 +00:00
|
|
|
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
data MigrateOptions = MigrateOptions
|
|
|
|
{ migrateThese :: CmdParams
|
|
|
|
, removeSize :: Bool
|
|
|
|
}
|
|
|
|
|
|
|
|
optParser :: CmdParamsDesc -> Parser MigrateOptions
|
|
|
|
optParser desc = MigrateOptions
|
|
|
|
<$> cmdParams desc
|
|
|
|
<*> switch
|
|
|
|
( long "remove-size"
|
|
|
|
<> help "remove size field from keys"
|
|
|
|
)
|
|
|
|
|
|
|
|
seek :: MigrateOptions -> CommandSeek
|
|
|
|
seek o = withFilesInGitAnnex ww seeker =<< workTreeItems ww (migrateThese o)
|
2020-05-28 19:55:17 +00:00
|
|
|
where
|
2023-04-25 23:26:20 +00:00
|
|
|
ww = WarnUnmatchLsFiles "migrate"
|
2020-07-13 21:04:02 +00:00
|
|
|
seeker = AnnexedFileSeeker
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
{ startAction = start o
|
2020-07-13 21:04:02 +00:00
|
|
|
, checkContentPresent = Nothing
|
|
|
|
, usesLocationLog = False
|
|
|
|
}
|
2011-01-08 19:54:14 +00:00
|
|
|
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
start :: MigrateOptions -> SeekInput -> RawFilePath -> Key -> CommandStart
|
|
|
|
start o si file key = do
|
2022-06-28 19:28:14 +00:00
|
|
|
forced <- Annex.getRead Annex.force
|
2019-12-05 18:36:43 +00:00
|
|
|
v <- Backend.getBackend (fromRawFilePath file) key
|
2014-04-17 22:03:39 +00:00
|
|
|
case v of
|
|
|
|
Nothing -> stop
|
|
|
|
Just oldbackend -> do
|
|
|
|
exists <- inAnnex key
|
2023-03-27 19:10:46 +00:00
|
|
|
newbackend <- chooseBackend file
|
2015-03-23 16:11:16 +00:00
|
|
|
if (newbackend /= oldbackend || upgradableKey oldbackend key || forced) && exists
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
then go False oldbackend newbackend
|
|
|
|
else if removeSize o && exists
|
|
|
|
then go True oldbackend oldbackend
|
|
|
|
else stop
|
|
|
|
where
|
|
|
|
go onlyremovesize oldbackend newbackend =
|
|
|
|
starting "migrate" (mkActionItem (key, file)) si $
|
|
|
|
perform onlyremovesize o file key oldbackend newbackend
|
2011-01-08 19:54:14 +00:00
|
|
|
|
2012-12-20 19:43:14 +00:00
|
|
|
{- Checks if a key is upgradable to a newer representation.
|
|
|
|
-
|
|
|
|
- Reasons for migration:
|
|
|
|
- - Ideally, all keys have file size metadata. Old keys may not.
|
|
|
|
- - Something has changed in the backend, such as a bug fix.
|
|
|
|
-}
|
|
|
|
upgradableKey :: Backend -> Key -> Bool
|
2019-11-22 20:24:04 +00:00
|
|
|
upgradableKey backend key = isNothing (fromKey keySize key) || backendupgradable
|
2012-12-20 19:43:14 +00:00
|
|
|
where
|
2014-07-10 21:06:04 +00:00
|
|
|
backendupgradable = maybe False (\a -> a key) (canUpgradeKey backend)
|
2011-07-05 22:31:46 +00:00
|
|
|
|
2011-11-19 19:16:38 +00:00
|
|
|
{- Store the old backend's key in the new backend
|
|
|
|
- The old backend's key is not dropped from it, because there may
|
2013-05-13 18:27:39 +00:00
|
|
|
- be other files still pointing at that key.
|
|
|
|
-
|
|
|
|
- To ensure that the data we have for the old key is valid, it's
|
|
|
|
- fscked here. First we generate the new key. This ensures that the
|
|
|
|
- data cannot get corrupted after the fsck but before the new key is
|
|
|
|
- generated.
|
|
|
|
-}
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
perform :: Bool -> MigrateOptions -> RawFilePath -> Key -> Backend -> Backend -> CommandPerform
|
|
|
|
perform onlyremovesize o file oldkey oldbackend newbackend = go =<< genkey (fastMigrate oldbackend)
|
2012-11-12 05:05:04 +00:00
|
|
|
where
|
2014-10-09 18:53:13 +00:00
|
|
|
go Nothing = stop
|
2014-07-10 21:06:04 +00:00
|
|
|
go (Just (newkey, knowngoodcontent))
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
| knowngoodcontent = finish (removesize newkey)
|
|
|
|
| otherwise = stopUnless checkcontent $
|
|
|
|
finish (removesize newkey)
|
2022-01-13 17:24:50 +00:00
|
|
|
checkcontent = Command.Fsck.checkBackend oldbackend oldkey KeyPresent afile
|
2016-01-07 18:51:28 +00:00
|
|
|
finish newkey = ifM (Command.ReKey.linkKey file oldkey newkey)
|
|
|
|
( do
|
2017-10-16 16:54:00 +00:00
|
|
|
_ <- copyMetaData oldkey newkey
|
2016-01-07 22:06:20 +00:00
|
|
|
-- If the old key had some associated urls, record them for
|
|
|
|
-- the new key as well.
|
|
|
|
urls <- getUrls oldkey
|
2018-10-04 21:33:25 +00:00
|
|
|
forM_ urls $ \url ->
|
|
|
|
setUrlPresent newkey url
|
include locked files in the keys database associated files
Before only unlocked files were included.
The initial scan now scans for locked as well as unlocked files. This
does mean it gets a little bit slower, although I optimised it as well
as I think it can be.
reconcileStaged changed to diff from the current index to the tree of
the previous index. This lets it handle deletions as well, removing
associated files for both locked and unlocked files, which did not
always happen before.
On upgrade, there will be no recorded previous tree, so it will diff
from the empty tree to current index, and so will fully populate the
associated files, as well as removing any stale associated files
that were present due to them not being removed before.
reconcileStaged now does a bit more work. Most of the time, this will
just be due to running more often, after some change is made to the
index, and since there will be few changes since the last time, it will
not be a noticable overhead. What may turn out to be a noticable
slowdown is after changing to a branch, it has to go through the diff
from the previous index to the new one, and if there are lots of
changes, that could take a long time. Also, after adding a lot of files,
or deleting a lot of files, or moving a large subdirectory, etc.
Command.Lock used removeAssociatedFile, but now that's wrong because a
newly locked file still needs to have its associated file tracked.
Command.Rekey used removeAssociatedFile when the file was unlocked.
It could remove it also when it's locked, but it is not really
necessary, because it changes the index, and so the next time git-annex
run and accesses the keys db, reconcileStaged will run and update it.
There are probably several other places that use addAssociatedFile and
don't need to any more for similar reasons. But there's no harm in
keeping them, and it probably is a good idea to, if only to support
mixing this with older versions of git-annex.
However, mixing this and older versions does risk reconcileStaged not
running, if the older version already ran it on a given index state. So
it's not a good idea to mix versions. This problem could be dealt with
by changing the name of the gitAnnexKeysDbIndexCache, but that would
leave the old file dangling, or it would need to keep trying to remove
it.
2021-05-21 19:47:37 +00:00
|
|
|
next $ Command.ReKey.cleanup file newkey
|
2018-10-16 19:52:40 +00:00
|
|
|
, giveup "failed creating link from old to new key"
|
2016-01-07 18:51:28 +00:00
|
|
|
)
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
genkey _ | onlyremovesize = return $ Just (oldkey, False)
|
2018-10-29 20:26:43 +00:00
|
|
|
genkey Nothing = do
|
|
|
|
content <- calcRepo $ gitAnnexLocation oldkey
|
|
|
|
let source = KeySource
|
2020-02-21 13:34:59 +00:00
|
|
|
{ keyFilename = file
|
|
|
|
, contentLocation = content
|
2018-10-29 20:26:43 +00:00
|
|
|
, inodeCache = Nothing
|
|
|
|
}
|
2023-03-27 19:10:46 +00:00
|
|
|
newkey <- fst <$> genKey source nullMeterUpdate newbackend
|
2020-05-15 16:51:09 +00:00
|
|
|
return $ Just (newkey, False)
|
2018-09-24 16:07:46 +00:00
|
|
|
genkey (Just fm) = fm oldkey newbackend afile >>= \case
|
2018-10-29 20:26:43 +00:00
|
|
|
Just newkey -> return (Just (newkey, True))
|
|
|
|
Nothing -> genkey Nothing
|
migrate: New --remove-size option
While intended for converting URL keys added by addurl --fast to be
as if added by addurl --relaxed, it can also be used to remove size
from other types of keys. Although that is not likely to be useful
for checksummed keys, I suppose it could be used for WORM or other
non-checksum keys.
Specifying the --remove-size option does not prevent other migrations
from taking effect if there's a key upgrade to perform, or if the
backend has changed. So --backend=URL needs to be used to prevent
migrating an URL key to the default backend.
Note that it's not possible to use git-annex migrate to convert from a
non-URL key to an URL key, as URL keys cannot be generated, except by
addurl. So while this can get the same effect as --relaxed would have
when addurl --fast was used, when --fast was not used, it won't work, or
if --backend=URL is not used will remove the size but not prevent
checksum verification, which is not useful. Due to this complexity, I
decided not to mention it in the git-annex addurl man page.
Sponsored-by: Jochen Bartl on Patreon
2021-11-12 16:59:30 +00:00
|
|
|
removesize k
|
|
|
|
| removeSize o = alterKey k $ \kd -> kd { keySize = Nothing }
|
|
|
|
| otherwise = k
|
2017-03-10 17:12:24 +00:00
|
|
|
afile = AssociatedFile (Just file)
|