Skip to content

Commit

Permalink
extension: use bool_flag to control extension link (#14240)
Browse files Browse the repository at this point in the history
Pulling bazel stuff out of #14094. Use the new kill request extension as example.

Signed-off-by: Lizan Zhou <lizan@tetrate.io>
  • Loading branch information
lizan authored Dec 8, 2020
1 parent 8188e23 commit 5cd2d42
Show file tree
Hide file tree
Showing 18 changed files with 119 additions and 121 deletions.
23 changes: 18 additions & 5 deletions bazel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -658,17 +658,30 @@ The following optional features can be enabled on the Bazel build command-line:
* Envoy can be linked to [`zlib-ng`](https://github.com/zlib-ng/zlib-ng) instead of
[`zlib`](https://zlib.net) with `--define zlib=ng`.

## Disabling extensions
## Enabling and disabling extensions

Envoy uses a modular build which allows extensions to be removed if they are not needed or desired.
Extensions that can be removed are contained in
[extensions_build_config.bzl](../source/extensions/extensions_build_config.bzl). Use the following
procedure to customize the extensions for your build:
[extensions_build_config.bzl](../source/extensions/extensions_build_config.bzl).

The extensions disabled by default can be enabled by adding the following parameter to Bazel, for example to enable
`envoy.filters.http.kill_request` extension, add `--//source/extensions/filters/http/kill_request:enabled`.
The extensions enabled by default can be disabled by adding the following parameter to Bazel, for example to disable
`envoy.wasm.runtime.v8` extension, add `--//source/extensions/wasm_runtime/v8:enabled=false`.
Note not all extensions can be disabled.

If you're building from a custom build repository, the parameters need to prefixed with `@envoy`, for example
`--@envoy//source/extensions/filters/http/kill_request:enabled`.

You may persist those options in `user.bazelrc` in Envoy repo or your `.bazelrc`.

## Customize extension build config

You can also use the following procedure to customize the extensions for your build:

* The Envoy build assumes that a Bazel repository named `@envoy_build_config` exists which
contains the file `@envoy_build_config//:extensions_build_config.bzl`. In the default build,
a synthetic repository is created containing [extensions_build_config.bzl](../source/extensions/extensions_build_config.bzl).
Thus, the default build has all extensions.
* Start by creating a new Bazel workspace somewhere in the filesystem that your build can access.
This workspace should contain:
* Empty WORKSPACE file.
Expand All @@ -683,7 +696,7 @@ To have your local build use your overridden configuration repository there are
2. Use the following snippet in your WORKSPACE before you load the Envoy repository. E.g.,

```
workspace(name = "envoy")
workspace(name = "envoy_filter_example")
local_repository(
name = "envoy_build_config",
Expand Down
13 changes: 12 additions & 1 deletion bazel/envoy_build_system.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,24 @@ load(
"@envoy_build_config//:extensions_build_config.bzl",
"EXTENSION_PACKAGE_VISIBILITY",
)
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")

def envoy_package():
native.package(default_visibility = ["//visibility:public"])

def envoy_extension_package():
def envoy_extension_package(enabled_default = True):
native.package(default_visibility = EXTENSION_PACKAGE_VISIBILITY)

bool_flag(
name = "enabled",
build_setting_default = enabled_default,
)

native.config_setting(
name = "is_enabled",
flag_values = {":enabled": "True"},
)

# A genrule variant that can output a directory. This is useful when doing things like
# generating a fuzz corpus mechanically.
def _envoy_directory_genrule_impl(ctx):
Expand Down
17 changes: 16 additions & 1 deletion bazel/envoy_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,22 @@ def envoy_cc_extension(
fail("Unknown extension status: " + status)
if "//visibility:public" not in visibility:
visibility = visibility + extra_visibility
envoy_cc_library(name, tags = tags, visibility = visibility, **kwargs)

ext_name = name + "_envoy_extension"
envoy_cc_library(
name = name,
tags = tags,
visibility = visibility,
**kwargs
)
cc_library(
name = ext_name,
deps = select({
":is_enabled": [":" + name],
"//conditions:default": [],
}),
visibility = visibility,
)

# Envoy C++ library targets should be specified with this function.
def envoy_cc_library(
Expand Down
2 changes: 2 additions & 0 deletions bazel/envoy_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,14 @@ def envoy_cc_test(
tags = [],
args = [],
copts = [],
condition = None,
shard_count = None,
coverage = True,
local = False,
size = "medium",
flaky = False):
coverage_tags = tags + ([] if coverage else ["nocoverage"])

cc_test(
name = name,
srcs = srcs,
Expand Down
4 changes: 3 additions & 1 deletion ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ elif [[ "$CI_TARGET" == "bazel.compile_time_options" ]]; then
"--define" "deprecated_features=disabled"
"--define" "use_new_codecs_in_integration_tests=false"
"--define" "tcmalloc=gperftools"
"--define" "zlib=ng")
"--define" "zlib=ng"
"--@envoy//source/extensions/filters/http/kill_request:enabled"
"--test_env=ENVOY_HAS_EXTRA_EXTENSIONS=true")

ENVOY_STDLIB="${ENVOY_STDLIB:-libstdc++}"
setup_clang_toolchain
Expand Down
4 changes: 1 addition & 3 deletions docs/generate_extension_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,9 @@ def GetExtensionMetadata(target):
if __name__ == '__main__':
output_path = sys.argv[1]
extension_db = {}
# Include all extensions from both EXTENSIONS and
# DISABLED_BY_DEFAULT_EXTENSIONS in source/extensions/extensions_build_config.bzl
# Include all extensions from source/extensions/extensions_build_config.bzl
all_extensions = {}
all_extensions.update(extensions_build_config.EXTENSIONS)
all_extensions.update(extensions_build_config.DISABLED_BY_DEFAULT_EXTENSIONS)
for extension, target in all_extensions.items():
extension_db[extension] = GetExtensionMetadata(target)
# The TLS and generic upstream extensions are hard-coded into the build, so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Kill Request
===============

The KillRequest filter can be used to crash Envoy when receiving a Kill request.
By default, KillRequest filter is not built into Envoy binary since it is included in *DISABLED_BY_DEFAULT_EXTENSIONS* in *extensions_build_config.bzl*. If you want to use this extension, please move it from *DISABLED_BY_DEFAULT_EXTENSIONS* to *EXTENSIONS*.
By default, KillRequest filter is not built into Envoy binary. If you want to use this extension,
build Envoy with `--//source/extensions/filters/http/kill_request:enabled`.

Configuration
-------------
Expand Down
16 changes: 8 additions & 8 deletions source/extensions/all_extensions.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
load("@bazel_skylib//lib:dicts.bzl", "dicts")
load("@envoy_build_config//:extensions_build_config.bzl", "DISABLED_BY_DEFAULT_EXTENSIONS", "EXTENSIONS")

GLOBAL_DENYLIST = DISABLED_BY_DEFAULT_EXTENSIONS.keys()
load("@envoy_build_config//:extensions_build_config.bzl", "EXTENSIONS")

# These extensions are registered using the extension system but are required for the core Envoy build.
# The map may be overridden by extensions specified in envoy_build_config.
Expand All @@ -10,14 +8,16 @@ _required_extensions = {
"envoy.transport_sockets.tls": "//source/extensions/transport_sockets/tls:config",
}

# Return the extension cc_library target after select
def _selected_extension_target(target):
return target + "_envoy_extension"

# Return all extensions to be compiled into Envoy.
def envoy_all_extensions(denylist = []):
all_extensions = dicts.add(_required_extensions, EXTENSIONS)

denylist = denylist + GLOBAL_DENYLIST

# These extensions can be removed on a site specific basis.
return [v for k, v in all_extensions.items() if not k in denylist]
return [_selected_extension_target(v) for k, v in all_extensions.items() if not k in denylist]

# Core extensions needed to run Envoy's integration tests.
_core_extensions = [
Expand All @@ -41,7 +41,7 @@ _http_filter_prefix = "envoy.filters.http"
def envoy_all_http_filters():
all_extensions = dicts.add(_required_extensions, EXTENSIONS)

return [v for k, v in all_extensions.items() if k.startswith(_http_filter_prefix) and k not in GLOBAL_DENYLIST]
return [_selected_extension_target(v) for k, v in all_extensions.items() if k.startswith(_http_filter_prefix)]

# All network-layer filters are extensions with names that have the following prefix.
_network_filter_prefix = "envoy.filters.network"
Expand All @@ -53,4 +53,4 @@ _thrift_filter_prefix = "envoy.filters.thrift"
def envoy_all_network_filters():
all_extensions = dicts.add(_required_extensions, EXTENSIONS)

return [v for k, v in all_extensions.items() if (k.startswith(_network_filter_prefix) or k.startswith(_thrift_filter_prefix)) and k not in GLOBAL_DENYLIST]
return [_selected_extension_target(v) for k, v in all_extensions.items() if (k.startswith(_network_filter_prefix) or k.startswith(_thrift_filter_prefix))]
9 changes: 3 additions & 6 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ EXTENSIONS = {
"envoy.filters.http.health_check": "//source/extensions/filters/http/health_check:config",
"envoy.filters.http.ip_tagging": "//source/extensions/filters/http/ip_tagging:config",
"envoy.filters.http.jwt_authn": "//source/extensions/filters/http/jwt_authn:config",
# Disabled by default
"envoy.filters.http.kill_request": "//source/extensions/filters/http/kill_request:kill_request_config",
"envoy.filters.http.local_ratelimit": "//source/extensions/filters/http/local_ratelimit:config",
"envoy.filters.http.lua": "//source/extensions/filters/http/lua:config",
"envoy.filters.http.oauth2": "//source/extensions/filters/http/oauth2:config",
"envoy.filters.http.oauth2": "//source/extensions/filters/http/oauth2:config",
"envoy.filters.http.on_demand": "//source/extensions/filters/http/on_demand:config",
"envoy.filters.http.original_src": "//source/extensions/filters/http/original_src:config",
"envoy.filters.http.ratelimit": "//source/extensions/filters/http/ratelimit:config",
Expand Down Expand Up @@ -228,11 +230,6 @@ EXTENSIONS = {
"envoy.wasm.runtime.wasmtime": "//source/extensions/wasm_runtime/wasmtime:config",
}

# These filters will not be built into Envoy by default. To build Envoy with any of these filter, please move it to EXTENSIONS.
DISABLED_BY_DEFAULT_EXTENSIONS = {
"envoy.filters.http.kill_request": "//source/extensions/filters/http/kill_request:kill_request_config",
}

# These can be changed to ["//visibility:public"], for downstream builds which
# need to directly reference Envoy extensions.
EXTENSION_CONFIG_VISIBILITY = ["//:extension_config"]
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/filters/http/kill_request/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ load(

licenses(["notice"]) # Apache 2

envoy_extension_package()
envoy_extension_package(enabled_default = False)

envoy_cc_library(
name = "kill_request_filter_lib",
Expand Down
11 changes: 10 additions & 1 deletion test/exe/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ envoy_cc_test(
srcs = ["main_common_test.cc"],
data = [
"//test/config/integration:google_com_proxy_port_0",
"//test/exe/testdata:test_with_kill_request_filter",
],
deps = [
"//source/common/api:api_lib",
Expand All @@ -75,6 +74,16 @@ envoy_cc_test(
],
)

envoy_cc_test(
name = "extra_extensions_test",
srcs = ["extra_extensions_test.cc"],
deps = [
# This dependency MUST be main_common_lib to meet the purpose of this test
"//source/exe:main_common_lib",
"//test/test_common:environment_lib",
],
)

envoy_cc_test(
name = "terminate_handler_test",
srcs = ["terminate_handler_test.cc"],
Expand Down
28 changes: 28 additions & 0 deletions test/exe/extra_extensions_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <string>
#include <vector>

#include "envoy/common/exception.h"
#include "envoy/registry/registry.h"
#include "envoy/server/filter_config.h"

#include "test/test_common/environment.h"
#include "test/test_common/utility.h"

#include "gtest/gtest.h"

namespace Envoy {
namespace {

// Verify KillRequest filter is not built into Envoy by default but in compile_time_options
TEST(ExtraExtensionsTest, KillRequestFilterIsNotBuiltByDefault) {
auto* factory = Registry::FactoryRegistry<Server::Configuration::NamedHttpFilterConfigFactory>::
getFactoryByType("envoy.extensions.filters.http.kill_request.v3.KillRequest");
if (TestEnvironment::getOptionalEnvVar("ENVOY_HAS_EXTRA_EXTENSIONS").value_or("") == "true") {
EXPECT_NE(nullptr, factory);
} else {
EXPECT_EQ(nullptr, factory);
}
}

} // namespace
} // namespace Envoy
11 changes: 0 additions & 11 deletions test/exe/main_common_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,4 @@ TEST_P(MainCommonTest, ConstructDestructLogger) {
Logger::Registry::getSink()->log(log_msg);
}

// Verify KillRequest filter is not built into Envoy by default.
TEST_P(MainCommonTest, KillRequestFilterIsNotBuiltByDefault) {
config_file_ = TestEnvironment::temporaryFileSubstitute(
"test/exe/testdata/test_with_kill_request_filter.yaml", TestEnvironment::ParamMap(),
TestEnvironment::PortMap(), GetParam());
argv_ = {"envoy-static", "--use-dynamic-base-id", "-c", config_file_.c_str(), nullptr};

EXPECT_THROW_WITH_REGEX(MainCommon main_common(argc(), argv()), EnvoyException,
"unknown type: envoy.extensions.filters.http.kill_request");
}

} // namespace Envoy
15 changes: 0 additions & 15 deletions test/exe/testdata/BUILD

This file was deleted.

34 changes: 0 additions & 34 deletions test/exe/testdata/test_with_kill_request_filter.yaml

This file was deleted.

Loading

0 comments on commit 5cd2d42

Please sign in to comment.