Add server-unix-socket config option (#1303)

Add ncat workaround to test socket connection on CircleCI
This commit is contained in:
Dan Amoroso
2019-06-05 12:57:47 -05:00
committed by Steve Chávez
parent e292fb5eb9
commit 78e5677fbe
8 changed files with 102 additions and 18 deletions
+5
View File
@@ -66,6 +66,11 @@ jobs:
- restore_cache:
keys:
- v1-stack-dependencies-{{ checksum "postgrest.cabal" }}-{{ checksum "stack.yaml" }}
- run:
name: install ncat
command: |
# utility needed to test socket connection with curl < 7.40
sudo apt-get install nmap
- run:
name: install stack & dependencies
command: |
+1
View File
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- #1186, Add support for user defined unix socket via `server-unix-socket` config option
- #690, Add `?columns` query parameter for faster bulk inserts, also ignores unspecified json keys in a payload - @steve-chavez
- #1239, Add support for resource embedding on materialized views - @vitorbaptista
- #1264, Add support for bulk RPC call - @steve-chavez
+49 -16
View File
@@ -15,13 +15,22 @@ import Control.Retry (RetryStatus, capDelay,
import Data.IORef (IORef, atomicWriteIORef, newIORef,
readIORef)
import Data.String (IsString (..))
import Data.Text (pack, replace, strip, stripPrefix)
import Data.Text (pack, replace, strip, stripPrefix,
unpack)
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Data.Text.IO (hPutStrLn, readFile)
import Data.Time.Clock (getCurrentTime)
import Network.Socket (Family (AF_UNIX),
SockAddr (SockAddrUnix), Socket,
SocketType (Stream), bind, close,
defaultProtocol, listen,
maxListenQueue, socket)
import Network.Wai.Handler.Warp (defaultSettings, runSettings,
setHost, setPort, setServerName)
runSettingsSocket, setHost, setPort,
setServerName)
import System.Directory (removeFile)
import System.IO (BufferMode (..), hSetBuffering)
import System.IO.Error (isDoesNotExistError)
import PostgREST.App (postgrest)
import PostgREST.Config (AppConfig (..), configPoolTimeout',
@@ -153,6 +162,7 @@ main = do
let host = configHost conf
port = configPort conf
proxy = configProxyUri conf
maybeSocketAddr = configSocket conf
pgSettings = toS (configDatabase conf) -- is the db-uri
roleClaimKey = configRoleClaimKey conf
appSettings =
@@ -170,7 +180,6 @@ main = do
when (isLeft roleClaimKey) $
panic $ show roleClaimKey
putStrLn $ ("Listening on port " :: Text) <> show (configPort conf)
--
-- create connection pool with the provided settings, returns either
-- a 'Connection' or a 'ConnectionError'. Does not throw.
@@ -222,19 +231,31 @@ main = do
-- ask for the OS time at most once per second
getTime <- mkAutoUpdate defaultUpdateSettings {updateAction = getCurrentTime}
-- run the postgrest application
runSettings appSettings $
postgrest
conf
refDbStructure
pool
getTime
(connectionWorker
mainTid
pool
(configSchema conf)
refDbStructure
refIsWorkerOn)
let postgrestApplication =
postgrest
conf
refDbStructure
pool
getTime
(connectionWorker
mainTid
pool
(configSchema conf)
refDbStructure
refIsWorkerOn)
in case maybeSocketAddr of
Nothing -> do
-- run the postgrest application
putStrLn $ ("Listening on port " :: Text) <> show (configPort conf)
runSettings appSettings postgrestApplication
Just socketAddr -> do
-- run postgrest application with user defined socket
sock <- createAndBindSocket (unpack socketAddr)
listen sock maxListenQueue
putStrLn $ ("Listening on unix socket " :: Text) <> show socketAddr
runSettingsSocket appSettings sock postgrestApplication
-- clean socket up when done
close sock
{-|
The purpose of this function is to load the JWT secret from a file if
@@ -302,3 +323,15 @@ loadDbUriFile conf = extractDbUri mDbUri
Nothing -> return dbUri
Just filename -> strip <$> readFile (toS filename)
setDbUri dbUri = conf {configDatabase = dbUri}
createAndBindSocket :: FilePath -> IO Socket
createAndBindSocket filePath = do
deleteSocketFileIfExist filePath
sock <- socket AF_UNIX Stream defaultProtocol
bind sock $ SockAddrUnix filePath
return sock
where
deleteSocketFileIfExist path = removeFile path `catch` handleDoesNotExist
handleDoesNotExist e
| isDoesNotExistError e = return ()
| otherwise = throwIO e
+5 -2
View File
@@ -33,17 +33,20 @@ executable postgrest
default-language: Haskell2010
build-depends: auto-update
, base >= 4.8 && < 4.10
, base64-bytestring
, bytestring
, hasql >= 1.3 && < 1.4
, hasql-pool >= 0.5 && < 0.6
, hasql-transaction >= 0.7 && < 0.8
, network == 2.6.3.2
, postgrest
, protolude == 0.2.2
, retry
, text
, time
, warp
, bytestring
, base64-bytestring
, retry
, directory
if !os(windows)
build-depends: unix
+6
View File
@@ -70,6 +70,7 @@ data AppConfig = AppConfig {
, configSchema :: Text
, configHost :: Text
, configPort :: Int
, configSocket :: Maybe Text
, configJwtSecret :: Maybe B.ByteString
, configJwtSecretIsBase64 :: Bool
@@ -149,6 +150,7 @@ readOptions = do
<*> reqString "db-schema"
<*> (fromMaybe "!4" . mfilter (/= "") <$> optString "server-host")
<*> (fromMaybe 3000 . join . fmap coerceInt <$> optValue "server-port")
<*> optString "server-unix-socket"
<*> (fmap encodeUtf8 . mfilter (/= "") <$> optString "jwt-secret")
<*> (fromMaybe False . join . fmap coerceBool <$> optValue "secret-is-base64")
<*> parseJwtAudience "jwt-aud"
@@ -231,6 +233,10 @@ readOptions = do
|server-host = "!4"
|server-port = 3000
|
|## unix socket location
|## if specified it takes precedence over server-port
|# server-unix-socket = "/tmp/pgrst.sock"
|
|## base url for swagger output
|# server-proxy-uri = ""
|
+2
View File
@@ -64,6 +64,8 @@ getEnvVarWithDefault var def = toS <$>
_baseCfg :: AppConfig
_baseCfg = -- Connection Settings
AppConfig mempty "postgrest_test_anonymous" Nothing "test" "localhost" 3000
-- No user configured Unix Socket
Nothing
-- Jwt settings
(Just $ encodeUtf8 "reallyreallyreallyreallyverysafe") False Nothing
-- Connection Modifiers
+27
View File
@@ -181,6 +181,30 @@ ensureAppSettings(){
pgrStop
}
getSocketStatus() {
curl -sL -w "%{http_code}\\n" -o /dev/null localhost:54321
}
socketConnection(){
# map port 54321 traffic to unix socket as workaround for curl below 7.40
# not supporting --unix-socket flag
ncat -vlk 54321 -c 'ncat -U /tmp/postgrest.sock' &
pgrStart "./configs/unix-socket.config"
while pgrStarted && test "$( getSocketStatus )" -ne 200
do
# wait for the server to start
sleep 0.1 \
|| sleep 1 # fallback: subsecond sleep is not standard and may fail
done
if test $( getSocketStatus ) -eq 200
then
ok "Succesfully connected through unix socket"
else
ko "Failed to connect through unix socket"
fi
pgrStop
}
# PRE: curl must be available
test -n "$(command -v curl)" || bailOut 'curl is not available'
@@ -191,6 +215,8 @@ setUp
echo "Running IO tests.."
socketConnection
readSecretFromFile word.noeol 'simple (no EOL)'
readSecretFromFile word.txt 'simple'
readSecretFromFile ascii.noeol 'ASCII (no EOL)'
@@ -224,6 +250,7 @@ invalidRoleClaimKey 1234
ensureIatClaimWorks
ensureAppSettings
cleanUp
exit $failedTests
+7
View File
@@ -0,0 +1,7 @@
db-uri = "postgres:///postgrest_test"
db-schema = "test"
db-anon-role = "postgrest_test_anonymous"
db-pool = 1
server-host = "127.0.0.1"
server-unix-socket = "/tmp/postgrest.sock"
jwt-secret = "reallyreallyreallyreallyverysafe"