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

docs/examples: Fix and add docs for Wasm C++ sandbox #13622

Merged
merged 29 commits into from
Oct 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion ci/run_clang_tidy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,13 @@ function exclude_wasm_test_data() {
grep -v wasm/test_data
}

# Exclude files which are part of the Wasm examples
function exclude_wasm_examples() {
grep -v examples/wasm
}

function filter_excludes() {
exclude_check_format_testdata | exclude_headersplit_testdata | exclude_chromium_url | exclude_win32_impl | exclude_macos_impl | exclude_third_party | exclude_wasm_emscripten | exclude_wasm_sdk | exclude_wasm_host | exclude_wasm_test_data
exclude_check_format_testdata | exclude_headersplit_testdata | exclude_chromium_url | exclude_win32_impl | exclude_macos_impl | exclude_third_party | exclude_wasm_emscripten | exclude_wasm_sdk | exclude_wasm_host | exclude_wasm_test_data | exclude_wasm_examples
}

function run_clang_tidy() {
Expand Down
3 changes: 1 addition & 2 deletions ci/verify_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
TESTFILTER="${1:-*}"
FAILED=()
SRCDIR="${SRCDIR:-$(pwd)}"
EXCLUDE_EXAMPLES=${EXCLUDED_EXAMPLES:-"wasm"}


trap_errors () {
Expand All @@ -30,7 +29,7 @@ trap exit 1 INT
run_examples () {
local examples example
cd "${SRCDIR}/examples" || exit 1
examples=$(find . -mindepth 1 -maxdepth 1 -type d -name "$TESTFILTER" | grep -vE "${EXCLUDE_EXAMPLES}" | sort)
examples=$(find . -mindepth 1 -maxdepth 1 -type d -name "$TESTFILTER" | sort)
for example in $examples; do
pushd "$example" > /dev/null || return 1
./verify.sh
Expand Down
4 changes: 2 additions & 2 deletions configs/configgen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ for FILE in "$@"; do
*.pem|*.der)
cp "$FILE" "$OUT_DIR/certs"
;;
*.lua)
*.lua|*.wasm)
cp "$FILE" "$OUT_DIR/lib"
;;
*.pb)
Expand All @@ -33,4 +33,4 @@ for FILE in "$@"; do
done

