module B9.Repository
( RepoCacheReader,
getRepoCache,
withSelectedRemoteRepo,
getSelectedRemoteRepo,
SelectedRemoteRepoReader,
Repository (..),
RepoImagesMap,
toRemoteRepository,
SelectedRemoteRepo (..),
remoteRepoCacheDir,
localRepoDir,
lookupRemoteRepo,
filterRepoImagesMap,
lookupCachedImages,
allCachedSharedImages,
allSharedImagesWithRepo,
maxSharedImageOfAllRepos,
allSharedImagesInRepo,
allSharedImages,
allRepositories,
groupBySharedImageName,
keepNLatestSharedImages,
dropAllButNLatestSharedImages,
module X,
)
where
import B9.B9Config
import B9.B9Config.Repository as X
import B9.B9Error
import B9.DiskImages
import Control.Eff
import Control.Eff.Reader.Lazy
import Data.Foldable
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.Generics
import System.FilePath
import Test.QuickCheck
import Text.Printf
data Repository
= Cache
| Remote String
deriving (Repository -> Repository -> Bool
(Repository -> Repository -> Bool)
-> (Repository -> Repository -> Bool) -> Eq Repository
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Repository -> Repository -> Bool
$c/= :: Repository -> Repository -> Bool
== :: Repository -> Repository -> Bool
$c== :: Repository -> Repository -> Bool
Eq, Eq Repository
Eq Repository
-> (Repository -> Repository -> Ordering)
-> (Repository -> Repository -> Bool)
-> (Repository -> Repository -> Bool)
-> (Repository -> Repository -> Bool)
-> (Repository -> Repository -> Bool)
-> (Repository -> Repository -> Repository)
-> (Repository -> Repository -> Repository)
-> Ord Repository
Repository -> Repository -> Bool
Repository -> Repository -> Ordering
Repository -> Repository -> Repository
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Repository -> Repository -> Repository
$cmin :: Repository -> Repository -> Repository
max :: Repository -> Repository -> Repository
$cmax :: Repository -> Repository -> Repository
>= :: Repository -> Repository -> Bool
$c>= :: Repository -> Repository -> Bool
> :: Repository -> Repository -> Bool
$c> :: Repository -> Repository -> Bool
<= :: Repository -> Repository -> Bool
$c<= :: Repository -> Repository -> Bool
< :: Repository -> Repository -> Bool
$c< :: Repository -> Repository -> Bool
compare :: Repository -> Repository -> Ordering
$ccompare :: Repository -> Repository -> Ordering
$cp1Ord :: Eq Repository
Ord, ReadPrec [Repository]
ReadPrec Repository
Int -> ReadS Repository
ReadS [Repository]
(Int -> ReadS Repository)
-> ReadS [Repository]
-> ReadPrec Repository
-> ReadPrec [Repository]
-> Read Repository
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Repository]
$creadListPrec :: ReadPrec [Repository]
readPrec :: ReadPrec Repository
$creadPrec :: ReadPrec Repository
readList :: ReadS [Repository]
$creadList :: ReadS [Repository]
readsPrec :: Int -> ReadS Repository
$creadsPrec :: Int -> ReadS Repository
Read, Int -> Repository -> ShowS
[Repository] -> ShowS
Repository -> String
(Int -> Repository -> ShowS)
-> (Repository -> String)
-> ([Repository] -> ShowS)
-> Show Repository
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Repository] -> ShowS
$cshowList :: [Repository] -> ShowS
show :: Repository -> String
$cshow :: Repository -> String
showsPrec :: Int -> Repository -> ShowS
$cshowsPrec :: Int -> Repository -> ShowS
Show, (forall x. Repository -> Rep Repository x)
-> (forall x. Rep Repository x -> Repository) -> Generic Repository
forall x. Rep Repository x -> Repository
forall x. Repository -> Rep Repository x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Repository x -> Repository
$cfrom :: forall x. Repository -> Rep Repository x
Generic)
instance Arbitrary Repository where
arbitrary :: Gen Repository
arbitrary =
[Gen Repository] -> Gen Repository
forall a. [Gen a] -> Gen a
Test.QuickCheck.oneof
[ Repository -> Gen Repository
forall (f :: * -> *) a. Applicative f => a -> f a
pure Repository
Cache,
String -> Repository
Remote (String -> Repository) -> (Int -> String) -> Int -> Repository
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"remote-repo-%0X" (Int -> Repository) -> Gen Int -> Gen Repository
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
31 :: Int)
]
instance Function Repository
instance CoArbitrary Repository
toRemoteRepository :: RemoteRepo -> Repository
toRemoteRepository :: RemoteRepo -> Repository
toRemoteRepository = String -> Repository
Remote (String -> Repository)
-> (RemoteRepo -> String) -> RemoteRepo -> Repository
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RemoteRepo -> String
remoteRepoRepoId
type RepoCacheReader = Reader RepoCache
getRepoCache :: Member RepoCacheReader e => Eff e RepoCache
getRepoCache :: Eff e RepoCache
getRepoCache = Eff e RepoCache
forall e (r :: [* -> *]). Member (Reader e) r => Eff r e
ask
withSelectedRemoteRepo ::
(Member B9ConfigReader e, Member ExcB9 e) =>
Eff (SelectedRemoteRepoReader ': e) a ->
Eff e a
withSelectedRemoteRepo :: Eff (SelectedRemoteRepoReader : e) a -> Eff e a
withSelectedRemoteRepo Eff (SelectedRemoteRepoReader : e) a
e = do
Set RemoteRepo
remoteRepos' <- B9Config -> Set RemoteRepo
_remoteRepos (B9Config -> Set RemoteRepo)
-> Eff e B9Config -> Eff e (Set RemoteRepo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Eff e B9Config
forall (e :: [* -> *]). Member B9ConfigReader e => Eff e B9Config
getB9Config
Maybe String
mSelectedRepoName <- B9Config -> Maybe String
_repository (B9Config -> Maybe String)
-> Eff e B9Config -> Eff e (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Eff e B9Config
forall (e :: [* -> *]). Member B9ConfigReader e => Eff e B9Config
getB9Config
case Maybe String
mSelectedRepoName of
Maybe String
Nothing -> SelectedRemoteRepo
-> Eff (SelectedRemoteRepoReader : e) a -> Eff e a
forall e (r :: [* -> *]) w. e -> Eff (Reader e : r) w -> Eff r w
runReader (Maybe RemoteRepo -> SelectedRemoteRepo
MkSelectedRemoteRepo Maybe RemoteRepo
forall a. Maybe a
Nothing) Eff (SelectedRemoteRepoReader : e) a
e
Just String
selectedRepoName ->
case Set RemoteRepo -> String -> Maybe RemoteRepo
lookupRemoteRepo Set RemoteRepo
remoteRepos' String
selectedRepoName of
Maybe RemoteRepo
Nothing ->
String -> Eff e a
forall (e :: [* -> *]) a. Member ExcB9 e => String -> Eff e a
throwB9Error
( String -> String -> ShowS
forall r. PrintfType r => String -> r
printf
String
"selected remote repo '%s' not configured, valid remote repos are: '%s'"
(ShowS
forall a. Show a => a -> String
show String
selectedRepoName)
(Set RemoteRepo -> String
forall a. Show a => a -> String
show Set RemoteRepo
remoteRepos')
)
Just RemoteRepo
r -> SelectedRemoteRepo
-> Eff (SelectedRemoteRepoReader : e) a -> Eff e a
forall e (r :: [* -> *]) w. e -> Eff (Reader e : r) w -> Eff r w
runReader (Maybe RemoteRepo -> SelectedRemoteRepo
MkSelectedRemoteRepo (RemoteRepo -> Maybe RemoteRepo
forall a. a -> Maybe a
Just RemoteRepo
r)) Eff (SelectedRemoteRepoReader : e) a
e
newtype SelectedRemoteRepo = MkSelectedRemoteRepo {SelectedRemoteRepo -> Maybe RemoteRepo
fromSelectedRemoteRepo :: Maybe RemoteRepo}
type SelectedRemoteRepoReader = Reader SelectedRemoteRepo
getSelectedRemoteRepo ::
Member SelectedRemoteRepoReader e => Eff e SelectedRemoteRepo
getSelectedRemoteRepo :: Eff e SelectedRemoteRepo
getSelectedRemoteRepo = Eff e SelectedRemoteRepo
forall e (r :: [* -> *]). Member (Reader e) r => Eff r e
ask
remoteRepoCacheDir ::
RepoCache ->
String ->
FilePath
remoteRepoCacheDir :: RepoCache -> ShowS
remoteRepoCacheDir (RepoCache String
cacheDir) String
repoId =
String
cacheDir String -> ShowS
</> String
"remote-repos" String -> ShowS
</> String
repoId
localRepoDir ::
RepoCache ->
FilePath
localRepoDir :: RepoCache -> String
localRepoDir (RepoCache String
cacheDir) = String
cacheDir String -> ShowS
</> String
"local-repo"
lookupRemoteRepo :: Set RemoteRepo -> String -> Maybe RemoteRepo
lookupRemoteRepo :: Set RemoteRepo -> String -> Maybe RemoteRepo
lookupRemoteRepo Set RemoteRepo
repos String
repoId = String -> Map String RemoteRepo -> Maybe RemoteRepo
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
repoId Map String RemoteRepo
repoIdRepoPairs
where
repoIdRepoPairs :: Map String RemoteRepo
repoIdRepoPairs =
[(String, RemoteRepo)] -> Map String RemoteRepo
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((RemoteRepo -> (String, RemoteRepo))
-> [RemoteRepo] -> [(String, RemoteRepo)]
forall a b. (a -> b) -> [a] -> [b]
map (\r :: RemoteRepo
r@(RemoteRepo String
rid String
_ SshPrivKey
_ SshRemoteHost
_ SshRemoteUser
_) -> (String
rid, RemoteRepo
r)) (Set RemoteRepo -> [RemoteRepo]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Set RemoteRepo
repos))
type RepoImagesMap = Map Repository (Set SharedImage)
filterRepoImagesMap ::
(Repository -> Bool) ->
(SharedImage -> Bool) ->
RepoImagesMap ->
RepoImagesMap
filterRepoImagesMap :: (Repository -> Bool)
-> (SharedImage -> Bool) -> RepoImagesMap -> RepoImagesMap
filterRepoImagesMap Repository -> Bool
repoPred SharedImage -> Bool
imgPred =
(Set SharedImage -> Set SharedImage)
-> RepoImagesMap -> RepoImagesMap
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map ((SharedImage -> Bool) -> Set SharedImage -> Set SharedImage
forall a. (a -> Bool) -> Set a -> Set a
Set.filter SharedImage -> Bool
imgPred)
(RepoImagesMap -> RepoImagesMap)
-> (RepoImagesMap -> RepoImagesMap)
-> RepoImagesMap
-> RepoImagesMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Repository -> Set SharedImage -> Bool)
-> RepoImagesMap -> RepoImagesMap
forall k a. (k -> a -> Bool) -> Map k a -> Map k a
Map.filterWithKey (Bool -> Set SharedImage -> Bool
forall a b. a -> b -> a
const (Bool -> Set SharedImage -> Bool)
-> (Repository -> Bool) -> Repository -> Set SharedImage -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repository -> Bool
repoPred)
lookupCachedImages ::
SharedImageName ->
RepoImagesMap ->
Set SharedImage
lookupCachedImages :: SharedImageName -> RepoImagesMap -> Set SharedImage
lookupCachedImages SharedImageName
name =
RepoImagesMap -> Set SharedImage
allSharedImages
(RepoImagesMap -> Set SharedImage)
-> (RepoImagesMap -> RepoImagesMap)
-> RepoImagesMap
-> Set SharedImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Repository -> Bool)
-> (SharedImage -> Bool) -> RepoImagesMap -> RepoImagesMap
filterRepoImagesMap (Repository -> Repository -> Bool
forall a. Eq a => a -> a -> Bool
== Repository
Cache) ((SharedImageName -> SharedImageName -> Bool
forall a. Eq a => a -> a -> Bool
== SharedImageName
name) (SharedImageName -> Bool)
-> (SharedImage -> SharedImageName) -> SharedImage -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SharedImage -> SharedImageName
sharedImageName)
allRepositories :: RepoImagesMap -> Set Repository
allRepositories :: RepoImagesMap -> Set Repository
allRepositories = RepoImagesMap -> Set Repository
forall k a. Map k a -> Set k
Map.keysSet
allSharedImages :: RepoImagesMap -> Set SharedImage
allSharedImages :: RepoImagesMap -> Set SharedImage
allSharedImages = RepoImagesMap -> Set SharedImage
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
allSharedImagesWithRepo :: RepoImagesMap -> Set (SharedImage, Repository)
allSharedImagesWithRepo :: RepoImagesMap -> Set (SharedImage, Repository)
allSharedImagesWithRepo = (Repository -> Set SharedImage -> Set (SharedImage, Repository))
-> RepoImagesMap -> Set (SharedImage, Repository)
forall m k a. Monoid m => (k -> a -> m) -> Map k a -> m
Map.foldMapWithKey ((SharedImage -> (SharedImage, Repository))
-> Set SharedImage -> Set (SharedImage, Repository)
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map ((SharedImage -> (SharedImage, Repository))
-> Set SharedImage -> Set (SharedImage, Repository))
-> (Repository -> SharedImage -> (SharedImage, Repository))
-> Repository
-> Set SharedImage
-> Set (SharedImage, Repository)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SharedImage -> Repository -> (SharedImage, Repository))
-> Repository -> SharedImage -> (SharedImage, Repository)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (,))
maxSharedImageOfAllRepos :: RepoImagesMap -> Maybe (SharedImage, Repository)
maxSharedImageOfAllRepos :: RepoImagesMap -> Maybe (SharedImage, Repository)
maxSharedImageOfAllRepos = Set (SharedImage, Repository) -> Maybe (SharedImage, Repository)
forall a. Set a -> Maybe a
Set.lookupMax (Set (SharedImage, Repository) -> Maybe (SharedImage, Repository))
-> (RepoImagesMap -> Set (SharedImage, Repository))
-> RepoImagesMap
-> Maybe (SharedImage, Repository)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RepoImagesMap -> Set (SharedImage, Repository)
allSharedImagesWithRepo
allSharedImagesInRepo :: Repository -> RepoImagesMap -> Set SharedImage
allSharedImagesInRepo :: Repository -> RepoImagesMap -> Set SharedImage
allSharedImagesInRepo Repository
repo = Set SharedImage -> Maybe (Set SharedImage) -> Set SharedImage
forall a. a -> Maybe a -> a
fromMaybe Set SharedImage
forall a. Set a
Set.empty (Maybe (Set SharedImage) -> Set SharedImage)
-> (RepoImagesMap -> Maybe (Set SharedImage))
-> RepoImagesMap
-> Set SharedImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repository -> RepoImagesMap -> Maybe (Set SharedImage)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Repository
repo
allCachedSharedImages ::
RepoImagesMap ->
Set SharedImage
allCachedSharedImages :: RepoImagesMap -> Set SharedImage
allCachedSharedImages = Repository -> RepoImagesMap -> Set SharedImage
allSharedImagesInRepo Repository
Cache
keepNLatestSharedImages :: Int -> Set SharedImage -> Set SharedImage
keepNLatestSharedImages :: Int -> Set SharedImage -> Set SharedImage
keepNLatestSharedImages Int
n =
Map SharedImageName (Set SharedImage) -> Set SharedImage
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
(Map SharedImageName (Set SharedImage) -> Set SharedImage)
-> (Set SharedImage -> Map SharedImageName (Set SharedImage))
-> Set SharedImage
-> Set SharedImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set SharedImage -> Set SharedImage)
-> Map SharedImageName (Set SharedImage)
-> Map SharedImageName (Set SharedImage)
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map
( \Set SharedImage
s ->
let nOld :: Int
nOld = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Set SharedImage -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Set SharedImage
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
in Int -> Set SharedImage -> Set SharedImage
forall a. Int -> Set a -> Set a
Set.drop Int
nOld Set SharedImage
s
)
(Map SharedImageName (Set SharedImage)
-> Map SharedImageName (Set SharedImage))
-> (Set SharedImage -> Map SharedImageName (Set SharedImage))
-> Set SharedImage
-> Map SharedImageName (Set SharedImage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set SharedImage -> Map SharedImageName (Set SharedImage)
groupBySharedImageName
dropAllButNLatestSharedImages :: Int -> Set SharedImage -> Set SharedImage
dropAllButNLatestSharedImages :: Int -> Set SharedImage -> Set SharedImage
dropAllButNLatestSharedImages Int
n =
Map SharedImageName (Set SharedImage) -> Set SharedImage
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
(Map SharedImageName (Set SharedImage) -> Set SharedImage)
-> (Set SharedImage -> Map SharedImageName (Set SharedImage))
-> Set SharedImage
-> Set SharedImage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set SharedImage -> Set SharedImage)
-> Map SharedImageName (Set SharedImage)
-> Map SharedImageName (Set SharedImage)
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map
( \Set SharedImage
s ->
let nOld :: Int
nOld = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Set SharedImage -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Set SharedImage
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
in Int -> Set SharedImage -> Set SharedImage
forall a. Int -> Set a -> Set a
Set.take Int
nOld Set SharedImage
s
)
(Map SharedImageName (Set SharedImage)
-> Map SharedImageName (Set SharedImage))
-> (Set SharedImage -> Map SharedImageName (Set SharedImage))
-> Set SharedImage
-> Map SharedImageName (Set SharedImage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set SharedImage -> Map SharedImageName (Set SharedImage)
groupBySharedImageName
groupBySharedImageName :: Set SharedImage -> Map SharedImageName (Set SharedImage)
groupBySharedImageName :: Set SharedImage -> Map SharedImageName (Set SharedImage)
groupBySharedImageName =
(SharedImage
-> Map SharedImageName (Set SharedImage)
-> Map SharedImageName (Set SharedImage))
-> Map SharedImageName (Set SharedImage)
-> Set SharedImage
-> Map SharedImageName (Set SharedImage)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
( \SharedImage
img ->
(Maybe (Set SharedImage) -> Maybe (Set SharedImage))
-> SharedImageName
-> Map SharedImageName (Set SharedImage)
-> Map SharedImageName (Set SharedImage)
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter
( Set SharedImage -> Maybe (Set SharedImage)
forall a. a -> Maybe a
Just
(Set SharedImage -> Maybe (Set SharedImage))
-> (Maybe (Set SharedImage) -> Set SharedImage)
-> Maybe (Set SharedImage)
-> Maybe (Set SharedImage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set SharedImage
-> (Set SharedImage -> Set SharedImage)
-> Maybe (Set SharedImage)
-> Set SharedImage
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(SharedImage -> Set SharedImage
forall a. a -> Set a
Set.singleton SharedImage
img)
(SharedImage -> Set SharedImage -> Set SharedImage
forall a. Ord a => a -> Set a -> Set a
Set.insert SharedImage
img)
)
(SharedImage -> SharedImageName
sharedImageName SharedImage
img)
)
Map SharedImageName (Set SharedImage)
forall k a. Map k a
Map.empty