From baf10f59da0da8cfad191898442bcd5a5ce11245 Mon Sep 17 00:00:00 2001 From: James Fish Date: Tue, 3 Feb 2026 08:42:39 -0500 Subject: [PATCH 01/23] Add retriable_serving_statuses to grpc health check to retry NOT_SERVING Signed-off-by: James Fish --- api/bazel/external_proto_deps.bzl | 3 + api/envoy/config/core/v3/BUILD | 1 + api/envoy/config/core/v3/health_check.proto | 12 ++ bazel/pgv.patch | 130 ++++++++++++++++++ .../grpc/health_checker_impl.cc | 34 ++--- .../grpc/health_checker_impl.h | 4 +- .../grpc_retry_not_serving | 51 +++++++ .../upstream/health_checker_impl_test.cc | 39 ++++++ .../health_check_integration_test.cc | 73 +++++++++- 9 files changed, 327 insertions(+), 20 deletions(-) create mode 100644 test/common/upstream/health_check_corpus/grpc_retry_not_serving diff --git a/api/bazel/external_proto_deps.bzl b/api/bazel/external_proto_deps.bzl index 9dfdfee41ab93..82b828e73f069 100644 --- a/api/bazel/external_proto_deps.bzl +++ b/api/bazel/external_proto_deps.bzl @@ -13,6 +13,7 @@ EXTERNAL_PROTO_IMPORT_BAZEL_DEP_MAP = { "google/api/expr/v1alpha1/syntax.proto": "@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto", "io/prometheus/client/metrics.proto": "@prometheus_metrics_model//:client_model", "opentelemetry/proto/common/v1/common.proto": "@opentelemetry-proto//:common_proto", + "src/proto/grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", } # This maps from the Bazel proto_library target to the Go language binding target for external dependencies. @@ -35,6 +36,7 @@ EXTERNAL_PROTO_GO_BAZEL_DEP_MAP = { "@opentelemetry-proto//:metrics_proto": "@opentelemetry-proto//:metrics_proto_go", "@opentelemetry-proto//:metrics_service_proto": "@opentelemetry-proto//:metrics_service_grpc_go", "@opentelemetry-proto//:common_proto": "@opentelemetry-proto//:common_proto_go", + "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto": "@org_golang_google_grpc//health/grpc_health_v1:go_default_library", } # This maps from the Bazel proto_library target to the C++ language binding target for external dependencies. @@ -48,4 +50,5 @@ EXTERNAL_PROTO_CC_BAZEL_DEP_MAP = { "@opentelemetry-proto//:metrics_proto": "@opentelemetry-proto//:metrics_proto_cc", "@opentelemetry-proto//:metrics_service_proto": "@opentelemetry-proto//:metrics_service_grpc_cc", "@opentelemetry-proto//:common_proto": "@opentelemetry-proto//:common_proto_cc", + "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_cc_proto", } diff --git a/api/envoy/config/core/v3/BUILD b/api/envoy/config/core/v3/BUILD index 0a3036dc86f8f..2ce68d84c6048 100644 --- a/api/envoy/config/core/v3/BUILD +++ b/api/envoy/config/core/v3/BUILD @@ -9,6 +9,7 @@ api_proto_package( "//envoy/annotations:pkg", "//envoy/type/matcher/v3:pkg", "//envoy/type/v3:pkg", + "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", "@xds//udpa/annotations:pkg", "@xds//xds/annotations/v3:pkg", "@xds//xds/core/v3:pkg", diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index a4ed6e9181898..1610f2664dbac 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -10,6 +10,8 @@ import "envoy/type/matcher/v3/string.proto"; import "envoy/type/v3/http.proto"; import "envoy/type/v3/range.proto"; +import "src/proto/grpc/health/v1/health.proto"; + import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; @@ -227,6 +229,16 @@ message HealthCheck { // see the documentation on :ref:`custom request headers // `. repeated HeaderValueOption initial_metadata = 3 [(validate.rules).repeated = {max_items: 1000}]; + + // Specifies a list of gRPC `grpc.health.v1.HealthCheckResponse.ServingStatus + // ` that will be treated + // as retriable health check failures and respect the unhealthy threshold instead of immediately marking the + // host unhealthy. SERVING status is not retriable because that is a successful health check. + repeated grpc.health.v1.HealthCheckResponse.ServingStatus retriable_serving_statuses = 4 + [(validate.rules).repeated = { + unique: true + items {enum {defined_only: true not_in: 1}} + }]; } // Custom health check. diff --git a/bazel/pgv.patch b/bazel/pgv.patch index e5af1d37788ac..0664ad118a557 100644 --- a/bazel/pgv.patch +++ b/bazel/pgv.patch @@ -29,3 +29,133 @@ index 1a41f68..4d95b0d 100644 executable = True, allow_single_file = True, ), +diff --git a/templates/cc/register.go b/templates/cc/register.go +index e927985..050efda 100644 +--- a/templates/cc/register.go ++++ b/templates/cc/register.go +@@ -315,7 +315,7 @@ func (fns CCFuncs) inType(f pgs.Field, x interface{}) string { + return fns.cTypeOfString(fns.Type(f).Value().String()) + } + +- return fns.PackageName(fldEn).String() + "::" + fns.Type(f).Value().String() ++ return fns.packageName(fldEn) + "::" + fns.Type(f).Value().String() + default: + return fns.cType(f.Type()) + } +diff --git a/templates/cc/repeated.go b/templates/cc/repeated.go +index 53b2a35..e7124f6 100644 +--- a/templates/cc/repeated.go ++++ b/templates/cc/repeated.go +@@ -26,6 +26,9 @@ const repTpl = ` + {{ end }} + + {{ if $r.GetUnique }} ++ {{ if isRepeatedEnum $f }} ++ std::unordered_set {{ lookup $f "Unique" }}; ++ {{ else }} + // Implement comparison for wrapped reference types + struct cmp { + bool operator() (const std::reference_wrapper<{{ $typ }}> lhs, const std::reference_wrapper<{{ $typ }}> rhs) const { +@@ -44,6 +47,7 @@ const repTpl = ` + // Save a set of references to avoid copying overhead + std::unordered_set, hash, cmp> {{ lookup $f "Unique" }}; + {{ end }} ++ {{ end }} + + {{ if or $r.GetUnique (ne (.Elem "" "").Typ "none") }} + for (int i = 0; i < {{ accessor . }}.size(); i++) { +@@ -51,7 +55,11 @@ const repTpl = ` + (void)item; + + {{ if $r.GetUnique }} ++ {{ if isRepeatedEnum $f }} ++ auto p = {{ lookup $f "Unique" }}.emplace(item); ++ {{ else }} + auto p = {{ lookup $f "Unique" }}.emplace(const_cast<{{ $typ }}&>(item)); ++ {{ end }} + if (p.second == false) { + {{ errIdx . "i" "repeated value must contain unique items" }} + } +diff --git a/templates/goshared/register.go b/templates/goshared/register.go +index 19a2a00..6a8fac7 100644 +--- a/templates/goshared/register.go ++++ b/templates/goshared/register.go +@@ -415,3 +415,29 @@ func (fns goSharedFuncs) enumPackages(enums []pgs.Enum) map[pgs.Name]NormalizedE + func (fns goSharedFuncs) snakeCase(name string) string { + return strcase.ToSnake(name) + } ++ ++func (fns goSharedFuncs) Type(f pgs.Field) pgsgo.TypeName { ++ if f.Type().ProtoType() == pgs.EnumT { ++ ens := fns.enumPackages(fns.externalEnums(f.File())) ++ // Check if the imported name of the enum has collided and been renamed ++ if len(ens) != 0 { ++ enType := f.Type().Enum() ++ if f.Type().IsRepeated() { ++ enType = f.Type().Element().Enum() ++ } ++ ++ enImportPath := fns.ImportPath(enType) ++ for pkg, en := range ens { ++ if en.FilePath == enImportPath { ++ name := fns.enumName(enType) ++ if f.Type().IsRepeated() { ++ return pgsgo.TypeName("[]" + pkg.String() + "." + name) ++ } ++ return pgsgo.TypeName(pkg.String() + "." + name) ++ } ++ } ++ } ++ } ++ ++ return fns.Context.Type(f) ++} +diff --git a/templates/shared/enums.go b/templates/shared/enums.go +index bb5f053..79fcf39 100644 +--- a/templates/shared/enums.go ++++ b/templates/shared/enums.go +@@ -11,6 +11,10 @@ func isEnum(f pgs.Field) bool { + return f.Type().IsEnum() + } + ++func isRepeatedEnum(f pgs.Field) bool { ++ return f.Type().IsRepeated() && f.Type().Element().IsEnum() ++} ++ + func enumNamesMap(values []pgs.EnumValue) (m map[int32]string) { + m = make(map[int32]string) + for _, v := range values { +diff --git a/templates/shared/functions.go b/templates/shared/functions.go +index eb10045..8ed5cd6 100644 +--- a/templates/shared/functions.go ++++ b/templates/shared/functions.go +@@ -8,16 +8,17 @@ import ( + + func RegisterFunctions(tpl *template.Template, params pgs.Parameters) { + tpl.Funcs(map[string]interface{}{ +- "disabled": Disabled, +- "ignored": Ignored, +- "required": RequiredOneOf, +- "context": rulesContext, +- "render": Render(tpl), +- "has": Has, +- "needs": Needs, +- "fileneeds": FileNeeds, +- "isEnum": isEnum, +- "enumList": enumList, +- "enumVal": enumVal, ++ "disabled": Disabled, ++ "ignored": Ignored, ++ "required": RequiredOneOf, ++ "context": rulesContext, ++ "render": Render(tpl), ++ "has": Has, ++ "needs": Needs, ++ "fileneeds": FileNeeds, ++ "isEnum": isEnum, ++ "isRepeatedEnum": isRepeatedEnum, ++ "enumList": enumList, ++ "enumVal": enumVal, + }) + } + \ No newline at end of file diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.cc b/source/extensions/health_checkers/grpc/health_checker_impl.cc index f8f82ebd3d358..5646e98d242b0 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.cc +++ b/source/extensions/health_checkers/grpc/health_checker_impl.cc @@ -40,6 +40,16 @@ const std::string& getHostname(const HostSharedPtr& host, } return HealthCheckerFactory::getHostname(host, EMPTY_STRING, cluster); } + +absl::flat_hash_set +buildRetriableStatuses(const envoy::config::core::v3::HealthCheck::GrpcHealthCheck& config) { + absl::flat_hash_set statuses; + statuses.reserve(config.retriable_serving_statuses_size()); + for (const auto status : config.retriable_serving_statuses()) { + statuses.insert(static_cast(status)); + } + return statuses; +} } // namespace Upstream::HealthCheckerSharedPtr GrpcHealthCheckerFactory::createCustomHealthChecker( @@ -64,7 +74,8 @@ GrpcHealthCheckerImpl::GrpcHealthCheckerImpl(const Cluster& cluster, "grpc.health.v1.Health.Check")), request_headers_parser_(THROW_OR_RETURN_VALUE( Router::HeaderParser::configure(config.grpc_health_check().initial_metadata()), - Router::HeaderParserPtr)) { + Router::HeaderParserPtr)), + retriable_statuses_(buildRetriableStatuses(config.grpc_health_check())) { if (!config.grpc_health_check().service_name().empty()) { service_name_ = config.grpc_health_check().service_name(); } @@ -290,27 +301,16 @@ void GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::onGoAway( } } -bool GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::isHealthCheckSucceeded( - Grpc::Status::GrpcStatus grpc_status) const { - if (grpc_status != Grpc::Status::WellKnownGrpcStatus::Ok) { - return false; - } - - if (!health_check_response_ || - health_check_response_->status() != grpc::health::v1::HealthCheckResponse::SERVING) { - return false; - } - - return true; -} - void GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::onRpcComplete( Grpc::Status::GrpcStatus grpc_status, const std::string& grpc_message, bool end_stream) { logHealthCheckStatus(grpc_status, grpc_message); - if (isHealthCheckSucceeded(grpc_status)) { + if (grpc_status != Grpc::Status::WellKnownGrpcStatus::Ok || !health_check_response_) { + handleFailure(envoy::data::core::v3::ACTIVE); + } else if (health_check_response_->status() == grpc::health::v1::HealthCheckResponse::SERVING) { handleSuccess(false); } else { - handleFailure(envoy::data::core::v3::ACTIVE); + const bool retriable = parent_.retriable_statuses_.contains(health_check_response_->status()); + handleFailure(envoy::data::core::v3::ACTIVE, /*retriable=*/retriable); } // Read the value as we may call resetState() and clear it. diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index a3e54bb454792..adb40f507a237 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -2,6 +2,7 @@ #include +#include "absl/container/flat_hash_set.h" #include "envoy/access_log/access_log.h" #include "envoy/api/api.h" #include "envoy/common/random_generator.h" @@ -60,7 +61,6 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { void onRpcComplete(Grpc::Status::GrpcStatus grpc_status, const std::string& grpc_message, bool end_stream); - bool isHealthCheckSucceeded(Grpc::Status::GrpcStatus grpc_status) const; void resetState(); void logHealthCheckStatus(Grpc::Status::GrpcStatus grpc_status, const std::string& grpc_message); @@ -148,6 +148,8 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { absl::optional service_name_; absl::optional authority_value_; Router::HeaderParserPtr request_headers_parser_; + const absl::flat_hash_set + retriable_statuses_; }; /** diff --git a/test/common/upstream/health_check_corpus/grpc_retry_not_serving b/test/common/upstream/health_check_corpus/grpc_retry_not_serving new file mode 100644 index 0000000000000..845c5d20a6719 --- /dev/null +++ b/test/common/upstream/health_check_corpus/grpc_retry_not_serving @@ -0,0 +1,51 @@ +health_check_config { + timeout { + seconds: 1 + } + interval { + seconds: 1 + } + unhealthy_threshold { + value: 2 + } + healthy_threshold { + value: 1 + } + grpc_health_check { + retriable_serving_statuses: NOT_SERVING + } +} +actions { + trigger_interval_timer { + } +} +actions { + respond { + http_respond { + headers { + } + status: 200 + body: "" + } + tcp_respond { + data: "" + } + grpc_respond { + grpc_respond_headers { + headers { + } + status: 200 + } + grpc_respond_bytes { + status: NOT_SERVING + chunk_size_for_structured_response: 1 + } + grpc_respond_trailers { + trailers { + headers { + } + } + } + } + } +} diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index aa51616f86822..05a02a247c8b3 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -4985,6 +4985,19 @@ class GrpcHealthCheckerImplTestBase : public Event::TestUsingSimulatedTime, addCompletionCallback(); } + void setupHCWithRetriableStatuses( + const std::vector& statuses, + int unhealthy_threshold) { + auto config = createGrpcHealthCheckConfig(); + config.mutable_unhealthy_threshold()->set_value(unhealthy_threshold); + auto* grpc_config = config.mutable_grpc_health_check(); + for (const auto status : statuses) { + grpc_config->add_retriable_serving_statuses(status); + } + allocHealthChecker(config); + addCompletionCallback(); + } + void setupServiceNameHC(const absl::optional& authority) { auto config = createGrpcHealthCheckConfig(); config.mutable_grpc_health_check()->set_service_name("service"); @@ -5700,6 +5713,32 @@ TEST_F(GrpcHealthCheckerImplTest, GrpcHealthFail) { expectHostHealthy(true); } +TEST_F(GrpcHealthCheckerImplTest, GrpcHealthFailRetriableNotServing) { + setupHCWithRetriableStatuses({grpc::health::v1::HealthCheckResponse::NOT_SERVING}, + /*unhealthy_threshold=*/2); + cluster_->prioritySet().getMockHostSet(0)->hosts_ = { + makeTestHost(cluster_->info_, "tcp://127.0.0.1:80")}; + + expectSessionCreate(); + expectHealthcheckStart(0); + EXPECT_CALL(event_logger_, logUnhealthy(_, _, _, true)); + health_checker_->start(); + + expectHealthcheckStop(0); + EXPECT_CALL(*this, onHostStatus(_, HealthTransition::ChangePending)); + respondServiceStatus(0, grpc::health::v1::HealthCheckResponse::NOT_SERVING); + expectHostHealthy(true); + + expectHealthcheckStart(0); + test_sessions_[0]->interval_timer_->invokeCallback(); + + expectHealthcheckStop(0); + EXPECT_CALL(*this, onHostStatus(_, HealthTransition::Changed)); + EXPECT_CALL(event_logger_, logEjectUnhealthy(_, _, _)); + respondServiceStatus(0, grpc::health::v1::HealthCheckResponse::NOT_SERVING); + expectHostHealthy(false); +} + // Test disconnects produce network-type failures which does not lead to immediate unhealthy state. TEST_F(GrpcHealthCheckerImplTest, Disconnect) { setupHC(); diff --git a/test/integration/health_check_integration_test.cc b/test/integration/health_check_integration_test.cc index 03b13d1aaf19b..4b814c7efaeb9 100644 --- a/test/integration/health_check_integration_test.cc +++ b/test/integration/health_check_integration_test.cc @@ -710,10 +710,17 @@ class GrpcHealthCheckIntegrationTest : public Event::TestUsingSimulatedTime, // Adds a gRPC active health check specifier to the given cluster, and waits for the first health // check probe to be received. - void initGrpcHealthCheck(uint32_t cluster_idx) { + void initGrpcHealthCheck(uint32_t cluster_idx, + const std::vector& + retriable_statuses = {}, + uint32_t unhealthy_threshold = 1) { auto& cluster_data = clusters_[cluster_idx]; auto health_check = addHealthCheck(cluster_data.cluster_); - health_check->mutable_grpc_health_check(); + auto* grpc_health_check = health_check->mutable_grpc_health_check(); + for (const auto status : retriable_statuses) { + grpc_health_check->add_retriable_serving_statuses(status); + } + health_check->mutable_unhealthy_threshold()->set_value(unhealthy_threshold); // Introduce the cluster using compareDiscoveryRequest / sendDiscoveryResponse. EXPECT_TRUE(compareDiscoveryRequest(Config::TestTypeUrl::get().Cluster, "", {}, {}, {}, true)); @@ -795,6 +802,68 @@ TEST_P(GrpcHealthCheckIntegrationTest, SingleEndpointNotServingGrpc) { EXPECT_EQ(1, test_server_->counter("cluster.cluster_1.health_check.failure")->value()); } +TEST_P(GrpcHealthCheckIntegrationTest, NotServingGrpcRetriesWhenConfigured) { + initialize(); + + const uint32_t cluster_idx = 0; + initGrpcHealthCheck(cluster_idx, {grpc::health::v1::HealthCheckResponse::NOT_SERVING}, + /*unhealthy_threshold=*/2); + + grpc::health::v1::HealthCheckResponse response; + response.set_status(grpc::health::v1::HealthCheckResponse::SERVING); + sendGrpcResponse( + cluster_idx, + Http::TestResponseHeaderMapImpl{ + {":status", "200"}, {"content-type", Http::Headers::get().ContentTypeValues.Grpc}}, + response); + + test_server_->waitForCounterGe("cluster.cluster_1.health_check.success", 1); + EXPECT_EQ(1, test_server_->counter("cluster.cluster_1.health_check.success")->value()); + EXPECT_EQ(0, test_server_->counter("cluster.cluster_1.health_check.failure")->value()); + EXPECT_EQ(1, test_server_->gauge("cluster.cluster_1.membership_healthy")->value()); + + // Wait until the next attempt is made. + test_server_->waitForCounterEq("cluster.cluster_1.health_check.attempt", 2); + + grpc::health::v1::HealthCheckRequest request; + auto& cluster_data = clusters_[cluster_idx]; + ASSERT_TRUE(cluster_data.host_fake_connection_->waitForNewStream(*dispatcher_, + cluster_data.host_stream_)); + ASSERT_TRUE(cluster_data.host_stream_->waitForGrpcMessage(*dispatcher_, request)); + ASSERT_TRUE(cluster_data.host_stream_->waitForEndStream(*dispatcher_)); + + response.set_status(grpc::health::v1::HealthCheckResponse::NOT_SERVING); + sendGrpcResponse( + cluster_idx, + Http::TestResponseHeaderMapImpl{ + {":status", "200"}, {"content-type", Http::Headers::get().ContentTypeValues.Grpc}}, + response); + + test_server_->waitForCounterGe("cluster.cluster_1.health_check.failure", 1); + EXPECT_EQ(1, test_server_->counter("cluster.cluster_1.health_check.success")->value()); + EXPECT_EQ(1, test_server_->counter("cluster.cluster_1.health_check.failure")->value()); + EXPECT_EQ(1, test_server_->gauge("cluster.cluster_1.membership_healthy")->value()); + + // Wait until the next attempt is made. + test_server_->waitForCounterEq("cluster.cluster_1.health_check.attempt", 3); + + ASSERT_TRUE(cluster_data.host_fake_connection_->waitForNewStream(*dispatcher_, + cluster_data.host_stream_)); + ASSERT_TRUE(cluster_data.host_stream_->waitForGrpcMessage(*dispatcher_, request)); + ASSERT_TRUE(cluster_data.host_stream_->waitForEndStream(*dispatcher_)); + + sendGrpcResponse( + cluster_idx, + Http::TestResponseHeaderMapImpl{ + {":status", "200"}, {"content-type", Http::Headers::get().ContentTypeValues.Grpc}}, + response); + + test_server_->waitForCounterGe("cluster.cluster_1.health_check.failure", 2); + EXPECT_EQ(1, test_server_->counter("cluster.cluster_1.health_check.success")->value()); + EXPECT_EQ(2, test_server_->counter("cluster.cluster_1.health_check.failure")->value()); + EXPECT_EQ(0, test_server_->gauge("cluster.cluster_1.membership_healthy")->value()); +} + // Tests that no gRPC health check response results in timeout and unhealthy endpoint. TEST_P(GrpcHealthCheckIntegrationTest, SingleEndpointTimeoutGrpc) { initialize(); From 204dbe06fdc0bbd457488099935ff2513132d8c0 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 4 Feb 2026 19:06:53 -0500 Subject: [PATCH 02/23] format Signed-off-by: James Fish --- api/envoy/config/core/v3/health_check.proto | 6 +++--- .../extensions/health_checkers/grpc/health_checker_impl.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index 1610f2664dbac..3d8a772887c76 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -10,13 +10,13 @@ import "envoy/type/matcher/v3/string.proto"; import "envoy/type/v3/http.proto"; import "envoy/type/v3/range.proto"; -import "src/proto/grpc/health/v1/health.proto"; - import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; +import "src/proto/grpc/health/v1/health.proto"; + import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -231,7 +231,7 @@ message HealthCheck { repeated HeaderValueOption initial_metadata = 3 [(validate.rules).repeated = {max_items: 1000}]; // Specifies a list of gRPC `grpc.health.v1.HealthCheckResponse.ServingStatus - // ` that will be treated + // `_ that will be treated // as retriable health check failures and respect the unhealthy threshold instead of immediately marking the // host unhealthy. SERVING status is not retriable because that is a successful health check. repeated grpc.health.v1.HealthCheckResponse.ServingStatus retriable_serving_statuses = 4 diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index adb40f507a237..dad9d9ddf84d5 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -2,7 +2,6 @@ #include -#include "absl/container/flat_hash_set.h" #include "envoy/access_log/access_log.h" #include "envoy/api/api.h" #include "envoy/common/random_generator.h" @@ -24,6 +23,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" +#include "absl/container/flat_hash_set.h" #include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { From ba4e88837cbcef1cd9c53b498396bf1d966bee2e Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 4 Feb 2026 20:17:28 -0500 Subject: [PATCH 03/23] Handle buf.yaml linting by remvoing grpc's /src/proto prefix Signed-off-by: James Fish --- api/bazel/external_proto_deps.bzl | 2 +- api/buf.lock | 26 +++++++++++-------- api/buf.yaml | 1 + api/envoy/config/core/v3/health_check.proto | 2 +- bazel/grpc.patch | 28 ++++++++++++++++++--- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/api/bazel/external_proto_deps.bzl b/api/bazel/external_proto_deps.bzl index 82b828e73f069..5440b88a46556 100644 --- a/api/bazel/external_proto_deps.bzl +++ b/api/bazel/external_proto_deps.bzl @@ -13,7 +13,7 @@ EXTERNAL_PROTO_IMPORT_BAZEL_DEP_MAP = { "google/api/expr/v1alpha1/syntax.proto": "@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto", "io/prometheus/client/metrics.proto": "@prometheus_metrics_model//:client_model", "opentelemetry/proto/common/v1/common.proto": "@opentelemetry-proto//:common_proto", - "src/proto/grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", + "grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", } # This maps from the Bazel proto_library target to the Go language binding target for external dependencies. diff --git a/api/buf.lock b/api/buf.lock index d1b96940301fa..0284ede3eba33 100644 --- a/api/buf.lock +++ b/api/buf.lock @@ -2,20 +2,26 @@ version: v2 deps: - name: buf.build/cncf/xds - commit: c313df85559e44248d0115969f2c8c24 - digest: b5:89db966d59cc9686658a12f40ba0bb38017d0bccf3e651d025ff6747d18f1a647814e0bd6dd534218d08fe949be33371ef506a1ac8a32c4978b6f9a288231bde + commit: 2456e1dfc0664e7596d7f3b20f4b62d0 + digest: b5:412ce915a722e7e653426107531cfbfea5a263afd438b2778c03f1dc8f75628e5baf791e513324e5ccff0197be2f91aa174629b8353966d38c295bd86bc2cebb - name: buf.build/envoyproxy/protoc-gen-validate - commit: 6607b10f00ed4a3d98f906807131c44a - digest: b5:ade405ac4328bd0a2cf83c93bcb4bc389d4897afd86a0096df4537b180916882da4e4f0c2d45f0b1554d7a6c87f6c5bc94b71b3555ca71cc31a9a8baed26a9f9 + commit: daf171c6cdb54629b5f51e345a79e4dd + digest: b5:c745e1521879f43740230b1df673d0729f55704efefdcfc489d4a0a2d40c92a26cacfeab62813403040a8b180142d53b398c7ca784a065e43823605ee49681de - name: buf.build/gogo/protobuf - commit: 5461a3dfa9d941da82028ab185dc2a0e - digest: b5:8e9cf66be25ae4fac7fe0867742f41d008491cf1e0f49c488b42ce2fadb663970d4179472f8835dd58a61448464ba0ad9c2d19f464553f86ed137d9f59ec5dff + commit: e1dbca2775a74a89955a99990de45a53 + digest: b5:9be593f336e8b0d35761a2fb5ebc4460aaee3f2d21e9d75b7fddbecb1dd53ea58a0bb447c20c33387f4e07fa7e1e439f7125663a624517cfde97c8bec68e4ecf + - name: buf.build/google/cel-spec + commit: 96eff7bcf453468dbd44b80598bfe1bf + digest: b5:660c244ec1e8a0f26c5431e1901f1d52d322c7ee3fd240cb6832f44d0694384a36ded008af457a9e5268c73adfa00170e972ac4fe44752a693424b3479f30b82 - name: buf.build/googleapis/googleapis commit: 62f35d8aed1149c291d606d958a7ce32 digest: b5:d66bf04adc77a0870bdc9328aaf887c7188a36fb02b83a480dc45ef9dc031b4d39fc6e9dc6435120ccf4fe5bfd5c6cb6592533c6c316595571f9a31420ab47fe + - name: buf.build/grpc/grpc + commit: e126be52bace42e49491e4015e464b59 + digest: b5:a01d4326f3e6590547c7cbb3bff8d6dab5cf564eeadd7c7c0d32ea739931a1d492322e6aa21312c9f419538044beea6740f9a6c51bb44647c627044936c55f36 - name: buf.build/opentelemetry/opentelemetry - commit: 43554dfbbfbd4873bde8993d32ea8332 - digest: b5:027a738207c1e66e1b628e49923dade94b8832049537f0a05375b086122ccc5db4351f86e4297ac0fe441b4351c901ada85e03e7f34a09a401e46e00f8c8062b + commit: 648a3e2f02e14fe187656ea4ac3befa1 + digest: b5:a0514be587ab2e8598f7102dfdaba5e985138b8c041c707e470a9c8b877410ada6e60cf2359352302f08c0504de685379f7f7a085d4699d69a2e6ed7035e78d9 - name: buf.build/prometheus/client-model - commit: 1d56a02d481a412a83b3c4984eb90c2e - digest: b5:030705921923d3a04902cb71f946d39db4ca6bb03d1da7fcb381b1f907b693572519f73fa9f9a0994d61cedb8935989675aca0c222e05e7c8790c808b2a14e47 + commit: e171c0b235c546d5a9a597c2961bd357 + digest: b5:c26899a8592079d1f0cc168dee57c70df022d07c450ad0560fac8a1c6b5b9f73cbc6c44a21a67afbeb32e1e2127cf02c4e7f34368c8685a33b56bd936ea4273e diff --git a/api/buf.yaml b/api/buf.yaml index fbd2876b1a484..811eaa0eb6426 100644 --- a/api/buf.yaml +++ b/api/buf.yaml @@ -4,6 +4,7 @@ deps: - buf.build/envoyproxy/protoc-gen-validate - buf.build/gogo/protobuf - buf.build/googleapis/googleapis:62f35d8aed1149c291d606d958a7ce32 +- buf.build/grpc/grpc - buf.build/opentelemetry/opentelemetry - buf.build/prometheus/client-model breaking: diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index 3d8a772887c76..bd66fbf9b7a3e 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -15,7 +15,7 @@ import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; -import "src/proto/grpc/health/v1/health.proto"; +import "grpc/health/v1/health.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 0f0be258d5949..f9bb704879def 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..f4a2ed3f13 100644 +index a3b8923b6e..5c11639f38 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -40,6 +40,20 @@ index a3b8923b6e..f4a2ed3f13 100644 "//conditions:default": [name + "_native"], }), outs = [name + "_binary"], +@@ -217,11 +211,13 @@ def grpc_internal_proto_library( + srcs = [], + deps = [], + visibility = None, ++ strip_import_prefix = None, + has_services = False): # buildifier: disable=unused-variable + proto_library( + name = name, + srcs = srcs, + deps = deps, ++ strip_import_prefix = strip_import_prefix, + visibility = visibility, + ) + diff --git a/include/grpc/event_engine/memory_request.h b/include/grpc/event_engine/memory_request.h index 76bcbb2036..ad8cab842e 100644 --- a/include/grpc/event_engine/memory_request.h @@ -249,10 +263,18 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..374653516a 100644 +index f6165e0392..120505f128 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD -@@ -44,3 +44,10 @@ filegroup( +@@ -24,6 +24,7 @@ grpc_package( + grpc_internal_proto_library( + name = "health_proto", + srcs = ["health.proto"], ++ strip_import_prefix = "/src/proto/", + has_services = True, + ) + +@@ -44,3 +45,10 @@ filegroup( "health.proto", ], ) From e6a1d2342f217aefca7bb286dbc9a5f87bbd6098 Mon Sep 17 00:00:00 2001 From: James Fish Date: Tue, 10 Feb 2026 21:36:18 -0500 Subject: [PATCH 04/23] Fix src/proto imports in grpc Signed-off-by: James Fish --- bazel/grpc.patch | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index f9bb704879def..5d1f09b92f6f1 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -249,6 +249,19 @@ index 3fb5d68146..583a2f9553 100644 return PromiseFactoryImpl(RepeatableToken{}, f_); } }; +diff --git a/src/core/load_balancing/health_check_client.cc b/src/core/load_balancing/health_check_client.cc +index c84f6d0a48..9f8bee2c53 100644 +--- a/src/core/load_balancing/health_check_client.cc ++++ b/src/core/load_balancing/health_check_client.cc +@@ -57,7 +57,7 @@ + #include "src/core/util/ref_counted_ptr.h" + #include "src/core/util/sync.h" + #include "src/core/util/work_serializer.h" +-#include "src/proto/grpc/health/v1/health.upb.h" ++#include "grpc/health/v1/health.upb.h" + #include "upb/base/string_view.h" + #include "upb/mem/arena.hpp" + diff --git a/src/core/util/glob.cc b/src/core/util/glob.cc index 1b1c16e23d..22e54259f0 100644 --- a/src/core/util/glob.cc @@ -263,14 +276,14 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..120505f128 100644 +index f6165e0392..90e86a5c50 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -24,6 +24,7 @@ grpc_package( grpc_internal_proto_library( name = "health_proto", srcs = ["health.proto"], -+ strip_import_prefix = "/src/proto/", ++ strip_import_prefix = "/src/proto", has_services = True, ) From e2e136d85528e7f35ff1627c2faa0017f869fdcc Mon Sep 17 00:00:00 2001 From: James Fish Date: Tue, 10 Feb 2026 21:38:55 -0500 Subject: [PATCH 05/23] Fix grpc patch indent Signed-off-by: James Fish --- bazel/grpc.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 5d1f09b92f6f1..bc54ee9523480 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..5c11639f38 100644 +index a3b8923b6e..87c59a932a 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -44,7 +44,7 @@ index a3b8923b6e..5c11639f38 100644 srcs = [], deps = [], visibility = None, -+ strip_import_prefix = None, ++ strip_import_prefix = None, has_services = False): # buildifier: disable=unused-variable proto_library( name = name, From 9485a03ae39084f4e470df85e8bd2f938e571f0d Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 11 Feb 2026 07:29:15 -0500 Subject: [PATCH 06/23] Fix imports for health.upb.h Signed-off-by: James Fish --- bazel/grpc.patch | 13 +++++++++++++ source/common/upstream/health_checker_impl.h | 2 +- .../health_checkers/grpc/health_checker_impl.h | 2 +- .../health_checkers/http/health_checker_impl.h | 2 +- .../health_checkers/tcp/health_checker_impl.h | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index bc54ee9523480..7b62b43884cd3 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -275,6 +275,19 @@ index 1b1c16e23d..22e54259f0 100644 #include "absl/strings/string_view.h" namespace grpc_core { +diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc +index 492ba694c1..1cd2ee17fd 100644 +--- a/src/cpp/server/health/default_health_check_service.cc ++++ b/src/cpp/server/health/default_health_check_service.cc +@@ -30,7 +30,7 @@ + + #include "absl/log/log.h" + #include "src/core/util/grpc_check.h" +-#include "src/proto/grpc/health/v1/health.upb.h" ++#include "grpc/health/v1/health.upb.h" + #include "upb/base/string_view.h" + #include "upb/mem/arena.hpp" + diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index f6165e0392..90e86a5c50 100644 --- a/src/proto/grpc/health/v1/BUILD diff --git a/source/common/upstream/health_checker_impl.h b/source/common/upstream/health_checker_impl.h index 259e9df96198f..8aa4dac5f5b6e 100644 --- a/source/common/upstream/health_checker_impl.h +++ b/source/common/upstream/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/stream_info/stream_info_impl.h" #include "source/common/upstream/health_checker_event_logger.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index dad9d9ddf84d5..4551c3a7f457e 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -24,7 +24,7 @@ #include "source/extensions/health_checkers/common/health_checker_base_impl.h" #include "absl/container/flat_hash_set.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/http/health_checker_impl.h b/source/extensions/health_checkers/http/health_checker_impl.h index 68fd6214f9166..30fdf43bae714 100644 --- a/source/extensions/health_checkers/http/health_checker_impl.h +++ b/source/extensions/health_checkers/http/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/tcp/health_checker_impl.h b/source/extensions/health_checkers/tcp/health_checker_impl.h index ec3b14ef37c81..0353c5267f843 100644 --- a/source/extensions/health_checkers/tcp/health_checker_impl.h +++ b/source/extensions/health_checkers/tcp/health_checker_impl.h @@ -22,7 +22,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { From 1c4e7ca2adec9f059376dee2ed652bee203dd19e Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 09:39:12 -0400 Subject: [PATCH 07/23] Revert "Fix imports for health.upb.h" This reverts commit 9485a03ae39084f4e470df85e8bd2f938e571f0d. Signed-off-by: James Fish --- bazel/grpc.patch | 13 ------------- source/common/upstream/health_checker_impl.h | 2 +- .../health_checkers/grpc/health_checker_impl.h | 2 +- .../health_checkers/http/health_checker_impl.h | 2 +- .../health_checkers/tcp/health_checker_impl.h | 2 +- 5 files changed, 4 insertions(+), 17 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 7b62b43884cd3..bc54ee9523480 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -275,19 +275,6 @@ index 1b1c16e23d..22e54259f0 100644 #include "absl/strings/string_view.h" namespace grpc_core { -diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc -index 492ba694c1..1cd2ee17fd 100644 ---- a/src/cpp/server/health/default_health_check_service.cc -+++ b/src/cpp/server/health/default_health_check_service.cc -@@ -30,7 +30,7 @@ - - #include "absl/log/log.h" - #include "src/core/util/grpc_check.h" --#include "src/proto/grpc/health/v1/health.upb.h" -+#include "grpc/health/v1/health.upb.h" - #include "upb/base/string_view.h" - #include "upb/mem/arena.hpp" - diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index f6165e0392..90e86a5c50 100644 --- a/src/proto/grpc/health/v1/BUILD diff --git a/source/common/upstream/health_checker_impl.h b/source/common/upstream/health_checker_impl.h index 8aa4dac5f5b6e..259e9df96198f 100644 --- a/source/common/upstream/health_checker_impl.h +++ b/source/common/upstream/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/stream_info/stream_info_impl.h" #include "source/common/upstream/health_checker_event_logger.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index 4551c3a7f457e..dad9d9ddf84d5 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -24,7 +24,7 @@ #include "source/extensions/health_checkers/common/health_checker_base_impl.h" #include "absl/container/flat_hash_set.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/http/health_checker_impl.h b/source/extensions/health_checkers/http/health_checker_impl.h index 30fdf43bae714..68fd6214f9166 100644 --- a/source/extensions/health_checkers/http/health_checker_impl.h +++ b/source/extensions/health_checkers/http/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/tcp/health_checker_impl.h b/source/extensions/health_checkers/tcp/health_checker_impl.h index 0353c5267f843..ec3b14ef37c81 100644 --- a/source/extensions/health_checkers/tcp/health_checker_impl.h +++ b/source/extensions/health_checkers/tcp/health_checker_impl.h @@ -22,7 +22,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { From 6624d4193ae6a0fb4426d10a3e573f517f1fb112 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 09:39:23 -0400 Subject: [PATCH 08/23] Revert "Fix grpc patch indent" This reverts commit e2e136d85528e7f35ff1627c2faa0017f869fdcc. Signed-off-by: James Fish --- bazel/grpc.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index bc54ee9523480..5d1f09b92f6f1 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..87c59a932a 100644 +index a3b8923b6e..5c11639f38 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -44,7 +44,7 @@ index a3b8923b6e..87c59a932a 100644 srcs = [], deps = [], visibility = None, -+ strip_import_prefix = None, ++ strip_import_prefix = None, has_services = False): # buildifier: disable=unused-variable proto_library( name = name, From 5ce7cbbb4ff4f426c3378ec529af01830ec18879 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 09:40:00 -0400 Subject: [PATCH 09/23] Revert "Fix src/proto imports in grpc" This reverts commit e6a1d2342f217aefca7bb286dbc9a5f87bbd6098. Signed-off-by: James Fish --- bazel/grpc.patch | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 5d1f09b92f6f1..f9bb704879def 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -249,19 +249,6 @@ index 3fb5d68146..583a2f9553 100644 return PromiseFactoryImpl(RepeatableToken{}, f_); } }; -diff --git a/src/core/load_balancing/health_check_client.cc b/src/core/load_balancing/health_check_client.cc -index c84f6d0a48..9f8bee2c53 100644 ---- a/src/core/load_balancing/health_check_client.cc -+++ b/src/core/load_balancing/health_check_client.cc -@@ -57,7 +57,7 @@ - #include "src/core/util/ref_counted_ptr.h" - #include "src/core/util/sync.h" - #include "src/core/util/work_serializer.h" --#include "src/proto/grpc/health/v1/health.upb.h" -+#include "grpc/health/v1/health.upb.h" - #include "upb/base/string_view.h" - #include "upb/mem/arena.hpp" - diff --git a/src/core/util/glob.cc b/src/core/util/glob.cc index 1b1c16e23d..22e54259f0 100644 --- a/src/core/util/glob.cc @@ -276,14 +263,14 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..90e86a5c50 100644 +index f6165e0392..120505f128 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -24,6 +24,7 @@ grpc_package( grpc_internal_proto_library( name = "health_proto", srcs = ["health.proto"], -+ strip_import_prefix = "/src/proto", ++ strip_import_prefix = "/src/proto/", has_services = True, ) From 22695dd6ac736c3d96a5f6ac2641a0d3f5323e30 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 09:40:12 -0400 Subject: [PATCH 10/23] Revert "Handle buf.yaml linting by remvoing grpc's /src/proto prefix" This reverts commit ba4e88837cbcef1cd9c53b498396bf1d966bee2e. Signed-off-by: James Fish --- api/bazel/external_proto_deps.bzl | 2 +- api/buf.lock | 26 ++++++++----------- api/buf.yaml | 1 - api/envoy/config/core/v3/health_check.proto | 2 +- bazel/grpc.patch | 28 +++------------------ 5 files changed, 15 insertions(+), 44 deletions(-) diff --git a/api/bazel/external_proto_deps.bzl b/api/bazel/external_proto_deps.bzl index 5440b88a46556..82b828e73f069 100644 --- a/api/bazel/external_proto_deps.bzl +++ b/api/bazel/external_proto_deps.bzl @@ -13,7 +13,7 @@ EXTERNAL_PROTO_IMPORT_BAZEL_DEP_MAP = { "google/api/expr/v1alpha1/syntax.proto": "@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto", "io/prometheus/client/metrics.proto": "@prometheus_metrics_model//:client_model", "opentelemetry/proto/common/v1/common.proto": "@opentelemetry-proto//:common_proto", - "grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", + "src/proto/grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", } # This maps from the Bazel proto_library target to the Go language binding target for external dependencies. diff --git a/api/buf.lock b/api/buf.lock index 0284ede3eba33..d1b96940301fa 100644 --- a/api/buf.lock +++ b/api/buf.lock @@ -2,26 +2,20 @@ version: v2 deps: - name: buf.build/cncf/xds - commit: 2456e1dfc0664e7596d7f3b20f4b62d0 - digest: b5:412ce915a722e7e653426107531cfbfea5a263afd438b2778c03f1dc8f75628e5baf791e513324e5ccff0197be2f91aa174629b8353966d38c295bd86bc2cebb + commit: c313df85559e44248d0115969f2c8c24 + digest: b5:89db966d59cc9686658a12f40ba0bb38017d0bccf3e651d025ff6747d18f1a647814e0bd6dd534218d08fe949be33371ef506a1ac8a32c4978b6f9a288231bde - name: buf.build/envoyproxy/protoc-gen-validate - commit: daf171c6cdb54629b5f51e345a79e4dd - digest: b5:c745e1521879f43740230b1df673d0729f55704efefdcfc489d4a0a2d40c92a26cacfeab62813403040a8b180142d53b398c7ca784a065e43823605ee49681de + commit: 6607b10f00ed4a3d98f906807131c44a + digest: b5:ade405ac4328bd0a2cf83c93bcb4bc389d4897afd86a0096df4537b180916882da4e4f0c2d45f0b1554d7a6c87f6c5bc94b71b3555ca71cc31a9a8baed26a9f9 - name: buf.build/gogo/protobuf - commit: e1dbca2775a74a89955a99990de45a53 - digest: b5:9be593f336e8b0d35761a2fb5ebc4460aaee3f2d21e9d75b7fddbecb1dd53ea58a0bb447c20c33387f4e07fa7e1e439f7125663a624517cfde97c8bec68e4ecf - - name: buf.build/google/cel-spec - commit: 96eff7bcf453468dbd44b80598bfe1bf - digest: b5:660c244ec1e8a0f26c5431e1901f1d52d322c7ee3fd240cb6832f44d0694384a36ded008af457a9e5268c73adfa00170e972ac4fe44752a693424b3479f30b82 + commit: 5461a3dfa9d941da82028ab185dc2a0e + digest: b5:8e9cf66be25ae4fac7fe0867742f41d008491cf1e0f49c488b42ce2fadb663970d4179472f8835dd58a61448464ba0ad9c2d19f464553f86ed137d9f59ec5dff - name: buf.build/googleapis/googleapis commit: 62f35d8aed1149c291d606d958a7ce32 digest: b5:d66bf04adc77a0870bdc9328aaf887c7188a36fb02b83a480dc45ef9dc031b4d39fc6e9dc6435120ccf4fe5bfd5c6cb6592533c6c316595571f9a31420ab47fe - - name: buf.build/grpc/grpc - commit: e126be52bace42e49491e4015e464b59 - digest: b5:a01d4326f3e6590547c7cbb3bff8d6dab5cf564eeadd7c7c0d32ea739931a1d492322e6aa21312c9f419538044beea6740f9a6c51bb44647c627044936c55f36 - name: buf.build/opentelemetry/opentelemetry - commit: 648a3e2f02e14fe187656ea4ac3befa1 - digest: b5:a0514be587ab2e8598f7102dfdaba5e985138b8c041c707e470a9c8b877410ada6e60cf2359352302f08c0504de685379f7f7a085d4699d69a2e6ed7035e78d9 + commit: 43554dfbbfbd4873bde8993d32ea8332 + digest: b5:027a738207c1e66e1b628e49923dade94b8832049537f0a05375b086122ccc5db4351f86e4297ac0fe441b4351c901ada85e03e7f34a09a401e46e00f8c8062b - name: buf.build/prometheus/client-model - commit: e171c0b235c546d5a9a597c2961bd357 - digest: b5:c26899a8592079d1f0cc168dee57c70df022d07c450ad0560fac8a1c6b5b9f73cbc6c44a21a67afbeb32e1e2127cf02c4e7f34368c8685a33b56bd936ea4273e + commit: 1d56a02d481a412a83b3c4984eb90c2e + digest: b5:030705921923d3a04902cb71f946d39db4ca6bb03d1da7fcb381b1f907b693572519f73fa9f9a0994d61cedb8935989675aca0c222e05e7c8790c808b2a14e47 diff --git a/api/buf.yaml b/api/buf.yaml index 811eaa0eb6426..fbd2876b1a484 100644 --- a/api/buf.yaml +++ b/api/buf.yaml @@ -4,7 +4,6 @@ deps: - buf.build/envoyproxy/protoc-gen-validate - buf.build/gogo/protobuf - buf.build/googleapis/googleapis:62f35d8aed1149c291d606d958a7ce32 -- buf.build/grpc/grpc - buf.build/opentelemetry/opentelemetry - buf.build/prometheus/client-model breaking: diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index bd66fbf9b7a3e..3d8a772887c76 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -15,7 +15,7 @@ import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; -import "grpc/health/v1/health.proto"; +import "src/proto/grpc/health/v1/health.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; diff --git a/bazel/grpc.patch b/bazel/grpc.patch index f9bb704879def..0f0be258d5949 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..5c11639f38 100644 +index a3b8923b6e..f4a2ed3f13 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -40,20 +40,6 @@ index a3b8923b6e..5c11639f38 100644 "//conditions:default": [name + "_native"], }), outs = [name + "_binary"], -@@ -217,11 +211,13 @@ def grpc_internal_proto_library( - srcs = [], - deps = [], - visibility = None, -+ strip_import_prefix = None, - has_services = False): # buildifier: disable=unused-variable - proto_library( - name = name, - srcs = srcs, - deps = deps, -+ strip_import_prefix = strip_import_prefix, - visibility = visibility, - ) - diff --git a/include/grpc/event_engine/memory_request.h b/include/grpc/event_engine/memory_request.h index 76bcbb2036..ad8cab842e 100644 --- a/include/grpc/event_engine/memory_request.h @@ -263,18 +249,10 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..120505f128 100644 +index f6165e0392..374653516a 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD -@@ -24,6 +24,7 @@ grpc_package( - grpc_internal_proto_library( - name = "health_proto", - srcs = ["health.proto"], -+ strip_import_prefix = "/src/proto/", - has_services = True, - ) - -@@ -44,3 +45,10 @@ filegroup( +@@ -44,3 +44,10 @@ filegroup( "health.proto", ], ) From 69f4ca8239f7934fd6ea783d04b148ee49d21d7d Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 09:46:06 -0400 Subject: [PATCH 11/23] Ignore health_check.proto Signed-off-by: James Fish --- api/buf.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/buf.yaml b/api/buf.yaml index fbd2876b1a484..61787f2ef6751 100644 --- a/api/buf.yaml +++ b/api/buf.yaml @@ -27,3 +27,11 @@ lint: - envoy/api/v2/listener.proto - envoy/config/bootstrap/v2/bootstrap.proto disallow_comment_ignores: true +modules: +- path: . + excludes: + # temporarily ignore proto linting errors as grpc health check import not handled by buf + # it requires grpc import to follow https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto + # but envoy uses https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto + # which has src/proto prefix + - envoy/config/core/v3/health_check.proto From 5def05115dd407a9e3db86fefb5188017a888071 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 10:00:07 -0400 Subject: [PATCH 12/23] Replace pgv patch with envoy load time check Signed-off-by: James Fish --- api/envoy/config/core/v3/health_check.proto | 6 +- bazel/pgv.patch | 130 ------------------ .../grpc/health_checker_impl.cc | 40 ++++-- .../grpc/health_checker_impl.h | 3 + .../upstream/health_checker_impl_test.cc | 27 ++++ 5 files changed, 61 insertions(+), 145 deletions(-) diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index 3d8a772887c76..047bbc083186b 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -234,11 +234,7 @@ message HealthCheck { // `_ that will be treated // as retriable health check failures and respect the unhealthy threshold instead of immediately marking the // host unhealthy. SERVING status is not retriable because that is a successful health check. - repeated grpc.health.v1.HealthCheckResponse.ServingStatus retriable_serving_statuses = 4 - [(validate.rules).repeated = { - unique: true - items {enum {defined_only: true not_in: 1}} - }]; + repeated grpc.health.v1.HealthCheckResponse.ServingStatus retriable_serving_statuses = 4; } // Custom health check. diff --git a/bazel/pgv.patch b/bazel/pgv.patch index 0664ad118a557..e5af1d37788ac 100644 --- a/bazel/pgv.patch +++ b/bazel/pgv.patch @@ -29,133 +29,3 @@ index 1a41f68..4d95b0d 100644 executable = True, allow_single_file = True, ), -diff --git a/templates/cc/register.go b/templates/cc/register.go -index e927985..050efda 100644 ---- a/templates/cc/register.go -+++ b/templates/cc/register.go -@@ -315,7 +315,7 @@ func (fns CCFuncs) inType(f pgs.Field, x interface{}) string { - return fns.cTypeOfString(fns.Type(f).Value().String()) - } - -- return fns.PackageName(fldEn).String() + "::" + fns.Type(f).Value().String() -+ return fns.packageName(fldEn) + "::" + fns.Type(f).Value().String() - default: - return fns.cType(f.Type()) - } -diff --git a/templates/cc/repeated.go b/templates/cc/repeated.go -index 53b2a35..e7124f6 100644 ---- a/templates/cc/repeated.go -+++ b/templates/cc/repeated.go -@@ -26,6 +26,9 @@ const repTpl = ` - {{ end }} - - {{ if $r.GetUnique }} -+ {{ if isRepeatedEnum $f }} -+ std::unordered_set {{ lookup $f "Unique" }}; -+ {{ else }} - // Implement comparison for wrapped reference types - struct cmp { - bool operator() (const std::reference_wrapper<{{ $typ }}> lhs, const std::reference_wrapper<{{ $typ }}> rhs) const { -@@ -44,6 +47,7 @@ const repTpl = ` - // Save a set of references to avoid copying overhead - std::unordered_set, hash, cmp> {{ lookup $f "Unique" }}; - {{ end }} -+ {{ end }} - - {{ if or $r.GetUnique (ne (.Elem "" "").Typ "none") }} - for (int i = 0; i < {{ accessor . }}.size(); i++) { -@@ -51,7 +55,11 @@ const repTpl = ` - (void)item; - - {{ if $r.GetUnique }} -+ {{ if isRepeatedEnum $f }} -+ auto p = {{ lookup $f "Unique" }}.emplace(item); -+ {{ else }} - auto p = {{ lookup $f "Unique" }}.emplace(const_cast<{{ $typ }}&>(item)); -+ {{ end }} - if (p.second == false) { - {{ errIdx . "i" "repeated value must contain unique items" }} - } -diff --git a/templates/goshared/register.go b/templates/goshared/register.go -index 19a2a00..6a8fac7 100644 ---- a/templates/goshared/register.go -+++ b/templates/goshared/register.go -@@ -415,3 +415,29 @@ func (fns goSharedFuncs) enumPackages(enums []pgs.Enum) map[pgs.Name]NormalizedE - func (fns goSharedFuncs) snakeCase(name string) string { - return strcase.ToSnake(name) - } -+ -+func (fns goSharedFuncs) Type(f pgs.Field) pgsgo.TypeName { -+ if f.Type().ProtoType() == pgs.EnumT { -+ ens := fns.enumPackages(fns.externalEnums(f.File())) -+ // Check if the imported name of the enum has collided and been renamed -+ if len(ens) != 0 { -+ enType := f.Type().Enum() -+ if f.Type().IsRepeated() { -+ enType = f.Type().Element().Enum() -+ } -+ -+ enImportPath := fns.ImportPath(enType) -+ for pkg, en := range ens { -+ if en.FilePath == enImportPath { -+ name := fns.enumName(enType) -+ if f.Type().IsRepeated() { -+ return pgsgo.TypeName("[]" + pkg.String() + "." + name) -+ } -+ return pgsgo.TypeName(pkg.String() + "." + name) -+ } -+ } -+ } -+ } -+ -+ return fns.Context.Type(f) -+} -diff --git a/templates/shared/enums.go b/templates/shared/enums.go -index bb5f053..79fcf39 100644 ---- a/templates/shared/enums.go -+++ b/templates/shared/enums.go -@@ -11,6 +11,10 @@ func isEnum(f pgs.Field) bool { - return f.Type().IsEnum() - } - -+func isRepeatedEnum(f pgs.Field) bool { -+ return f.Type().IsRepeated() && f.Type().Element().IsEnum() -+} -+ - func enumNamesMap(values []pgs.EnumValue) (m map[int32]string) { - m = make(map[int32]string) - for _, v := range values { -diff --git a/templates/shared/functions.go b/templates/shared/functions.go -index eb10045..8ed5cd6 100644 ---- a/templates/shared/functions.go -+++ b/templates/shared/functions.go -@@ -8,16 +8,17 @@ import ( - - func RegisterFunctions(tpl *template.Template, params pgs.Parameters) { - tpl.Funcs(map[string]interface{}{ -- "disabled": Disabled, -- "ignored": Ignored, -- "required": RequiredOneOf, -- "context": rulesContext, -- "render": Render(tpl), -- "has": Has, -- "needs": Needs, -- "fileneeds": FileNeeds, -- "isEnum": isEnum, -- "enumList": enumList, -- "enumVal": enumVal, -+ "disabled": Disabled, -+ "ignored": Ignored, -+ "required": RequiredOneOf, -+ "context": rulesContext, -+ "render": Render(tpl), -+ "has": Has, -+ "needs": Needs, -+ "fileneeds": FileNeeds, -+ "isEnum": isEnum, -+ "isRepeatedEnum": isRepeatedEnum, -+ "enumList": enumList, -+ "enumVal": enumVal, - }) - } - \ No newline at end of file diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.cc b/source/extensions/health_checkers/grpc/health_checker_impl.cc index 5646e98d242b0..401387bc3067c 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.cc +++ b/source/extensions/health_checkers/grpc/health_checker_impl.cc @@ -4,6 +4,7 @@ #include #include +#include "envoy/common/exception.h" #include "envoy/config/core/v3/health_check.pb.h" #include "envoy/data/core/v3/health_check_event.pb.h" #include "envoy/server/health_checker_config.h" @@ -41,15 +42,6 @@ const std::string& getHostname(const HostSharedPtr& host, return HealthCheckerFactory::getHostname(host, EMPTY_STRING, cluster); } -absl::flat_hash_set -buildRetriableStatuses(const envoy::config::core::v3::HealthCheck::GrpcHealthCheck& config) { - absl::flat_hash_set statuses; - statuses.reserve(config.retriable_serving_statuses_size()); - for (const auto status : config.retriable_serving_statuses()) { - statuses.insert(static_cast(status)); - } - return statuses; -} } // namespace Upstream::HealthCheckerSharedPtr GrpcHealthCheckerFactory::createCustomHealthChecker( @@ -75,7 +67,8 @@ GrpcHealthCheckerImpl::GrpcHealthCheckerImpl(const Cluster& cluster, request_headers_parser_(THROW_OR_RETURN_VALUE( Router::HeaderParser::configure(config.grpc_health_check().initial_metadata()), Router::HeaderParserPtr)), - retriable_statuses_(buildRetriableStatuses(config.grpc_health_check())) { + retriable_statuses_(buildAndValidateRetriableStatuses( + config.grpc_health_check().retriable_serving_statuses())) { if (!config.grpc_health_check().service_name().empty()) { service_name_ = config.grpc_health_check().service_name(); } @@ -85,6 +78,33 @@ GrpcHealthCheckerImpl::GrpcHealthCheckerImpl(const Cluster& cluster, } } +absl::flat_hash_set +GrpcHealthCheckerImpl::buildAndValidateRetriableStatuses( + const Protobuf::RepeatedField& retriable_serving_statuses) { + absl::flat_hash_set statuses; + statuses.reserve(retriable_serving_statuses.size()); + for (const auto status : retriable_serving_statuses) { + // Validation occurs inside envoy due to issues validating repeated enums with + // protoc-gen-validate, see https://github.com/bufbuild/protoc-gen-validate/pull/1360 + if (!grpc::health::v1::HealthCheckResponse::ServingStatus_IsValid(status)) { + throw EnvoyException( + absl::StrCat("unknown gRPC health check retriable serving status: ", status)); + } + const auto typed_status = + static_cast(status); + if (typed_status == grpc::health::v1::HealthCheckResponse::SERVING) { + throw EnvoyException("gRPC health check retriable serving statuses must not include SERVING"); + } + const auto [_, inserted] = statuses.insert(typed_status); + if (!inserted) { + throw EnvoyException( + absl::StrCat("duplicate gRPC health check retriable serving status: ", + grpc::health::v1::HealthCheckResponse::ServingStatus_Name(typed_status))); + } + } + return statuses; +} + GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::GrpcActiveHealthCheckSession( GrpcHealthCheckerImpl& parent, const HostSharedPtr& host) : ActiveHealthCheckSession(parent, host), parent_(parent), diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index dad9d9ddf84d5..80ae69d3e2f8c 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -53,6 +53,9 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { Random::RandomGenerator& random, HealthCheckEventLoggerPtr&& event_logger); private: + static absl::flat_hash_set + buildAndValidateRetriableStatuses(const Protobuf::RepeatedField& retriable_serving_statuses); + struct GrpcActiveHealthCheckSession : public ActiveHealthCheckSession, public Http::ResponseDecoderImplBase, public Http::StreamCallbacks { diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index 05a02a247c8b3..9335ce1067763 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -5267,6 +5267,33 @@ void PrintTo(const GrpcHealthCheckerImplTestBase::ResponseSpec& spec, std::ostre class GrpcHealthCheckerImplTest : public testing::Test, public GrpcHealthCheckerImplTestBase {}; +TEST_F(GrpcHealthCheckerImplTest, RetriableServingStatusUnknownRejected) { + auto config = createGrpcHealthCheckConfig(); + config.mutable_grpc_health_check()->add_retriable_serving_statuses( + static_cast(999)); + EXPECT_THROW_WITH_MESSAGE(allocHealthChecker(config), EnvoyException, + "unknown gRPC health check retriable serving status: 999"); +} + +TEST_F(GrpcHealthCheckerImplTest, RetriableServingStatusServingRejected) { + auto config = createGrpcHealthCheckConfig(); + config.mutable_grpc_health_check()->add_retriable_serving_statuses( + grpc::health::v1::HealthCheckResponse::SERVING); + EXPECT_THROW_WITH_MESSAGE( + allocHealthChecker(config), EnvoyException, + "gRPC health check retriable serving statuses must not include SERVING"); +} + +TEST_F(GrpcHealthCheckerImplTest, RetriableServingStatusDuplicateRejected) { + auto config = createGrpcHealthCheckConfig(); + config.mutable_grpc_health_check()->add_retriable_serving_statuses( + grpc::health::v1::HealthCheckResponse::NOT_SERVING); + config.mutable_grpc_health_check()->add_retriable_serving_statuses( + grpc::health::v1::HealthCheckResponse::NOT_SERVING); + EXPECT_THROW_WITH_MESSAGE(allocHealthChecker(config), EnvoyException, + "duplicate gRPC health check retriable serving status: NOT_SERVING"); +} + // Test single host check success. TEST_F(GrpcHealthCheckerImplTest, Success) { testSingleHostSuccess(absl::nullopt); } From ddf495a2c07d19c45b3213980c6b8786725a70e4 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 11:46:26 -0400 Subject: [PATCH 13/23] Fix whitespace Signed-off-by: James Fish --- source/extensions/health_checkers/grpc/health_checker_impl.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.cc b/source/extensions/health_checkers/grpc/health_checker_impl.cc index 401387bc3067c..64415bcd90d93 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.cc +++ b/source/extensions/health_checkers/grpc/health_checker_impl.cc @@ -41,7 +41,6 @@ const std::string& getHostname(const HostSharedPtr& host, } return HealthCheckerFactory::getHostname(host, EMPTY_STRING, cluster); } - } // namespace Upstream::HealthCheckerSharedPtr GrpcHealthCheckerFactory::createCustomHealthChecker( From 7217caa171b4f405b29e2c60065ec0752b22f524 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 13:51:32 -0400 Subject: [PATCH 14/23] Revert "Revert "Handle buf.yaml linting by remvoing grpc's /src/proto prefix"" This reverts commit 22695dd6ac736c3d96a5f6ac2641a0d3f5323e30. Signed-off-by: James Fish --- api/bazel/external_proto_deps.bzl | 2 +- api/buf.lock | 26 +++++++++++-------- api/buf.yaml | 1 + api/envoy/config/core/v3/health_check.proto | 2 +- bazel/grpc.patch | 28 ++++++++++++++++++--- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/api/bazel/external_proto_deps.bzl b/api/bazel/external_proto_deps.bzl index 82b828e73f069..5440b88a46556 100644 --- a/api/bazel/external_proto_deps.bzl +++ b/api/bazel/external_proto_deps.bzl @@ -13,7 +13,7 @@ EXTERNAL_PROTO_IMPORT_BAZEL_DEP_MAP = { "google/api/expr/v1alpha1/syntax.proto": "@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto", "io/prometheus/client/metrics.proto": "@prometheus_metrics_model//:client_model", "opentelemetry/proto/common/v1/common.proto": "@opentelemetry-proto//:common_proto", - "src/proto/grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", + "grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", } # This maps from the Bazel proto_library target to the Go language binding target for external dependencies. diff --git a/api/buf.lock b/api/buf.lock index d1b96940301fa..0284ede3eba33 100644 --- a/api/buf.lock +++ b/api/buf.lock @@ -2,20 +2,26 @@ version: v2 deps: - name: buf.build/cncf/xds - commit: c313df85559e44248d0115969f2c8c24 - digest: b5:89db966d59cc9686658a12f40ba0bb38017d0bccf3e651d025ff6747d18f1a647814e0bd6dd534218d08fe949be33371ef506a1ac8a32c4978b6f9a288231bde + commit: 2456e1dfc0664e7596d7f3b20f4b62d0 + digest: b5:412ce915a722e7e653426107531cfbfea5a263afd438b2778c03f1dc8f75628e5baf791e513324e5ccff0197be2f91aa174629b8353966d38c295bd86bc2cebb - name: buf.build/envoyproxy/protoc-gen-validate - commit: 6607b10f00ed4a3d98f906807131c44a - digest: b5:ade405ac4328bd0a2cf83c93bcb4bc389d4897afd86a0096df4537b180916882da4e4f0c2d45f0b1554d7a6c87f6c5bc94b71b3555ca71cc31a9a8baed26a9f9 + commit: daf171c6cdb54629b5f51e345a79e4dd + digest: b5:c745e1521879f43740230b1df673d0729f55704efefdcfc489d4a0a2d40c92a26cacfeab62813403040a8b180142d53b398c7ca784a065e43823605ee49681de - name: buf.build/gogo/protobuf - commit: 5461a3dfa9d941da82028ab185dc2a0e - digest: b5:8e9cf66be25ae4fac7fe0867742f41d008491cf1e0f49c488b42ce2fadb663970d4179472f8835dd58a61448464ba0ad9c2d19f464553f86ed137d9f59ec5dff + commit: e1dbca2775a74a89955a99990de45a53 + digest: b5:9be593f336e8b0d35761a2fb5ebc4460aaee3f2d21e9d75b7fddbecb1dd53ea58a0bb447c20c33387f4e07fa7e1e439f7125663a624517cfde97c8bec68e4ecf + - name: buf.build/google/cel-spec + commit: 96eff7bcf453468dbd44b80598bfe1bf + digest: b5:660c244ec1e8a0f26c5431e1901f1d52d322c7ee3fd240cb6832f44d0694384a36ded008af457a9e5268c73adfa00170e972ac4fe44752a693424b3479f30b82 - name: buf.build/googleapis/googleapis commit: 62f35d8aed1149c291d606d958a7ce32 digest: b5:d66bf04adc77a0870bdc9328aaf887c7188a36fb02b83a480dc45ef9dc031b4d39fc6e9dc6435120ccf4fe5bfd5c6cb6592533c6c316595571f9a31420ab47fe + - name: buf.build/grpc/grpc + commit: e126be52bace42e49491e4015e464b59 + digest: b5:a01d4326f3e6590547c7cbb3bff8d6dab5cf564eeadd7c7c0d32ea739931a1d492322e6aa21312c9f419538044beea6740f9a6c51bb44647c627044936c55f36 - name: buf.build/opentelemetry/opentelemetry - commit: 43554dfbbfbd4873bde8993d32ea8332 - digest: b5:027a738207c1e66e1b628e49923dade94b8832049537f0a05375b086122ccc5db4351f86e4297ac0fe441b4351c901ada85e03e7f34a09a401e46e00f8c8062b + commit: 648a3e2f02e14fe187656ea4ac3befa1 + digest: b5:a0514be587ab2e8598f7102dfdaba5e985138b8c041c707e470a9c8b877410ada6e60cf2359352302f08c0504de685379f7f7a085d4699d69a2e6ed7035e78d9 - name: buf.build/prometheus/client-model - commit: 1d56a02d481a412a83b3c4984eb90c2e - digest: b5:030705921923d3a04902cb71f946d39db4ca6bb03d1da7fcb381b1f907b693572519f73fa9f9a0994d61cedb8935989675aca0c222e05e7c8790c808b2a14e47 + commit: e171c0b235c546d5a9a597c2961bd357 + digest: b5:c26899a8592079d1f0cc168dee57c70df022d07c450ad0560fac8a1c6b5b9f73cbc6c44a21a67afbeb32e1e2127cf02c4e7f34368c8685a33b56bd936ea4273e diff --git a/api/buf.yaml b/api/buf.yaml index 61787f2ef6751..263fc8e77b006 100644 --- a/api/buf.yaml +++ b/api/buf.yaml @@ -4,6 +4,7 @@ deps: - buf.build/envoyproxy/protoc-gen-validate - buf.build/gogo/protobuf - buf.build/googleapis/googleapis:62f35d8aed1149c291d606d958a7ce32 +- buf.build/grpc/grpc - buf.build/opentelemetry/opentelemetry - buf.build/prometheus/client-model breaking: diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index 047bbc083186b..dc1909fbd5b7c 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -15,7 +15,7 @@ import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; -import "src/proto/grpc/health/v1/health.proto"; +import "grpc/health/v1/health.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 0f0be258d5949..f9bb704879def 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..f4a2ed3f13 100644 +index a3b8923b6e..5c11639f38 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -40,6 +40,20 @@ index a3b8923b6e..f4a2ed3f13 100644 "//conditions:default": [name + "_native"], }), outs = [name + "_binary"], +@@ -217,11 +211,13 @@ def grpc_internal_proto_library( + srcs = [], + deps = [], + visibility = None, ++ strip_import_prefix = None, + has_services = False): # buildifier: disable=unused-variable + proto_library( + name = name, + srcs = srcs, + deps = deps, ++ strip_import_prefix = strip_import_prefix, + visibility = visibility, + ) + diff --git a/include/grpc/event_engine/memory_request.h b/include/grpc/event_engine/memory_request.h index 76bcbb2036..ad8cab842e 100644 --- a/include/grpc/event_engine/memory_request.h @@ -249,10 +263,18 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..374653516a 100644 +index f6165e0392..120505f128 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD -@@ -44,3 +44,10 @@ filegroup( +@@ -24,6 +24,7 @@ grpc_package( + grpc_internal_proto_library( + name = "health_proto", + srcs = ["health.proto"], ++ strip_import_prefix = "/src/proto/", + has_services = True, + ) + +@@ -44,3 +45,10 @@ filegroup( "health.proto", ], ) From eaca650df26bdecca59b5297b1561ba79c709256 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 13:51:59 -0400 Subject: [PATCH 15/23] Revert "Revert "Fix src/proto imports in grpc"" This reverts commit 5ce7cbbb4ff4f426c3378ec529af01830ec18879. Signed-off-by: James Fish --- bazel/grpc.patch | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index f9bb704879def..5d1f09b92f6f1 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -249,6 +249,19 @@ index 3fb5d68146..583a2f9553 100644 return PromiseFactoryImpl(RepeatableToken{}, f_); } }; +diff --git a/src/core/load_balancing/health_check_client.cc b/src/core/load_balancing/health_check_client.cc +index c84f6d0a48..9f8bee2c53 100644 +--- a/src/core/load_balancing/health_check_client.cc ++++ b/src/core/load_balancing/health_check_client.cc +@@ -57,7 +57,7 @@ + #include "src/core/util/ref_counted_ptr.h" + #include "src/core/util/sync.h" + #include "src/core/util/work_serializer.h" +-#include "src/proto/grpc/health/v1/health.upb.h" ++#include "grpc/health/v1/health.upb.h" + #include "upb/base/string_view.h" + #include "upb/mem/arena.hpp" + diff --git a/src/core/util/glob.cc b/src/core/util/glob.cc index 1b1c16e23d..22e54259f0 100644 --- a/src/core/util/glob.cc @@ -263,14 +276,14 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..120505f128 100644 +index f6165e0392..90e86a5c50 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -24,6 +24,7 @@ grpc_package( grpc_internal_proto_library( name = "health_proto", srcs = ["health.proto"], -+ strip_import_prefix = "/src/proto/", ++ strip_import_prefix = "/src/proto", has_services = True, ) From ae83feb8d5e23e8514647d13ab9e021c7140b9ff Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 13:52:14 -0400 Subject: [PATCH 16/23] Revert "Revert "Fix grpc patch indent"" This reverts commit 6624d4193ae6a0fb4426d10a3e573f517f1fb112. Signed-off-by: James Fish --- bazel/grpc.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 5d1f09b92f6f1..bc54ee9523480 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..5c11639f38 100644 +index a3b8923b6e..87c59a932a 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -44,7 +44,7 @@ index a3b8923b6e..5c11639f38 100644 srcs = [], deps = [], visibility = None, -+ strip_import_prefix = None, ++ strip_import_prefix = None, has_services = False): # buildifier: disable=unused-variable proto_library( name = name, From dc79d1523fa395bc0f6270eae5f25756446bc68b Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 13:52:59 -0400 Subject: [PATCH 17/23] Revert "Revert "Fix imports for health.upb.h"" This reverts commit 1c4e7ca2adec9f059376dee2ed652bee203dd19e. Signed-off-by: James Fish --- bazel/grpc.patch | 13 +++++++++++++ source/common/upstream/health_checker_impl.h | 2 +- .../health_checkers/grpc/health_checker_impl.h | 2 +- .../health_checkers/http/health_checker_impl.h | 2 +- .../health_checkers/tcp/health_checker_impl.h | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index bc54ee9523480..7b62b43884cd3 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -275,6 +275,19 @@ index 1b1c16e23d..22e54259f0 100644 #include "absl/strings/string_view.h" namespace grpc_core { +diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc +index 492ba694c1..1cd2ee17fd 100644 +--- a/src/cpp/server/health/default_health_check_service.cc ++++ b/src/cpp/server/health/default_health_check_service.cc +@@ -30,7 +30,7 @@ + + #include "absl/log/log.h" + #include "src/core/util/grpc_check.h" +-#include "src/proto/grpc/health/v1/health.upb.h" ++#include "grpc/health/v1/health.upb.h" + #include "upb/base/string_view.h" + #include "upb/mem/arena.hpp" + diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index f6165e0392..90e86a5c50 100644 --- a/src/proto/grpc/health/v1/BUILD diff --git a/source/common/upstream/health_checker_impl.h b/source/common/upstream/health_checker_impl.h index 259e9df96198f..8aa4dac5f5b6e 100644 --- a/source/common/upstream/health_checker_impl.h +++ b/source/common/upstream/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/stream_info/stream_info_impl.h" #include "source/common/upstream/health_checker_event_logger.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index 80ae69d3e2f8c..dd70ef1e4587f 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -24,7 +24,7 @@ #include "source/extensions/health_checkers/common/health_checker_base_impl.h" #include "absl/container/flat_hash_set.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/http/health_checker_impl.h b/source/extensions/health_checkers/http/health_checker_impl.h index 68fd6214f9166..30fdf43bae714 100644 --- a/source/extensions/health_checkers/http/health_checker_impl.h +++ b/source/extensions/health_checkers/http/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/tcp/health_checker_impl.h b/source/extensions/health_checkers/tcp/health_checker_impl.h index ec3b14ef37c81..0353c5267f843 100644 --- a/source/extensions/health_checkers/tcp/health_checker_impl.h +++ b/source/extensions/health_checkers/tcp/health_checker_impl.h @@ -22,7 +22,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "src/proto/grpc/health/v1/health.pb.h" +#include "grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { From 45098c5a31928d4eab7d84e75deae060520762d7 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 25 Mar 2026 13:54:50 -0400 Subject: [PATCH 18/23] Revert "Ignore health_check.proto" This reverts commit 69f4ca8239f7934fd6ea783d04b148ee49d21d7d. Signed-off-by: James Fish --- api/buf.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/api/buf.yaml b/api/buf.yaml index 263fc8e77b006..811eaa0eb6426 100644 --- a/api/buf.yaml +++ b/api/buf.yaml @@ -28,11 +28,3 @@ lint: - envoy/api/v2/listener.proto - envoy/config/bootstrap/v2/bootstrap.proto disallow_comment_ignores: true -modules: -- path: . - excludes: - # temporarily ignore proto linting errors as grpc health check import not handled by buf - # it requires grpc import to follow https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto - # but envoy uses https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto - # which has src/proto prefix - - envoy/config/core/v3/health_check.proto From 616acc7a8abe1e5dac532f0503d2b34934c6d59e Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 13 May 2026 11:16:53 -0700 Subject: [PATCH 19/23] Revert "Revert "Revert "Fix imports for health.upb.h""" This reverts commit dc79d1523fa395bc0f6270eae5f25756446bc68b. Signed-off-by: James Fish --- bazel/grpc.patch | 13 ------------- source/common/upstream/health_checker_impl.h | 2 +- .../health_checkers/grpc/health_checker_impl.h | 2 +- .../health_checkers/http/health_checker_impl.h | 2 +- .../health_checkers/tcp/health_checker_impl.h | 2 +- 5 files changed, 4 insertions(+), 17 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 7b62b43884cd3..bc54ee9523480 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -275,19 +275,6 @@ index 1b1c16e23d..22e54259f0 100644 #include "absl/strings/string_view.h" namespace grpc_core { -diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc -index 492ba694c1..1cd2ee17fd 100644 ---- a/src/cpp/server/health/default_health_check_service.cc -+++ b/src/cpp/server/health/default_health_check_service.cc -@@ -30,7 +30,7 @@ - - #include "absl/log/log.h" - #include "src/core/util/grpc_check.h" --#include "src/proto/grpc/health/v1/health.upb.h" -+#include "grpc/health/v1/health.upb.h" - #include "upb/base/string_view.h" - #include "upb/mem/arena.hpp" - diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index f6165e0392..90e86a5c50 100644 --- a/src/proto/grpc/health/v1/BUILD diff --git a/source/common/upstream/health_checker_impl.h b/source/common/upstream/health_checker_impl.h index 8aa4dac5f5b6e..259e9df96198f 100644 --- a/source/common/upstream/health_checker_impl.h +++ b/source/common/upstream/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/stream_info/stream_info_impl.h" #include "source/common/upstream/health_checker_event_logger.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/grpc/health_checker_impl.h b/source/extensions/health_checkers/grpc/health_checker_impl.h index dd70ef1e4587f..80ae69d3e2f8c 100644 --- a/source/extensions/health_checkers/grpc/health_checker_impl.h +++ b/source/extensions/health_checkers/grpc/health_checker_impl.h @@ -24,7 +24,7 @@ #include "source/extensions/health_checkers/common/health_checker_base_impl.h" #include "absl/container/flat_hash_set.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/http/health_checker_impl.h b/source/extensions/health_checkers/http/health_checker_impl.h index 30fdf43bae714..68fd6214f9166 100644 --- a/source/extensions/health_checkers/http/health_checker_impl.h +++ b/source/extensions/health_checkers/http/health_checker_impl.h @@ -23,7 +23,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { diff --git a/source/extensions/health_checkers/tcp/health_checker_impl.h b/source/extensions/health_checkers/tcp/health_checker_impl.h index 0353c5267f843..ec3b14ef37c81 100644 --- a/source/extensions/health_checkers/tcp/health_checker_impl.h +++ b/source/extensions/health_checkers/tcp/health_checker_impl.h @@ -22,7 +22,7 @@ #include "source/common/upstream/health_checker_impl.h" #include "source/extensions/health_checkers/common/health_checker_base_impl.h" -#include "grpc/health/v1/health.pb.h" +#include "src/proto/grpc/health/v1/health.pb.h" namespace Envoy { namespace Upstream { From 8ee8bf3ed31b02a169e8b20934c24d4a5678d156 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 13 May 2026 11:17:18 -0700 Subject: [PATCH 20/23] Revert "Revert "Revert "Fix grpc patch indent""" This reverts commit ae83feb8d5e23e8514647d13ab9e021c7140b9ff. Signed-off-by: James Fish --- bazel/grpc.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index bc54ee9523480..5d1f09b92f6f1 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..87c59a932a 100644 +index a3b8923b6e..5c11639f38 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -44,7 +44,7 @@ index a3b8923b6e..87c59a932a 100644 srcs = [], deps = [], visibility = None, -+ strip_import_prefix = None, ++ strip_import_prefix = None, has_services = False): # buildifier: disable=unused-variable proto_library( name = name, From b3f7f4fbaeeb7ded3e45063753ee817550a376da Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 13 May 2026 11:17:28 -0700 Subject: [PATCH 21/23] Revert "Revert "Revert "Fix src/proto imports in grpc""" This reverts commit eaca650df26bdecca59b5297b1561ba79c709256. Signed-off-by: James Fish --- bazel/grpc.patch | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/bazel/grpc.patch b/bazel/grpc.patch index 5d1f09b92f6f1..f9bb704879def 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -249,19 +249,6 @@ index 3fb5d68146..583a2f9553 100644 return PromiseFactoryImpl(RepeatableToken{}, f_); } }; -diff --git a/src/core/load_balancing/health_check_client.cc b/src/core/load_balancing/health_check_client.cc -index c84f6d0a48..9f8bee2c53 100644 ---- a/src/core/load_balancing/health_check_client.cc -+++ b/src/core/load_balancing/health_check_client.cc -@@ -57,7 +57,7 @@ - #include "src/core/util/ref_counted_ptr.h" - #include "src/core/util/sync.h" - #include "src/core/util/work_serializer.h" --#include "src/proto/grpc/health/v1/health.upb.h" -+#include "grpc/health/v1/health.upb.h" - #include "upb/base/string_view.h" - #include "upb/mem/arena.hpp" - diff --git a/src/core/util/glob.cc b/src/core/util/glob.cc index 1b1c16e23d..22e54259f0 100644 --- a/src/core/util/glob.cc @@ -276,14 +263,14 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..90e86a5c50 100644 +index f6165e0392..120505f128 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -24,6 +24,7 @@ grpc_package( grpc_internal_proto_library( name = "health_proto", srcs = ["health.proto"], -+ strip_import_prefix = "/src/proto", ++ strip_import_prefix = "/src/proto/", has_services = True, ) From dda7e3005dcbc9084fcf7a186fa7857891935c16 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 13 May 2026 11:18:02 -0700 Subject: [PATCH 22/23] Revert "Revert "Revert "Handle buf.yaml linting by remvoing grpc's /src/proto prefix""" This reverts commit 7217caa171b4f405b29e2c60065ec0752b22f524. Signed-off-by: James Fish --- api/bazel/external_proto_deps.bzl | 2 +- api/buf.lock | 26 ++++++++----------- api/buf.yaml | 1 - api/envoy/config/core/v3/health_check.proto | 2 +- bazel/grpc.patch | 28 +++------------------ 5 files changed, 15 insertions(+), 44 deletions(-) diff --git a/api/bazel/external_proto_deps.bzl b/api/bazel/external_proto_deps.bzl index 5440b88a46556..82b828e73f069 100644 --- a/api/bazel/external_proto_deps.bzl +++ b/api/bazel/external_proto_deps.bzl @@ -13,7 +13,7 @@ EXTERNAL_PROTO_IMPORT_BAZEL_DEP_MAP = { "google/api/expr/v1alpha1/syntax.proto": "@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto", "io/prometheus/client/metrics.proto": "@prometheus_metrics_model//:client_model", "opentelemetry/proto/common/v1/common.proto": "@opentelemetry-proto//:common_proto", - "grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", + "src/proto/grpc/health/v1/health.proto": "@com_github_grpc_grpc//src/proto/grpc/health/v1:health_proto", } # This maps from the Bazel proto_library target to the Go language binding target for external dependencies. diff --git a/api/buf.lock b/api/buf.lock index 0284ede3eba33..d1b96940301fa 100644 --- a/api/buf.lock +++ b/api/buf.lock @@ -2,26 +2,20 @@ version: v2 deps: - name: buf.build/cncf/xds - commit: 2456e1dfc0664e7596d7f3b20f4b62d0 - digest: b5:412ce915a722e7e653426107531cfbfea5a263afd438b2778c03f1dc8f75628e5baf791e513324e5ccff0197be2f91aa174629b8353966d38c295bd86bc2cebb + commit: c313df85559e44248d0115969f2c8c24 + digest: b5:89db966d59cc9686658a12f40ba0bb38017d0bccf3e651d025ff6747d18f1a647814e0bd6dd534218d08fe949be33371ef506a1ac8a32c4978b6f9a288231bde - name: buf.build/envoyproxy/protoc-gen-validate - commit: daf171c6cdb54629b5f51e345a79e4dd - digest: b5:c745e1521879f43740230b1df673d0729f55704efefdcfc489d4a0a2d40c92a26cacfeab62813403040a8b180142d53b398c7ca784a065e43823605ee49681de + commit: 6607b10f00ed4a3d98f906807131c44a + digest: b5:ade405ac4328bd0a2cf83c93bcb4bc389d4897afd86a0096df4537b180916882da4e4f0c2d45f0b1554d7a6c87f6c5bc94b71b3555ca71cc31a9a8baed26a9f9 - name: buf.build/gogo/protobuf - commit: e1dbca2775a74a89955a99990de45a53 - digest: b5:9be593f336e8b0d35761a2fb5ebc4460aaee3f2d21e9d75b7fddbecb1dd53ea58a0bb447c20c33387f4e07fa7e1e439f7125663a624517cfde97c8bec68e4ecf - - name: buf.build/google/cel-spec - commit: 96eff7bcf453468dbd44b80598bfe1bf - digest: b5:660c244ec1e8a0f26c5431e1901f1d52d322c7ee3fd240cb6832f44d0694384a36ded008af457a9e5268c73adfa00170e972ac4fe44752a693424b3479f30b82 + commit: 5461a3dfa9d941da82028ab185dc2a0e + digest: b5:8e9cf66be25ae4fac7fe0867742f41d008491cf1e0f49c488b42ce2fadb663970d4179472f8835dd58a61448464ba0ad9c2d19f464553f86ed137d9f59ec5dff - name: buf.build/googleapis/googleapis commit: 62f35d8aed1149c291d606d958a7ce32 digest: b5:d66bf04adc77a0870bdc9328aaf887c7188a36fb02b83a480dc45ef9dc031b4d39fc6e9dc6435120ccf4fe5bfd5c6cb6592533c6c316595571f9a31420ab47fe - - name: buf.build/grpc/grpc - commit: e126be52bace42e49491e4015e464b59 - digest: b5:a01d4326f3e6590547c7cbb3bff8d6dab5cf564eeadd7c7c0d32ea739931a1d492322e6aa21312c9f419538044beea6740f9a6c51bb44647c627044936c55f36 - name: buf.build/opentelemetry/opentelemetry - commit: 648a3e2f02e14fe187656ea4ac3befa1 - digest: b5:a0514be587ab2e8598f7102dfdaba5e985138b8c041c707e470a9c8b877410ada6e60cf2359352302f08c0504de685379f7f7a085d4699d69a2e6ed7035e78d9 + commit: 43554dfbbfbd4873bde8993d32ea8332 + digest: b5:027a738207c1e66e1b628e49923dade94b8832049537f0a05375b086122ccc5db4351f86e4297ac0fe441b4351c901ada85e03e7f34a09a401e46e00f8c8062b - name: buf.build/prometheus/client-model - commit: e171c0b235c546d5a9a597c2961bd357 - digest: b5:c26899a8592079d1f0cc168dee57c70df022d07c450ad0560fac8a1c6b5b9f73cbc6c44a21a67afbeb32e1e2127cf02c4e7f34368c8685a33b56bd936ea4273e + commit: 1d56a02d481a412a83b3c4984eb90c2e + digest: b5:030705921923d3a04902cb71f946d39db4ca6bb03d1da7fcb381b1f907b693572519f73fa9f9a0994d61cedb8935989675aca0c222e05e7c8790c808b2a14e47 diff --git a/api/buf.yaml b/api/buf.yaml index 811eaa0eb6426..fbd2876b1a484 100644 --- a/api/buf.yaml +++ b/api/buf.yaml @@ -4,7 +4,6 @@ deps: - buf.build/envoyproxy/protoc-gen-validate - buf.build/gogo/protobuf - buf.build/googleapis/googleapis:62f35d8aed1149c291d606d958a7ce32 -- buf.build/grpc/grpc - buf.build/opentelemetry/opentelemetry - buf.build/prometheus/client-model breaking: diff --git a/api/envoy/config/core/v3/health_check.proto b/api/envoy/config/core/v3/health_check.proto index dc1909fbd5b7c..047bbc083186b 100644 --- a/api/envoy/config/core/v3/health_check.proto +++ b/api/envoy/config/core/v3/health_check.proto @@ -15,7 +15,7 @@ import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; -import "grpc/health/v1/health.proto"; +import "src/proto/grpc/health/v1/health.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; diff --git a/bazel/grpc.patch b/bazel/grpc.patch index f9bb704879def..0f0be258d5949 100644 --- a/bazel/grpc.patch +++ b/bazel/grpc.patch @@ -12,7 +12,7 @@ index 9e067aa29e..089a447ec4 100644 ) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl -index a3b8923b6e..5c11639f38 100644 +index a3b8923b6e..f4a2ed3f13 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -27,7 +27,6 @@ @@ -40,20 +40,6 @@ index a3b8923b6e..5c11639f38 100644 "//conditions:default": [name + "_native"], }), outs = [name + "_binary"], -@@ -217,11 +211,13 @@ def grpc_internal_proto_library( - srcs = [], - deps = [], - visibility = None, -+ strip_import_prefix = None, - has_services = False): # buildifier: disable=unused-variable - proto_library( - name = name, - srcs = srcs, - deps = deps, -+ strip_import_prefix = strip_import_prefix, - visibility = visibility, - ) - diff --git a/include/grpc/event_engine/memory_request.h b/include/grpc/event_engine/memory_request.h index 76bcbb2036..ad8cab842e 100644 --- a/include/grpc/event_engine/memory_request.h @@ -263,18 +249,10 @@ index 1b1c16e23d..22e54259f0 100644 namespace grpc_core { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD -index f6165e0392..120505f128 100644 +index f6165e0392..374653516a 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD -@@ -24,6 +24,7 @@ grpc_package( - grpc_internal_proto_library( - name = "health_proto", - srcs = ["health.proto"], -+ strip_import_prefix = "/src/proto/", - has_services = True, - ) - -@@ -44,3 +45,10 @@ filegroup( +@@ -44,3 +44,10 @@ filegroup( "health.proto", ], ) From 3f23d72b80dbf38203c8df57047a359a85cd5b77 Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 13 May 2026 11:18:59 -0700 Subject: [PATCH 23/23] Vendor health.proto Signed-off-by: James Fish --- api/.bazelignore | 2 + api/src/proto/grpc/health/v1/README.md | 16 ++++++ api/src/proto/grpc/health/v1/health.proto | 63 +++++++++++++++++++++++ tools/proto_format/BUILD | 3 ++ 4 files changed, 84 insertions(+) create mode 100644 api/.bazelignore create mode 100644 api/src/proto/grpc/health/v1/README.md create mode 100644 api/src/proto/grpc/health/v1/health.proto diff --git a/api/.bazelignore b/api/.bazelignore new file mode 100644 index 0000000000000..749630b5a8235 --- /dev/null +++ b/api/.bazelignore @@ -0,0 +1,2 @@ +# See explanation in src/proto/grpc/health/v1/README.md +src/proto/grpc/health/v1/health.proto diff --git a/api/src/proto/grpc/health/v1/README.md b/api/src/proto/grpc/health/v1/README.md new file mode 100644 index 0000000000000..affa859fc5271 --- /dev/null +++ b/api/src/proto/grpc/health/v1/README.md @@ -0,0 +1,16 @@ +Vendored health.proto for buf linting +------------------------------------- + +The `health.proto` file is copied and vendored here from +https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto. +This provides the matching `health.proto` to buf linting but strictly not to +the bazel build, which uses protobuf files from @grpc. + +The buf linter, https://buf.build/docs/, uses +https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto. However +this has a different import path, `grpc/health/v1/health.proto` compared to +`src/proto/grpc/health/v1/health.proto`. Therefore by vendoring the `health.proto` +we can avoid patching gRPC BUILD definitions and maintain correct protobuf linting. + +Note this file should only be required in the envoy repository for buf linting and +not for any builds. diff --git a/api/src/proto/grpc/health/v1/health.proto b/api/src/proto/grpc/health/v1/health.proto new file mode 100644 index 0000000000000..38843ff1e73ac --- /dev/null +++ b/api/src/proto/grpc/health/v1/health.proto @@ -0,0 +1,63 @@ +// Copyright 2015 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto + +syntax = "proto3"; + +package grpc.health.v1; + +option csharp_namespace = "Grpc.Health.V1"; +option go_package = "google.golang.org/grpc/health/grpc_health_v1"; +option java_multiple_files = true; +option java_outer_classname = "HealthProto"; +option java_package = "io.grpc.health.v1"; + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. + } + ServingStatus status = 1; +} + +service Health { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); +} diff --git a/tools/proto_format/BUILD b/tools/proto_format/BUILD index 565705ec595cc..ad2c17a639a94 100644 --- a/tools/proto_format/BUILD +++ b/tools/proto_format/BUILD @@ -23,6 +23,9 @@ API_FILES_IGNORED = [ "test/**", "tools/**", "envoy/service/auth/**/*", + # Vendored only for buf linting; not part of the normalized Bazel API tree. + # See api/src/proto/grpc/health/v1/README.md. + "src/proto/grpc/health/v1/health.proto", ] # Bazel query doesnt support json output, and jq insists on inputs with json suffix,