Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasm: Add WAMR support #16057

Merged
merged 25 commits into from
May 31, 2021
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
013f626
Add WAMR for Envoy WASM runtime
leyao-daily Mar 19, 2021
ad1b66b
Build WAMR from source code
leyao-daily Apr 7, 2021
4791b2f
Fix the factory name typo
leyao-daily Apr 9, 2021
2870ce8
Fix external rules based on envoy version
leyao-daily Apr 9, 2021
4d55dac
Update the WAMR configuration and release version
leyao-daily Apr 12, 2021
0f64660
Fix the pre-check and update version
Apr 19, 2021
92af1c5
Add wamr tests executed in CI
Apr 20, 2021
b064ed4
Update the WAMR repo to official and fix format
Apr 20, 2021
7e609b4
Update the Repo dependency to latest WAMR
Apr 30, 2021
1b6bc39
use envoy_cmake_external to replace cmake_external
lum1n0us Apr 20, 2021
635adb0
Add dependency for wamr to llvm
Apr 30, 2021
dd15bc8
Update the dependency and rebase
May 6, 2021
2b79298
Lower wasm_runtime coverage for wamr
May 7, 2021
904e258
Fix the sort alphabetically and comments
May 7, 2021
4af6ab8
Fix comments format
May 7, 2021
af5cc19
Integrate the document changes
May 7, 2021
13b52d6
Merge branch 'main' into main
leyao-daily May 20, 2021
7f0f522
Enable WMAR JIT mode
lum1n0us May 12, 2021
6300297
Merge pull request #61 from lum1n0us/enable_wamr_jit
leyao-daily May 20, 2021
1eaf38f
Enable JIT and fix date errors
May 20, 2021
053ae9d
Merge 'envoy/main' into main and fix conflicts
May 28, 2021
b7e910e
Add wamr runtime metadata
May 28, 2021
5df2800
Merge branch 'main' into main
May 28, 2021
49e1784
Conflict fixed based on main
May 28, 2021
86420be
Add the unknown security posture comments
May 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api/envoy/extensions/wasm/v3/wasm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ message VmConfig {
//
// **envoy.wasm.runtime.v8**: `V8 <https://v8.dev/>`_-based WebAssembly runtime.
//
// .. _extension_envoy.wasm.runtime.wamr:
//
// **envoy.wasm.runtime.wamr**: `WAMR <https://github.com/bytecodealliance/wasm-micro-runtime/>`_-based WebAssembly runtime.
// This runtime is not enabled in the official build.
//
// .. _extension_envoy.wasm.runtime.wavm:
//
// **envoy.wasm.runtime.wavm**: `WAVM <https://wavm.github.io/>`_-based WebAssembly runtime.
Expand Down
5 changes: 5 additions & 0 deletions bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ config_setting(
values = {"define": "wasm=v8"},
)

config_setting(
name = "wasm_wamr",
values = {"define": "wasm=wamr"},
)

config_setting(
name = "wasm_wasmtime",
values = {"define": "wasm=wasmtime"},
Expand Down
4 changes: 3 additions & 1 deletion bazel/envoy_build_system.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ load(
_envoy_select_wasm_cpp_tests = "envoy_select_wasm_cpp_tests",
_envoy_select_wasm_rust_tests = "envoy_select_wasm_rust_tests",
_envoy_select_wasm_v8 = "envoy_select_wasm_v8",
_envoy_select_wasm_wamr = "envoy_select_wasm_wamr",
_envoy_select_wasm_wasmtime = "envoy_select_wasm_wasmtime",
_envoy_select_wasm_wavm = "envoy_select_wasm_wavm",
)
Expand Down Expand Up @@ -208,9 +209,10 @@ envoy_select_enable_http3 = _envoy_select_enable_http3
envoy_select_hot_restart = _envoy_select_hot_restart
envoy_select_wasm_cpp_tests = _envoy_select_wasm_cpp_tests
envoy_select_wasm_rust_tests = _envoy_select_wasm_rust_tests
envoy_select_wasm_v8 = _envoy_select_wasm_v8
envoy_select_wasm_wamr = _envoy_select_wasm_wamr
envoy_select_wasm_wavm = _envoy_select_wasm_wavm
envoy_select_wasm_wasmtime = _envoy_select_wasm_wasmtime
envoy_select_wasm_v8 = _envoy_select_wasm_v8

# Binary wrappers (from envoy_binary.bzl)
envoy_cc_binary = _envoy_cc_binary
Expand Down
8 changes: 8 additions & 0 deletions bazel/envoy_select.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,20 @@ def envoy_select_wasm_rust_tests(xs):
# Selects the given values depending on the Wasm runtimes enabled in the current build.
def envoy_select_wasm_v8(xs):
return select({
"@envoy//bazel:wasm_wamr": [],
"@envoy//bazel:wasm_wasmtime": [],
"@envoy//bazel:wasm_wavm": [],
"@envoy//bazel:wasm_none": [],
"//conditions:default": xs,
})

# Selects the given values depending on the Wasm runtimes enabled in the current build.
def envoy_select_wasm_wamr(xs):
return select({
"@envoy//bazel:wasm_wamr": xs,
"//conditions:default": [],
})

# Selects the given values depending on the Wasm runtimes enabled in the current build.
def envoy_select_wasm_wavm(xs):
return select({
Expand Down
12 changes: 12 additions & 0 deletions bazel/external/proxy_wasm_cpp_host.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ cc_library(
],
)

cc_library(
name = "wamr_lib",
srcs = glob([
"src/wamr/*.h",
"src/wamr/*.cc",
]),
deps = [
":common_lib",
"@envoy//bazel/foreign_cc:wamr",
],
)

cc_library(
name = "wavm_lib",
srcs = glob([
Expand Down
84 changes: 48 additions & 36 deletions bazel/foreign_cc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -230,70 +230,63 @@ envoy_cmake_external(
lib_source = "@org_llvm_llvm//:all",
static_libraries = select({
"//conditions:default": [
# Order from llvm-config --libnames.
# Order from llvm-config --libnames asmparser core debuginfodwarf
# engine lto mcparser mirparser orcjit passes runtimedyld
# support x86asmparser x86desc
"libLLVMOrcJIT.a",
"libLLVMOrcError.a",
"libLLVMJITLink.a",
"libLLVMMIRParser.a",
"libLLVMLTO.a",
"libLLVMPasses.a",
"libLLVMObjCARCOpts.a",
"libLLVMSymbolize.a",
"libLLVMDebugInfoPDB.a",
"libLLVMDebugInfoDWARF.a",
"libLLVMFuzzMutate.a",
"libLLVMTableGen.a",
"libLLVMDlltoolDriver.a",
"libLLVMLineEditor.a",
"libLLVMOrcJIT.a",
"libLLVMCoverage.a",
"libLLVMMIRParser.a",
"libLLVMObjectYAML.a",
"libLLVMLibDriver.a",
"libLLVMOption.a",
"libLLVMWindowsManifest.a",
"libLLVMipo.a",
"libLLVMInstrumentation.a",
"libLLVMVectorize.a",
"libLLVMLinker.a",
"libLLVMIRReader.a",
"libLLVMX86Disassembler.a",
"libLLVMX86AsmParser.a",
"libLLVMX86CodeGen.a",
"libLLVMCFGuard.a",
"libLLVMGlobalISel.a",
"libLLVMSelectionDAG.a",
"libLLVMAsmPrinter.a",
"libLLVMDebugInfoCodeView.a",
"libLLVMDebugInfoMSF.a",
"libLLVMCodeGen.a",
"libLLVMScalarOpts.a",
"libLLVMInstCombine.a",
"libLLVMAggressiveInstCombine.a",
"libLLVMTransformUtils.a",
"libLLVMBitWriter.a",
"libLLVMX86Desc.a",
"libLLVMMCDisassembler.a",
"libLLVMX86Info.a",
"libLLVMX86Utils.a",
"libLLVMX86Info.a",
"libLLVMMCJIT.a",
"libLLVMInterpreter.a",
"libLLVMExecutionEngine.a",
"libLLVMRuntimeDyld.a",
"libLLVMCodeGen.a",
"libLLVMTarget.a",
"libLLVMCoroutines.a",
"libLLVMipo.a",
"libLLVMInstrumentation.a",
"libLLVMVectorize.a",
"libLLVMScalarOpts.a",
"libLLVMLinker.a",
"libLLVMIRReader.a",
"libLLVMAsmParser.a",
"libLLVMInstCombine.a",
"libLLVMTransformUtils.a",
"libLLVMBitWriter.a",
"libLLVMAnalysis.a",
"libLLVMProfileData.a",
"libLLVMRuntimeDyld.a",
"libLLVMDebugInfoDWARF.a",
"libLLVMObject.a",
"libLLVMTextAPI.a",
"libLLVMMCParser.a",
"libLLVMMC.a",
"libLLVMDebugInfoCodeView.a",
"libLLVMDebugInfoMSF.a",
"libLLVMBitReader.a",
"libLLVMBitstreamReader.a",
"libLLVMAsmParser.a",
"libLLVMCore.a",
"libLLVMRemarks.a",
"libLLVMBitstreamReader.a",
"libLLVMBinaryFormat.a",
"libLLVMSupport.a",
"libLLVMDemangle.a",
"libLLVMRemarks.a",
"libLLVMCFGuard.a",
"libLLVMTextAPI.a",
PiotrSikora marked this conversation as resolved.
Show resolved Hide resolved
],
}),
tags = ["skip_on_windows"],
alwayslink = True,
)

envoy_cmake_external(
Expand All @@ -315,6 +308,25 @@ envoy_cmake_external(
}),
)

envoy_cmake_external(
name = "wamr",
cache_entries = {
"LLVM_DIR": "$EXT_BUILD_DEPS/copy_llvm/llvm/lib/cmake/llvm",
"WAMR_BUILD_INTERP": "1",
"WAMR_BUILD_JIT": "0",
"WAMR_BUILD_AOT": "0",
"WAMR_BUILD_SIMD": "0",
"WAMR_BUILD_MULTI_MODULE": "1",
"WAMR_BUILD_LIBC_WASI": "0",
"WAMR_BUILD_TAIL_CALL": "1",
},
defines = ["ENVOY_WASM_WAMR"],
lib_source = "@com_github_wamr//:all",
static_libraries = ["libvmlib.a"],
tags = ["skip_on_windows"],
deps = [":llvm"],
)

envoy_cmake_external(
name = "wavm",
binaries = ["wavm"],
Expand Down
11 changes: 11 additions & 0 deletions bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def envoy_dependencies(skip_targets = []):
_kafka_deps()

_org_llvm_llvm()
_com_github_wamr()
_com_github_wavm_wavm()
_com_github_wasmtime()
_com_github_wasm_c_api()
Expand Down Expand Up @@ -927,6 +928,16 @@ def _org_llvm_llvm():
actual = "@envoy//bazel/foreign_cc:llvm",
)

def _com_github_wamr():
external_http_archive(
name = "com_github_wamr",
build_file_content = BUILD_ALL_CONTENT,
)
native.bind(
name = "wamr",
actual = "@envoy//bazel/foreign_cc:wamr",
)

def _com_github_wavm_wavm():
external_http_archive(
name = "com_github_wavm_wavm",
Expand Down
26 changes: 22 additions & 4 deletions bazel/repository_locations.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,25 @@ REPOSITORY_LOCATIONS_SPEC = dict(
urls = ["https://github.com/llvm/llvm-project/releases/download/llvmorg-{version}/llvm-{version}.src.tar.xz"],
release_date = "2020-03-23",
use_category = ["dataplane_ext"],
extensions = ["envoy.wasm.runtime.wavm"],
extensions = [
"envoy.wasm.runtime.wamr",
"envoy.wasm.runtime.wavm",
],
cpe = "cpe:2.3:a:llvm:*:*",
),
com_github_wamr = dict(
project_name = "Webassembly Micro Runtime",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PiotrSikora what's our end game here? Will we eventually bring every Wasm runtime into the Envoy OSS build? Do we need this or can we be opinionated?

My main worry here is the increase in build time in CI, security risk envelope, etc.

CC @envoyproxy/dependency-shepherds

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are good questions.

From Proxy-Wasm C++ Host's perspective, supporting any decent Wasm runtime is desireable, since they all have a bit different features, and most implement variants of Wasm C/C++ API, so both implementation and maintanance have relatively small cost.

From Envoy's perspective, it's definitely not neccessary, and we could be opinionated, but since those are optional alternatives, I don't think there are too many downsides, especially since the common logic is abstracted away.

Regarding build time - Wasm runtimes are updated once a month or once a quarter, and the alternative ones are built only in bazel.compile_time_options target, so their artifacts should be pretty much always cached, and the overhead shouldn't be much of an issue.

Regarding security risk - we could officially support only the default Wasm runtime (currently: V8), and be upfront that there won't be any security releases for other runtimes.

Regarding WAMR specifically, it has interpreted mode, and claims very small binary size overhead and low memory usage, so it might be more desirable in Envoy Mobile than V8, for example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, can we add to this PR a change to threat model https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/threat_model#core-and-extensions stating this explicitly?

I think this is a pretty important thing to get clear as we add more runtimes; we won't support anything other than V8 for now from a security perspective.

project_desc = "A standalone runtime with a small footprint for WebAssembly",
project_url = "https://github.com/bytecodealliance/wasm-micro-runtime",
version = "a14a4487bb8b493bf6c68d83b03f12028d16f58a",
sha256 = "d68668e129f16a9ddd7a1a0da22b17905a25001ae2de398726d37880b61fee9e",
strip_prefix = "wasm-micro-runtime-{version}",
urls = ["https://github.com/bytecodealliance/wasm-micro-runtime/archive/{version}.tar.gz"],
release_date = "2021-05-14",
use_category = ["dataplane_ext"],
extensions = ["envoy.wasm.runtime.wamr"],
cpe = "N/A",
),
com_github_wavm_wavm = dict(
project_name = "WAVM",
project_desc = "WebAssembly Virtual Machine",
Expand Down Expand Up @@ -938,6 +954,7 @@ REPOSITORY_LOCATIONS_SPEC = dict(
"envoy.stat_sinks.wasm",
"envoy.wasm.runtime.null",
"envoy.wasm.runtime.v8",
"envoy.wasm.runtime.wamr",
"envoy.wasm.runtime.wavm",
"envoy.wasm.runtime.wasmtime",
],
Expand All @@ -948,8 +965,8 @@ REPOSITORY_LOCATIONS_SPEC = dict(
project_name = "WebAssembly for Proxies (C++ host implementation)",
project_desc = "WebAssembly for Proxies (C++ host implementation)",
project_url = "https://github.com/proxy-wasm/proxy-wasm-cpp-host",
version = "31c75e0039f2f5c42dc6e12556cb151a38da6d8b",
sha256 = "779e7a8e0fd8ed8b3133b464a8e5a9974bdedb345792d3a6148cb5a87e26976b",
version = "e641ffa8893477cdb4720f572f50f003cd51a083",
sha256 = "20abaa0ff37b3765111fb81774bf4fa4630e23dc9c468b42016c4ebf4f27a38a",
strip_prefix = "proxy-wasm-cpp-host-{version}",
urls = ["https://github.com/proxy-wasm/proxy-wasm-cpp-host/archive/{version}.tar.gz"],
use_category = ["dataplane_ext"],
Expand All @@ -961,10 +978,11 @@ REPOSITORY_LOCATIONS_SPEC = dict(
"envoy.stat_sinks.wasm",
"envoy.wasm.runtime.null",
"envoy.wasm.runtime.v8",
"envoy.wasm.runtime.wamr",
"envoy.wasm.runtime.wavm",
"envoy.wasm.runtime.wasmtime",
],
release_date = "2021-05-06",
release_date = "2021-05-07",
cpe = "N/A",
),
proxy_wasm_rust_sdk = dict(
Expand Down
3 changes: 3 additions & 0 deletions ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,9 @@ elif [[ "$CI_TARGET" == "bazel.compile_time_options" ]]; then
TEST_TARGETS=("${TEST_TARGETS[@]/#\/\//@envoy\/\/}")

# Building all the dependencies from scratch to link them against libc++.
echo "Building and testing with wasm=wamr: ${TEST_TARGETS[*]}"
bazel_with_collection test "${BAZEL_BUILD_OPTIONS[@]}" --define wasm=wamr "${COMPILE_TIME_OPTIONS[@]}" -c dbg "${TEST_TARGETS[@]}" --test_tag_filters=-nofips --build_tests_only

echo "Building and testing with wasm=wasmtime: ${TEST_TARGETS[*]}"
bazel_with_collection test "${BAZEL_BUILD_OPTIONS[@]}" --define wasm=wasmtime "${COMPILE_TIME_OPTIONS[@]}" -c dbg "${TEST_TARGETS[@]}" --test_tag_filters=-nofips --build_tests_only

Expand Down
3 changes: 2 additions & 1 deletion docs/root/configuration/other_features/wasm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ The following runtimes are supported by Envoy:
:widths: 1, 2

envoy.wasm.runtime.v8, "`V8 <https://v8.dev>`_-based runtime"
envoy.wasm.runtime.wamr, "`WAMR <https://github.com/bytecodealliance/wasm-micro-runtime>`_ runtime"
envoy.wasm.runtime.wasmtime, "`Wasmtime <https://github.com/bytecodealliance/wasmtime>`_ runtime"
envoy.wasm.runtime.wavm, "`WAVM <https://github.com/WAVM/WAVM>`_ runtime"
envoy.wasm.runtime.null, "Compiled modules linked into Envoy"

Wasmtime and WAVM runtimes are not included in Envoy release image by default.
WAMR(WASM-Micro-Runtime), Wasmtime and WAVM runtimes are not included in Envoy release image by default.

Wasm runtime emits the following statistics:

Expand Down
5 changes: 5 additions & 0 deletions generated_api_shadow/envoy/extensions/wasm/v3/wasm.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ EXTENSIONS = {

"envoy.wasm.runtime.null": "//source/extensions/wasm_runtime/null:config",
"envoy.wasm.runtime.v8": "//source/extensions/wasm_runtime/v8:config",
"envoy.wasm.runtime.wamr": "//source/extensions/wasm_runtime/wamr:config",
"envoy.wasm.runtime.wavm": "//source/extensions/wasm_runtime/wavm:config",
"envoy.wasm.runtime.wasmtime": "//source/extensions/wasm_runtime/wasmtime:config",

Expand Down
5 changes: 5 additions & 0 deletions source/extensions/extensions_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,11 @@ envoy.wasm.runtime.v8:
- envoy.wasm.runtime
security_posture: unknown
status: alpha
envoy.wasm.runtime.wamr:
categories:
- envoy.wasm.runtime
security_posture: unknown
status: alpha
leyao-daily marked this conversation as resolved.
Show resolved Hide resolved
envoy.wasm.runtime.wasmtime:
categories:
- envoy.wasm.runtime
Expand Down
21 changes: 21 additions & 0 deletions source/extensions/wasm_runtime/wamr/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_extension_package",
)
load("//bazel:envoy_select.bzl", "envoy_select_wasm_wamr")

licenses(["notice"]) # Apache 2

envoy_extension_package()

envoy_cc_extension(
name = "config",
srcs = ["config.cc"],
deps = [
"//include/envoy/registry",
"//source/extensions/common/wasm:wasm_runtime_factory_interface",
] + envoy_select_wasm_wamr([
"@proxy_wasm_cpp_host//:wamr_lib",
]),
)
26 changes: 26 additions & 0 deletions source/extensions/wasm_runtime/wamr/config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "envoy/registry/registry.h"

#include "extensions/common/wasm/wasm_runtime_factory.h"

#include "include/proxy-wasm/wamr.h"

namespace Envoy {
namespace Extensions {
namespace Common {
namespace Wasm {

class WamrRuntimeFactory : public WasmRuntimeFactory {
public:
WasmVmPtr createWasmVm() override { return proxy_wasm::createWamrVm(); }

absl::string_view name() override { return "envoy.wasm.runtime.wamr"; }
};

#if defined(ENVOY_WASM_WAMR)
REGISTER_FACTORY(WamrRuntimeFactory, WasmRuntimeFactory);
#endif

} // namespace Wasm
} // namespace Common
} // namespace Extensions
} // namespace Envoy
Loading