automatically derive an annex-uuid from a gcrypt-uuids

This commit is contained in:
Joey Hess 2013-09-05 16:02:39 -04:00
parent 76d5611da8
commit a48a4e2f8a
4 changed files with 90 additions and 0 deletions

View file

@ -17,8 +17,11 @@ module Annex.UUID (
getUncachedUUID, getUncachedUUID,
prepUUID, prepUUID,
genUUID, genUUID,
genUUIDInNameSpace,
gCryptNameSpace,
removeRepoUUID, removeRepoUUID,
storeUUID, storeUUID,
setUUID,
) where ) where
import Common.Annex import Common.Annex
@ -27,7 +30,9 @@ import qualified Git.Config
import Config import Config
import qualified Data.UUID as U import qualified Data.UUID as U
import qualified Data.UUID.V5 as U5
import System.Random import System.Random
import Data.Bits.Utils
configkey :: ConfigKey configkey :: ConfigKey
configkey = annexConfig "uuid" configkey = annexConfig "uuid"
@ -36,6 +41,17 @@ configkey = annexConfig "uuid"
genUUID :: IO UUID genUUID :: IO UUID
genUUID = UUID . show <$> (randomIO :: IO U.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. -} {- Get current repository's UUID. -}
getUUID :: Annex UUID getUUID :: Annex UUID
getUUID = getRepoUUID =<< gitRepo getUUID = getRepoUUID =<< gitRepo
@ -72,3 +88,9 @@ prepUUID = whenM ((==) NoUUID <$> getUUID) $
storeUUID :: ConfigKey -> UUID -> Annex () storeUUID :: ConfigKey -> UUID -> Annex ()
storeUUID configfield = setConfig configfield . fromUUID 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
View 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

View file

@ -26,6 +26,7 @@ import qualified Git
import qualified Git.Config import qualified Git.Config
import qualified Git.Construct import qualified Git.Construct
import qualified Git.Command import qualified Git.Command
import qualified Git.GCrypt
import qualified Annex import qualified Annex
import Logs.Presence import Logs.Presence
import Logs.Transfer import Logs.Transfer
@ -152,6 +153,12 @@ tryGitConfigRead r
| Git.repoIsHttp r = do | Git.repoIsHttp r = do
headers <- getHttpHeaders headers <- getHttpHeaders
store $ geturlconfig headers 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 | Git.repoIsUrl r = return r
| otherwise = store $ safely $ onLocal r $ do | otherwise = store $ safely $ onLocal r $ do
ensureInitialized ensureInitialized

8
doc/design/gcrypt.mdwn Normal file
View 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/"