cachix-1.6.1: src/Cachix/Client/Daemon/Client.hs
module Cachix.Client.Daemon.Client (push, stop) where
import Cachix.Client.Config as Config
import Cachix.Client.Daemon.Listen (getSocketPath)
import Cachix.Client.Daemon.Types (ClientMessage (..), PushRequest (..))
import Cachix.Client.Env as Env
import Cachix.Client.OptionsParser (DaemonOptions (..))
import Cachix.Types.BinaryCache (BinaryCacheName)
import qualified Data.Aeson as Aeson
import qualified Network.Socket as Socket
import qualified Network.Socket.ByteString.Lazy as Socket.LBS
import Protolude
import qualified System.Posix.IO as Posix
-- | Queue up push requests with the daemon
--
-- TODO: wait for the daemon to respond that it has received the request
push :: Env -> DaemonOptions -> BinaryCacheName -> [FilePath] -> IO ()
push Env {config, cachixoptions} daemonOptions cacheName storePaths = do
sock <- connectToDaemon (daemonSocketPath daemonOptions)
Socket.LBS.sendAll sock (Aeson.encode pushRequest)
where
pushRequest =
ClientPushRequest $
PushRequest (Config.authToken config) cacheName (Config.host cachixoptions) storePaths
-- | Tell the daemon to stop and wait for it gracefully exit
stop :: Env -> DaemonOptions -> IO ()
stop _env daemonOptions = do
sock <- connectToDaemon (daemonSocketPath daemonOptions)
Socket.LBS.sendAll sock (Aeson.encode ClientStop)
-- Wait for the socket to close
void $ Socket.LBS.recv sock 1
connectToDaemon :: Maybe FilePath -> IO Socket.Socket
connectToDaemon optionalSocketPath = do
socketPath <- maybe getSocketPath pure optionalSocketPath
sock <- Socket.socket Socket.AF_UNIX Socket.Stream Socket.defaultProtocol
Socket.connect sock (Socket.SockAddrUnix socketPath)
-- Network.Socket.accept sets the socket to non-blocking by default.
Socket.withFdSocket sock $ \fd ->
Posix.setFdOption (fromIntegral fd) Posix.NonBlockingRead False
return sock