aboutsummaryrefslogtreecommitdiffstats
path: root/configd/src/apps/sentinel/config-handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'configd/src/apps/sentinel/config-handler.cpp')
-rw-r--r--configd/src/apps/sentinel/config-handler.cpp341
1 files changed, 12 insertions, 329 deletions
diff --git a/configd/src/apps/sentinel/config-handler.cpp b/configd/src/apps/sentinel/config-handler.cpp
index d9f4d1f8bd7..a2ac35edd7f 100644
--- a/configd/src/apps/sentinel/config-handler.cpp
+++ b/configd/src/apps/sentinel/config-handler.cpp
@@ -14,20 +14,6 @@ LOG_SETUP(".config-handler");
namespace config::sentinel {
-int
-ConfigHandler::listen(int port) {
- auto handle = vespalib::SocketAddress::select_local(port).listen();
- if (!handle) {
- LOG(error, "Fatal: listen on command control socket failed: %s", strerror(errno));
- EV_STOPPING("config-sentinel", "listen on command control socket failed");
- exit(EXIT_FAILURE);
- }
- int fd = handle.release();
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
- fcntl(fd, F_SETFD, FD_CLOEXEC);
- return fd;
-}
-
void
ConfigHandler::configure_port(int port)
{
@@ -43,21 +29,21 @@ ConfigHandler::configure_port(int port)
EV_STOPPING("config-sentinel", "bad port");
exit(EXIT_FAILURE);
}
- LOG(debug, "Config-sentinel accepts connections on port %d", port);
- close(_commandSocket);
- _commandSocket = listen(port);
- _boundPort = port;
+ if (port != _boundPort) {
+ LOG(debug, "Config-sentinel accepts connections on port %d", port);
+ _stateServer = std::make_unique<vespalib::StateServer>(
+ port, _stateApi.myHealth, _startMetrics.producer, _stateApi.myComponents);
+ _boundPort = port;
+ }
}
ConfigHandler::ConfigHandler()
: _subscriber(),
_services(),
- _connections(),
_outputConnections(),
_boundPort(0),
- _commandSocket(listen(0)),
_startMetrics(),
- _stateApi(_startMetrics.producer)
+ _stateApi()
{
_startMetrics.startedTime = time(nullptr);
}
@@ -65,17 +51,11 @@ ConfigHandler::ConfigHandler()
ConfigHandler::~ConfigHandler()
{
terminateServices(false);
- std::list<CommandConnection *>::iterator i;
- for (i = _connections.begin(); i != _connections.end(); ++i)
- {
- delete *i;
- }
std::list<OutputConnection *>::iterator it;
for (it = _outputConnections.begin(); it != _outputConnections.end(); ++it)
{
delete *it;
}
- close(_commandSocket);
}
void
@@ -154,7 +134,6 @@ ConfigHandler::doConfigure()
if (config.port.telnet != _boundPort) {
configure_port(config.port.telnet);
- _stateApi.bound(_boundPort);
}
if (!_rpcServer || config.port.rpc != _rpcServer->getPort()) {
@@ -245,25 +224,6 @@ ConfigHandler::updateActiveFdset(fd_set *fds, int *maxNum)
}
}
}
- FD_SET(_commandSocket, fds);
- if (_commandSocket >= *maxNum) {
- *maxNum = _commandSocket + 1;
- }
-
- std::list<CommandConnection *>::const_iterator
- connections = _connections.begin();
-
- while (connections != _connections.end()) {
- CommandConnection *c = *connections;
- ++connections;
- int fd = c->fd();
- if (fd != -1) {
- FD_SET(fd, fds);
- if (fd >= *maxNum) {
- *maxNum = fd + 1;
- }
- }
- }
}
void
@@ -292,47 +252,12 @@ ConfigHandler::handleOutputs()
void
ConfigHandler::handleCommands()
{
- {
- // handle RPC commands
- std::vector<Cmd::UP> got = _cmdQ.drain();
- for (const Cmd::UP & cmd : got) {
- handleCmd(*cmd);
- }
- // implicit return via Cmd destructor
- }
-
- // Accept new command connections, and read commands.
- int fd;
- struct sockaddr_storage sad;
- socklen_t sadLen = sizeof(sad);
- while ((fd = accept(_commandSocket,
- reinterpret_cast<struct sockaddr *>(&sad),
- &sadLen)) >= 0)
- {
- LOG(debug, "Got new command connection!");
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
- CommandConnection *c = new CommandConnection(fd);
- _connections.push_back(c);
- }
-
- std::list<CommandConnection *>::iterator dst;
- std::list<CommandConnection *>::const_iterator src;
-
- src = _connections.begin();
- dst = _connections.begin();
- while (src != _connections.end()) {
- CommandConnection *c = *src;
- ++src;
- handleCommand(c);
- if (c->isFinished()) {
- LOG(debug, "Connection is finished..");
- delete c;
- } else {
- *dst = c;
- ++dst;
- }
+ // handle RPC commands
+ std::vector<Cmd::UP> got = _cmdQ.drain();
+ for (const Cmd::UP & cmd : got) {
+ handleCmd(*cmd);
}
- _connections.erase(dst, _connections.end());
+ // implicit return via Cmd destructor
}
Service *
@@ -359,23 +284,6 @@ ConfigHandler::serviceByName(const vespalib::string & name)
void
-splitCommand(char *line, char *&cmd, char *&args)
-{
- cmd = line;
- while (*line && !isspace(*line)) {
- *line = tolower(*line);
- ++line;
- }
- if (*line) {
- *line++ = '\0';
- while (*line && isspace(*line)) {
- ++line;
- }
- }
- args = line;
-}
-
-void
ConfigHandler::handleCmd(const Cmd& cmd)
{
switch (cmd.type()) {
@@ -449,234 +357,9 @@ ConfigHandler::handleCmd(const Cmd& cmd)
}
void
-ConfigHandler::handleCommand(CommandConnection *c)
-{
- while (char *line = c->getCommand()) {
- LOG(debug, "Got command from connection: '%s'", line);
-
- char *cmd, *args;
- splitCommand(line, cmd, args);
- LOG(debug, "Command is '%s', args is '%s'", cmd, args);
- if (strcmp(cmd, "ls") == 0) {
- doLs(c, args);
- } else if (strcmp(cmd, "get") == 0) {
- doGet(c, args);
- } else if (strcmp(cmd, "restart") == 0) {
- doRestart(c, args);
- } else if (strcmp(cmd, "forcerestart") == 0) {
- doRestart(c, args, true);
- } else if (strcmp(cmd, "start") == 0) {
- doStart(c, args);
- } else if (strcmp(cmd, "stop") == 0) {
- doStop(c, args);
- } else if (strcmp(cmd, "forcestop") == 0) {
- doStop(c, args, true);
- } else if (strcmp(cmd, "auto") == 0) {
- doAuto(c, args);
- } else if (strcmp(cmd, "manual") == 0) {
- doManual(c, args);
- } else if (strcmp(cmd, "quit") == 0) {
- doQuit(c, args);
- } else {
- c->printf("ERROR: Unknown cmd '%s' "
- "(ls/restart/start/stop/auto/manual/quit)\n", cmd);
- }
- }
-}
-
-void
ConfigHandler::updateMetrics()
{
_startMetrics.maybeLog();
}
-void
-ConfigHandler::doGet(CommandConnection *c, char *args)
-{
- char *path, *extra;
- splitCommand(args, path, extra);
- if (path[0] == '/') {
- updateMetrics();
- vespalib::string response = _stateApi.get(path);
- if (response.size() > 0) {
- c->printf("HTTP/1.0 200 OK\r\n"
- "Content-Type: application/json; charset=ASCII\r\n\r\n");
- c->printf("%s", response.c_str());
- c->printf("\r\n");
- } else {
- c->printf("HTTP/1.0 404 Not found\r\n"
- "Content-Type: text/plain; charset=ASCII\r\n\r\n"
- "This web server only has metrics\r\n");
- }
- } else {
- c->printf("HTTP/1.0 400 Bad URL\r\nContent-Type: text/plain; charset=ASCII\r\n\r\nThis web server only has metrics\r\n");
- }
- c->finish();
- while (! c->isFinished()) {
- c->getCommand();
- }
-}
-
-void
-ConfigHandler::doLs(CommandConnection *c, char *args)
-{
- for (ServiceMap::iterator it(_services.begin()), mt(_services.end()); it != mt; it++) {
- Service *service = it->second.get();
- if (*args && strcmp(args, service->name().c_str()) != 0) {
- continue;
- }
- const SentinelConfig::Service& config = service->serviceConfig();
- c->printf("%s state=%s mode=%s pid=%d exitstatus=%d "
- "autostart=%s autorestart=%s id=\"%s\"\n",
- service->name().c_str(), service->stateName(),
- service->isAutomatic() ? "AUTO" : "MANUAL",
- service->pid(), service->exitStatus(),
- config.autostart ? "TRUE" : "FALSE",
- config.autorestart ? "TRUE" : "FALSE",
- config.id.c_str());
- }
- c->printf("\n");
-}
-
-void
-ConfigHandler::doQuit(CommandConnection *c, char *)
-{
- c->printf("Exiting.\n");
- c->finish();
-}
-
-void
-ConfigHandler::doStart(CommandConnection *c, char *args)
-{
- Service *service = serviceByName(args);
- if (service == nullptr) {
- c->printf("Cannot find any service named '%s'\n", args);
- return;
- }
-
- if (service->isRunning()) {
- c->printf("ERROR: %s is already running as pid %d!\n", args,
- service->pid());
- } else {
- service->resetRestartPenalty();
- service->start();
- c->printf("%s started as pid %d, mode=%s\n", args, service->pid(),
- service->isAutomatic() ? "AUTO" : "MANUAL");
- }
-}
-
-void
-ConfigHandler::doRestart(CommandConnection *c, char *args)
-{
- doRestart(c, args, false);
-}
-
-void
-ConfigHandler::doRestart(CommandConnection *c, char *args, bool force)
-{
- Service *service = serviceByName(args);
- if (service == nullptr) {
- c->printf("Cannot find any service named '%s'\n", args);
- return;
- }
-
- if (!service->isRunning()) {
- service->resetRestartPenalty();
- service->start();
- c->printf("%s started as pid %d, mode=%s\n", args, service->pid(),
- service->isAutomatic() ? "AUTO" : "MANUAL");
- return;
- }
-
- if (!service->isAutomatic()) {
- c->printf("ERROR: %s is in MANUAL mode, use stop+start\n", args);
- return;
- }
- const SentinelConfig::Service& config = service->serviceConfig();
- if (!config.autorestart) {
- c->printf("ERROR: %s does not autorestart, use stop+start\n", args);
- return;
- }
- c->printf("terminating service %s pid %d, will be autorestarted\n",
- args, service->pid());
- service->terminate(!force, false);
-}
-
-void
-ConfigHandler::doStop(CommandConnection *c, char *args)
-{
- doStop(c, args, false);
-}
-
-void
-ConfigHandler::doStop(CommandConnection *c, char *args, bool force)
-{
- Service *service = serviceByName(args);
- if (service == nullptr) {
- c->printf("Cannot find any service named '%s'\n", args);
- return;
- }
-
- if (!service->isRunning()) {
- c->printf("%s is not running, it is in state %s. Cannot stop.\n",
- service->name().c_str(), service->stateName());
- return;
- }
- const SentinelConfig::Service& config = service->serviceConfig();
- if (service->isAutomatic() && config.autorestart) {
- c->printf("ERROR: %s in AUTO mode. Use restart, or manual+stop.\n",
- args);
- return;
- }
- c->printf("Stopping %s.\n", args);
- service->terminate(!force, false);
-}
-
-void
-ConfigHandler::doAuto(CommandConnection *c, char *args)
-{
- Service *service = serviceByName(args);
- if (service == nullptr) {
- c->printf("Cannot find any service named '%s'\n", args);
- return;
- }
-
- if (service->isAutomatic()) {
- c->printf("%s is already automatic.\n", args);
- } else {
- service->setAutomatic(true);
- const SentinelConfig::Service& config = service->serviceConfig();
- if (service->isRunning()) {
- c->printf("%s is now automatic again (and running).\n", args);
- } else if (config.autostart || config.autorestart) {
- service->start();
- c->printf("%s is now automatic again (and started).\n", args);
- } else {
- c->printf("%s is now automatic again (but not started)\n", args);
- }
- }
-}
-
-
-void
-ConfigHandler::doManual(CommandConnection *c, char *args)
-{
- Service *service = serviceByName(args);
- if (service == nullptr) {
- c->printf("Cannot find any service named '%s'\n", args);
- return;
- }
-
- if (!service->isAutomatic()) {
- c->printf("%s is already manual.\n", args);
- } else {
- service->setAutomatic(false);
- if (service->isRunning()) {
- c->printf("%s is now manual (but still running).\n", args);
- } else {
- c->printf("%s is now manual).\n", args);
- }
- }
-}
-
}