envoyproxy / envoyproxy/examples
Add a tested, docs-first native filter build example (`filter-cc`) using bzlmod
- Linguagem predominante
- Shell
- Estrelas
- 74
- Forks
- 38
- Merge médio
- 2d 17h
- PRs com merge (30d)
- 16
Descrição
## Context
envoyproxy/envoy#47155 (docs/bazel: Switch to bzlmod) moves the Envoy docs build to bzlmod. Once it lands, the final phase of the bzlmod migration is unblocked.
It has been agreed that a **hard blocker** for completing the migration is that we provide an example, somewhere, showing how a downstream developer builds an Envoy extension using bzlmod.
- Historically this was covered by `envoy-filter-example`, which has long since stopped being maintained.
- This repo already has one build example — `wasm-cc` — which was recently brought back to working order and is the natural model for a new example.
Whichever path is taken, the end state is the same: a **full, tested example in this repo**. Examples are docs-first, so a working example here covers the documentation requirement as well.
A **dynamic modules (`dynmod`) example** will also be added at some point; the structure/testing approach chosen here should be reusable for that.
## Principles
- **Docs-first.** The example *is* the documentation. `example.rst` + `README.md` + the config/`MODULE.bazel` are what people read and copy.
- **Must be tested.** Every example has a `verify.sh` and is exercised in CI.
- **Tests test the docs — not the other way round.** The tested artefacts must be exactly what is documented (the `MODULE.bazel`, `BUILD`, `envoy.yaml`, etc. that users see). We should not maintain a separate "real" build that the docs merely describe.
## Proposal: `filter-cc`
A native HTTP filter built and statically linked into Envoy with bzlmod, modelled on `wasm-cc`.
```
filter-cc/
├── .bazelrc
├── .bazelversion
├── MODULE.bazel # the thing people actually copy
├── BUILD
├── http_filter.proto # filter config proto
├── http_filter.h / .cc # StreamDecoderFilter that adds a header
├── http_filter_config.cc # NamedHttpFilterConfigFactory + REGISTER_FACTORY
├── http_filter_integration_test.cc
├── envoy.yaml # uses the filter
├── docker-compose.yaml # proxy (from built binary) + echo backend
├── docker-compose-build.yaml # builds the binary via shared/build, as wasm-cc does
├── Dockerfile-proxy
├── verify.sh
├── example.rst
└── README.md
```
Plus `.bcr/filter-cc/{presubmit.yml,source.template.json}` so it is published to the registry alongside `wasm-cc`.
### `MODULE.bazel` (sketch)
```starlark
module(
name = "envoy-example-filter-cc",
version = "0.2.5.envoy",
)
bazel_dep(name = "envoy", version = "1.40.0-dev")
bazel_dep(name = "envoy_api", version = "1.40.0-dev")
bazel_dep(name = "rules_cc", version = "0.2.22")
bazel_dep(name = "protobuf", version = "35.1.bcr.envoy")
bazel_dep(name = "protoc-gen-validate", version = "1.3.0.envoy")
bazel_dep(name = "rules_pkg", version = "1.1.0")
envoy_toolchains_ext = use_extension("@envoy//bazel:extensions.bzl", "envoy_toolchains_extension")
use_repo(envoy_toolchains_ext, "clang_platform")
# Compiler toolchain as dev_dependency — identical setup to wasm-cc/MODULE.bazel
bazel_dep(name = "toolchains_llvm", version = "1.8.0.envoy", dev_dependency = True)
bazel_dep(name = "envoy_toolshed", version = "0.4.10.envoy", dev_dependency = True)
```
The exact `use_extension` wiring (e.g. extension registry / `envoy_build_config`) needs validating against `@envoy//bazel:extensions.bzl` on head once #47155 is merged.
### `BUILD` (sketch)
```starlark
load("@envoy//bazel:envoy_build_system.bzl", "envoy_cc_binary", "envoy_cc_extension", "envoy_cc_test")
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
api_proto_package()
envoy_cc_extension(
name = "http_filter_lib",
srcs = ["http_filter.cc"],
hdrs = ["http_filter.h"],
deps = [
":pkg_cc_proto",
"@envoy//envoy/http:filter_interface",
"@envoy//source/common/http:header_map_lib",
],
)
envoy_cc_extension(
name = "http_filter_config",
srcs = ["http_filter_config.cc"],
deps = [
":http_filter_lib",
"@envoy//envoy/registry",
"@envoy//envoy/server:filter_config_interface",
],
)
envoy_cc_binary(
name = "envoy",
repository = "@envoy",
deps = [
":http_filter_config",
"@envoy//source/exe:envoy_main_entry_lib",
],
)
envoy_cc_test(
name = "http_filter_integration_test",
srcs = ["http_filter_integration_test.cc"],
repository = "@envoy",
deps = [
":http_filter_config",
"@envoy//test/integration:http_integration_lib",
],
)
```
### Filter content
Simplest credible thing: a decoder filter that reads `key`/`val` from its proto config and adds it as a response header — the same as the old `http-filter-example`, which readers may recognise.
## Testing
- **Standalone (`verify.sh`)**: `docker compose -f docker-compose-build.yaml run build` builds `//:envoy` via `shared/build` (same pattern as `wasm_compile_update`), the binary is copied into `Dockerfile-proxy`, `docker compose up`, and the test asserts the filter's header appears on responses. `envoy_cc_test` provides a real integration test for `bazel test //...` and BCR presubmit.
- **Against envoy dev head**: add `bazel_dep(name = "envoy-example-filter-cc", ...)` to `envoy-examples` and to envoy's `docs/MODULE.bazel`, so the `local_path_override` on `envoy` builds/tests it against the current checkout — the same mechanism as `wasm-cc`.
- **Docs**: `example.rst` goes into the sandboxes toctree via the existing `docs_rst` / `examples_docs` genrule; `envoy.yaml` into `:configs` for the config test.
## Related: test the build examples against envoy dev head
The `wasm-cc` example is currently **not** tested in the envoy repo. This is probably bzlmod+ work, but the build examples (`wasm-cc`, `filter-cc`, and later `dynmod`) should be tested against dev head in envoy, as is already done for the rest of the examples. The head-testing mechanism above should be set up so it covers all build examples, not just the new one.
## Open decisions
1. **Full binary vs. library-only in envoy CI.** Building `//:envoy` (a full static link) in `verify_examples` is heavy. Suggested split: BCR presubmit + `verify.sh` build the full binary (that *is* what is being demonstrated); the envoy-side head test only runs `http_filter_integration_test`, which proves the wiring at a fraction of the cost.
2. **Filter content.** Port the old `http-filter-example` header filter vs. inventing something new (suggest porting).
## Blocked by
- envoyproxy/envoy#47155 — the `MODULE.bazel` extension wiring can only be finalised once this is merged.
## Follow-ups
- `dynmod` example (dynamic modules) using the same docs-first/tested structure.
- Test all build examples (`wasm-cc`, `filter-cc`, `dynmod`) against envoy dev head.
Guia de contribuição
Nenhum guia de contribuição indexado para este repositório
Avaliação
Esta issue ainda não foi avaliada.