diff --git a/arangod/Cluster/ClusterFeature.cpp b/arangod/Cluster/ClusterFeature.cpp index e3d10a78a7..8574fbc866 100644 --- a/arangod/Cluster/ClusterFeature.cpp +++ b/arangod/Cluster/ClusterFeature.cpp @@ -35,10 +35,12 @@ #include "Logger/Logger.h" #include "ProgramOptions/ProgramOptions.h" #include "ProgramOptions/Section.h" +#include "Rest/Version.h" #include "RestServer/DatabaseFeature.h" #include "Scheduler/Scheduler.h" #include "Scheduler/SchedulerFeature.h" #include "SimpleHttpClient/ConnectionManager.h" +#include "StorageEngine/EngineSelectorFeature.h" #include "V8Server/V8DealerFeature.h" using namespace arangodb; @@ -79,10 +81,10 @@ void ClusterFeature::collectOptions(std::shared_ptr options) { options->addSection("cluster", "Configure the cluster"); options->addObsoleteOption("--cluster.username", - "username used for cluster-internal communication", + "username used for cluster-internal communication", true); options->addObsoleteOption("--cluster.password", - "password used for cluster-internal communication", + "password used for cluster-internal communication", true); options->addObsoleteOption("--cluster.disable-dispatcher-kickstarter", "The dispatcher feature isn't available anymore; Use ArangoDBStarter for this now!", @@ -105,7 +107,7 @@ void ClusterFeature::collectOptions(std::shared_ptr options) { options->addObsoleteOption("--cluster.arangod-path", "path to the arangod for the cluster", true); - + options->addOption("--cluster.agency-endpoint", "agency endpoint to connect to", new VectorParameter(&_agencyEndpoints)); @@ -132,7 +134,7 @@ void ClusterFeature::collectOptions(std::shared_ptr options) { options->addHiddenOption("--cluster.create-waits-for-sync-replication", "active coordinator will wait for all replicas to create collection", new BooleanParameter(&_createWaitsForSyncReplication)); - + options->addHiddenOption("--cluster.index-create-timeout", "amount of time (in seconds) the coordinator will wait for an index to be created before giving up", new DoubleParameter(&_indexCreationTimeout)); @@ -145,7 +147,7 @@ void ClusterFeature::validateOptions(std::shared_ptr options) { << "The dispatcher feature isn't available anymore. Use ArangoDBStarter for this now! See https://github.com/arangodb-helper/ArangoDBStarter/ for more details."; FATAL_ERROR_EXIT(); } - + // check if the cluster is enabled _enableCluster = !_agencyEndpoints.empty(); @@ -200,8 +202,8 @@ void ClusterFeature::validateOptions(std::shared_ptr options) { if (!_myRole.empty()) { _requestedRole = ServerState::stringToRole(_myRole); - std::vector const disallowedRoles= { - /*ServerState::ROLE_SINGLE,*/ ServerState::ROLE_AGENT, ServerState::ROLE_UNDEFINED + std::vector const disallowedRoles= { + /*ServerState::ROLE_SINGLE,*/ ServerState::ROLE_AGENT, ServerState::ROLE_UNDEFINED }; if (std::find(disallowedRoles.begin(), disallowedRoles.end(), _requestedRole) != disallowedRoles.end()) { @@ -276,7 +278,7 @@ void ClusterFeature::prepare() { // register the prefix with the communicator AgencyCommManager::initialize(_agencyPrefix); TRI_ASSERT(AgencyCommManager::MANAGER != nullptr); - + for (size_t i = 0; i < _agencyEndpoints.size(); ++i) { std::string const unified = Endpoint::unifiedForm(_agencyEndpoints[i]); @@ -312,8 +314,8 @@ void ClusterFeature::prepare() { auto role = ServerState::instance()->getRole(); auto endpoints = AgencyCommManager::MANAGER->endpointsString(); - - + + if (role == ServerState::ROLE_UNDEFINED) { // no role found LOG_TOPIC(FATAL, arangodb::Logger::CLUSTER) << "unable to determine unambiguous role for server '" @@ -337,7 +339,7 @@ void ClusterFeature::prepare() { auto ci = ClusterInfo::instance(); double start = TRI_microtime(); - + while (true) { LOG_TOPIC(INFO, arangodb::Logger::CLUSTER) << "Waiting for DBservers to show up..."; ci->loadCurrentDBServers(); @@ -349,7 +351,7 @@ void ClusterFeature::prepare() { } sleep(1); } - + } if (_myAddress.empty()) { @@ -366,7 +368,7 @@ void ClusterFeature::prepare() { << "' specified for --cluster.my-address"; FATAL_ERROR_EXIT(); } - + } void ClusterFeature::start() { @@ -445,6 +447,8 @@ void ClusterFeature::start() { VPackObjectBuilder b(&builder); builder.add("endpoint", VPackValue(_myAddress)); builder.add("host", VPackValue(ServerState::instance()->getHost())); + builder.add("version", VPackValue(rest::Version::getNumericServerVersion())); + builder.add("storageEngine", VPackValue(EngineSelectorFeature::engineName())); } catch (...) { LOG_TOPIC(FATAL, arangodb::Logger::CLUSTER) << "out of memory"; FATAL_ERROR_EXIT(); @@ -477,7 +481,7 @@ void ClusterFeature::stop() { if (_heartbeatThread != nullptr) { _heartbeatThread->beginShutdown(); } - + if (_heartbeatThread != nullptr) { int counter = 0; while (_heartbeatThread->isRunning()) { @@ -540,7 +544,7 @@ void ClusterFeature::unprepare() { ServerState::RoleEnum role = ServerState::instance()->getRole(); std::string alk = ServerState::roleToAgencyListKey(role); std::string me = ServerState::instance()->getId(); - + AgencyWriteTransaction unreg; unreg.operations.push_back(AgencyOperation("Current/" + alk + "/" + me, AgencySimpleOperationType::DELETE_OP)); diff --git a/lib/Rest/Version.cpp b/lib/Rest/Version.cpp index b2a6edc62d..2dc8fefb16 100644 --- a/lib/Rest/Version.cpp +++ b/lib/Rest/Version.cpp @@ -47,7 +47,7 @@ using namespace arangodb::rest; std::map Version::Values; - + /// @brief parse a version string into major, minor /// returns -1, -1 when the version string has an invalid format /// returns major, -1 when only the major version can be determined @@ -75,7 +75,7 @@ std::pair Version::parseVersionString(std::string const& str) { result.second = std::stoi(std::string(p, q - p)); } } - } + } return result; } @@ -191,7 +191,7 @@ void Version::initialize() { #else Values["fd-client-event-handler"] = "select"; #endif - + for (auto& it : Values) { arangodb::basics::StringUtils::trimInPlace(it.second); } @@ -220,7 +220,21 @@ int32_t Version::getNumericServerVersion() { TRI_ASSERT((*p == '.' || *p == '-' || *p == '\0') && p != apiVersion); int32_t minor = TRI_Int32String(apiVersion, (p - apiVersion)); - return (int32_t)(minor * 100L + major * 10000L); + int32_t patch = 0; + if (*p == '.') { + apiVersion = ++p; + + // read minor version + while (*p >= '0' && *p <= '9') { + ++p; + } + + if (p != apiVersion) { + patch = TRI_Int32String(apiVersion, (p - apiVersion)); + } + } + + return (int32_t)(patch + minor * 100L + major * 10000L); } /// @brief get server version @@ -249,7 +263,7 @@ std::string Version::getBoostReactorType() { return std::string("select"); #endif } - + /// @brief get RocksDB version std::string Version::getRocksDBVersion() { return std::to_string(ROCKSDB_MAJOR) + "." + std::to_string(ROCKSDB_MINOR) + "." + std::to_string(ROCKSDB_PATCH); @@ -321,7 +335,7 @@ std::string Version::getEndianness() { if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 && p[4] == 0xab && p[5] == 0xcd && p[6] == 0xef && p[7] == 0x99) { return "big"; } - + if (p[0] == 0x99 && p[1] == 0xef && p[2] == 0xcd && p[3] == 0xab && p[4] == 0x78 && p[5] == 0x56 && p[6] == 0x34 && p[7] == 0x12) { return "little"; } @@ -363,13 +377,13 @@ std::string Version::getVerboseVersionString() { #ifdef ARANGODB_HAVE_JEMALLOC << "jemalloc, " #endif -#ifdef HAVE_ARANGODB_BUILD_REPOSITORY - << "build " << getBuildRepository() << ", " +#ifdef HAVE_ARANGODB_BUILD_REPOSITORY + << "build " << getBuildRepository() << ", " #endif << "VPack " << getVPackVersion() << ", " << "RocksDB " << getRocksDBVersion() << ", " << "ICU " << getICUVersion() << ", " - << "V8 " << getV8Version() << ", " + << "V8 " << getV8Version() << ", " << getOpenSSLVersion(); return version.str(); @@ -409,4 +423,3 @@ void Version::getVPack(VPackBuilder& dst) { } } } -