The Configuration and Runtime Control Library

The Console library implements a runtime interactive (network) console which allows to configure, control and manipulate a running application in any way. Additionally this library provides support for configuration files and command line parsing which can be used with or without the network console.

1. Introduction

There are three parts to the Config/console library:

The Config/Console library is built around several components

  • The Node tree represents all configuration options and commands organized in a filesystem like structure.
  • Actions are added to the node tree in the form of command nodes.
  • There exist several interfaces to access entries in the node tree: interactive console, reading configuration files etc.
The node tree works like a directory structure. Commands are entered into this directory structure and can be called passing arbitrary arguments. Configuration parameters are just commands which set their respective parameter, however the library allows commands to do much more than just that.

2. Example

The following example shows a very short summary on how to integrate the config/console library. See above links for more:
#include <senf/Console.hh>

// Define callback function.
void mycommand(std::ostream & os, int foo, int bar)
{
    // ...
    os << "!! Important message ...\n";
}

namespace kw = senf::console::kw;
namespace fty = senf::console::factory;

int main(int argc, char** argv)
{
    // Provide global documentation
    senf::console::root()
        .doc("This is someServer server");

    // Add a command
    senf::console::root().add("mycommand", fty::Command(&mycommand)
        .doc("If <bar> is given, flurgle the <foo>, otherwise burgle it")
        .arg("foo")
        .arg(kw::name = "bar", kw::default_value = 0) );

   // Parse command line parameters
   senf::console::parseOptions(argc,argv);

    // Start the interactive console server
    senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u))
        .name("someServer");

    // Run the scheduler
   senf::scheduler::process();
}

after this registration, we can call the command from the command-line using

$ someServer --mycommand="1 2"

the console can be accessed easily via telnet:

$ telnet localhost 23232
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'
xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Registered new client 0xxxxxxx
someServer:/# ls
mycommand
someServer:/# mycommand
!! Important message  ...
someServer:/# exit
xxxx-xx-xx xx:xx:xx.xxxxxx-0000 [NOTICE][senf::console::Server] Disposing client 0xxxxxxx
Connection closed by foreign host.
$
See also:
Test Server for a complete example application

3. Using the Console: Configuration files, Network console

     →  see Accessing the Console/Config tree

There are several ways to access the node tree:

  • By parsing configuration files
  • By parsing command line parameters
  • By providing interactive or non-interactive network console access

4. The node tree

     →  see The node tree

The basic idea is, that the console/config library manages a directory structure of parameters and auxiliary commands. Parameters are just commands which set a parameter value so everything is either a directory entry (senf::console::DirectoryNode) or a command (senf::console::CommandNode).

5. Implementing console/config commands

     →  see Supported command types
     →  see senf::console::factory

The console/config language does not define, how arguments are passed to the commands, it just tokenizes the input and passes the tokens to the commands which then handle the conversion.

Since parsing the tokens into something usable is quite tedious and error prone, the library implements automatic argument parsing where the argument tokens are automatically parsed depending on argument types. This enables you to register a command taking an integer argument which will be called with an already parsed integer value (or throw a senf::console::SyntaxErrorException if the conversion fails). This will be the most often used command.