@@ -10,11 +10,11 @@ module System.Nix.Store.Remote
1010 , MonadStore
1111 -- * Runners
1212 , runStore
13- , runStoreOpts
14- , runStoreOptsTCP
13+ , runStoreConnection
14+ , runStoreSocket
1515 -- ** Daemon
1616 , runDaemon
17- , runDaemonOpts
17+ , runDaemonConnection
1818 , justdoit
1919 ) where
2020
@@ -30,15 +30,16 @@ import System.Nix.Store.Remote.MonadStore
3030 , RemoteStoreT
3131 , RemoteStoreError (RemoteStoreError_GetAddrInfoFailed ))
3232import System.Nix.Store.Remote.Client
33+ import System.Nix.Store.Remote.Server (WorkerHelper , runProxyDaemon )
3334import System.Nix.Store.Remote.Types
3435
3536import qualified Control.Monad.Catch
3637import qualified Network.Socket
37- import qualified System.Directory
38+ -- see TODO bellow
39+ -- import qualified System.Directory
3840
39- -- wip daemon
41+ -- wip justdoit
4042import System.Nix.StorePath (StorePath )
41- import System.Nix.Store.Remote.Server (WorkerHelper , runDaemonSocket )
4243import qualified System.Nix.StorePath
4344
4445-- * Compat
@@ -53,67 +54,48 @@ runStore
5354 )
5455 => RemoteStoreT m a
5556 -> Run m a
56- runStore = runStoreOpts defaultSockPath
57+ runStore = runStoreConnection def
5758
58- defaultSockPath :: String
59- defaultSockPath = " /nix/var/nix/daemon-socket/socket"
60-
61- runStoreOpts
62- :: ( MonadIO m
63- , MonadMask m
64- )
65- => FilePath
66- -> RemoteStoreT m a
67- -> Run m a
68- runStoreOpts socketPath =
69- runStoreOpts'
70- Network.Socket. AF_UNIX
71- (SockAddrUnix socketPath)
72-
73- runStoreOptsTCP
59+ runStoreConnection
7460 :: ( MonadIO m
7561 , MonadMask m
7662 )
77- => String
78- -> Int
63+ => StoreConnection
7964 -> RemoteStoreT m a
8065 -> Run m a
81- runStoreOptsTCP host port code = do
82- addrInfo <- liftIO $ Network.Socket. getAddrInfo
83- (Just Network.Socket. defaultHints)
84- (Just host)
85- (Just $ show port)
86- case addrInfo of
87- (sockAddr: _) ->
88- runStoreOpts'
89- (Network.Socket. addrFamily sockAddr)
90- (Network.Socket. addrAddress sockAddr)
91- code
92- _ -> pure (Left RemoteStoreError_GetAddrInfoFailed , mempty )
66+ runStoreConnection sc k =
67+ connectionToSocket sc
68+ >>= \ case
69+ Left e -> pure (Left e, mempty )
70+ Right (fam, sock) -> runStoreSocket fam sock k
9371
94- runStoreOpts'
72+ runStoreSocket
9573 :: ( MonadIO m
9674 , MonadMask m
9775 )
9876 => Family
9977 -> SockAddr
10078 -> RemoteStoreT m a
10179 -> Run m a
102- runStoreOpts' sockFamily sockAddr code =
80+ runStoreSocket sockFamily sockAddr code =
10381 Control.Monad.Catch. bracket
10482 (liftIO open)
10583 (liftIO . Network.Socket. close . hasStoreSocket)
106- (\ s -> runRemoteStoreT s $ runStoreSocket code)
84+ (\ s -> runRemoteStoreT s $ greetServer >> code)
10785 where
10886 open = do
109- soc <- Network.Socket. socket sockFamily Network.Socket. Stream 0
87+ soc <-
88+ Network.Socket. socket
89+ sockFamily
90+ Network.Socket. Stream
91+ Network.Socket. defaultProtocol
11092 Network.Socket. connect soc sockAddr
11193 pure soc
11294
11395justdoit :: Run IO (Bool , Bool )
11496justdoit = do
115- runDaemonOpts handler " /tmp/dsock" $
116- runStoreOpts " /tmp/dsock"
97+ runDaemonConnection handler ( StoreConnection_Socket " /tmp/dsock" ) $
98+ runStoreConnection ( StoreConnection_Socket " /tmp/dsock" )
11799 $ do
118100 a <- isValidPath pth
119101 b <- isValidPath pth
@@ -140,31 +122,81 @@ runDaemon
140122 -> m a
141123 -> m a
142124runDaemon workerHelper =
143- runDaemonOpts
125+ runDaemonConnection
144126 workerHelper
145- defaultSockPath
127+ def
128+
129+ -- | Run an emulated nix daemon using given @StoreConnection@
130+ -- the deamon will close when the continuation returns.
131+ runDaemonConnection
132+ :: forall m a
133+ . ( MonadIO m
134+ , MonadConc m
135+ )
136+ => WorkerHelper m
137+ -> StoreConnection
138+ -> m a
139+ -> m a
140+ runDaemonConnection workerHelper sc k =
141+ connectionToSocket sc
142+ >>= \ case
143+ Left e -> error $ show e
144+ Right (fam, sock) -> runDaemonSocket workerHelper fam sock k
146145
147- -- | Run an emulated nix daemon on given socket address.
146+ -- | Run an emulated nix daemon using given @StoreConnection@
148147-- the deamon will close when the continuation returns.
149- runDaemonOpts
148+ runDaemonSocket
150149 :: forall m a
151150 . ( MonadIO m
152151 , MonadConc m
153152 )
154153 => WorkerHelper m
155- -> FilePath
154+ -> Family
155+ -> SockAddr
156156 -> m a
157157 -> m a
158- runDaemonOpts workerHelper f k = Control.Monad.Catch. bracket
159- (liftIO
160- $ Network.Socket. socket
161- Network.Socket. AF_UNIX
162- Network.Socket. Stream
163- Network.Socket. defaultProtocol
164- )
165- (\ lsock -> liftIO $ Network.Socket. close lsock *> System.Directory. removeFile f)
166- $ \ lsock -> do
167- -- ^ ^^^^^^^^^^^
168- -- TODO: this: --------------------------------------------------////////////
169- liftIO $ Network.Socket. bind lsock (SockAddrUnix f)
170- runDaemonSocket workerHelper lsock k
158+ runDaemonSocket workerHelper sockFamily sockAddr k =
159+ Control.Monad.Catch. bracket
160+ (liftIO
161+ $ Network.Socket. socket
162+ sockFamily
163+ Network.Socket. Stream
164+ Network.Socket. defaultProtocol
165+ )
166+ (\ lsock -> liftIO $ Network.Socket. close lsock) -- *> System.Directory.removeFile f)
167+ $ \ lsock -> do
168+ -- ^ ^^^^^^^^^^^
169+ -- TODO: this: -------------------------------------------------------////////////
170+ -- should really be
171+ -- a file lock followed by unlink *before* bind rather than after close. If
172+ -- the program crashes (or loses power or something) then a stale unix
173+ -- socket will stick around and prevent the daemon from starting. using a
174+ -- lock file instead means only one "copy" of the daemon can hold the lock,
175+ -- and can safely unlink the socket before binding no matter how shutdown
176+ -- occured.
177+
178+ -- set up the listening socket
179+ liftIO $ Network.Socket. bind lsock sockAddr
180+ runProxyDaemon workerHelper lsock k
181+
182+ connectionToSocket
183+ :: MonadIO m
184+ => StoreConnection
185+ -> m (Either RemoteStoreError (Family , SockAddr ))
186+ connectionToSocket (StoreConnection_Socket (StoreSocketPath f)) =
187+ pure $ pure
188+ ( Network.Socket. AF_UNIX
189+ , SockAddrUnix f
190+ )
191+ connectionToSocket (StoreConnection_TCP StoreTCP {.. }) = do
192+ addrInfo <- liftIO $ Network.Socket. getAddrInfo
193+ (Just Network.Socket. defaultHints)
194+ (Just storeTCPHost)
195+ (Just $ show storeTCPPort)
196+ case addrInfo of
197+ (sockAddr: _) ->
198+ pure $ pure
199+ ( Network.Socket. addrFamily sockAddr
200+ , Network.Socket. addrAddress sockAddr
201+ )
202+ _ -> pure (Left RemoteStoreError_GetAddrInfoFailed )
0 commit comments