aboutsummaryrefslogtreecommitdiffstats
path: root/configd/src
diff options
context:
space:
mode:
authorArne Juul <arnej@yahoo-inc.com>2019-03-13 11:28:25 +0000
committerArne Juul <arnej@yahoo-inc.com>2019-03-13 11:28:25 +0000
commit6ff41ca29c8fb36e7a59f0649f746051e1310a6f (patch)
treebb60df58aecf605e1a330345a5d59be87bd666da /configd/src
parente572223ee498e58b5b6b69cd0dd00480029d3e82 (diff)
remove telnet API, use state server
Diffstat (limited to 'configd/src')
-rw-r--r--configd/src/apps/sentinel/config-handler.cpp341
-rw-r--r--configd/src/apps/sentinel/config-handler.h17
-rw-r--r--configd/src/apps/sentinel/state-api.cpp27
-rw-r--r--configd/src/apps/sentinel/state-api.h10
4 files changed, 14 insertions, 381 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);
- }
- }
-}
-
}
diff --git a/configd/src/apps/sentinel/config-handler.h b/configd/src/apps/sentinel/config-handler.h
index e33bbf1c8da..a1ae054f888 100644
--- a/configd/src/apps/sentinel/config-handler.h
+++ b/configd/src/apps/sentinel/config-handler.h
@@ -8,6 +8,7 @@
#include "rpcserver.h"
#include <vespa/config-sentinel.h>
#include <vespa/config/config.h>
+#include <vespa/vespalib/net/state_server.h>
#include <sys/types.h>
#include <sys/select.h>
@@ -19,7 +20,6 @@ using config::ConfigHandle;
namespace config::sentinel {
-class CommandConnection;
class OutputConnection;
class ConfigHandler {
@@ -29,14 +29,13 @@ private:
ConfigSubscriber _subscriber;
ConfigHandle<SentinelConfig>::UP _sentinelHandle;
ServiceMap _services;
- std::list<CommandConnection *> _connections;
std::list<OutputConnection *> _outputConnections;
CommandQueue _cmdQ;
std::unique_ptr<RpcServer> _rpcServer;
int _boundPort;
- int _commandSocket;
StartMetrics _startMetrics;
StateApi _stateApi;
+ std::unique_ptr<vespalib::StateServer> _stateServer;
ConfigHandler(const ConfigHandler&);
ConfigHandler& operator =(const ConfigHandler&);
@@ -44,7 +43,6 @@ private:
Service *serviceByPid(pid_t pid);
Service *serviceByName(const vespalib::string & name);
void handleCommands();
- void handleCommand(CommandConnection *c);
void handleCmd(const Cmd& cmd);
void handleOutputs();
void handleChildDeaths();
@@ -54,17 +52,6 @@ private:
void updateMetrics();
- void doGet(CommandConnection *c, char *args);
- void doLs(CommandConnection *c, char *args);
- void doRestart(CommandConnection *c, char *args);
- void doRestart(CommandConnection *c, char *args, bool force);
- void doStart(CommandConnection *c, char *args);
- void doStop(CommandConnection *c, char *args);
- void doStop(CommandConnection *c, char *args, bool force);
- void doAuto(CommandConnection *c, char *args);
- void doManual(CommandConnection *c, char *args);
- void doQuit(CommandConnection *c, char *args);
-
void terminateServices(bool catchable, bool printDebug = false);
void doConfigure();
diff --git a/configd/src/apps/sentinel/state-api.cpp b/configd/src/apps/sentinel/state-api.cpp
index 56df10908f2..e63fee1863b 100644
--- a/configd/src/apps/sentinel/state-api.cpp
+++ b/configd/src/apps/sentinel/state-api.cpp
@@ -1,30 +1,3 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "state-api.h"
-#include <vespa/vespalib/util/host_name.h>
-#include <vespa/vespalib/util/stringfmt.h>
-
-namespace {
-
-std::map<vespalib::string, vespalib::string> noParams;
-
-} // namespace <unnamed>
-
-
-namespace config {
-namespace sentinel {
-
-vespalib::string
-StateApi::get(const char *path) const
-{
- return myStateApi.get(host_and_port, path, noParams);
-}
-
-void
-StateApi::bound(int port)
-{
- host_and_port = vespalib::make_string("%s:%d", vespalib::HostName::get().c_str(), port);
-}
-
-} // namespace config::sentinel
-} // namespace config
diff --git a/configd/src/apps/sentinel/state-api.h b/configd/src/apps/sentinel/state-api.h
index ca080a35865..94c62209bec 100644
--- a/configd/src/apps/sentinel/state-api.h
+++ b/configd/src/apps/sentinel/state-api.h
@@ -2,7 +2,6 @@
#pragma once
-#include <vespa/vespalib/net/state_api.h>
#include <vespa/vespalib/net/simple_health_producer.h>
#include <vespa/vespalib/net/simple_component_config_producer.h>
#include <vespa/vespalib/metrics/simple_metrics.h>
@@ -11,17 +10,8 @@ namespace config {
namespace sentinel {
struct StateApi {
- vespalib::string host_and_port;
vespalib::SimpleHealthProducer myHealth;
vespalib::SimpleComponentConfigProducer myComponents;
- vespalib::StateApi myStateApi;
-
- StateApi(vespalib::metrics::Producer &myMetrics)
- : myStateApi(myHealth, myMetrics, myComponents)
- {}
-
- vespalib::string get(const char *path) const;
- void bound(int port);
};
} // namespace config::sentinel