module Ecluse.CheckConfig (runCheckConfig) where
import Data.Text.IO qualified as TIO
import Ecluse.Boot (loadBootConfig, refuseBoot, runtimeOverridesOf)
import Ecluse.Composition.BootError (renderAdvisory, renderBootErrors)
import Ecluse.Composition.Plan (
BootInputs (BootInputs, biConfig, biDocument, biEnvVars, biFdLimit, biRuntimePlan),
BootPlan (bpLines, bpWarnings),
BootReport (brAdvisories, brOutcome, brProvenance),
resolveBootPlan,
roleRefusalWarnings,
)
import Ecluse.Composition.Sizing (openFileSoftLimit)
import Ecluse.Composition.Types (BootRole (BootWithoutPipeline))
import Ecluse.Config (AppConfig (cfgRuntime), Config (configApp))
import Ecluse.Rts (
appliedRuntimePlan,
currentRtsPosture,
readCgroupLimits,
renderEffectivePosture,
renderPostureWarnings,
resolveRuntimePlan,
)
runCheckConfig :: IO ()
runCheckConfig :: IO ()
runCheckConfig = do
(envVars, docBlob, config) <- (Text -> Text) -> IO ([(String, String)], Maybe ByteString, Config)
loadBootConfig (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\nconfiguration: refused")
rts <- currentRtsPosture
cgroup <- readCgroupLimits
fdLimit <- openFileSoftLimit
let overrides = RuntimeSettings -> RuntimeOverrides
runtimeOverridesOf (AppConfig -> RuntimeSettings
cfgRuntime (Config -> AppConfig
configApp Config
config))
runtimePlan = RuntimeOverrides -> CgroupLimits -> RtsPosture -> RuntimePlan
resolveRuntimePlan RuntimeOverrides
overrides CgroupLimits
cgroup RtsPosture
rts
effective = CgroupLimits -> RuntimePlan -> RtsPosture -> EffectiveRuntimePlan
appliedRuntimePlan CgroupLimits
cgroup RuntimePlan
runtimePlan RtsPosture
rts
let inputs =
BootInputs
{ biEnvVars :: [(String, String)]
biEnvVars = [(String, String)]
envVars
, biDocument :: Maybe ByteString
biDocument = Maybe ByteString
docBlob
, biConfig :: Config
biConfig = Config
config
, biRuntimePlan :: EffectiveRuntimePlan
biRuntimePlan = EffectiveRuntimePlan
effective
, biFdLimit :: Int
biFdLimit = Int
fdLimit
}
report = BootRole -> BootInputs -> BootReport
resolveBootPlan BootRole
BootWithoutPipeline BootInputs
inputs
traverse_ TIO.putStrLn (renderEffectivePosture effective)
traverse_ warn (renderPostureWarnings effective)
traverse_ TIO.putStrLn (brProvenance report)
bootPlan <- case brOutcome report of
Left [BootError]
errs -> do
(Advisory -> IO ()) -> [Advisory] -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Text -> IO ()
warn (Text -> IO ()) -> (Advisory -> Text) -> Advisory -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Advisory -> Text
renderAdvisory) (BootReport -> [Advisory]
brAdvisories BootReport
report)
Text -> IO BootPlan
forall a. Text -> IO a
refuseBoot ([BootError] -> Text
renderBootErrors [BootError]
errs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\nconfiguration: refused")
Right BootPlan
plan -> BootPlan -> IO BootPlan
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure BootPlan
plan
traverse_ TIO.putStrLn (bpLines bootPlan)
traverse_ warn (bpWarnings bootPlan)
traverse_ (warn . renderAdvisory) (brAdvisories report)
traverse_ warn (roleRefusalWarnings BootWithoutPipeline inputs)
TIO.putStrLn "configuration: valid"
where
warn :: Text -> IO ()
warn :: Text -> IO ()
warn = Text -> IO ()
TIO.putStrLn (Text -> IO ()) -> (Text -> Text) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
"warning: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>)