YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/util/version_info.cc
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
33
#include "yb/util/version_info.h"
34
35
#include <fstream>
36
#include <string>
37
38
#include <rapidjson/document.h>
39
#include <rapidjson/error/en.h>
40
#include <rapidjson/istreamwrapper.h>
41
#include <rapidjson/writer.h>
42
43
#include "yb/util/env_util.h"
44
#include "yb/util/path_util.h"
45
#include "yb/util/status.h"
46
#include "yb/util/status_log.h"
47
48
DEFINE_string(version_file_json_path, "",
49
              "Path to directory containing JSON file with version info.");
50
51
using std::string;
52
53
namespace yb {
54
55
const char* kVersionJsonFileName = "version_metadata.json";
56
57
std::once_flag VersionInfo::init_once_;
58
std::shared_ptr<const VersionData> VersionInfo::version_data_ = nullptr;
59
60
0
string VersionInfo::GetGitHash() {
61
0
  auto data = GetVersionData();
62
63
0
  string ret = data->pb.git_hash();
64
0
  if (!data->pb.build_clean_repo()) {
65
0
    ret += "-dirty";
66
0
  }
67
0
  return ret;
68
0
}
69
70
1.31M
string VersionInfo::GetShortVersionString() {
71
1.31M
  auto data = GetVersionData();
72
73
1.31M
  return strings::Substitute("version $0 build $1 revision $2 build_type $3 built at $4",
74
1.31M
                             data->pb.version_number(),
75
1.31M
                             data->pb.build_number(),
76
1.31M
                             data->pb.git_hash(),
77
1.31M
                             data->pb.build_type(),
78
1.31M
                             data->pb.build_timestamp());
79
1.31M
}
80
81
0
string VersionInfo::GetAllVersionInfo() {
82
0
  auto data = GetVersionData();
83
84
0
  string ret = strings::Substitute(
85
0
      "version $0\n"
86
0
      "build $1\n"
87
0
      "revision $2\n"
88
0
      "build_type $3\n"
89
0
      "built by $4 at $5 on $6",
90
0
      data->pb.version_number(),
91
0
      data->pb.build_number(),
92
0
      GetGitHash(),
93
0
      data->pb.build_type(),
94
0
      data->pb.build_username(),
95
0
      data->pb.build_timestamp(),
96
0
      data->pb.build_hostname());
97
0
  if (data->pb.build_id().size() > 0) {
98
0
    strings::SubstituteAndAppend(&ret, "\nbuild id $0", data->pb.build_id());
99
0
  }
100
#ifdef ADDRESS_SANITIZER
101
  ret += "\nASAN enabled";
102
#endif
103
#ifdef THREAD_SANITIZER
104
  ret += "\nTSAN enabled";
105
#endif
106
0
  return ret;
107
0
}
108
109
4
string VersionInfo::GetAllVersionInfoJson() {
110
4
  return std::atomic_load_explicit(&version_data_, std::memory_order_acquire)->json;
111
4
}
112
113
4.70k
void VersionInfo::GetVersionInfoPB(VersionInfoPB* pb) {
114
4.70k
  pb->CopyFrom(GetVersionData()->pb);
115
4.70k
}
116
117
16.7k
Status VersionInfo::ReadVersionDataFromFile() {
118
16.7k
  SCHECK(std::atomic_load_explicit(&version_data_, std::memory_order_acquire) == nullptr,
119
16.7k
         IllegalState, "Cannot reload version data from file...");
120
121
16.7k
  std::string version_file_path = FLAGS_version_file_json_path;
122
16.7k
  if (version_file_path.empty()) {
123
16.7k
    version_file_path = yb::env_util::GetRootDir("bin");
124
16.7k
  }
125
126
16.7k
  std::string config_file_path = JoinPathSegments(version_file_path, kVersionJsonFileName);
127
16.7k
  std::ifstream json_file(config_file_path);
128
16.7k
  SCHECK(!json_file.fail(),
129
16.7k
          IllegalState, strings::Substitute("Could not open JSON file $0", config_file_path));
130
131
16.7k
  rapidjson::IStreamWrapper isw(json_file);
132
16.7k
  rapidjson::Document d;
133
16.7k
  d.ParseStream(isw);
134
16.7k
  SCHECK(!d.HasParseError(),
135
16.7k
         IllegalState, strings::Substitute("Failed to parse json. Error: $0 ",
136
16.7k
            rapidjson::GetParseError_En(d.GetParseError())));
137
138
16.7k
  auto version_data = std::make_shared<VersionData>();
139
140
16.7k
  rapidjson::StringBuffer buffer;
141
16.7k
  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
142
16.7k
  d.Accept(writer);
143
144
16.7k
  version_data->json = buffer.GetString();
145
146
16.7k
  const std::map<std::string, std::string*> keys_and_outputs = {
147
16.7k
    { "git_hash", version_data->pb.mutable_git_hash() },
148
16.7k
    { "build_hostname", version_data->pb.mutable_build_hostname() },
149
16.7k
    { "build_timestamp", version_data->pb.mutable_build_timestamp() },
150
16.7k
    { "build_username", version_data->pb.mutable_build_username() },
151
16.7k
    { "build_id", version_data->pb.mutable_build_id() },
152
16.7k
    { "build_type", version_data->pb.mutable_build_type() },
153
16.7k
    { "version_number", version_data->pb.mutable_version_number() },
154
16.7k
    { "build_number", version_data->pb.mutable_build_number() }
155
16.7k
  };
156
157
134k
  for (const auto& entry : keys_and_outputs) {
158
134k
    const auto& key = entry.first;
159
134k
    auto* output = entry.second;
160
134k
    if (!d.HasMember(key.c_str())) {
161
0
      return STATUS(IllegalState, strings::Substitute("Key $0 does not exist", key));
162
134k
    } else if(!d[key.c_str()].IsString()) {
163
0
      return STATUS(IllegalState, strings::Substitute("Key $0 is of invalid type $1",
164
0
                                                      key, d[key.c_str()].GetType()));
165
0
    }
166
134k
    *output = d[key.c_str()].GetString();
167
134k
  }
168
169
  // Special case the only boolean flag...
170
16.7k
  if (!d.HasMember("build_clean_repo")) {
171
0
    return STATUS(IllegalState, strings::Substitute("Key $0 does not exist", "build_clean_repo"));
172
16.7k
  } else if(!d["build_clean_repo"].IsString()) {
173
0
    return STATUS(IllegalState,
174
0
                  strings::Substitute("Key $0 is of invalid type $1",
175
0
                                      "build_clean_repo", d["build_clean_repo"].GetType()));
176
16.7k
  } else {
177
16.7k
    version_data->pb.set_build_clean_repo(d["build_clean_repo"] == "true");
178
16.7k
  }
179
180
16.7k
  std::atomic_store_explicit(&version_data_,
181
16.7k
                             static_cast<std::shared_ptr<const VersionData>>(version_data),
182
16.7k
                             std::memory_order_release);
183
16.7k
  return Status::OK();
184
16.7k
}
185
186
1.33M
Status VersionInfo::Init() {
187
1.33M
  Status status;
188
1.33M
  std::call_once(init_once_, InitInternal, &status);
189
1.33M
  return status;
190
1.33M
}
191
192
1.32M
std::shared_ptr<const VersionData> VersionInfo::GetVersionData() {
193
1.32M
  CHECK_OK(Init());
194
1.32M
  return std::atomic_load_explicit(&version_data_, std::memory_order_acquire);
195
1.32M
}
196
197
16.7k
void VersionInfo::InitInternal(Status* status_dest) {
198
16.7k
  *status_dest = ReadVersionDataFromFile();
199
16.7k
}
200
201
} // namespace yb