mirror of https://github.com/voidlizard/hbs2
wip, updateRepoHead
This commit is contained in:
parent
f7aa86a647
commit
d993501b1f
|
@ -94,6 +94,7 @@ data GroupKeyIdScheme = GroupKeyIdBasic1 -- encrypt zeroes then hash
|
||||||
|
|
||||||
newtype GroupKeyId = GroupKeyId N.ByteString
|
newtype GroupKeyId = GroupKeyId N.ByteString
|
||||||
deriving stock (Eq,Ord,Generic,Show)
|
deriving stock (Eq,Ord,Generic,Show)
|
||||||
|
deriving newtype Hashable
|
||||||
|
|
||||||
instance Pretty GroupKeyId where
|
instance Pretty GroupKeyId where
|
||||||
pretty what = pretty (AsBase58 (coerce @_ @N.ByteString what))
|
pretty what = pretty (AsBase58 (coerce @_ @N.ByteString what))
|
||||||
|
|
|
@ -6,7 +6,12 @@ import HBS2.Git3.Prelude
|
||||||
import HBS2.Git3.State
|
import HBS2.Git3.State
|
||||||
import HBS2.Git3.Repo.Types
|
import HBS2.Git3.Repo.Types
|
||||||
|
|
||||||
|
import HBS2.Data.Detect
|
||||||
import HBS2.System.Dir
|
import HBS2.System.Dir
|
||||||
|
import HBS2.Net.Auth.GroupKeySymm
|
||||||
|
import HBS2.CLI.Run.MetaData
|
||||||
|
import HBS2.Net.Auth.Credentials
|
||||||
|
import HBS2.KeyMan.Keys.Direct
|
||||||
|
|
||||||
import HBS2.Git.Local.CLI
|
import HBS2.Git.Local.CLI
|
||||||
|
|
||||||
|
@ -18,12 +23,14 @@ import Data.ByteString.Lazy.Char8 qualified as LBS8
|
||||||
import Data.ByteString.Lazy qualified as LBS
|
import Data.ByteString.Lazy qualified as LBS
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.HashMap.Strict qualified as HM
|
import Data.HashMap.Strict qualified as HM
|
||||||
|
import Data.HashSet qualified as HS
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text qualified as Text
|
import Data.Text qualified as Text
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Lens.Micro.Platform
|
import Lens.Micro.Platform
|
||||||
import System.Random hiding (next)
|
import System.Random hiding (next)
|
||||||
|
|
||||||
|
import Streaming.Prelude qualified as S
|
||||||
|
|
||||||
{- HLINT ignore "Functor law" -}
|
{- HLINT ignore "Functor law" -}
|
||||||
|
|
||||||
|
@ -81,4 +88,107 @@ newRemoteName key = do
|
||||||
if not (HM.member name refs) then pure name
|
if not (HM.member name refs) then pure name
|
||||||
else again (succ <$> ( i <|> Just 0) )
|
else again (succ <$> ( i <|> Just 0) )
|
||||||
|
|
||||||
|
updateRepoHead :: (HBS2GitPerks m)
|
||||||
|
=> GitRepoKey
|
||||||
|
-> [Syntax C]
|
||||||
|
-> [HashRef]
|
||||||
|
-> Git3 m ()
|
||||||
|
updateRepoHead repo manifest gkRefs' = do
|
||||||
|
|
||||||
|
sto <- getStorage
|
||||||
|
lwwAPI <- getClientAPI @LWWRefAPI @UNIX
|
||||||
|
|
||||||
|
creds <- liftIO $ runKeymanClientRO (loadCredentials repo)
|
||||||
|
>>= orThrow GitRepoNoAccess
|
||||||
|
|
||||||
|
let (wsk, wpk) = (view peerSignSk creds, view peerSignPk creds)
|
||||||
|
|
||||||
|
let mfs = vcat $ fmap pretty manifest
|
||||||
|
manifestTree <- createTreeWithMetadata sto Nothing mempty (LBS8.pack (show mfs))
|
||||||
|
>>= orThrowPassIO
|
||||||
|
|
||||||
|
LWWRef{..} <- getRepoRefMaybe >>= orThrow GitRepoRefEmpty
|
||||||
|
|
||||||
|
repoHead <- readLogThrow (getBlock sto) lwwValue
|
||||||
|
|
||||||
|
oldKeys <- fromMaybe mempty <$> runMaybeT do
|
||||||
|
h <- headMay (tailSafe repoHead) & toMPlus
|
||||||
|
readLogThrow (getBlock sto) h
|
||||||
|
|
||||||
|
|
||||||
|
let gkRefs = HS.toList $ HS.fromList (gkRefs' <> oldKeys)
|
||||||
|
|
||||||
|
gkTree <- if null gkRefs
|
||||||
|
then pure Nothing
|
||||||
|
else do
|
||||||
|
tree <- makeMerkle 0 (toPTree (MaxSize defHashListChunk) (MaxNum defTreeChildNum) gkRefs)
|
||||||
|
(\(_,_,bs) -> void $ putBlock sto bs)
|
||||||
|
pure $ Just (HashRef tree)
|
||||||
|
|
||||||
|
let refs = manifestTree : maybeToList gkTree
|
||||||
|
|
||||||
|
blk <- makeMerkle 0 (toPTree (MaxSize defHashListChunk) (MaxNum defTreeChildNum) refs)
|
||||||
|
(\(_,_,bs) -> void $ putBlock sto bs)
|
||||||
|
|
||||||
|
now <- liftIO getPOSIXTime <&> round
|
||||||
|
let box = makeSignedBox wpk wsk (LWWRef now (coerce blk) Nothing)
|
||||||
|
|
||||||
|
callRpcWaitMay @RpcLWWRefUpdate (TimeoutSec 1) lwwAPI box
|
||||||
|
>>= orThrow RpcTimeout
|
||||||
|
|
||||||
|
updateGroupKey :: HBS2GitPerks m => GitRepoKey -> HashRef -> Git3 m ()
|
||||||
|
updateGroupKey repo new = do
|
||||||
|
waitRepo (Just 10) repo
|
||||||
|
sto <- getStorage
|
||||||
|
LWWRef{..} <- getRepoRefMaybe >>= orThrow GitRepoRefEmpty
|
||||||
|
RepoManifest manifest <- getRepoManifest
|
||||||
|
deps <- readLogThrow (getBlock sto) (coerce lwwValue)
|
||||||
|
|
||||||
|
gkNew <- loadGroupKeyMaybe @HBS2Basic sto new
|
||||||
|
>>= orThrow (GitRepoNoGroupKey new)
|
||||||
|
|
||||||
|
flip runContT pure do
|
||||||
|
|
||||||
|
gkth <- ContT $ maybe1 (headMay (tailSafe deps)) none
|
||||||
|
gkTree <- readLogThrow (getBlock sto) gkth
|
||||||
|
|
||||||
|
r <- newTVarIO mempty
|
||||||
|
lift $ for_ gkTree $ \gh -> void $ runMaybeT do
|
||||||
|
gk <- loadGroupKeyMaybe @HBS2Basic sto gh >>= toMPlus
|
||||||
|
gkId <- groupKeyId gk & toMPlus
|
||||||
|
liftIO $ print $ "gk" <+> pretty gh <+> pretty gkId
|
||||||
|
|
||||||
|
let missed = HM.keysSet $ recipients gkNew `HM.difference` recipients gk
|
||||||
|
|
||||||
|
unless (HS.null missed) do
|
||||||
|
atomically $ modifyTVar r (HM.insert gkId (gk,missed))
|
||||||
|
none
|
||||||
|
|
||||||
|
keys <- readTVarIO r <&> HM.elems
|
||||||
|
|
||||||
|
oldKeys <- liftIO $ runKeymanClientRO do
|
||||||
|
for keys $ \(gk, missed) -> do
|
||||||
|
-- FIXME: what-if-no-access?
|
||||||
|
-- предполагается, что это делает owner.
|
||||||
|
-- owner имеет все ключи.
|
||||||
|
-- но это может сделать и чел, который просто имеет все ключи,
|
||||||
|
-- но нет, т.к. он не сможет записать lwwref
|
||||||
|
gks <- extractGroupKeySecret gk >>= orThrow GitRepoNoAccess
|
||||||
|
gkNew <- generateGroupKey @'HBS2Basic (Just gks) (HS.toList missed)
|
||||||
|
writeAsMerkle sto (serialise gkNew) <&> HashRef
|
||||||
|
|
||||||
|
let newKeys = HS.toList $ HS.fromList ( new : oldKeys )
|
||||||
|
|
||||||
|
for_ newKeys $ \k -> do
|
||||||
|
liftIO $ print $ "new gk" <+> pretty k
|
||||||
|
|
||||||
|
--
|
||||||
|
let newManifest0 = flip mapMaybe manifest $ \case
|
||||||
|
ListVal [StringLike "gk", HashLike x] -> Nothing
|
||||||
|
x -> Just x
|
||||||
|
let newManifest = newManifest0 <> [ mkForm "gk" [ mkSym (show $ pretty new) ] ]
|
||||||
|
|
||||||
|
lift do
|
||||||
|
updateRepoHead repo newManifest newKeys
|
||||||
|
updateRepoKey repo
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import HBS2.Git3.Prelude
|
||||||
import HBS2.Data.Log.Structured
|
import HBS2.Data.Log.Structured
|
||||||
|
|
||||||
import HBS2.CLI.Run.Internal.Merkle (getTreeContents)
|
import HBS2.CLI.Run.Internal.Merkle (getTreeContents)
|
||||||
|
import HBS2.Data.Detect hiding (Blob)
|
||||||
import HBS2.System.Dir
|
import HBS2.System.Dir
|
||||||
|
|
||||||
import HBS2.Git3.Git
|
import HBS2.Git3.Git
|
||||||
|
@ -251,7 +251,9 @@ compression ; prints compression level
|
||||||
let f = makeRelative cur f'
|
let f = makeRelative cur f'
|
||||||
liftIO $ print $ fill 10 (pretty s) <+> pretty f
|
liftIO $ print $ fill 10 (pretty s) <+> pretty f
|
||||||
|
|
||||||
entry $ bindMatch "reflog:index:list:tx" $ nil_ $ const $ lift $ connectedDo do
|
entry $ bindMatch "reflog:index:list:tx" $ nil_ $ \syn -> lift $ connectedDo do
|
||||||
|
resolveRepoKeyThrow syn >>= setGitRepoKey
|
||||||
|
waitRepo Nothing =<< getGitRepoKeyThrow
|
||||||
r <- newIORef ( mempty :: HashSet HashRef )
|
r <- newIORef ( mempty :: HashSet HashRef )
|
||||||
index <- openIndex
|
index <- openIndex
|
||||||
enumEntries index $ \bs -> do
|
enumEntries index $ \bs -> do
|
||||||
|
@ -315,6 +317,7 @@ compression ; prints compression level
|
||||||
let (opts,argz) = splitOpts [] syn
|
let (opts,argz) = splitOpts [] syn
|
||||||
|
|
||||||
let what = headDef "HEAD" [ x | StringLike x <- argz ]
|
let what = headDef "HEAD" [ x | StringLike x <- argz ]
|
||||||
|
|
||||||
h0 <- gitRevParseThrow what
|
h0 <- gitRevParseThrow what
|
||||||
|
|
||||||
no_ <- newTVarIO 0
|
no_ <- newTVarIO 0
|
||||||
|
@ -360,16 +363,16 @@ compression ; prints compression level
|
||||||
|
|
||||||
entry $ bindMatch "reflog:tx:list" $ nil_ $ \syn -> lift $ connectedDo do
|
entry $ bindMatch "reflog:tx:list" $ nil_ $ \syn -> lift $ connectedDo do
|
||||||
|
|
||||||
resolveRepoKeyThrow syn >>= setGitRepoKey
|
let (opts, argz) = splitOpts [ ("--checkpoints",0)
|
||||||
waitRepo Nothing =<< getGitRepoKeyThrow
|
|
||||||
|
|
||||||
let (opts, _) = splitOpts [ ("--checkpoints",0)
|
|
||||||
, ("--segments",0)
|
, ("--segments",0)
|
||||||
] syn
|
] syn
|
||||||
|
|
||||||
let cpOnly = or [ True | ListVal [StringLike "--checkpoints"] <- opts ]
|
let cpOnly = or [ True | ListVal [StringLike "--checkpoints"] <- opts ]
|
||||||
let sOnly = or [ True | ListVal [StringLike "--segments"] <- opts ]
|
let sOnly = or [ True | ListVal [StringLike "--segments"] <- opts ]
|
||||||
|
|
||||||
|
resolveRepoKeyThrow argz >>= setGitRepoKey
|
||||||
|
waitRepo Nothing =<< getGitRepoKeyThrow
|
||||||
|
|
||||||
hxs <- txListAll Nothing
|
hxs <- txListAll Nothing
|
||||||
|
|
||||||
liftIO $ forM_ hxs $ \(h,tx) -> do
|
liftIO $ forM_ hxs $ \(h,tx) -> do
|
||||||
|
@ -413,11 +416,13 @@ compression ; prints compression level
|
||||||
|
|
||||||
entry $ bindMatch "reflog:imported" $ nil_ $ \syn -> lift $ connectedDo do
|
entry $ bindMatch "reflog:imported" $ nil_ $ \syn -> lift $ connectedDo do
|
||||||
resolveRepoKeyThrow syn >>= setGitRepoKey
|
resolveRepoKeyThrow syn >>= setGitRepoKey
|
||||||
|
waitRepo Nothing =<< getGitRepoKeyThrow
|
||||||
p <- importedCheckpoint
|
p <- importedCheckpoint
|
||||||
liftIO $ print $ pretty p
|
liftIO $ print $ pretty p
|
||||||
|
|
||||||
entry $ bindMatch "reflog:import" $ nil_ $ \syn -> lift $ connectedDo do
|
entry $ bindMatch "reflog:import" $ nil_ $ \syn -> lift $ connectedDo do
|
||||||
resolveRepoKeyThrow syn >>= setGitRepoKey
|
resolveRepoKeyThrow syn >>= setGitRepoKey
|
||||||
|
waitRepo Nothing =<< getGitRepoKeyThrow
|
||||||
importGitRefLog
|
importGitRefLog
|
||||||
|
|
||||||
brief "shows repo manifest" $
|
brief "shows repo manifest" $
|
||||||
|
@ -447,13 +452,46 @@ compression ; prints compression level
|
||||||
for_ gk' $ \(gkh, _) -> do
|
for_ gk' $ \(gkh, _) -> do
|
||||||
liftIO $ print $ pretty $ mkForm @C "gk" [ mkSym (show $ pretty gkh) ]
|
liftIO $ print $ pretty $ mkForm @C "gk" [ mkSym (show $ pretty gkh) ]
|
||||||
|
|
||||||
|
brief "updates group key for repo" $
|
||||||
|
args [arg "string" "repo", arg "hash" "group-key-hash" ] $
|
||||||
|
entry $ bindMatch "repo:gk:update" $ nil_ $ \case
|
||||||
|
[ x@(StringLike{}), HashLike h ] -> lift $ connectedDo do
|
||||||
|
repo <- resolveRepoKeyThrow [x]
|
||||||
|
updateGroupKey repo h
|
||||||
|
|
||||||
|
_ -> throwIO $ BadFormException @C nil
|
||||||
|
|
||||||
|
entry $ bindMatch "repo:gk:journal" $ nil_ $ \syn -> lift $ connectedDo $ do
|
||||||
|
resolveRepoKeyThrow syn >>= setGitRepoKey
|
||||||
|
waitRepo Nothing =<< getGitRepoKeyThrow
|
||||||
|
|
||||||
|
ref <- getGitRepoKeyThrow
|
||||||
|
|
||||||
|
lwwAPI <- getClientAPI @LWWRefAPI @UNIX
|
||||||
|
|
||||||
|
sto <- getStorage
|
||||||
|
|
||||||
|
runMaybeT do
|
||||||
|
|
||||||
|
LWWRef{..} <- liftIO (callRpcWaitMay @RpcLWWRefGet (TimeoutSec 1) lwwAPI (coerce ref))
|
||||||
|
>>= orThrow RpcTimeout
|
||||||
|
>>= toMPlus
|
||||||
|
|
||||||
|
hrefs <- lift $ readLogThrow (getBlock sto) lwwValue
|
||||||
|
|
||||||
|
journal <- headMay (tail hrefs) & toMPlus
|
||||||
|
|
||||||
|
keys <- lift $ readLogThrow (getBlock sto) journal
|
||||||
|
|
||||||
|
liftIO $ for_ keys $ \k -> do
|
||||||
|
liftIO $ print $ pretty k
|
||||||
|
|
||||||
entry $ bindMatch "repo:init" $ nil_ $ \syn -> lift $ connectedDo do
|
entry $ bindMatch "repo:init" $ nil_ $ \syn -> lift $ connectedDo do
|
||||||
Repo.initRepo syn
|
Repo.initRepo syn
|
||||||
|
|
||||||
entry $ bindMatch "repo:relay-only" $ nil_ $ \case
|
entry $ bindMatch "repo:relay-only" $ nil_ $ \case
|
||||||
[ SignPubKeyLike repo ] -> lift $ connectedDo do
|
[ SignPubKeyLike repo ] -> lift $ connectedDo do
|
||||||
setGitRepoKey repo
|
setGitRepoKey repo
|
||||||
|
|
||||||
waitRepo (Just 2) =<< getGitRepoKeyThrow
|
waitRepo (Just 2) =<< getGitRepoKeyThrow
|
||||||
|
|
||||||
_ -> throwIO (BadFormException @C nil)
|
_ -> throwIO (BadFormException @C nil)
|
||||||
|
@ -461,4 +499,3 @@ compression ; prints compression level
|
||||||
exportEntries "reflog:"
|
exportEntries "reflog:"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ readLocalConf = do
|
||||||
<&> parseTop
|
<&> parseTop
|
||||||
>>= either (const $ pure mempty) pure
|
>>= either (const $ pure mempty) pure
|
||||||
|
|
||||||
data HBS2GitExcepion =
|
data HBS2GitException =
|
||||||
RefLogNotSet
|
RefLogNotSet
|
||||||
| GitRepoRefNotSet
|
| GitRepoRefNotSet
|
||||||
| GitRepoRefEmpty
|
| GitRepoRefEmpty
|
||||||
|
@ -60,9 +60,11 @@ data HBS2GitExcepion =
|
||||||
| NoGitDir
|
| NoGitDir
|
||||||
| GitRemoteKeyNotResolved String
|
| GitRemoteKeyNotResolved String
|
||||||
| GitCantGenerateRemoteName
|
| GitCantGenerateRemoteName
|
||||||
|
| GitRepoNoGroupKey HashRef
|
||||||
|
| GitRepoNoAccess
|
||||||
deriving stock (Show,Typeable)
|
deriving stock (Show,Typeable)
|
||||||
|
|
||||||
instance Exception HBS2GitExcepion
|
instance Exception HBS2GitException
|
||||||
|
|
||||||
defSegmentSize :: Int
|
defSegmentSize :: Int
|
||||||
defSegmentSize = 50 * 1024 * 1024
|
defSegmentSize = 50 * 1024 * 1024
|
||||||
|
|
|
@ -12,6 +12,7 @@ import HBS2.KeyMan.State
|
||||||
|
|
||||||
import HBS2.Prelude
|
import HBS2.Prelude
|
||||||
import HBS2.Base58
|
import HBS2.Base58
|
||||||
|
import HBS2.Storage
|
||||||
|
|
||||||
-- FIXME: remove-this
|
-- FIXME: remove-this
|
||||||
import HBS2.Net.Auth.Credentials()
|
import HBS2.Net.Auth.Credentials()
|
||||||
|
@ -27,10 +28,18 @@ import Prettyprinter
|
||||||
import Lens.Micro.Platform
|
import Lens.Micro.Platform
|
||||||
import UnliftIO
|
import UnliftIO
|
||||||
|
|
||||||
|
data StorageNotBound =
|
||||||
|
StorageNotBound
|
||||||
|
deriving stock (Show, Typeable)
|
||||||
|
|
||||||
|
instance Exception StorageNotBound
|
||||||
|
|
||||||
|
|
||||||
data AppEnv =
|
data AppEnv =
|
||||||
AppEnv
|
AppEnv
|
||||||
{ appConf :: [Syntax C]
|
{ appConf :: [Syntax C]
|
||||||
, appDb :: DBPipeEnv
|
, appDb :: DBPipeEnv
|
||||||
|
, appSto :: TVar (Maybe AnyStorage)
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype KeyManCLI m a = KeyManCLI { fromKeyManCLI :: ReaderT AppEnv m a }
|
newtype KeyManCLI m a = KeyManCLI { fromKeyManCLI :: ReaderT AppEnv m a }
|
||||||
|
@ -48,6 +57,7 @@ newAppEnv = do
|
||||||
let dbOpts = dbPipeOptsDef
|
let dbOpts = dbPipeOptsDef
|
||||||
AppEnv <$> readConfig
|
AppEnv <$> readConfig
|
||||||
<*> (getStatePath >>= newDBPipeEnv dbOpts)
|
<*> (getStatePath >>= newDBPipeEnv dbOpts)
|
||||||
|
<*> newTVarIO Nothing
|
||||||
|
|
||||||
runApp :: MonadUnliftIO m => KeyManCLI m () -> m ()
|
runApp :: MonadUnliftIO m => KeyManCLI m () -> m ()
|
||||||
runApp action = do
|
runApp action = do
|
||||||
|
@ -92,4 +102,11 @@ instance MonadIO m => HasConf (ReaderT AppEnv m) where
|
||||||
instance MonadIO m => HasConf (KeyManCLI m) where
|
instance MonadIO m => HasConf (KeyManCLI m) where
|
||||||
getConf = asks appConf
|
getConf = asks appConf
|
||||||
|
|
||||||
|
-- instance MonadIO m => HasStorage (KeyManCLI m) where
|
||||||
|
-- getStorage = do
|
||||||
|
-- msto <- asks appSto >>= readTVarIO
|
||||||
|
-- case msto of
|
||||||
|
-- Just x -> pure x
|
||||||
|
-- Nothing -> do
|
||||||
|
-- throwIO StorageNotBound
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
{-# Language AllowAmbiguousTypes #-}
|
||||||
|
{-# Language UndecidableInstances #-}
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
import HBS2.KeyMan.Prelude
|
import HBS2.KeyMan.Prelude
|
||||||
|
@ -5,7 +7,9 @@ import HBS2.KeyMan.App.Types
|
||||||
import HBS2.KeyMan.Config
|
import HBS2.KeyMan.Config
|
||||||
import HBS2.KeyMan.State
|
import HBS2.KeyMan.State
|
||||||
|
|
||||||
|
import HBS2.OrDie
|
||||||
import HBS2.Net.Auth.Credentials
|
import HBS2.Net.Auth.Credentials
|
||||||
|
import HBS2.Net.Auth.GroupKeySymm
|
||||||
|
|
||||||
import HBS2.Data.KeyRing qualified as KeyRing
|
import HBS2.Data.KeyRing qualified as KeyRing
|
||||||
|
|
||||||
|
@ -42,6 +46,7 @@ import Control.Monad.Reader
|
||||||
import Control.Monad.Except
|
import Control.Monad.Except
|
||||||
import Codec.Serialise
|
import Codec.Serialise
|
||||||
import Data.Coerce
|
import Data.Coerce
|
||||||
|
import System.Exit (exitSuccess)
|
||||||
|
|
||||||
import Streaming.Prelude qualified as S
|
import Streaming.Prelude qualified as S
|
||||||
|
|
||||||
|
@ -55,7 +60,12 @@ type Command m = m ()
|
||||||
globalOptions :: Parser GlobalOptions
|
globalOptions :: Parser GlobalOptions
|
||||||
globalOptions = pure GlobalOptions
|
globalOptions = pure GlobalOptions
|
||||||
|
|
||||||
type AppPerks m = (MonadIO m, MonadUnliftIO m, MonadReader AppEnv m, HasConf m, SerialisedCredentials 'HBS2Basic)
|
type AppPerks m = ( MonadIO m
|
||||||
|
, MonadUnliftIO m
|
||||||
|
, MonadReader AppEnv m
|
||||||
|
, HasConf m
|
||||||
|
, SerialisedCredentials 'HBS2Basic
|
||||||
|
)
|
||||||
|
|
||||||
-- TODO: key-mamagement-command-about-to-move-here
|
-- TODO: key-mamagement-command-about-to-move-here
|
||||||
|
|
||||||
|
@ -67,6 +77,7 @@ commands = hsubparser
|
||||||
<> command "set-weight" (O.info (setWeightCmd <**> helper) (progDesc "set weight for a key"))
|
<> command "set-weight" (O.info (setWeightCmd <**> helper) (progDesc "set weight for a key"))
|
||||||
<> command "add-mask" (O.info (addPath <**> helper) (progDesc "add path/mask to search keys, ex. '/home/user/keys/*.key'"))
|
<> command "add-mask" (O.info (addPath <**> helper) (progDesc "add path/mask to search keys, ex. '/home/user/keys/*.key'"))
|
||||||
<> command "config" (O.info (showConfig <**> helper) (progDesc "show hbs2-keyman config"))
|
<> command "config" (O.info (showConfig <**> helper) (progDesc "show hbs2-keyman config"))
|
||||||
|
<> command "run" (O.info (runScript <**> helper) (progDesc "run command"))
|
||||||
)
|
)
|
||||||
|
|
||||||
opts :: (AppPerks m) => ParserInfo (GlobalOptions, Command m)
|
opts :: (AppPerks m) => ParserInfo (GlobalOptions, Command m)
|
||||||
|
@ -75,6 +86,79 @@ opts = O.info (liftA2 (,) globalOptions commands <**> helper)
|
||||||
<> header "hbs2-keyman" )
|
<> header "hbs2-keyman" )
|
||||||
|
|
||||||
|
|
||||||
|
quit :: MonadIO m => m ()
|
||||||
|
quit = liftIO exitSuccess
|
||||||
|
|
||||||
|
theDict :: forall m . ( AppPerks m
|
||||||
|
) => AnyStorage -> Dict C m
|
||||||
|
|
||||||
|
theDict sto = do
|
||||||
|
makeDict @C do
|
||||||
|
-- TODO: write-man-entries
|
||||||
|
myHelpEntry
|
||||||
|
myEntries
|
||||||
|
|
||||||
|
-- entry $ bindValue "internal:storage" $ mkOpaque (22 ::Int )
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
myHelpEntry = do
|
||||||
|
entry $ bindMatch "help" $ nil_ $ \case
|
||||||
|
HelpEntryBound what -> do
|
||||||
|
helpEntry what
|
||||||
|
quit
|
||||||
|
|
||||||
|
[StringLike s] -> helpList False (Just s) >> quit
|
||||||
|
|
||||||
|
_ -> helpList False Nothing >> quit
|
||||||
|
|
||||||
|
myEntries = do
|
||||||
|
|
||||||
|
entry $ bindMatch "stdin" $ nil_ $ const do
|
||||||
|
|
||||||
|
co <- liftIO getContents
|
||||||
|
<&> parseTop
|
||||||
|
>>= either (error.show) pure
|
||||||
|
|
||||||
|
lift $ run (theDict sto) co
|
||||||
|
|
||||||
|
entry $ bindMatch "gk:track" $ nil_ $ \case
|
||||||
|
[HashLike gkhash] -> lift do
|
||||||
|
|
||||||
|
runMaybeT do
|
||||||
|
gk <- loadGroupKeyMaybe @'HBS2Basic sto gkhash
|
||||||
|
>>= toMPlus
|
||||||
|
|
||||||
|
gkId <- groupKeyId gk & toMPlus
|
||||||
|
|
||||||
|
-- notice $ "fuck?"
|
||||||
|
lift $ withState $ transactional do
|
||||||
|
insertGKTrack gkId gkhash
|
||||||
|
insertGKAccess gkhash gk
|
||||||
|
|
||||||
|
liftIO $ print $ pretty $ mkForm @C "gk:added" [mkSym (show $ pretty gkhash)]
|
||||||
|
|
||||||
|
_ -> throwIO (BadFormException @C nil)
|
||||||
|
|
||||||
|
|
||||||
|
runScript :: (AppPerks m, MonadReader AppEnv m) => Parser (Command m)
|
||||||
|
runScript = do
|
||||||
|
argz <- some (argument str (metavar "TERM"))
|
||||||
|
pure do
|
||||||
|
|
||||||
|
AppEnv{..} <- ask
|
||||||
|
|
||||||
|
flip runContT pure do
|
||||||
|
so' <- detectRPC
|
||||||
|
so <- ContT $ maybe1 so' (err $ red "peer is down")
|
||||||
|
sto <- ContT (withRPC2 @StorageAPI so) <&> AnyStorage . StorageClient
|
||||||
|
atomically $ writeTVar appSto(Just sto)
|
||||||
|
|
||||||
|
cli <- parseTop (unlines $ unwords <$> splitForms argz)
|
||||||
|
& either (error.show) pure
|
||||||
|
|
||||||
|
lift $ run (theDict sto) cli >>= display
|
||||||
|
|
||||||
showConfig :: (AppPerks m) => Parser (Command m)
|
showConfig :: (AppPerks m) => Parser (Command m)
|
||||||
showConfig = do
|
showConfig = do
|
||||||
pure do
|
pure do
|
||||||
|
@ -242,7 +326,6 @@ updateKeys = do
|
||||||
commitAll
|
commitAll
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setWeightCmd :: (AppPerks m) => Parser (Command m)
|
setWeightCmd :: (AppPerks m) => Parser (Command m)
|
||||||
setWeightCmd = do
|
setWeightCmd = do
|
||||||
k <- argument str (metavar "KEY" <> help "Key identifier")
|
k <- argument str (metavar "KEY" <> help "Key identifier")
|
||||||
|
|
Loading…
Reference in New Issue