17 #include <kea_version.h>
26 namespace ph = std::placeholders;
34 DControllerBase::DControllerBase(
const char* app_name,
const char* bin_name)
35 : app_name_(app_name), bin_name_(bin_name),
36 verbose_(false), check_only_(false),
47 "Multiple controller instances attempted.");
50 controller_ = controller;
75 return (EXIT_SUCCESS);
97 }
catch (
const std::exception& ex) {
99 .arg(app_name_).arg(ex.what());
107 .arg(bin_name_).arg(ex.
what());
109 }
catch (
const std::exception& ex) {
111 .arg(app_name_).arg(ex.what());
120 .arg(PACKAGE_VERSION_TYPE);
122 if (std::string(PACKAGE_VERSION_TYPE) ==
"development") {
128 }
catch (
const std::exception& ex) {
130 .arg(app_name_).arg(ex.what());
132 "Application Process initialization failed: " << ex.
what());
143 .arg(app_name_).arg(comment->stringValue());
145 << comment->stringValue());
149 start_ = boost::posix_time::second_clock::universal_time();
157 }
catch (
const std::exception& ex) {
159 .arg(app_name_).arg(ex.what());
161 "Application process event loop failed: " << ex.
what());
166 .arg(app_name_).arg(getpid()).arg(VERSION);
177 setenv(
"KEA_LOCKFILE_DIR",
"none", 0);
184 if (config_file.empty()) {
194 std::cerr <<
"Syntax check OK" << std::endl;
199 module_config = whole_config->get(
getAppName());
200 if (!module_config) {
202 " does not include '" <<
getAppName() <<
"' entry");
204 if (module_config->getType() != Element::map) {
206 " includes not map '" <<
getAppName() <<
"' entry");
211 if (!errmsg.empty()) {
223 << answer->stringValue());
229 }
catch (
const std::exception& ex) {
249 while ((ch = getopt(argc, argv, opts.c_str())) != -1) {
277 if (optarg == NULL) {
291 << static_cast<char>(optopt) <<
"] "
292 << (!optarg ?
"" : optarg));
302 << static_cast<char>(ch) <<
"] "
303 << (!optarg ?
"" : optarg));
329 }
catch (
const std::exception& ex) {
357 if (config_file.empty()) {
360 "use -c command line option.");
368 whole_config = Element::fromJSONFile(config_file,
true);
372 module_config = whole_config->get(
getAppName());
373 if (!module_config) {
375 " does not include '" <<
378 if (module_config->getType() != Element::map) {
380 " includes not map '" <<
getAppName() <<
"' entry");
385 if (!errmsg.empty()) {
401 storage->applyLoggingCfg();
405 process_->getCfgMgr()->getContext()->applyLoggingCfg();
406 }
catch (
const std::exception& ex) {
408 process_->getCfgMgr()->getContext()->applyLoggingCfg();
412 std::string(
"Configuration parsing failed: ") + ex.what());
436 return (process_->configure(new_config,
false));
442 return (process_->configure(new_config,
true));
448 ConstElementPtr config = process_->getCfgMgr()->getContext()->toElement();
456 std::string filename;
459 if (args->getType() != Element::map) {
460 return (
createAnswer(COMMAND_ERROR,
"Argument must be a map"));
463 if (filename_param) {
464 if (filename_param->getType() != Element::string) {
466 "passed parameter 'filename' "
469 filename = filename_param->stringValue();
473 if (filename.empty()) {
477 if (filename.empty()) {
479 "Unable to determine filename."
480 "Please specify filename explicitly."));
487 ElementPtr cfg = process_->getCfgMgr()->getContext()->toElement();
493 std::string(
"Error during write-config:")
498 "Error writing configuration to " + filename));
503 params->set(
"size", Element::create(static_cast<long long>(size)));
504 params->set(
"filename", Element::create(filename));
507 + filename +
" successful", params));
515 for (
auto obj : args->mapValue()) {
516 const std::string& obj_name = obj.first;
517 if (obj_name == app_name) {
521 .arg(
"'" + obj_name +
"', defining anything in global level besides '"
522 + app_name +
"' is no longer supported.");
523 if (errmsg.empty()) {
524 errmsg =
" contains unsupported '" + obj_name +
"' parameter";
526 errmsg +=
" (and '" + obj_name +
"')";
534 const int status_code = COMMAND_ERROR;
542 message =
"Missing mandatory 'arguments' parameter.";
544 module_config = args->get(app_name);
545 if (!module_config) {
546 message =
"Missing mandatory '" + app_name +
"' parameter.";
547 }
else if (module_config->getType() != Element::map) {
548 message =
"'" + app_name +
"' parameter expected to be a map.";
552 if (message.empty()) {
555 if (!errmsg.empty()) {
556 message =
"'arguments' parameter" + errmsg;
560 if (!message.empty()) {
586 const int status_code = COMMAND_ERROR;
594 message =
"Missing mandatory 'arguments' parameter.";
596 module_config = args->get(app_name);
597 if (!module_config) {
598 message =
"Missing mandatory '" + app_name +
"' parameter.";
599 }
else if (module_config->getType() != Element::map) {
600 message =
"'" + app_name +
"' parameter expected to be a map.";
604 if (!message.empty()) {
631 storage->applyLoggingCfg();
637 process_->getCfgMgr()->getContext()->applyLoggingCfg();
639 }
catch (
const std::exception& ex) {
641 process_->getCfgMgr()->getContext()->applyLoggingCfg();
645 std::string(
"Configuration parsing failed: ") + ex.what());
652 const std::string& tag = process_->getCfgMgr()->getContext()->getServerTag();
654 response->set(
"server-tag", Element::create(tag));
662 status->set(
"pid", Element::create(static_cast<int>(getpid())));
664 auto now = boost::posix_time::second_clock::universal_time();
665 if (!
start_.is_not_a_date_time()) {
666 auto uptime = now -
start_;
667 status->set(
"uptime", Element::create(uptime.total_seconds()));
670 auto last_commit = process_->getCfgMgr()->getContext()->getLastCommitTime();
671 if (!last_commit.is_not_a_date_time()) {
672 auto reload = now - last_commit;
673 status->set(
"reload", Element::create(reload.total_seconds()));
686 arguments->set(
"extended", extended);
703 int exit_value = EXIT_SUCCESS;
706 if (args->getType() != Element::map) {
712 if (param->getType() != Element::integer) {
714 "parameter 'exit-value' is not an integer"));
717 exit_value = param->intValue();
728 return (process_->shutdown(args));
734 return (
createAnswer(COMMAND_SUCCESS,
"Process has not been initialized"));
747 io_signal_set_->add(SIGHUP);
748 io_signal_set_->add(SIGINT);
749 io_signal_set_->add(SIGTERM);
763 .arg(comment->stringValue());
788 std::cerr <<
"Usage error: " << text << std::endl;
791 std::cerr <<
"Usage: " << bin_name_ << std::endl
792 <<
" -v: print version number and exit" << std::endl
793 <<
" -V: print extended version information and exit"
795 <<
" -W: display the configuration report and exit"
797 <<
" -d: optional, verbose output " << std::endl
798 <<
" -c <config file name> : mandatory,"
799 <<
" specify name of configuration file" << std::endl
800 <<
" -t <config file name> : check the"
801 <<
" configuration file and exit" << std::endl;
815 std::stringstream tmp;
819 tmp << std::endl << EXTENDED_VERSION << std::endl;
820 tmp <<
"linked with:" << std::endl;
virtual isc::data::ConstElementPtr parseFile(const std::string &file_name)
Parse a given file into Elements.
boost::shared_ptr< DControllerBase > DControllerBasePtr
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
std::string getVersion(bool extended)
returns Kea version on stdout and exit.
isc::data::ConstElementPtr statusGetHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for status-get command
isc::data::ConstElementPtr configTestHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for config-test command
isc::data::ConstElementPtr serverTagGetHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for server-tag-get command
virtual isc::data::ConstElementPtr configFromFile()
Reconfigures the process from a configuration file.
void usage(const std::string &text)
Prints the program usage text to std error.
virtual size_t writeConfigFile(const std::string &config_file, isc::data::ConstElementPtr cfg=isc::data::ConstElementPtr()) const
Writes current configuration to specified file.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
const isc::log::MessageID DCTL_INIT_PROCESS
isc::data::ConstElementPtr configReloadHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for config-reload command
Exception thrown when the application process fails.
virtual void processSignal(int signum)
Application-level signal processing method.
void parseArgs(int argc, char *argv[])
Processes the command line arguments.
const isc::log::MessageID DCTL_RUN_PROCESS
virtual ~DControllerBase()
Destructor.
const isc::log::MessageID DCTL_STANDALONE
Base class for all configurations.
const isc::log::MessageID DCTL_CFG_FILE_RELOAD_SIGNAL_RECVD
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
isc::log::Logger dctl_logger("dctl")
Defines the logger used within libkea-process library.
boost::shared_ptr< Element > ElementPtr
boost::posix_time::ptime start_
Timestamp of the start of the daemon.
void runProcess()
Invokes the application process's event loop,(DBaseProcess::run).
const isc::log::MessageID DCTL_INIT_PROCESS_FAIL
int getExitValue()
Fetches the exit value.
virtual bool customOption(int option, char *optarg)
Virtual method that provides derivations the opportunity to support additional command line options...
const isc::log::MessageID DCTL_CFG_FILE_RELOAD_ERROR
isc::data::ConstElementPtr shutdownHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for 'shutdown' command
const isc::log::MessageID DCTL_SHUTDOWN_SIGNAL_RECVD
The IOService class is a wrapper for the ASIO io_service class.
Exception used to convey version info upwards.
virtual std::string getVersionAddendum()
Fetches text containing additional version specifics.
static void setDefaultLoggerName(const std::string &logger)
Sets the default logger name.
const isc::log::MessageID DCTL_DEVELOPMENT_VERSION
isc::data::ConstElementPtr shutdownProcess(isc::data::ConstElementPtr args)
Initiates shutdown procedure.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const std::string getCustomOpts() const
Virtual method which returns a string containing the option letters for any custom command line optio...
const isc::log::MessageID DCTL_ALREADY_RUNNING
const char *const * d_config_report
Exception thrown when the controller encounters an operational error.
const char *const config_report[]
Implements an asynchronous "signal" for IOService driven processing.
static void setProcName(const std::string &proc_name)
Sets the process name.
const isc::log::MessageID DCTL_PROCESS_FAILED
virtual isc::data::ConstElementPtr checkConfig(isc::data::ConstElementPtr new_config)
Instance method invoked by the configuration event handler and which processes the actual configurati...
void setConfigFile(const std::string &config_file)
Sets the configuration file name.
bool isCheckOnly() const
Supplies whether or not check only mode is enabled.
std::string handleOtherObjects(isc::data::ConstElementPtr args)
Deals with other (i.e.
boost::shared_ptr< const Element > ConstElementPtr
isc::data::ConstElementPtr configWriteHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for config-write command
void checkConfigOnly()
Check the configuration.
virtual const std::string getUsageText() const
Virtual method which can be used to contribute derivation specific usage text.
const isc::log::MessageID DCTL_STARTING
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static void setVerbose(const bool verbose)
Sets or clears verbose mode.
virtual isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr new_config)
Instance method invoked by the configuration event handler and which processes the actual configurati...
virtual int launch(int argc, char *argv[], const bool test_mode)
Acts as the primary entry point into the controller execution and provides the outermost application ...
Exception thrown when the command line is invalid.
This is a base class for exceptions thrown from the DNS library module.
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
static void setController(const DControllerBasePtr &controller)
Static setter which sets the singleton instance.
Defines the logger used by the top-level component of kea-dhcp-ddns.
const isc::log::MessageID DCTL_CONFIG_DEPRECATED
isc::data::ConstElementPtr configGetHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for config-get command
static void loggerInit(const char *log_name, bool verbose)
Initializes logger.
Logging initialization functions.
void setExitValue(int value)
Sets the exit value.
void initProcess()
Instantiates the application process and then initializes it.
const isc::log::MessageID DCTL_NOT_RUNNING
isc::data::ConstElementPtr configSetHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for config-set command
This file contains several functions and constants that are used for handling commands and responses ...
Exception thrown when the controller launch fails.
A wrapper interface for the ASIO library.
std::string getAppName() const
Fetches the name of the application under control.
std::string getConfigFile() const
Returns config file name.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
static std::string getVersion()
Version.
std::string getConfigReport()
#define LOG_FATAL(LOGGER, MESSAGE)
Macro to conveniently test fatal output and log it.
const isc::log::MessageID DCTL_SHUTDOWN
isc::data::ConstElementPtr buildReportHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for 'build-report' command
Exception thrown when the PID file points to a live PID.
Exception thrown when the application process encounters an operation in its event loop (i...
void initSignalHandling()
Initializes signal handling.
const isc::log::MessageID DCTL_CONFIG_FILE_LOAD_FAIL
void createPIDFile(int pid=0)
Creates the PID file.
void checkConfigFile() const
Checks the configuration file name.
const int DBGLVL_START_SHUT
This is given a value of 0 as that is the level selected if debugging is enabled without giving a lev...
const isc::log::MessageID DCTL_PID_FILE_ERROR
virtual DProcessBase * createProcess()=0
Abstract method that is responsible for instantiating the application process object.
isc::data::ConstElementPtr versionGetHandler(const std::string &command, isc::data::ConstElementPtr args)
handler for version-get command
boost::shared_ptr< ConfigBase > ConfigPtr
Non-const pointer to the ConfigBase.
static void configureLogger(const isc::data::ConstElementPtr &log_config, const isc::process::ConfigPtr &storage)
Configures logger.
const isc::log::MessageID DCTL_UNSUPPORTED_SIGNAL