# tar is having issues with -C for some reason so just cd into OUT_DIR.
(cd "$OUT_DIR"; tar -hcvf example_configs.tar -- *.yaml certs/*.pem certs/*.der protos/*.pb lib/*.lua)
(cd "$OUT_DIR"; tar -hcvf example_configs.tar -- *.yaml certs/*.pem certs/*.der protos/*.pb lib/*.wasm lib/*.lua)
8 changes: 8 additions & 0 deletions docs/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ generate_api_rst v3
find "${GENERATED_RST_DIR}"/api-v3 -name "*.rst" -print0 | xargs -0 sed -i -e "s#envoy_api_#envoy_v3_api_#g"
find "${GENERATED_RST_DIR}"/api-v3 -name "*.rst" -print0 | xargs -0 sed -i -e "s#config_resource_monitors#v3_config_resource_monitors#g"

copy_example_configs () {
mkdir -p "${GENERATED_RST_DIR}/start/sandboxes/_include/wasm-cc"
cp -a "${SRC_DIR}"/examples/wasm-cc/*.cc "${GENERATED_RST_DIR}/start/sandboxes/_include/wasm-cc"
cp -a "${SRC_DIR}"/examples/wasm-cc/Dockerfile-proxy "${GENERATED_RST_DIR}/start/sandboxes/_include/wasm-cc"
}

copy_example_configs

# xDS protocol spec.
mkdir -p ${GENERATED_RST_DIR}/api-docs
cp -f "${API_DIR}"/xds_protocol.rst "${GENERATED_RST_DIR}/api-docs/xds_protocol.rst"
Expand Down
141 changes: 141 additions & 0 deletions docs/root/start/sandboxes/wasm-cc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
.. _install_sandboxes_wasm_filter:

WASM C++ filter
===============

This sandbox demonstrates a basic C++ Wasm filter which injects content into the body of an ``HTTP`` response, and adds
and updates some headers.

It also takes you through the steps required to build your own C++ Wasm filter, and run it with Envoy.

Running the Sandbox
~~~~~~~~~~~~~~~~~~~

.. include:: _include/docker-env-setup.rst

Step 3: Start all of our containers
***********************************

.. note::

The provided Wasm binary was compiled for the ``x86_64`` architecture. If you would like to use this sandbox
with the ``arm64`` architecture, skip to Step 5.

First lets start the containers - an Envoy proxy which uses a Wasm Filter, and a backend which echos back our request.

Change to the ``examples/wasm-cc`` folder in the Envoy repo, and start the composition:

.. code-block:: console

$ pwd
envoy/examples/wasm-cc
$ docker-compose build --pull
$ docker-compose up -d
$ docker-compose ps

Name Command State Ports
-----------------------------------------------------------------------------------------------
wasm_proxy_1 /docker-entrypoint.sh /usr ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp
wasm_web_service_1 node ./index.js Up 0.0.0.0:9000->9000/tcp

Step 4: Check web response
**************************

The Wasm filter should inject "Hello, world" at the end of the response body when you make a request to the proxy.

.. code-block:: console

$ curl -s http://localhost:8000 | grep "Hello, world"
}Hello, world

The filter also sets the ``content-type`` header to ``text/plain``, and adds a custom ``x-wasm-custom`` header.

.. code-block:: console

$ curl -v http://localhost:8000 | grep "content-type: "
content-type: text/plain; charset=utf-8

$ curl -v http://localhost:8000 | grep "x-wasm-custom: "
x-wasm-custom: FOO

Step 5: Compile the updated filter
**********************************

There are two source code files provided for the Wasm filter.

:download:`envoy_filter_http_wasm_example.cc <_include/wasm-cc/envoy_filter_http_wasm_example.cc>` provides the source code for
the included prebuilt binary.

:download:`envoy_filter_http_wasm_updated_example.cc <_include/wasm-cc/envoy_filter_http_wasm_updated_example.cc>` makes a few
changes to the original.

The following diff shows the changes that have been made:

.. literalinclude:: _include/wasm-cc/envoy_filter_http_wasm_updated_example.cc
:diff: _include/wasm-cc/envoy_filter_http_wasm_example.cc

.. warning::

These instructions for compiling an updated Wasm binary use the
`envoyproxy/envoy-build-ubuntu <https://hub.docker.com/r/envoyproxy/envoy-build-ubuntu/tags>`_ image.
You will need 4-5GB of disk space to accommodate this image.

Stop the proxy server and compile the Wasm binary with the updated code:

.. code-block:: console

$ docker-compose stop proxy
$ docker-compose -f docker-compose-wasm.yaml up --remove-orphans wasm_compile_update

The compiled binary should now be in the ``lib`` folder.

.. code-block:: console

$ ls -l lib
total 120
-r-xr-xr-x 1 root root 59641 Oct 20 00:00 envoy_filter_http_wasm_example.wasm
-r-xr-xr-x 1 root root 59653 Oct 20 10:16 envoy_filter_http_wasm_updated_example.wasm

Step 6: Edit the Dockerfile and restart the proxy
*************************************************

Edit the ``Dockerfile-proxy`` recipe provided in the example to use the updated binary you created in step 5.

Find the ``COPY`` line that adds the Wasm binary to the image:

.. literalinclude:: _include/wasm-cc/Dockerfile-proxy
:language: dockerfile
:emphasize-lines: 3
:linenos:

Replace this line with the following:

.. code-block:: dockerfile

COPY ./lib/envoy_filter_http_wasm_updated_example.wasm /lib/envoy_filter_http_wasm_example.wasm

Now, rebuild and start the proxy container.

.. code-block:: console

$ docker-compose up --build -d proxy

Step 7: Check the proxy has been updated
****************************************

The Wasm filter should instead inject "Hello, Wasm world" at the end of the response body.

.. code-block:: console

$ curl -s http://localhost:8000 | grep "Hello, Wasm world"
}Hello, Wasm world

The ``content-type`` and ``x-wasm-custom`` headers should also have changed

.. code-block:: console

$ curl -v http://localhost:8000 | grep "content-type: "
content-type: text/html; charset=utf-8

$ curl -v http://localhost:8000 | grep "x-wasm-custom: "
x-wasm-custom: BAR
1 change: 1 addition & 0 deletions docs/root/start/start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,5 @@ features. The following sandboxes are available:
sandboxes/mysql
sandboxes/postgres
sandboxes/redis
sandboxes/wasm-cc
sandboxes/zipkin_tracing
5 changes: 3 additions & 2 deletions examples/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ envoy_package()

filegroup(
name = "configs",
srcs = glob(
srcs = [
"//examples/wasm-cc:configs",
] + glob(
[
"**/*.yaml",
"**/*.lua",
],
exclude = [
"cache/responses.yaml",
"jaeger-native-tracing/*",
"wasm/envoy.yaml",
"**/*docker-compose*.yaml",
],
),
Expand Down
50 changes: 50 additions & 0 deletions examples/wasm-cc/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
load("@bazel_skylib//lib:selects.bzl", "selects")
load(
"//bazel:envoy_build_system.bzl",
"envoy_package",
)
load("//bazel/wasm:wasm.bzl", "envoy_wasm_cc_binary")

