1
2 /**
3 * Copyright (C) 2018-present MongoDB, Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the Server Side Public License, version 1,
7 * as published by MongoDB, Inc.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * Server Side Public License for more details.
13 *
14 * You should have received a copy of the Server Side Public License
15 * along with this program. If not, see
16 * <http://www.mongodb.com/licensing/server-side-public-license>.
17 *
18 * As a special exception, the copyright holders give permission to link the
19 * code of portions of this program with the OpenSSL library under certain
20 * conditions as described in each individual source file and distribute
21 * linked combinations including the program with the OpenSSL library. You
22 * must comply with the Server Side Public License in all respects for
23 * all of the code used other than as permitted herein. If you modify file(s)
24 * with this exception, you may extend this exception to your version of the
25 * file(s), but you are not obligated to do so. If you do not wish to do so,
26 * delete this exception statement from your version. If you delete this
27 * exception statement from all source files in the program, then also delete
28 * it in the license file.
29 */
30
31 #define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kControl
32
33 #include "mongo/platform/basic.h"
34
35 #include "mongo/util/version.h"
36
37 #include "mongo/config.h"
38
39 #ifdef MONGO_CONFIG_SSL
40 #include <openssl/crypto.h>
41 #endif
42
43 #include <pcrecpp.h>
44
45 #include <sstream>
46
47 #include "mongo/db/jsobj.h"
48 #include "mongo/util/assert_util.h"
49 #include "mongo/util/log.h"
50
51 namespace mongo {
52 namespace {
53
54 const class : public VersionInfoInterface {
55 public:
majorVersion() const56 int majorVersion() const noexcept final {
57 return 0;
58 }
59
minorVersion() const60 int minorVersion() const noexcept final {
61 return 0;
62 }
63
patchVersion() const64 int patchVersion() const noexcept final {
65 return 0;
66 }
67
extraVersion() const68 int extraVersion() const noexcept final {
69 return 0;
70 }
71
version() const72 StringData version() const noexcept final {
73 return "unknown";
74 }
75
gitVersion() const76 StringData gitVersion() const noexcept final {
77 return "none";
78 }
79
modules() const80 std::vector<StringData> modules() const final {
81 return {"unknown"};
82 }
83
allocator() const84 StringData allocator() const noexcept final {
85 return "unknown";
86 }
87
jsEngine() const88 StringData jsEngine() const noexcept final {
89 return "unknown";
90 }
91
targetMinOS() const92 StringData targetMinOS() const noexcept final {
93 return "unknown";
94 }
95
buildInfo() const96 std::vector<BuildInfoTuple> buildInfo() const final {
97 return {};
98 }
99
100 } kFallbackVersionInfo{};
101
102 const VersionInfoInterface* globalVersionInfo = nullptr;
103
104 } // namespace
105
enable(const VersionInfoInterface * handler)106 void VersionInfoInterface::enable(const VersionInfoInterface* handler) {
107 globalVersionInfo = handler;
108 }
109
instance(NotEnabledAction action)110 const VersionInfoInterface& VersionInfoInterface::instance(NotEnabledAction action) noexcept {
111 if (globalVersionInfo)
112 return *globalVersionInfo;
113 if (action == NotEnabledAction::kFallback)
114 return kFallbackVersionInfo;
115 severe() << "Terminating because valid version info has not been configured";
116 fassertFailed(40278);
117 }
118
isSameMajorVersion(const char * otherVersion) const119 bool VersionInfoInterface::isSameMajorVersion(const char* otherVersion) const noexcept {
120 int major = -1, minor = -1;
121 pcrecpp::RE ver_regex("^(\\d+)\\.(\\d+)\\.");
122 ver_regex.PartialMatch(otherVersion, &major, &minor);
123
124 if (major == -1 || minor == -1)
125 return false;
126
127 return (major == majorVersion() && minor == minorVersion());
128 }
129
makeVersionString(StringData binaryName) const130 std::string VersionInfoInterface::makeVersionString(StringData binaryName) const {
131 std::stringstream ss;
132 ss << binaryName << " v" << version();
133 return ss.str();
134 }
135
appendBuildInfo(BSONObjBuilder * result) const136 void VersionInfoInterface::appendBuildInfo(BSONObjBuilder* result) const {
137 *result << "version" << version() << "gitVersion" << gitVersion()
138 #if defined(_WIN32)
139 << "targetMinOS" << targetMinOS()
140 #endif
141 << "modules" << modules() << "allocator" << allocator() << "javascriptEngine"
142 << jsEngine() << "sysInfo"
143 << "deprecated";
144
145 BSONArrayBuilder versionArray(result->subarrayStart("versionArray"));
146 versionArray << majorVersion() << minorVersion() << patchVersion() << extraVersion();
147 versionArray.done();
148
149 BSONObjBuilder opensslInfo(result->subobjStart("openssl"));
150 #ifdef MONGO_CONFIG_SSL
151 opensslInfo << "running" << openSSLVersion() << "compiled" << OPENSSL_VERSION_TEXT;
152 #else
153 opensslInfo << "running"
154 << "disabled"
155 << "compiled"
156 << "disabled";
157 #endif
158 opensslInfo.done();
159
160 BSONObjBuilder buildvarsInfo(result->subobjStart("buildEnvironment"));
161 for (auto&& envDataEntry : buildInfo()) {
162 if (std::get<2>(envDataEntry)) {
163 buildvarsInfo << std::get<0>(envDataEntry) << std::get<1>(envDataEntry);
164 }
165 }
166 buildvarsInfo.done();
167
168 *result << "bits" << (int)sizeof(void*) * 8;
169 result->appendBool("debug", kDebugBuild);
170 result->appendNumber("maxBsonObjectSize", BSONObjMaxUserSize);
171 }
172
openSSLVersion(StringData prefix,StringData suffix) const173 std::string VersionInfoInterface::openSSLVersion(StringData prefix, StringData suffix) const {
174 #ifndef MONGO_CONFIG_SSL
175 return "";
176 #else
177 return prefix.toString() + SSLeay_version(SSLEAY_VERSION) + suffix;
178 #endif
179 }
180
logTargetMinOS() const181 void VersionInfoInterface::logTargetMinOS() const {
182 log() << "targetMinOS: " << targetMinOS();
183 }
184
logBuildInfo() const185 void VersionInfoInterface::logBuildInfo() const {
186 log() << "git version: " << gitVersion();
187
188 #ifdef MONGO_CONFIG_SSL
189 log() << openSSLVersion("OpenSSL version: ");
190 #endif
191
192 log() << "allocator: " << allocator();
193
194 std::stringstream ss;
195 ss << "modules: ";
196 auto modules_list = modules();
197 if (modules_list.size() == 0) {
198 ss << "none";
199 } else {
200 for (const auto& m : modules_list) {
201 ss << m << " ";
202 }
203 }
204 log() << ss.str();
205
206 log() << "build environment:";
207 for (auto&& envDataEntry : buildInfo()) {
208 if (std::get<3>(envDataEntry)) {
209 auto val = std::get<1>(envDataEntry);
210 if (val.size() == 0)
211 continue;
212 log() << " " << std::get<0>(envDataEntry) << ": " << std::get<1>(envDataEntry);
213 }
214 }
215 }
216
mongoShellVersion(const VersionInfoInterface & provider)217 std::string mongoShellVersion(const VersionInfoInterface& provider) {
218 std::stringstream ss;
219 ss << "MongoDB shell version v" << provider.version();
220 return ss.str();
221 }
222
mongosVersion(const VersionInfoInterface & provider)223 std::string mongosVersion(const VersionInfoInterface& provider) {
224 std::stringstream ss;
225 ss << "mongos version v" << provider.version();
226 return ss.str();
227 }
228
mongodVersion(const VersionInfoInterface & provider)229 std::string mongodVersion(const VersionInfoInterface& provider) {
230 std::stringstream ss;
231 ss << "db version v" << provider.version();
232 return ss.str();
233 }
234
235 } // namespace mongo
236