Skip to content

Commit a8a44ab

Browse files
committed
remote: heavy lifting
Co-Authored-By: Guillaume Maudoux <layus.on@gmail.com> Co-Authored-By: John Ericson <John.Ericson@Obsidian.Systems> Related to #72
1 parent 70eb0d3 commit a8a44ab

File tree

7 files changed

+434
-190
lines changed

7 files changed

+434
-190
lines changed

hnix-store-remote/src/Data/Serializer.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ tup a b = Serializer
193193
data GetSerializerError customGetError
194194
= SerializerError_GetFail String
195195
| SerializerError_Get customGetError
196-
deriving (Eq, Show)
196+
deriving (Eq, Ord, Show)
197197

198198
-- | Helper for transforming nested Eithers
199199
-- into @GetSerializerError@ wrapper

hnix-store-remote/src/System/Nix/Store/Remote.hs

+81-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
{-# LANGUAGE OverloadedStrings #-}
44

55
module System.Nix.Store.Remote
6-
( addToStore
6+
(
7+
-- * Operations
8+
addToStore
79
, addTextToStore
810
, addSignatures
911
, addIndirectRoot
@@ -25,51 +27,124 @@ module System.Nix.Store.Remote
2527
, queryPathFromHashPart
2628
, queryMissing
2729
, optimiseStore
28-
, runStore
2930
, syncWithGC
3031
, verifyStore
3132
, module System.Nix.Store.Types
3233
, module System.Nix.Store.Remote.MonadStore
3334
, module System.Nix.Store.Remote.Types
35+
-- * Compat
36+
, MonadStore
37+
-- * Runners
38+
, runStore
39+
, runStoreOpts
40+
, runStoreOptsTCP
3441
) where
3542

3643
import Crypto.Hash (SHA256)
3744
import Data.ByteString (ByteString)
45+
import Data.Default.Class (Default(def))
3846
import Data.Dependent.Sum (DSum((:=>)))
3947
import Data.HashSet (HashSet)
4048
import Data.Map (Map)
4149
import Data.Text (Text)
4250
import Data.Word (Word64)
51+
import Network.Socket (Family, SockAddr(SockAddrUnix))
4352
import System.Nix.Nar (NarSource)
4453
import System.Nix.Derivation (Derivation)
4554
import System.Nix.Store.Types (FileIngestionMethod(..), RepairMode(..))
4655
import System.Nix.Build (BuildMode, BuildResult)
4756
import System.Nix.Hash (NamedAlgo(..), BaseEncoding(Base16), decodeDigestWith)
48-
import System.Nix.StorePath (StorePath, StorePathName, StorePathHashPart, InvalidPathError)
57+
import System.Nix.StorePath (StoreDir(..), StorePath, StorePathName, StorePathHashPart, InvalidPathError)
4958
import System.Nix.StorePath.Metadata (Metadata(..), StorePathTrust(..))
5059

5160
import qualified Data.Text
61+
import qualified Control.Exception
5262
import qualified Control.Monad
5363
import qualified Data.Attoparsec.Text
5464
import qualified Data.Text.Encoding
5565
import qualified Data.Map.Strict
5666
import qualified Data.Serialize.Put
5767
import qualified Data.Set
68+
import qualified Network.Socket
5869

5970
import qualified System.Nix.ContentAddress
6071
import qualified System.Nix.Hash
6172
import qualified System.Nix.Signature
6273
import qualified System.Nix.StorePath
6374

64-
import System.Nix.Store.Remote.MonadStore
65-
import System.Nix.Store.Remote.Protocol
75+
import System.Nix.Store.Remote.MonadStore (MonadRemoteStore, getStoreDir, RemoteStoreError(RemoteStoreError_GetAddrInfoFailed))
76+
import System.Nix.Store.Remote.Protocol (Run, runStoreSocket, runOp, runOpArgs, runOpArgsIO, simpleOp, simpleOpArgs)
6677
import System.Nix.Store.Remote.Socket
6778
import System.Nix.Store.Remote.Types
6879

6980
import Data.Serialize (get)
70-
import System.Nix.Store.Remote.Serialize
81+
import System.Nix.Store.Remote.Serialize (putDerivation)
7182
import System.Nix.Store.Remote.Serialize.Prim
7283

84+
-- * Compat
85+
86+
type MonadStore = MonadRemoteStore
87+
88+
-- * Runners
89+
90+
runStore :: MonadStore a -> Run a
91+
runStore = runStoreOpts defaultSockPath def
92+
where
93+
defaultSockPath :: String
94+
defaultSockPath = "/nix/var/nix/daemon-socket/socket"
95+
96+
runStoreOpts
97+
:: FilePath
98+
-> StoreDir
99+
-> MonadStore a
100+
-> Run a
101+
runStoreOpts socketPath =
102+
runStoreOpts'
103+
Network.Socket.AF_UNIX
104+
(SockAddrUnix socketPath)
105+
106+
runStoreOptsTCP
107+
:: String
108+
-> Int
109+
-> StoreDir
110+
-> MonadStore a
111+
-> Run a
112+
runStoreOptsTCP host port sd code = do
113+
Network.Socket.getAddrInfo
114+
(Just Network.Socket.defaultHints)
115+
(Just host)
116+
(Just $ show port)
117+
>>= \case
118+
(sockAddr:_) ->
119+
runStoreOpts'
120+
(Network.Socket.addrFamily sockAddr)
121+
(Network.Socket.addrAddress sockAddr)
122+
sd
123+
code
124+
_ -> pure (Left RemoteStoreError_GetAddrInfoFailed, [])
125+
126+
runStoreOpts'
127+
:: Family
128+
-> SockAddr
129+
-> StoreDir
130+
-> MonadStore a
131+
-> Run a
132+
runStoreOpts' sockFamily sockAddr storeRootDir code =
133+
Control.Exception.bracket
134+
open
135+
(Network.Socket.close . hasStoreSocket)
136+
(flip runStoreSocket code)
137+
where
138+
open = do
139+
soc <- Network.Socket.socket sockFamily Network.Socket.Stream 0
140+
Network.Socket.connect soc sockAddr
141+
pure PreStoreConfig
142+
{ preStoreConfig_socket = soc
143+
, preStoreConfig_dir = storeRootDir
144+
}
145+
146+
-- * Operations
147+
73148
-- | Pack `Nar` and add it to the store.
74149
addToStore
75150
:: forall a

hnix-store-remote/src/System/Nix/Store/Remote/Logger.hs

+19-10
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@ import Data.Serialize (Result(..))
88
import System.Nix.Store.Remote.Serialize.Prim (putByteString)
99
import System.Nix.Store.Remote.Serializer (LoggerSError, logger, runSerialT)
1010
import System.Nix.Store.Remote.Socket (sockGet8, sockPut)
11-
import System.Nix.Store.Remote.MonadStore (MonadStore, clearData)
12-
import System.Nix.Store.Remote.Types (Logger(..), ProtoVersion, hasProtoVersion)
11+
import System.Nix.Store.Remote.MonadStore (MonadRemoteStore0, RemoteStoreError(..), clearData, getData, getProtoVersion)
12+
import System.Nix.Store.Remote.Types.Logger (Logger(..))
13+
import System.Nix.Store.Remote.Types.ProtoVersion (HasProtoVersion(..), ProtoVersion)
14+
import System.Nix.Store.Remote.Types.StoreConfig (HasStoreSocket(..))
1315

1416
import qualified Control.Monad
15-
import qualified Control.Monad.Reader
16-
import qualified Control.Monad.State.Strict
1717
import qualified Data.Serialize.Get
1818
import qualified Data.Serializer
1919

20-
processOutput :: MonadStore [Logger]
20+
processOutput
21+
:: ( HasProtoVersion r
22+
, HasStoreSocket r
23+
)
24+
=> MonadRemoteStore0 r [Logger]
2125
processOutput = do
22-
protoVersion <- Control.Monad.Reader.asks hasProtoVersion
26+
protoVersion <- getProtoVersion
2327
sockGet8 >>= go . (decoder protoVersion)
2428
where
2529
decoder
@@ -30,14 +34,19 @@ processOutput = do
3034
Data.Serialize.Get.runGetPartial
3135
(runSerialT protoVersion $ Data.Serializer.getS logger)
3236

33-
go :: Result (Either LoggerSError Logger) -> MonadStore [Logger]
37+
go
38+
:: ( HasProtoVersion r
39+
, HasStoreSocket r
40+
)
41+
=> Result (Either LoggerSError Logger)
42+
-> MonadRemoteStore0 r [Logger]
3443
go (Done ectrl leftover) = do
3544

3645
Control.Monad.unless (leftover == mempty) $
3746
-- TODO: throwError
3847
error $ "Leftovers detected: '" ++ show leftover ++ "'"
3948

40-
protoVersion <- Control.Monad.Reader.asks hasProtoVersion
49+
protoVersion <- getProtoVersion
4150
case ectrl of
4251
-- TODO: tie this with throwError and better error type
4352
Left e -> error $ show e
@@ -46,9 +55,9 @@ processOutput = do
4655
e@(Logger_Error _) -> pure [e]
4756
Logger_Last -> pure [Logger_Last]
4857
Logger_Read _n -> do
49-
(mdata, _) <- Control.Monad.State.Strict.get
58+
mdata <- getData
5059
case mdata of
51-
Nothing -> throwError "No data to read provided"
60+
Nothing -> throwError RemoteStoreError_NoDataProvided
5261
Just part -> do
5362
-- XXX: we should check/assert part size against n of (Read n)
5463
sockPut $ putByteString part

0 commit comments

Comments
 (0)