licenses(["notice"]) # Apache 2

envoy_package()

selects.config_setting_group(
name = "include_wasm_config",
match_all = ["//bazel:x86", "//bazel:wasm_all"],
)

filegroup(
name = "configs",
srcs = glob(
[
"**/*.wasm",
],
) + select({
":include_wasm_config": glob(
[
"**/*.yaml",
],
exclude = [
"**/*docker-compose*.yaml",
],
),
"//conditions:default": [],
}),
)

envoy_wasm_cc_binary(
name = "envoy_filter_http_wasm_example.wasm",
srcs = ["envoy_filter_http_wasm_example.cc"],
deps = [
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
],
)

envoy_wasm_cc_binary(
name = "envoy_filter_http_wasm_updated_example.wasm",
srcs = ["envoy_filter_http_wasm_updated_example.cc"],
deps = [
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
],
)
5 changes: 5 additions & 0 deletions examples/wasm-cc/Dockerfile-proxy
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM envoyproxy/envoy-dev:latest
COPY ./envoy.yaml /etc/envoy.yaml
COPY ./lib/envoy_filter_http_wasm_example.wasm /lib/envoy_filter_http_wasm_example.wasm
RUN chmod go+r /etc/envoy.yaml /lib/envoy_filter_http_wasm_example.wasm
CMD ["/usr/local/bin/envoy", "-c", "/etc/envoy.yaml", "--service-cluster", "proxy"]
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
FROM solsson/http-echo
ENV PORT=9000
File renamed without changes.
23 changes: 23 additions & 0 deletions examples/wasm-cc/docker-compose-wasm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: "3.7"

services:

wasm_compile_update:
image: envoyproxy/envoy-build-ubuntu:b480535e8423b5fd7c102fd30c92f4785519e33a
command: |
bash -c "bazel build //examples/wasm-cc:envoy_filter_http_wasm_updated_example.wasm \
&& cp -a bazel-bin/examples/wasm-cc/* /build"
working_dir: /source
volumes:
- ../..:/source
- ./lib:/build

wasm_compile:
image: envoyproxy/envoy-build-ubuntu:b480535e8423b5fd7c102fd30c92f4785519e33a
command: |
bash -c "bazel build //examples/wasm-cc:envoy_filter_http_wasm_example.wasm \
&& cp -a bazel-bin/examples/wasm-cc/* /build"
working_dir: /source
volumes:
- ../..:/source
- ./lib:/build
23 changes: 23 additions & 0 deletions examples/wasm-cc/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: '3.7'
services:

proxy:
build:
context: .
dockerfile: Dockerfile-proxy
depends_on:
- web_service
networks:
- envoymesh
ports:
- "8000:8000"

web_service:
build:
context: .
dockerfile: Dockerfile-web-service
networks:
- envoymesh

networks:
envoymesh: {}
42 changes: 4 additions & 38 deletions examples/wasm/envoy.yaml → examples/wasm-cc/envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,14 @@ static_resources:
vm_id: "my_vm_id"
code:
local:
filename: "/etc/envoy_filter_http_wasm_example.wasm"
filename: "lib/envoy_filter_http_wasm_example.wasm"
configuration: {}
- name: envoy.filters.http.router
typed_config: {}
- name: staticreply
address:
socket_address:
address: 127.0.0.1
port_value: 8099
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: auto
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
direct_response:
status: 200
body:
inline_string: "foo\n"
http_filters:
- name: envoy.router
config: {}
clusters:
- name: web_service
connect_timeout: 0.25s
type: static
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: service1
Expand All @@ -84,11 +56,5 @@ static_resources:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8099
admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 8001
address: web_service
port_value: 9000
Loading