summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/Ccache.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Propellor/Property/Ccache.hs')
-rw-r--r--src/Propellor/Property/Ccache.hs71
1 files changed, 52 insertions, 19 deletions
diff --git a/src/Propellor/Property/Ccache.hs b/src/Propellor/Property/Ccache.hs
index b721e684..692fea0f 100644
--- a/src/Propellor/Property/Ccache.hs
+++ b/src/Propellor/Property/Ccache.hs
@@ -1,38 +1,77 @@
-- | Maintainer: Sean Whitton <spwhitton@spwhitton.name>
-module Propellor.Property.Ccache where
+module Propellor.Property.Ccache (
+ hasCache,
+ hasLimits,
+ Limit(..),
+ DataSize,
+) where
import Propellor.Base
import qualified Propellor.Property.File as File
import qualified Propellor.Property.Apt as Apt
import Utility.FileMode
+import Utility.DataUnits
import System.Posix.Files
-- | Limits on the size of a ccache
data Limit
-- | The maximum size of the cache, as a string such as "4G"
- --
- -- See ccache(1) for more on the size specification.
- = MaxSize String
+ = MaxSize DataSize
-- | The maximum number of files in the cache
- | MaxFiles Int
+ | MaxFiles Integer
-- | A cache with no limit specified
| NoLimit
+ | Limit :+ Limit
+
+instance Monoid Limit where
+ mempty = NoLimit
+ mappend = (:+)
+
+-- | A string that will be parsed to get a data size.
+--
+-- Examples: "100 megabytes" or "0.5tb"
+type DataSize = String
+
+maxSizeParam :: DataSize -> Maybe String
+maxSizeParam s = readSize dataUnits s
+ >>= \sz -> Just $ "--max-size=" ++ ccacheSizeUnits sz
+
+-- Generates size units as used in ccache.conf. The smallest unit we can
+-- specify in a ccache config files is a kilobyte
+ccacheSizeUnits :: Integer -> String
+ccacheSizeUnits sz = filter (/= ' ') (roughSize cfgfileunits True sz)
+ where
+ cfgfileunits :: [Unit]
+ cfgfileunits =
+ [ Unit (p 4) "Ti" "terabyte"
+ , Unit (p 3) "Gi" "gigabyte"
+ , Unit (p 2) "Mi" "megabyte"
+ , Unit (p 1) "Ki" "kilobyte"
+ ]
+ p :: Integer -> Integer
+ p n = 1024^n
+
+-- | Set limits on a given ccache.
+hasLimits :: FilePath -> Limit -> Property UnixLike
+hasLimits = undefined
+
+-- limitToParams :: Limit -> [String]
+-- limitToParams NoLimit = []
+-- limitToParams (MaxSize s) =
+-- limitToParams (MaxFiles f) =
+-- limitToParams (l1 :+ l2) = limitToParams l1 <> limitToParams l2
-- | Configures a ccache in /var/cache for a group
--
-- If you say
--
--- > & (Group "foo") `Ccache.hasGroupCache` (Ccache.MaxSize "4g")
+-- > & (Group "foo") `Ccache.hasGroupCache` (Ccache.MaxSize "4G"
+-- <> Ccache.MaxFiles 10000)
--
-- you instruct propellor to create a ccache in /var/cache/ccache-foo owned and
--- writeable by the foo group, with a maximum cache size of 4GB.
---
--- It is safe to specify this property more than once for a given group if you
--- wish to limit both the maximum size of the cache and the maximum number of
--- files in the cache. However, setting only one of these two limits is
--- generally sufficient.
+-- writeable by the foo group, with a maximum cache size of 4GB or 10000 files.
hasCache :: Group -> Limit -> RevertableProperty DebianLike UnixLike
group@(Group g) `hasCache` limit = (make `requires` installed) <!> delete
where
@@ -42,19 +81,13 @@ group@(Group g) `hasCache` limit = (make `requires` installed) <!> delete
& File.mode path (combineModes $
readModes ++ executeModes
++ [ownerWriteMode, groupWriteMode])
- & case limit of
- NoLimit -> doNothing
- MaxSize s -> setSizeLimit s
- MaxFiles f -> setFileLimit (show f)
+ & hasLimits path limit
delete = check (doesDirectoryExist path) $
cmdProperty "rm" ["-r", path] `assume` MadeChange
`describe` ("ccache for " ++ g ++ " does not exist")
- setSizeLimit s = conf `File.containsLine` ("max_size = " ++ s)
- setFileLimit f = conf `File.containsLine` ("max_files = " ++ f)
path = "/var/cache/ccache-" ++ g
- conf = path </> "ccache.conf"
installed :: Property DebianLike
installed = Apt.installed ["ccache"]