summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-06-01 17:49:37 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-06-01 17:57:31 -0400
commita8fb97d2ce8e75b36b8e1572a83efd341e67d43e (patch)
treeab24a8af581281ff8b006309acfb4000317ad072
parent7a3d9d8c2e2bd53d0d4290e99186c6e37f18456d (diff)
Add --trust, --untrust, and --semitrust options.
-rw-r--r--Annex.hs3
-rw-r--r--Backend/File.hs5
-rw-r--r--Command/Move.hs5
-rw-r--r--GitAnnex.hs14
-rw-r--r--Remote.hs28
-rw-r--r--RemoteUtils.hs42
-rw-r--r--Trust.hs30
-rw-r--r--TrustLevel.hs23
-rw-r--r--debian/changelog1
-rw-r--r--doc/forum/new_microfeatures.mdwn5
-rw-r--r--doc/git-annex.mdwn8
-rw-r--r--doc/trust.mdwn11
12 files changed, 117 insertions, 58 deletions
diff --git a/Annex.hs b/Annex.hs
index c5a098d98..13505de46 100644
--- a/Annex.hs
+++ b/Annex.hs
@@ -24,6 +24,7 @@ import qualified GitQueue
import qualified BackendClass
import qualified RemoteClass
import qualified CryptoTypes
+import TrustLevel
-- git-annex's monad
type Annex = StateT AnnexState IO
@@ -44,6 +45,7 @@ data AnnexState = AnnexState
, toremote :: Maybe String
, fromremote :: Maybe String
, exclude :: [String]
+ , forcetrust :: [(String, TrustLevel)]
, cipher :: Maybe CryptoTypes.Cipher
}
@@ -63,6 +65,7 @@ newState gitrepo allbackends = AnnexState
, toremote = Nothing
, fromremote = Nothing
, exclude = []
+ , forcetrust = []
, cipher = Nothing
}
diff --git a/Backend/File.hs b/Backend/File.hs
index 543f02af7..58506c861 100644
--- a/Backend/File.hs
+++ b/Backend/File.hs
@@ -21,6 +21,7 @@ import Data.String.Utils
import BackendClass
import LocationLog
import qualified Remote
+import qualified RemoteUtils
import qualified GitRepo as Git
import Content
import qualified Annex
@@ -53,7 +54,7 @@ dummyStore _ _ = return True
- and copy it to here. -}
copyKeyFile :: Key -> FilePath -> Annex Bool
copyKeyFile key file = do
- (remotes, _) <- Remote.keyPossibilities key
+ (remotes, _) <- RemoteUtils.keyPossibilities key
if null remotes
then do
showNote "not available"
@@ -96,7 +97,7 @@ checkRemoveKey key numcopiesM = do
if force || numcopiesM == Just 0
then return True
else do
- (remotes, trusteduuids) <- Remote.keyPossibilities key
+ (remotes, trusteduuids) <- RemoteUtils.keyPossibilities key
untrusteduuids <- trustGet UnTrusted
let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids++untrusteduuids)
numcopies <- getNumCopies numcopiesM
diff --git a/Command/Move.hs b/Command/Move.hs
index f49fe20e0..6a23aee92 100644
--- a/Command/Move.hs
+++ b/Command/Move.hs
@@ -16,6 +16,7 @@ import LocationLog
import Types
import Content
import qualified Remote
+import qualified RemoteUtils
import UUID
import Messages
@@ -89,7 +90,7 @@ toPerform dest move key = do
let fastcheck = fast && not move && not (Remote.hasKeyCheap dest)
isthere <- if fastcheck
then do
- (remotes, _) <- Remote.keyPossibilities key
+ (remotes, _) <- RemoteUtils.keyPossibilities key
return $ Right $ dest `elem` remotes
else Remote.hasKey dest key
case isthere of
@@ -123,7 +124,7 @@ fromStart :: Remote.Remote Annex -> Bool -> CommandStartString
fromStart src move file = isAnnexed file $ \(key, _) -> do
g <- Annex.gitRepo
u <- getUUID g
- (remotes, _) <- Remote.keyPossibilities key
+ (remotes, _) <- RemoteUtils.keyPossibilities key
if (u == Remote.uuid src) || (null $ filter (== src) remotes)
then stop
else do
diff --git a/GitAnnex.hs b/GitAnnex.hs
index 37a73424a..64b0888b0 100644
--- a/GitAnnex.hs
+++ b/GitAnnex.hs
@@ -14,6 +14,7 @@ import CmdLine
import Command
import Options
import Utility
+import TrustLevel
import qualified Annex
import qualified Command.Add
@@ -83,7 +84,9 @@ cmds = concat
options :: [Option]
options = commonOptions ++
- [ Option ['t'] ["to"] (ReqArg setto paramRemote)
+ [ Option ['k'] ["key"] (ReqArg setkey paramKey)
+ "specify a key to use"
+ , Option ['t'] ["to"] (ReqArg setto paramRemote)
"specify to where to transfer content"
, Option ['f'] ["from"] (ReqArg setfrom paramRemote)
"specify from where to transfer content"
@@ -91,8 +94,12 @@ options = commonOptions ++
"skip files matching the glob pattern"
, Option ['N'] ["numcopies"] (ReqArg setnumcopies paramNumber)
"override default number of copies"
- , Option ['k'] ["key"] (ReqArg setkey paramKey)
- "specify a key to use"
+ , Option [] ["trust"] (ReqArg (settrust Trusted) paramRemote)
+ "override trust setting"
+ , Option [] ["semitrust"] (ReqArg (settrust SemiTrusted) paramRemote)
+ "override trust setting back to default value"
+ , Option [] ["untrust"] (ReqArg (settrust UnTrusted) paramRemote)
+ "override trust setting to untrusted"
]
where
setto v = Annex.changeState $ \s -> s { Annex.toremote = Just v }
@@ -100,6 +107,7 @@ options = commonOptions ++
addexclude v = Annex.changeState $ \s -> s { Annex.exclude = v:(Annex.exclude s) }
setnumcopies v = Annex.changeState $ \s -> s {Annex.forcenumcopies = readMaybe v }
setkey v = Annex.changeState $ \s -> s { Annex.defaultkey = Just v }
+ settrust t v = Annex.changeState $ \s -> s { Annex.forcetrust = (v, t):(Annex.forcetrust s) }
header :: String
header = "Usage: git-annex command [option ..]"
diff --git a/Remote.hs b/Remote.hs
index 7df84a5da..51da5e471 100644
--- a/Remote.hs
+++ b/Remote.hs
@@ -16,9 +16,9 @@ module Remote (
hasKeyCheap,
remoteTypes,
+ genList,
byName,
nameToUUID,
- keyPossibilities,
remotesWithUUID,
remotesWithoutUUID,
@@ -42,8 +42,6 @@ import RemoteClass
import Types
import UUID
import qualified Annex
-import Trust
-import LocationLog
import Locations
import Utility
import Config
@@ -104,30 +102,6 @@ nameToUUID :: String -> Annex UUID
nameToUUID "." = getUUID =<< Annex.gitRepo -- special case for current repo
nameToUUID n = liftM uuid (byName n)
-{- Cost ordered lists of remotes that the LocationLog indicate may have a key.
- -
- - Also returns a list of UUIDs that are trusted to have the key
- - (some may not have configured remotes).
- -}
-keyPossibilities :: Key -> Annex ([Remote Annex], [UUID])
-keyPossibilities key = do
- g <- Annex.gitRepo
- u <- getUUID g
- trusted <- trustGet Trusted
-
- -- get uuids of all remotes that are recorded to have the key
- uuids <- liftIO $ keyLocations g key
- let validuuids = filter (/= u) uuids
-
- -- note that validuuids is assumed to not have dups
- let validtrusteduuids = intersect validuuids trusted
-
- -- remotes that match uuids that have the key
- allremotes <- genList
- let validremotes = remotesWithUUID allremotes validuuids
-
- return (sort validremotes, validtrusteduuids)
-
{- Filters a list of remotes to ones that have the listed uuids. -}
remotesWithUUID :: [Remote Annex] -> [UUID] -> [Remote Annex]
remotesWithUUID rs us = filter (\r -> uuid r `elem` us) rs
diff --git a/RemoteUtils.hs b/RemoteUtils.hs
new file mode 100644
index 000000000..d042780e4
--- /dev/null
+++ b/RemoteUtils.hs
@@ -0,0 +1,42 @@
+{- git-annex remotes overflow (can't go in there due to dependency cycles)
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module RemoteUtils where
+
+import Control.Monad.State (liftIO)
+import Data.List
+
+import Annex
+import Trust
+import Remote
+import UUID
+import LocationLog
+import Key
+
+{- Cost ordered lists of remotes that the LocationLog indicate may have a key.
+ -
+ - Also returns a list of UUIDs that are trusted to have the key
+ - (some may not have configured remotes).
+ -}
+keyPossibilities :: Key -> Annex ([Remote Annex], [UUID])
+keyPossibilities key = do
+ g <- Annex.gitRepo
+ u <- getUUID g
+ trusted <- trustGet Trusted
+
+ -- get uuids of all remotes that are recorded to have the key
+ uuids <- liftIO $ keyLocations g key
+ let validuuids = filter (/= u) uuids
+
+ -- note that validuuids is assumed to not have dups
+ let validtrusteduuids = intersect validuuids trusted
+
+ -- remotes that match uuids that have the key
+ allremotes <- genList
+ let validremotes = remotesWithUUID allremotes validuuids
+
+ return (sort validremotes, validtrusteduuids)
diff --git a/Trust.hs b/Trust.hs
index 7b2cf9ff8..d6d0516ab 100644
--- a/Trust.hs
+++ b/Trust.hs
@@ -1,4 +1,4 @@
-{- git-annex trust levels
+{- git-annex trust
-
- Copyright 2010 Joey Hess <joey@kitenet.net>
-
@@ -17,26 +17,15 @@ module Trust (
import Control.Monad.State
import qualified Data.Map as M
+import TrustLevel
import qualified GitRepo as Git
import Types
import UUID
import Locations
import qualified Annex
+import qualified Remote
import Utility
-data TrustLevel = SemiTrusted | UnTrusted | Trusted
- deriving Eq
-
-instance Show TrustLevel where
- show SemiTrusted = "?"
- show UnTrusted = "0"
- show Trusted = "1"
-
-instance Read TrustLevel where
- readsPrec _ "1" = [(Trusted, "")]
- readsPrec _ "0" = [(UnTrusted, "")]
- readsPrec _ _ = [(SemiTrusted, "")]
-
{- Filename of trust.log. -}
trustLog :: Annex FilePath
trustLog = do
@@ -49,18 +38,23 @@ trustGet level = do
m <- trustMap
return $ M.keys $ M.filter (== level) m
-{- Read the trustLog into a map. -}
+{- Read the trustLog into a map, overriding with any
+ - values from forcetrust -}
trustMap :: Annex (M.Map UUID TrustLevel)
trustMap = do
logfile <- trustLog
+ overrides <- Annex.getState Annex.forcetrust >>= mapM findoverride
s <- liftIO $ catch (readFile logfile) ignoreerror
- return $ trustMapParse s
+ return $ M.fromList $ trustMapParse s ++ overrides
where
ignoreerror _ = return ""
+ findoverride (name, t) = do
+ uuid <- Remote.nameToUUID name
+ return (uuid, t)
{- Trust map parser. -}
-trustMapParse :: String -> M.Map UUID TrustLevel
-trustMapParse s = M.fromList $ map pair $ filter (not . null) $ lines s
+trustMapParse :: String -> [(UUID, TrustLevel)]
+trustMapParse s = map pair $ filter (not . null) $ lines s
where
pair l
| length w > 1 = (w !! 0, read (w !! 1) :: TrustLevel)
diff --git a/TrustLevel.hs b/TrustLevel.hs
new file mode 100644
index 000000000..5da142ca3
--- /dev/null
+++ b/TrustLevel.hs
@@ -0,0 +1,23 @@
+{- git-annex trust levels
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module TrustLevel (
+ TrustLevel(..),
+) where
+
+data TrustLevel = SemiTrusted | UnTrusted | Trusted
+ deriving Eq
+
+instance Show TrustLevel where
+ show SemiTrusted = "?"
+ show UnTrusted = "0"
+ show Trusted = "1"
+
+instance Read TrustLevel where
+ readsPrec _ "1" = [(Trusted, "")]
+ readsPrec _ "0" = [(UnTrusted, "")]
+ readsPrec _ _ = [(SemiTrusted, "")]
diff --git a/debian/changelog b/debian/changelog
index 0d531a320..8cb256099 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
git-annex (0.20110602) UNRELEASED; urgency=low
* Add --numcopies option.
+ * Add --trust, --untrust, and --semitrust options.
-- Joey Hess <joeyh@debian.org> Wed, 01 Jun 2011 16:26:48 -0400
diff --git a/doc/forum/new_microfeatures.mdwn b/doc/forum/new_microfeatures.mdwn
index 9b1f8231c..e992bfb4f 100644
--- a/doc/forum/new_microfeatures.mdwn
+++ b/doc/forum/new_microfeatures.mdwn
@@ -5,13 +5,14 @@ Here are a few I've been considering:
---
* --numcopies would be a useful command line switch.
- > Update: Added. Also allows for things like `git annex drop
- > --numcopies=2` when in a repo that normally needs 3 copies, if you need
+ > Update: Added. Also allows for things like `git annex drop --numcopies=2` when in a repo that normally needs 3 copies, if you need
> to urgently free up space.
* A way to make `drop` and other commands temporarily trust a given remote, or possibly all remotes.
Combined, this would allow `git annex drop --numcopies=2 --trust=repoa --trust=repob` to remove files that have been replicated out to the other 2 repositories, which could be offline. (Slightly unsafe, but in this case the files are podcasts so not really.)
+> Update: done --[[Joey]]
+
---
[[wishlist:_git-annex_replicate]] suggests some way for git-annex to have the smarts to copy content around on its own to ensure numcopies is satisfied. I'd be satisfied with a `git annex copy --to foo --if-needed-by-numcopies`
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index e4924d373..b15ce1a29 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -359,6 +359,14 @@ Many git-annex commands will stage changes for later `git commit` by you.
Overrides the `annex.numcopies` setting, forcing git-annex to ensure the
specified number of copies exist.
+* --trust=repository
+* --semitrust=repository
+* --untrust=repository
+
+ Overrides trust settings for a repository. May be specified more than once.
+
+ The repository should be specified using the name of a configured remote.
+
* --backend=name
Specifies which key-value backend to use. This can be used when
diff --git a/doc/trust.mdwn b/doc/trust.mdwn
index 317e4b541..7505a7af6 100644
--- a/doc/trust.mdwn
+++ b/doc/trust.mdwn
@@ -20,7 +20,9 @@ depended on to retain a copy of the file content; possibly the only
[[copy|copies]].
(Being semitrusted is the default. The `git annex semitrust` command
-restores a repository to this default, when it has been overridden.)
+restores a repository to this default, when it has been overridden.
+The `--semitrust` option can temporarily restore a repository to this
+default.)
## untrusted
@@ -42,7 +44,8 @@ archival drive, from which you rarely or never remove content. Deciding
when it makes sense to trust the tracking info is up to you.
One way to handle this is just to use `--force` when a command cannot
-access a remote you trust.
+access a remote you trust. Or to use `--trust` to specify a repisitory to
+trust temporarily.
-To configure a repository as fully trusted, use the `git annex trust`
-command.
+To configure a repository as fully and permanently trusted,
+use the `git annex trust` command.