File: Main.hs

package info (click to toggle)
haskell-pid1 0.1.3.1-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 92 kB
  • sloc: haskell: 194; makefile: 6
file content (39 lines) | stat: -rw-r--r-- 1,808 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module Main (main) where
-- | This is a valid PID 1 process in Haskell, intended as a Docker
-- entrypoint. It will handle reaping orphans and handling TERM and
-- INT signals.

import Data.Maybe (fromMaybe)
import System.Process.PID1
import System.Environment
import System.Console.GetOpt
import System.IO (stderr, hPutStr)
import System.Exit (exitFailure)

-- | `GetOpt` command line options
options :: [(String, String)] -> [OptDescr (RunOptions -> RunOptions)]
options defaultEnv =
  [ Option ['e'] ["env"] (ReqArg (\opt opts -> setRunEnv (optEnvList (getRunEnv opts) opt) opts) "ENV") "override environment variable from given name=value pair. Can be specified multiple times to set multiple environment variables"
  , Option ['u'] ["user"] (ReqArg setRunUser "USER") "run command as user"
  , Option ['g'] ["group"] (ReqArg setRunGroup "GROUP") "run command as group"
  , Option ['w'] ["workdir"] (ReqArg setRunWorkDir "DIR") "command working directory"
  , Option ['t'] ["timeout"] (ReqArg (setRunExitTimeoutSec . read) "TIMEOUT") "timeout (in seconds) to wait for all child processes to exit" ]
  where optEnv env' kv =
          let kvp = fmap (drop 1) $ span (/= '=') kv in
            kvp:filter ((fst kvp /=) . fst) env'
        optEnvList = optEnv . fromMaybe defaultEnv

main :: IO ()
main = do
    -- Figure out the actual thing to run and spawn it off.
    args0 <- getArgs
    defaultEnv <- getEnvironment
    progName <- getProgName
    let opts = options defaultEnv
    case getOpt RequireOrder opts args0 of
      (o, (cmd:args), []) -> let runOpts = foldl (flip id) defaultRunOptions o in
        runWithOptions runOpts cmd args
      _ -> do
        let usage = "Usage: " ++ progName ++ " [OPTION...] command [args...]"
        hPutStr stderr (usageInfo usage opts)
        exitFailure