automatically derive an annex-uuid from a gcrypt-uuids
This commit is contained in:
parent
76d5611da8
commit
a48a4e2f8a
4 changed files with 90 additions and 0 deletions
|
@ -17,8 +17,11 @@ module Annex.UUID (
|
|||
getUncachedUUID,
|
||||
prepUUID,
|
||||
genUUID,
|
||||
genUUIDInNameSpace,
|
||||
gCryptNameSpace,
|
||||
removeRepoUUID,
|
||||
storeUUID,
|
||||
setUUID,
|
||||
) where
|
||||
|
||||
import Common.Annex
|
||||
|
@ -27,7 +30,9 @@ import qualified Git.Config
|
|||
import Config
|
||||
|
||||
import qualified Data.UUID as U
|
||||
import qualified Data.UUID.V5 as U5
|
||||
import System.Random
|
||||
import Data.Bits.Utils
|
||||
|
||||
configkey :: ConfigKey
|
||||
configkey = annexConfig "uuid"
|
||||
|
@ -36,6 +41,17 @@ configkey = annexConfig "uuid"
|
|||
genUUID :: IO UUID
|
||||
genUUID = UUID . show <$> (randomIO :: IO U.UUID)
|
||||
|
||||
{- Generates a UUID from a given string, using a namespace.
|
||||
- Given the same namespace, the same string will always result
|
||||
- in the same UUID. -}
|
||||
genUUIDInNameSpace :: U.UUID -> String -> UUID
|
||||
genUUIDInNameSpace namespace = UUID . show . U5.generateNamed namespace . s2w8
|
||||
|
||||
{- Namespace used for UUIDs derived from git-remote-gcrypt ids. -}
|
||||
gCryptNameSpace :: U.UUID
|
||||
gCryptNameSpace = U5.generateNamed U5.namespaceURL $
|
||||
s2w8 "http://git-annex.branchable.com/design/gcrypt/"
|
||||
|
||||
{- Get current repository's UUID. -}
|
||||
getUUID :: Annex UUID
|
||||
getUUID = getRepoUUID =<< gitRepo
|
||||
|
@ -72,3 +88,9 @@ prepUUID = whenM ((==) NoUUID <$> getUUID) $
|
|||
|
||||
storeUUID :: ConfigKey -> UUID -> Annex ()
|
||||
storeUUID configfield = setConfig configfield . fromUUID
|
||||
|
||||
{- Only sets the configkey in the Repo; does not change .git/config -}
|
||||
setUUID :: Git.Repo -> UUID -> IO Git.Repo
|
||||
setUUID r u = do
|
||||
let s = show configkey ++ "=" ++ fromUUID u
|
||||
Git.Config.store s r
|
||||
|
|
53
Git/GCrypt.hs
Normal file
53
Git/GCrypt.hs
Normal file
|
@ -0,0 +1,53 @@
|
|||
{- git-remote-gcrypt support
|
||||
-
|
||||
- https://github.com/blake2-ppc/git-remote-gcrypt
|
||||
-
|
||||
- Copyright 2013 Joey Hess <joey@kitenet.net>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
||||
module Git.GCrypt where
|
||||
|
||||
import Common
|
||||
import Git.Types
|
||||
import Git.Construct
|
||||
import Git.Config
|
||||
|
||||
urlPrefix :: String
|
||||
urlPrefix = "gcrypt::"
|
||||
|
||||
isEncrypted :: Repo -> Bool
|
||||
isEncrypted Repo { location = Url url } = urlPrefix `isPrefixOf` show url
|
||||
isEncrypted _ = False
|
||||
|
||||
{- The first Repo is the git repository that has the second Repo
|
||||
- as one of its remotes.
|
||||
-
|
||||
- When the remote Repo uses gcrypt, returns the actual underlying
|
||||
- git repository that gcrypt is using to store its data.
|
||||
-
|
||||
- Throws an exception if an url is invalid or the repo does not use
|
||||
- gcrypt.
|
||||
-}
|
||||
encryptedRepo :: Repo -> Repo -> IO Repo
|
||||
encryptedRepo baserepo = go
|
||||
where
|
||||
go Repo { location = Url url }
|
||||
| urlPrefix `isPrefixOf` u =
|
||||
fromRemoteLocation (drop plen u) baserepo
|
||||
| otherwise = notencrypted
|
||||
where
|
||||
u = show url
|
||||
plen = length urlPrefix
|
||||
go _ = notencrypted
|
||||
notencrypted = error "not a gcrypt encrypted repository"
|
||||
|
||||
{- gcrypt gives each encrypted repository a uique gcrypt-id,
|
||||
- which is stored in the repository (in encrypted form)
|
||||
- and cached in a per-remote gcrypt-id configuration setting. -}
|
||||
remoteRepoId :: Repo -> Repo -> Maybe String
|
||||
remoteRepoId baserepo remote = do
|
||||
name <- remoteName remote
|
||||
let key = "remote." ++ name ++ ".gcrypt-id"
|
||||
getMaybe key baserepo
|
|
@ -26,6 +26,7 @@ import qualified Git
|
|||
import qualified Git.Config
|
||||
import qualified Git.Construct
|
||||
import qualified Git.Command
|
||||
import qualified Git.GCrypt
|
||||
import qualified Annex
|
||||
import Logs.Presence
|
||||
import Logs.Transfer
|
||||
|
@ -152,6 +153,12 @@ tryGitConfigRead r
|
|||
| Git.repoIsHttp r = do
|
||||
headers <- getHttpHeaders
|
||||
store $ geturlconfig headers
|
||||
| Git.GCrypt.isEncrypted r = do
|
||||
g <- gitRepo
|
||||
case Git.GCrypt.remoteRepoId g r of
|
||||
Nothing -> return r
|
||||
Just v -> store $ liftIO $ setUUID r $
|
||||
genUUIDInNameSpace gCryptNameSpace v
|
||||
| Git.repoIsUrl r = return r
|
||||
| otherwise = store $ safely $ onLocal r $ do
|
||||
ensureInitialized
|
||||
|
|
8
doc/design/gcrypt.mdwn
Normal file
8
doc/design/gcrypt.mdwn
Normal file
|
@ -0,0 +1,8 @@
|
|||
To integrate with git-remote-gcrypt, a key thing is to have a way to map
|
||||
from the gcrypt-id of an encrypted repository to a git-annex repository
|
||||
uuid.
|
||||
|
||||
To do this, we'll make a v5 UUID, feeding in the gcrypt-id.
|
||||
The namespace used is itself a v5 UUID, generated using the URL
|
||||
namespace and the URL of this page at the time this scheme was
|
||||
developed: "http://git-annex.branchable.com/design/gcrypt/"
|
Loading…
Reference in a new issue