diff --git a/cardano-config.cabal b/cardano-config.cabal index d5407da..a5c8fd6 100644 --- a/cardano-config.cabal +++ b/cardano-config.cabal @@ -31,10 +31,10 @@ common warnings -Wall -Wunused-packages --- Deliberately small. library reexported-modules: - Cardano.Configuration + Cardano.Configuration, + Cardano.Configuration.CliArgs, build-depends: cardano-config:internal diff --git a/src/Cardano/Configuration.hs b/src/Cardano/Configuration.hs index 79f765b..6891bb9 100644 --- a/src/Cardano/Configuration.hs +++ b/src/Cardano/Configuration.hs @@ -8,6 +8,7 @@ module Cardano.Configuration NodeConfiguration (..) , resolveConfiguration , resolveConfigurationWith + , resolveConfigurationFromFile -- ** Consistency checks , ConfigCheck (..) @@ -36,6 +37,7 @@ module Cardano.Configuration , File.RequiresNetworkMagic (..) , File.Hashed (..) , CLI.Credentials (..) + , CLI.emptyCredentials , CLI.KESSource (..) -- ** Network @@ -43,6 +45,8 @@ module Cardano.Configuration , File.DiffusionMode (..) , File.AcceptedConnectionsLimit (..) , File.LocalConnectionsConfig (..) + , File.ResponderCoreAffinityPolicy (..) + , File.TxSubmissionLogicVersion (..) -- ** Testing , File.TestingConfiguration (..) @@ -62,8 +66,15 @@ module Cardano.Configuration , CLI.ShutdownOn (..) -- * CLI + + -- | The 'CLI.CliArgs' type is exported here, but its constructor and field + -- selectors are not (they would clash with the same-named 'NodeConfiguration' + -- fields). Consumers that build or override a 'CLI.CliArgs' directly should + -- import "Cardano.Configuration.CliArgs", which the public library also + -- re-exposes; 'CLI.defaultCliArgs' is a convenient starting point. , CLI.CliArgs , CLI.parseCliArgs + , CLI.defaultCliArgs -- ** Reusable option parsers , CLI.parseConfigFile @@ -99,6 +110,7 @@ import qualified Cardano.Configuration.Common as File import qualified Cardano.Configuration.File as File import Cardano.Configuration.File.Consensus import qualified Cardano.Configuration.File.Consensus as File +import qualified Cardano.Configuration.File.Network as File import qualified Cardano.Configuration.File.Protocol as File import qualified Cardano.Configuration.File.Storage as File import Cardano.Configuration.Genesis.Byron (ByronGenesisConfig) @@ -112,6 +124,7 @@ import Control.Exception (Exception) import Data.Functor.Identity import Data.IP import Data.List.NonEmpty (NonEmpty (..)) +import GHC.Stack (HasCallStack) import Network.Socket import System.Posix.Types @@ -249,6 +262,29 @@ resolveConfiguration :: Either ConfigResolutionError (NodeConfiguration, [File.ConfigWarning]) resolveConfiguration = resolveConfigurationWith defaultConfigChecks +-- | Resolve a full 'NodeConfiguration' from a configuration file alone, with no +-- command-line overrides. This is the common case for tools that consume a node +-- configuration file but have no node command line of their own (eg db-analyser, +-- db-immutaliser): the file is parsed with 'File.parseConfigurationFiles' and +-- resolved against 'CLI.defaultCliArgs', so every value comes from the file (and +-- the always-applied defaults layer). The returned warnings combine those raised +-- while parsing the files with those from the consistency checks. +-- +-- File-level parse failures are thrown as a 'File.ConfigurationParsingError' (as +-- in 'File.parseConfigurationFiles'); a well-formed file that fails a consistency +-- check is returned as a 'Left'. Consumers that need to supply command-line +-- overrides should instead build a 'CLI.CliArgs' (starting, if convenient, from +-- 'CLI.defaultCliArgs') and call 'resolveConfiguration' directly. +resolveConfigurationFromFile :: + HasCallStack => + FilePath -> + IO (Either ConfigResolutionError (NodeConfiguration, [File.ConfigWarning])) +resolveConfigurationFromFile configFile = do + (fileCfg, fileWarnings) <- File.parseConfigurationFiles configFile + pure $ case resolveConfiguration (CLI.defaultCliArgs configFile) fileCfg of + Left err -> Left err + Right (nc, checkWarnings) -> Right (nc, fileWarnings <> checkWarnings) + -- | As 'resolveConfiguration', but with an explicit set of consistency checks, -- so consumers can add their own (typically @'defaultConfigChecks' <> myChecks@). -- On success returns the resolved configuration together with any non-fatal diff --git a/src/Cardano/Configuration/CliArgs.hs b/src/Cardano/Configuration/CliArgs.hs index f882702..265756e 100644 --- a/src/Cardano/Configuration/CliArgs.hs +++ b/src/Cardano/Configuration/CliArgs.hs @@ -2,6 +2,7 @@ module Cardano.Configuration.CliArgs ( -- * CLI Arguments CliArgs (..) , parseCliArgs + , defaultCliArgs , ShutdownOn (..) -- * Tracing @@ -10,6 +11,7 @@ module Cardano.Configuration.CliArgs -- * Credentials , Credentials (..) + , emptyCredentials , KESSource (..) -- * Individual option parsers @@ -39,7 +41,7 @@ module Cardano.Configuration.CliArgs ) where import Cardano.Configuration.Common -import Cardano.Ledger.BaseTypes (StrictMaybe, maybeToStrictMaybe) +import Cardano.Ledger.BaseTypes (StrictMaybe (..), maybeToStrictMaybe) import Control.Monad (when) import Data.Bifunctor (second) import Data.IP (IPv4, IPv6) @@ -98,6 +100,20 @@ data Credentials = Credentials } deriving Show +-- | The block-forging credentials with nothing supplied: the value +-- 'parseCredentials' yields when no credential flag is given. A node with these +-- credentials is not a block producer. +emptyCredentials :: Credentials +emptyCredentials = + Credentials + { byronDelegationCertificate = SNothing + , byronSigningKey = SNothing + , shelleyKES = SNothing + , shelleyVRFKey = SNothing + , shelleyOperationalCertificate = SNothing + , bulkCredentialsFile = SNothing + } + -- | The CLI arguments, parsed with 'parseCliArgs' data CliArgs = CliArgs { configFilePath :: FilePath @@ -152,6 +168,38 @@ parseCliArgs = <*> optionalStrict parseEnableGrpc <*> optionalStrict parseGrpcSocketPath +-- | The 'CliArgs' for resolving a configuration from its file alone, with no +-- command-line overrides: every field takes the value 'parseCliArgs' would +-- produce were the command line to carry nothing but @--config CONFIGFILE@. +-- Intended for tools that consume a node configuration file but expose no node +-- command line of their own (see +-- 'Cardano.Configuration.resolveConfigurationFromFile'). Consumers that do need +-- to override some fields can start from this value and update the ones they +-- care about, rather than spelling out every default. +defaultCliArgs :: FilePath -> CliArgs +defaultCliArgs configFile = + CliArgs + { configFilePath = configFile + , topologyFile = defaultTopologyFile + , databasePathCLI = SNothing + , validateDatabase = False + , socketPath = SNothing + , credentials = emptyCredentials + , startAsNonProducingNode = SNothing + , hostAddr = SNothing + , hostIPv6Addr = SNothing + , port = SNothing + , tracerSocket = SNothing + , shutdownIPC = SNothing + , shutdownOnTarget = SNothing + , enableGrpcCLI = SNothing + , grpcSocketPathCLI = SNothing + } + +-- | The topology file path used when @--topology@ is not given. +defaultTopologyFile :: FilePath +defaultTopologyFile = "configuration/cardano/mainnet-topology.json" + parseTopologyFile :: Parser FilePath parseTopologyFile = strOption $ @@ -160,7 +208,7 @@ parseTopologyFile = , metavar "FILEPATH" , help "The path to a file describing the topology" , completer (bashCompleter "file") - , value "configuration/cardano/mainnet-topology.json" + , value defaultTopologyFile , showDefault ]