on master help sign in
Merge branch 'eac@use-ss-on-linux' into qa
commit502e465b0642c445d6c23a65a114dee120b3c2dd authorElliot Cameron <eacameron@gmail.com> dateFri 13 Dec 2019, 16:20 (7 years ago) parenta3732bd5048650
3 files changed+35−16
default.nix+4−1 lib/run/obelisk-run.cabal+3 lib/run/src/Obelisk/Run.hs+28−15
default.nix+4−1
@@ -48,6 +48,7 @@ let
4848 # Add obelisk packages
4949 (self: super: let
5050 pkgs = self.callPackage ({ pkgs }: pkgs) {};
51+ onLinux = pkg: f: if pkgs.stdenv.isLinux then f pkg else pkg;
5152 in {
5253 obelisk-executable-config-inject = pkgs.obeliskExecutableConfig.platforms.web.inject self;
5354
@@ -62,7 +63,9 @@ let
6263 ];
6364 };
6465 obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
65− obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
66+ obelisk-run = onLinux (self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {}) (pkg:
67+ haskellLib.overrideCabal pkg (drv: { librarySystemDepends = [ pkgs.iproute ]; })
68+ );
6669 obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
6770 obelisk-selftest = self.callCabal2nix "obelisk-selftest" (cleanSource ./lib/selftest) {};
6871 obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
lib/run/obelisk-run.cabal+3
@@ -48,3 +48,6 @@ library
4848 exposed-modules:
4949 Obelisk.Run
5050 ghc-options: -Wall -fwarn-redundant-constraints
51+ if os(linux)
52+ cpp-options: -DIPROUTE_SUPPORTED
53+ build-depends: which
lib/run/src/Obelisk/Run.hs+28−15
@@ -1,3 +1,8 @@
1+{-# LANGUAGE CPP #-}
2+#if defined(IPROUTE_SUPPORTED)
3+{-# LANGUAGE TemplateHaskell #-}
4+#endif
5+
16{-# LANGUAGE ConstraintKinds #-}
27{-# LANGUAGE FlexibleContexts #-}
38{-# LANGUAGE FlexibleInstances #-}
@@ -62,12 +67,15 @@ import Snap.Core (Snap)
6267import System.Environment
6368import System.IO
6469import System.Process
65−import System.Exit (ExitCode(..))
6670import Text.URI (URI)
6771import qualified Text.URI as URI
6872import Text.URI.Lens
6973import Web.Cookie
7074
75+#if defined(IPROUTE_SUPPORTED)
76+import qualified System.Which
77+#endif
78+
7179run
7280 :: Int -- ^ Port to run the backend
7381 -> ([Text] -> Snap ()) -- ^ Static asset handler
@@ -99,7 +107,7 @@ runServeAsset rootPath = Snap.serveAsset "" rootPath . T.unpack . T.intercalate
99107
100108getConfigRoute :: Map Text ByteString -> Either Text URI
101109getConfigRoute configs = case Map.lookup "common/route" configs of
102− Just r ->
110+ Just r ->
103111 let stripped = T.strip (T.decodeUtf8 r)
104112 in case URI.mkURI stripped of
105113 Just route -> Right route
@@ -122,20 +130,20 @@ runWidget conf configs frontend validFullEncoder = do
122130 settings = setBeforeMainLoop beforeMainLoop (setPort port (setTimeout 3600 defaultSettings))
123131 -- Providing TLS here will also incidentally provide it to proxied requests to the backend.
124132 prepareRunner = case (uri ^? uriScheme . _Just . unRText) of
125− Just "https" -> do
133+ Just "https" -> do
126134 -- Generate a private key and self-signed certificate for TLS
127135 privateKey <- RSA.generateRSAKey' 2048 3
128136
129137 certRequest <- X509Request.newX509Req
130138 _ <- X509Request.setPublicKey certRequest privateKey
131− _ <- X509Request.signX509Req certRequest privateKey Nothing
139+ _ <- X509Request.signX509Req certRequest privateKey Nothing
132140
133141 cert <- X509.newX509 >>= X509Request.makeX509FromReq certRequest
134142 _ <- X509.setPublicKey cert privateKey
135143 now <- getCurrentTime
136144 _ <- X509.setNotBefore cert $ addUTCTime (-1) now
137145 _ <- X509.setNotAfter cert $ addUTCTime (365 * 24 * 60 * 60) now
138− _ <- X509.signX509 cert privateKey Nothing
146+ _ <- X509.signX509 cert privateKey Nothing
139147
140148 certByteString <- BSUTF8.fromString <$> PEM.writeX509 cert
141149 privateKeyByteString <- BSUTF8.fromString <$> PEM.writePKCS8PrivateKey privateKey Nothing
@@ -212,17 +220,22 @@ logPortBindErr p e = getProcessIdForPort p >>= \case
212220 Nothing -> putStrLn $ "runWidget: " <> show e
213221 Just pid -> putStrLn $ unwords [ "Port", show p, "is being used by process ID", show pid <> ".", "Please kill that process or change the port in config/common/route."]
214222
223+ssPath :: Maybe String
224+ssPath =
225+#if defined(IPROUTE_SUPPORTED)
226+ Just $(System.Which.staticWhich "ss")
227+#else
228+ Nothing
229+#endif
230+
215231getProcessIdForPort :: Int -> IO (Maybe Int)
216−getProcessIdForPort port = do
217− -- First check if 'ss' is available
218− (c, _, _) <- readProcessWithExitCode "which" ["ss"] mempty
219− case c of
220− ExitSuccess -> do
221− xs <- lines <$> readProcess "ss" ["-lptn", "sport = " <> show port] mempty
222− case uncons xs of
223− Just (_, x:_) -> return $ A.maybeResult $ A.parse parseSsPid $ BSC.pack x
224− _ -> return Nothing
225− _ -> return Nothing
232+getProcessIdForPort port = case ssPath of
233+ Just ss -> do
234+ xs <- lines <$> readProcess ss ["-lptn", "sport = " <> show port] mempty
235+ case uncons xs of
236+ Just (_, x:_) -> return $ A.maybeResult $ A.parse parseSsPid $ BSC.pack x
237+ _ -> return Nothing
238+ _ -> return Nothing
226239
227240parseSsPid :: A.Parser Int
228241parseSsPid = do