packages feed

sensu-run 0.4.0.5 → 0.5.0

raw patch · 4 files changed

+61/−21 lines, 4 filesdep +asyncdep +http-client-tlsdep ~temporarydep ~unix

Dependencies added: async, http-client-tls

Dependency ranges changed: temporary, unix

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for sensu-run +## 0.5.0 -- 2018-04-20++* Add support for HTTPS (#18)+* Do not append new line to the output when the command was successful+* Add --redirect option (#12)+* Relax upper version bound for temporary+* Tighten upper version bound for unix+ ## 0.4.0.5 -- 2018-04-09  * Relax upper version bounds for base and aeson
README.md view
@@ -10,11 +10,13 @@  ## Installation +NOTE: Currently sensu-run doesn't work on Windows. See [#16](https://github.com/maoe/sensu-run/issues/16).+ Binary releases are available at [GitHub Releases](https://github.com/maoe/sensu-run/releases). Currently supported platforms for the binary releases are:  * Ubuntu (64bit) * macOS-* Windows (x64)+* Windows (x64, x86)  You can also build it yourself using [stack](https://docs.haskellstack.org/en/stable/README/): ```sh@@ -28,8 +30,8 @@ % sensu-run --help Usage: sensu-run ([-n|--name NAME] [--source SOURCE] [--ttl SECONDS]                  [--timeout SECONDS] [--handler HANDLER] ([--port PORT] |-                 [--server URL]) [--dry|--dry-run] [-s|--shell] [COMMAND] |-                 [-v|--version])+                 [--server URL]) [--redirect] [--dry|--dry-run] [-s|--shell]+                 [COMMAND] | [-v|--version])  Available options:   -h,--help                Show this help text@@ -44,6 +46,8 @@   --port PORT              Send results to the local sensu-client listening on                            the specified port (default: 3030)   --server URL             Send results to the specified Sensu server+  --redirect               Redirect command output to sensu-run's output+  --dry,--dry-run          Dump the JSON object which is supposed to be sent   -s,--shell               Execute the command using the shell ``` 
sensu-run.cabal view
@@ -1,5 +1,5 @@ name: sensu-run-version: 0.4.0.5+version: 0.5.0 synopsis: A tool to send command execution results to Sensu description:   @sensu-run@ is a command line tool to send command execution results to Sensu@@ -26,16 +26,18 @@   main-is: sensu-run.hs   build-depends:       aeson >= 0.11 && < 1.4+    , async < 2.3     , base >= 4.9 && < 4.12     , bytestring >= 0.10 && < 0.11     , filepath >= 1.4.1 && < 1.5     , http-client >= 0.5.6 && < 0.6+    , http-client-tls < 0.4     , http-types >= 0.9.1 && < 0.13     , lens >= 4.15 && < 4.17     , network >= 2.2.3 && < 2.7     , optparse-applicative >= 0.12 && < 0.15     , process >= 1.4 && < 1.7-    , temporary >= 1.1 && < 1.3+    , temporary >= 1.1 && < 1.4     , text >= 1.2.2 && < 1.3     , time >= 1.5.0.1 && < 1.10     , unix-compat < 0.6@@ -47,6 +49,6 @@   if os(windows)     cpp-options: -DWINDOWS   else-    build-depends: unix+    build-depends: unix < 2.8   ghc-options: -Wall -threaded   default-language: Haskell2010
sensu-run.hs view
@@ -13,7 +13,9 @@ {-# LANGUAGE ViewPatterns #-} module Main where import Control.Exception+import Control.Monad import Data.Foldable+import Data.Function import Data.List.NonEmpty (NonEmpty) import Data.Maybe import Data.Monoid@@ -24,17 +26,21 @@ import qualified System.Timeout as Timeout import Prelude +import Control.Concurrent.Async import Control.Lens hiding ((.=)) import Data.Time import Data.Time.Clock.POSIX import Network.HTTP.Client (HttpException)+import Network.HTTP.Client.TLS import Network.Socket import System.FilePath ((</>)) import System.IO.Temp import System.Process import System.PosixCompat.User (getEffectiveUserName)+import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy.Char8 as BL8+import qualified Data.ByteString.Lazy.Internal as BLI import qualified Data.Text as T import qualified Data.Text.Encoding.Error as TE import qualified Data.Text.Lazy as TL@@ -64,12 +70,18 @@     RunOptions {..} -> withSystemTempFile "sensu-run.XXX" $ \path hdl -> do       executed <- getCurrentTime       rawStatus <- try $ bracket-        (startProcess cmdspec hdl)-        (\ph -> do+        (startProcess cmdspec)+        (\(_, _, ph) -> do           terminateProcess ph           killProcessTree ph           waitForProcess ph)-        (withTimeout timeout . waitForProcess)+        $ \(out, err, ph) -> do+          aout <- async $ redirectOutput out $ if redirect+            then [hdl, stdout] else [hdl]+          aerr <- async $ redirectOutput err $ if redirect+            then [hdl, stderr] else [hdl]+          mapM_ waitCatch [aout, aerr]+          withTimeout timeout $ waitForProcess ph       hClose hdl       exited <- getCurrentTime       rawOutput <- BL.readFile path@@ -79,10 +91,9 @@           { command = cmdspec           , output = TL.toLazyText $ mconcat             [ TL.fromLazyText (TL.decodeUtf8With TE.lenientDecode rawOutput)-            , "\n"-            , TL.fromString $ case rawStatus of-              Left ioe -> show (ioe :: IOException)-              Right Nothing -> "sensu-run: timed out"+            , case rawStatus of+              Left (ioe :: IOException) -> "\n" <> TL.fromString (show ioe)+              Right Nothing -> "\n" <> "sensu-run: timed out"               Right _ -> mempty             ]           , status = case rawStatus of@@ -140,22 +151,23 @@         | HT.statusIsSuccessful status -> return ()         | otherwise ->           fail $ "sendToSensuServer: unexpected status " ++ show status-    params = W.defaults &-      W.header "Content-Type" .~ ["application/json"]+    params = W.defaults+      & W.header "Content-Type" .~ ["application/json"]+      & W.manager .~ Left tlsManagerSettings     handleError reason = do       hPutStrLn stderr $         "Failed to POST results to Sensu server (" ++ reason ++ ")"       exitFailure -startProcess :: CmdSpec -> Handle -> IO ProcessHandle-startProcess cmdspec hdl = do-  (_, _, _, ph) <- createProcess CreateProcess+startProcess :: CmdSpec -> IO (Handle, Handle, ProcessHandle)+startProcess cmdspec = do+  (_, Just out, Just err, ph) <- createProcess CreateProcess     { cmdspec     , cwd = Nothing     , env = Nothing     , std_in = Inherit-    , std_out = UseHandle hdl-    , std_err = UseHandle hdl+    , std_out = CreatePipe+    , std_err = CreatePipe     , close_fds = False     , create_group = True -- necessary to not kill sensu-run itself     , delegate_ctlc = False@@ -168,8 +180,16 @@     , use_process_jobs = True #endif     }-  return ph+  return (out, err, ph) +redirectOutput :: Handle -> [Handle] -> IO ()+redirectOutput source sinks = fix $ \loop -> do+  eof <- hIsEOF source+  unless eof $ do+    chunk <- B.hGetSome source BLI.defaultChunkSize+    mapM_ (flip B.hPut chunk) sinks+    loop+ withTimeout :: Maybe NominalDiffTime -> IO a -> IO (Maybe a) withTimeout time io = case time of   Just n -> Timeout.timeout (seconds n) io@@ -187,6 +207,7 @@     , timeout :: Maybe NominalDiffTime     , handlers :: [T.Text]     , endpoint :: Endpoint+    , redirect :: Bool     , dryRun :: Bool     } @@ -239,9 +260,14 @@         [ ClientSocketInput <$> portOption         , SensuServer . NE.fromList <$> O.some serverOption         ]+      redirect <- O.switch $ mconcat+        [ O.long "redirect"+        , O.help "Redirect command output to sensu-run's output"+        ]       dryRun <- O.switch $ mconcat         [ O.long "dry-run"         , O.long "dry"+        , O.help "Dump the JSON object which is supposed to be sent"         ]       cmdspec <- cmdSpecOption       return RunOptions {..}