on master help sign in
Obelink.Run: Depend on "ss" on Linux only
commit50486507a01307475e819701896ecd110deea59c authorElliot Cameron <eacameron@gmail.com> dateFri 6 Dec 2019, 14:58 (7 years ago) parentcce6b67
3 files changed+31−12
default.nix+4−1 lib/run/obelisk-run.cabal+3 lib/run/src/Obelisk/Run.hs+24−11
default.nix+4−1
@@ -46,6 +46,7 @@ let
4646 # Add obelisk packages
4747 (self: super: let
4848 pkgs = self.callPackage ({ pkgs }: pkgs) {};
49+ onLinux = pkg: f: if pkgs.stdenv.isLinux then f pkg else pkg;
4950 in {
5051 obelisk-executable-config-inject = pkgs.obeliskExecutableConfig.platforms.web.inject self;
5152
@@ -55,7 +56,9 @@ let
5556 obelisk-cliapp = self.callCabal2nix "obelisk-cliapp" (cleanSource ./lib/cliapp) {};
5657 obelisk-command = haskellLib.overrideCabal (self.callCabal2nix "obelisk-command" (cleanSource ./lib/command) {}) { librarySystemDepends = [ pkgs.nix ]; };
5758 obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
58− obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
59+ obelisk-run = onLinux (self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {}) (pkg:
60+ haskellLib.overrideCabal pkg (drv: { librarySystemDepends = [ pkgs.iproute ]; })
61+ );
5962 obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
6063 obelisk-selftest = self.callCabal2nix "obelisk-selftest" (cleanSource ./lib/selftest) {};
6164 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+24−11
@@ -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
@@ -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