Merge pull request #25147 from markdroth/xds_bootstrap_fallback

Add internal API for setting fallback xDS bootstrap contents.
reviewable/pr22082/r1
Mark D. Roth 4 years ago committed by GitHub
commit 652d10cd1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 52
      src/core/ext/xds/xds_bootstrap.cc
  2. 3
      src/core/ext/xds/xds_bootstrap.h
  3. 13
      src/core/ext/xds/xds_client.cc
  4. 3
      src/core/ext/xds/xds_client.h

@ -132,13 +132,40 @@ std::string BootstrapString(const XdsBootstrap& bootstrap) {
return absl::StrJoin(parts, ""); return absl::StrJoin(parts, "");
} }
std::unique_ptr<XdsBootstrap> ParseJsonAndCreate(
XdsClient* client, TraceFlag* tracer, absl::string_view json_string,
absl::string_view bootstrap_source, grpc_error** error) {
Json json = Json::Parse(json_string, error);
if (*error != GRPC_ERROR_NONE) {
grpc_error* error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
absl::StrCat("Failed to parse bootstrap from ", bootstrap_source)
.c_str(),
error, 1);
GRPC_ERROR_UNREF(*error);
*error = error_out;
return nullptr;
}
std::unique_ptr<XdsBootstrap> result =
absl::make_unique<XdsBootstrap>(std::move(json), error);
if (*error == GRPC_ERROR_NONE && GRPC_TRACE_FLAG_ENABLED(*tracer)) {
gpr_log(GPR_INFO,
"[xds_client %p] Bootstrap config for creating xds client:\n%s",
client, BootstrapString(*result).c_str());
}
return result;
}
} // namespace } // namespace
std::unique_ptr<XdsBootstrap> XdsBootstrap::ReadFromFile(XdsClient* client, std::unique_ptr<XdsBootstrap> XdsBootstrap::ReadFromFile(
TraceFlag* tracer, XdsClient* client, TraceFlag* tracer, const char* fallback_config,
grpc_error** error) { grpc_error** error) {
grpc_core::UniquePtr<char> path(gpr_getenv("GRPC_XDS_BOOTSTRAP")); grpc_core::UniquePtr<char> path(gpr_getenv("GRPC_XDS_BOOTSTRAP"));
if (path == nullptr) { if (path == nullptr) {
if (fallback_config != nullptr) {
return ParseJsonAndCreate(client, tracer, fallback_config,
"fallback config", error);
}
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Environment variable GRPC_XDS_BOOTSTRAP not defined"); "Environment variable GRPC_XDS_BOOTSTRAP not defined");
return nullptr; return nullptr;
@ -157,23 +184,10 @@ std::unique_ptr<XdsBootstrap> XdsBootstrap::ReadFromFile(XdsClient* client,
gpr_log(GPR_DEBUG, "[xds_client %p] Bootstrap file contents: %s", client, gpr_log(GPR_DEBUG, "[xds_client %p] Bootstrap file contents: %s", client,
std::string(contents_str_view).c_str()); std::string(contents_str_view).c_str());
} }
Json json = Json::Parse(contents_str_view, error); std::string bootstrap_source = absl::StrCat("file ", path.get());
auto result = ParseJsonAndCreate(client, tracer, contents_str_view,
bootstrap_source, error);
grpc_slice_unref_internal(contents); grpc_slice_unref_internal(contents);
if (*error != GRPC_ERROR_NONE) {
grpc_error* error_out = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
absl::StrCat("Failed to parse bootstrap file ", path.get()).c_str(),
error, 1);
GRPC_ERROR_UNREF(*error);
*error = error_out;
return nullptr;
}
std::unique_ptr<XdsBootstrap> result =
absl::make_unique<XdsBootstrap>(std::move(json), error);
if (*error == GRPC_ERROR_NONE && GRPC_TRACE_FLAG_ENABLED(*tracer)) {
gpr_log(GPR_INFO,
"[xds_client %p] Bootstrap config for creating xds client:\n%s",
client, BootstrapString(*result).c_str());
}
return result; return result;
} }

