import Types.TransferrerPool
import Types.VectorClock
import Types.Cluster
+import Types.MaxSize
import Annex.VectorClock.Utility
import Annex.Debug.Utility
import qualified Database.Keys.Handle as Keys
, requiredcontentmap :: Maybe (FileMatcherMap Annex)
, remoteconfigmap :: Maybe (M.Map UUID RemoteConfig)
, clusters :: Maybe (Annex Clusters)
+ , maxsizes :: Maybe (M.Map UUID MaxSize)
, forcetrust :: TrustMap
, trustmap :: Maybe TrustMap
, groupmap :: Maybe GroupMap
, requiredcontentmap = Nothing
, remoteconfigmap = Nothing
, clusters = Nothing
+ , maxsizes = Nothing
, forcetrust = M.empty
, trustmap = Nothing
, groupmap = Nothing
own purposes.
* Support "balanced=" and "fullybalanced=" in preferred content expressions.
* Added --rebalance option.
+ * maxsize: New command to tell git-annex how large the expected maximum
+ size of a repository is.
+ * vicfg: Include maxsize configuration.
-- Joey Hess <id@joeyh.name> Wed, 31 Jul 2024 15:52:03 -0400
import qualified Command.UpdateCluster
import qualified Command.ExtendCluster
import qualified Command.UpdateProxy
+import qualified Command.MaxSize
import qualified Command.Version
import qualified Command.RemoteDaemon
#ifdef WITH_ASSISTANT
, Command.UpdateCluster.cmd
, Command.ExtendCluster.cmd
, Command.UpdateProxy.cmd
+ , Command.MaxSize.cmd
, Command.Version.cmd
, Command.RemoteDaemon.cmd
#ifdef WITH_ASSISTANT
{- git-annex command
-
- - Copyright 2012-2022 Joey Hess <id@joeyh.name>
+ - Copyright 2012-2024 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
import Logs.Schedule
import Logs.Config
import Logs.NumCopies
+import Logs.MaxSize
import Types.StandardGroups
import Types.ScheduledActivity
import Types.NumCopies
import Remote
import Git.Types (fromConfigKey, fromConfigValue)
+import Utility.DataUnits
import qualified Utility.RawFilePath as R
cmd :: Command
, cfgGlobalConfigs :: M.Map ConfigKey ConfigValue
, cfgNumCopies :: Maybe NumCopies
, cfgMinCopies :: Maybe MinCopies
+ , cfgMaxSizeMap :: M.Map UUID (Maybe MaxSize)
}
getCfg :: Annex Cfg
<*> loadGlobalConfig
<*> getGlobalNumCopies
<*> getGlobalMinCopies
+ <*> (M.map Just <$> getMaxSizes)
setCfg :: Cfg -> Cfg -> Annex ()
setCfg curcfg newcfg = do
mapM_ (uncurry setGlobalConfig) $ M.toList $ cfgGlobalConfigs diff
maybe noop setGlobalNumCopies $ cfgNumCopies diff
maybe noop setGlobalMinCopies $ cfgMinCopies diff
+ mapM_ (uncurry setmaxsize) $ M.toList $ cfgMaxSizeMap diff
+ where
+ setmaxsize _u Nothing = noop
+ setmaxsize u (Just sz) = recordMaxSize u sz
{- Default config has all the keys from the input config, but with their
- default values. -}
, cfgGlobalConfigs = mapdef $ cfgGlobalConfigs curcfg
, cfgNumCopies = Nothing
, cfgMinCopies = Nothing
+ , cfgMaxSizeMap = mapdef $ cfgMaxSizeMap curcfg
}
where
mapdef :: forall k v. Default v => M.Map k v -> M.Map k v
, cfgGlobalConfigs = diff cfgGlobalConfigs
, cfgNumCopies = cfgNumCopies newcfg
, cfgMinCopies = cfgMinCopies newcfg
+ , cfgMaxSizeMap = diff cfgMaxSizeMap
}
where
diff f = M.differenceWith (\x y -> if x == y then Nothing else Just x)
, grouppreferredcontent
, standardgroups
, requiredcontent
+ , maxsizes
, schedule
, numcopies
, globalconfigs
, fromGroup (fromStandardGroup g), "=", standardPreferredContent g
]
+ maxsizes = settings cfg descs cfgMaxSizeMap
+ [ com "Maximum repository sizes"
+ ]
+ (\(sz, u) -> line "maxsize" u $ maybe "" (\(MaxSize n) -> preciseSize storageUnits False n) sz)
+ (\u -> line "maxsize" u "")
+
schedule = settings cfg descs cfgScheduleMap
[ com "Scheduled activities"
, com "(Separate multiple activities with \"; \")"
Nothing ->
let m = M.insert (toGroup f) val (cfgGroupPreferredContentMap cfg)
in Right $ cfg { cfgGroupPreferredContentMap = m }
+ | setting == "maxsize" = case readSize dataUnits val of
+ Nothing -> Left "parse error (expected a size such as \"100 gb\")"
+ Just n ->
+ let m = M.insert u (Just (MaxSize n)) (cfgMaxSizeMap cfg)
+ in Right $ cfg { cfgMaxSizeMap = m }
| setting == "schedule" = case parseScheduledActivities val of
Left e -> Left e
Right l ->
[ exportLog
, proxyLog
, clusterLog
+ , maxSizeLog
]
{- Other top-level logs. -}
clusterLog :: RawFilePath
clusterLog = "cluster.log"
+maxSizeLog :: RawFilePath
+maxSizeLog = "maxsize.log"
+
{- This is not a log file, it's where exported treeishes get grafted into
- the git-annex branch. -}
exportTreeGraftPoint :: RawFilePath
--- /dev/null
+{- git-annex maxsize log
+ -
+ - Copyright 2024 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU AGPL version 3 or higher.
+ -}
+
+module Logs.MaxSize (
+ MaxSize(..),
+ getMaxSizes,
+ recordMaxSize,
+) where
+
+import qualified Annex
+import Annex.Common
+import Types.MaxSize
+import Logs
+import Logs.UUIDBased
+import Logs.MapLog
+import qualified Annex.Branch
+
+import qualified Data.Map as M
+import Data.ByteString.Builder
+import qualified Data.Attoparsec.ByteString as A
+
+getMaxSizes :: Annex (M.Map UUID MaxSize)
+getMaxSizes = maybe loadMaxSizes return =<< Annex.getState Annex.maxsizes
+
+loadMaxSizes :: Annex (M.Map UUID MaxSize)
+loadMaxSizes = do
+ maxsizes <- M.map value . fromMapLog . parseLogNew parseMaxSize
+ <$> Annex.Branch.get maxSizeLog
+ Annex.changeState $ \s -> s { Annex.maxsizes = Just maxsizes }
+ return maxsizes
+
+recordMaxSize :: UUID -> MaxSize -> Annex ()
+recordMaxSize uuid maxsize = do
+ c <- currentVectorClock
+ Annex.Branch.change (Annex.Branch.RegardingUUID [uuid]) maxSizeLog $
+ (buildLogNew buildMaxSize)
+ . changeLog c uuid maxsize
+ . parseLogNew parseMaxSize
+
+buildMaxSize :: MaxSize -> Builder
+buildMaxSize (MaxSize n) = byteString (encodeBS (show n))
+
+parseMaxSize :: A.Parser MaxSize
+parseMaxSize = maybe (fail "maxsize parse failed") (pure . MaxSize)
+ . readish . decodeBS =<< A.takeByteString
--- /dev/null
+{- git-annex maxsize type
+ -
+ - Copyright 2024 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU AGPL version 3 or higher.
+ -}
+
+module Types.MaxSize where
+
+newtype MaxSize = MaxSize Integer
+ deriving (Show, Eq, Ord)
git annex maxsize repository size
-git annex maxsize here --auto
-
git annex maxsize repository
# DESCRIPTION
This configures the maximum combined size of annexed files that can be
-stored in a repository. When run without a size or the --auto option,
+stored in a repository. When run without a size,
it displays the currently configured maxsize.
The repository can be specified by git remote name or
# OPTIONS
-* The [[git-annex-common-options]](1) can be used.
+* `--bytes`
+
+ Displays the maximum size in bytes, disabling the default nicer units.
+
+* The [[git-annex-common-options]](1) can also be used.
# SEE ALSO
See [[git-annex-required]](1) for details.
+* `maxsize repository [size]`
+
+ Get or set maximum size of repository.
+
* `initcluster`
Initializes a new cluster.
space, then the group name followed by a space and then the preferred
content expression.
+## `maxsize.log`
+
+Records the maximum combined size of annexed files that can be stored in
+a repository.
+
+The file format is a timestamp, followed by the UUID of a repository,
+followed by the size in bytes. For example:
+
+ 1317929189.157237s e605dca6-446a-11e0-8b2a-002170d25c55 100000000000
+
## `export.log`
Tracks what trees have been exported to special remotes by
Also note that "fullybalanced=foo:2" is not currently actually
implemented!
-* Add `git-annex maxsize` command.
+* `git-annex info` can use maxsize to display how full repositories are
* balanced= and fullybalanced= need to limit the set of repositories to
ones with enough free space to contain a key.
Command.LookupKey
Command.Map
Command.MatchExpression
+ Command.MaxSize
Command.Merge
Command.MetaData
Command.Migrate
Logs.Line
Logs.Location
Logs.MapLog
+ Logs.MaxSize
Logs.MetaData
Logs.MetaData.Pure
Logs.Migrate
Types.KeySource
Types.Link
Types.LockCache
+ Types.MaxSize
Types.Messages
Types.MetaData
Types.Mime