@ -67,10 +67,13 @@ class XdsBootstrap {
bool ShouldUseV3() const; bool ShouldUseV3() const;
}; };
// Normally locates the bootstrap file via an env var. If no env var
// is set, fallback_config will be used instead (if non-null).
// If *error is not GRPC_ERROR_NONE after returning, then there was an // If *error is not GRPC_ERROR_NONE after returning, then there was an
// error reading the file. // error reading the file.
static std::unique_ptr<XdsBootstrap> ReadFromFile(XdsClient* client, static std::unique_ptr<XdsBootstrap> ReadFromFile(XdsClient* client,
TraceFlag* tracer, TraceFlag* tracer,
const char* fallback_config,
grpc_error** error); grpc_error** error);
// Do not instantiate directly -- use ReadFromFile() above instead. // Do not instantiate directly -- use ReadFromFile() above instead.

@ -72,6 +72,7 @@ namespace {
Mutex* g_mu = nullptr; Mutex* g_mu = nullptr;
const grpc_channel_args* g_channel_args = nullptr; const grpc_channel_args* g_channel_args = nullptr;
XdsClient* g_xds_client = nullptr; XdsClient* g_xds_client = nullptr;
char* g_fallback_bootstrap_config = nullptr;
} // namespace } // namespace
@ -1740,8 +1741,8 @@ XdsClient::XdsClient(grpc_error** error)
: nullptr), : nullptr),
request_timeout_(GetRequestTimeout()), request_timeout_(GetRequestTimeout()),
interested_parties_(grpc_pollset_set_create()), interested_parties_(grpc_pollset_set_create()),
bootstrap_( bootstrap_(XdsBootstrap::ReadFromFile(
XdsBootstrap::ReadFromFile(this, &grpc_xds_client_trace, error)), this, &grpc_xds_client_trace, g_fallback_bootstrap_config, error)),
certificate_provider_store_(MakeOrphanable<CertificateProviderStore>( certificate_provider_store_(MakeOrphanable<CertificateProviderStore>(
bootstrap_ == nullptr bootstrap_ == nullptr
? CertificateProviderStore::PluginDefinitionMap() ? CertificateProviderStore::PluginDefinitionMap()
@ -2207,6 +2208,8 @@ void XdsClientGlobalInit() { g_mu = new Mutex; }
void XdsClientGlobalShutdown() { void XdsClientGlobalShutdown() {
delete g_mu; delete g_mu;
g_mu = nullptr; g_mu = nullptr;
gpr_free(g_fallback_bootstrap_config);
g_fallback_bootstrap_config = nullptr;
} }
RefCountedPtr<XdsClient> XdsClient::GetOrCreate(grpc_error** error) { RefCountedPtr<XdsClient> XdsClient::GetOrCreate(grpc_error** error) {
@ -2232,6 +2235,12 @@ void UnsetGlobalXdsClientForTest() {
g_xds_client = nullptr; g_xds_client = nullptr;
} }
void SetXdsFallbackBootstrapConfig(char* config) {
MutexLock lock(g_mu);
gpr_free(g_fallback_bootstrap_config);
g_fallback_bootstrap_config = config;
}
} // namespace internal } // namespace internal
} // namespace grpc_core } // namespace grpc_core

@ -329,6 +329,9 @@ class XdsClient : public DualRefCounted<XdsClient> {
namespace internal { namespace internal {
void SetXdsChannelArgsForTest(grpc_channel_args* args); void SetXdsChannelArgsForTest(grpc_channel_args* args);
void UnsetGlobalXdsClientForTest(); void UnsetGlobalXdsClientForTest();
// Sets bootstrap config to be used when no env var is set.
// Takes ownership of config.
void SetXdsFallbackBootstrapConfig(char* config);
} // namespace internal } // namespace internal
} // namespace grpc_core } // namespace grpc_core

Loading…
Cancel
Save