Skip to content
Draft
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
5 changes: 5 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
common --enable_bzlmod=0
common --color=yes
common:ci --noshow_progress
common:ci --noshow_loading_progress
common:ci --test_output=errors
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.5.0
59 changes: 59 additions & 0 deletions .github/workflows/modules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Build modules

on:
push:
branches:
- main
pull_request:
paths:
release:
types:
released

permissions:
contents: read

jobs:
build:
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- arch: x86_64
runs-on: ubuntu-22.04
- arch: aarch64
runs-on: ubuntu-22.04-arm
steps:
- uses: actions/checkout@v4
- name: Fetch versions
id: deps
run: |
bazel build //wasm/http-hello-world:module

publish:
if: github.event_name == 'release'
runs-on: ubuntu-24.04
needs:
- build
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all workflow run artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Upload release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
for artifact in artifacts/*; do
[[ ! -d "$artifact" ]] && continue
name=$(basename "$artifact")
file=$(ls "$artifact"/*.tar.xz)
echo "Uploading $file as $name.tar.xz"
gh release upload "${{ github.event.release.tag_name }}" \
"$file#$name.tar.xz" \
--clobber
done
8 changes: 8 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
licenses(["notice"]) # Apache 2

pkg_tar(
name = "modules",
deps = [
"//wasm:modules",
],
)
16 changes: 16 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
workspace(name = "envoy-modules")

load(":archives.bzl", "load_archives")
load_archives()

load(":deps.bzl", "resolve_dependencies")
resolve_dependencies()

load(":toolchains.bzl", "load_toolchains")
load_toolchains()

load(":packages.bzl", "load_packages")
load_packages()

load("@toolshed_pip3//:requirements.bzl", "install_deps")
install_deps()
38 changes: 38 additions & 0 deletions archives.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//:versions.bzl", "VERSIONS")

def load_github_archives():
for k, v in VERSIONS.items():
if type(v) == type("") or v.get("type") != "github_archive":
continue
kwargs = dict(name = k, **v)
# Format string values, but not lists
formatted_kwargs = {}
for arg_k, arg_v in kwargs.items():
if arg_k in ["repo", "type", "version"]:
continue
if type(arg_v) == type(""):
formatted_kwargs[arg_k] = arg_v.format(**kwargs)
else:
formatted_kwargs[arg_k] = arg_v
http_archive(**formatted_kwargs)

def load_http_archives():
for k, v in VERSIONS.items():
if type(v) == type("") or v.get("type") != "http_archive":
continue
kwargs = dict(name = k, **v)
# Format string values, but not lists
formatted_kwargs = {}
for arg_k, arg_v in kwargs.items():
if arg_k in ["type", "version"]:
continue
if type(arg_v) == type(""):
formatted_kwargs[arg_k] = arg_v.format(**kwargs)
else:
formatted_kwargs[arg_k] = arg_v
http_archive(**formatted_kwargs)

def load_archives():
load_github_archives()
load_http_archives()
32 changes: 32 additions & 0 deletions deps.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
load("@rules_perl//perl:deps.bzl", "perl_register_toolchains", "perl_rules_dependencies")
load("@rules_python//python:repositories.bzl", "py_repositories")
load("@toolchains_llvm//toolchain:deps.bzl", "bazel_toolchain_dependencies")
load("@toolchains_llvm//toolchain:rules.bzl", "llvm_toolchain")
load("//:versions.bzl", "VERSIONS")
load("@envoy_toolshed//sysroot:sysroot.bzl", "setup_sysroots")

def resolve_dependencies(
cmake_version=None,
llvm_version=None,
ninja_version=None,
setup_autotools_toolchain=True):
py_repositories()
bazel_toolchain_dependencies()
rules_foreign_cc_dependencies(
register_preinstalled_tools = True,
register_default_tools = True,
cmake_version = cmake_version or VERSIONS["cmake"],
ninja_version = ninja_version or VERSIONS["ninja"],
)
perl_rules_dependencies()
perl_register_toolchains()
setup_sysroots()
llvm_toolchain(
name = "llvm_toolchain",
llvm_version = llvm_version or VERSIONS["llvm"],
sysroot = {
"linux-x86_64": "@sysroot_linux_amd64//:sysroot",
"linux-aarch64": "@sysroot_linux_arm64//:sysroot",
}
)
12 changes: 12 additions & 0 deletions packages.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load("@bazel_features//:deps.bzl", "bazel_features_deps")
load("@rules_python//python:pip.bzl", "pip_parse")
load("//:versions.bzl", "VERSIONS")

def load_packages():
# This is empty - it should be overridden in your repo
pip_parse(
name = "toolshed_pip3",
requirements_lock = "@envoy_toolshed//:requirements.txt",
python_interpreter_target = "@python3_12_host//:python",
)
bazel_features_deps()
10 changes: 10 additions & 0 deletions toolchains.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains")
load("@rules_python//python:repositories.bzl", "python_register_toolchains")
load("//:versions.bzl", "VERSIONS")

def load_toolchains():
llvm_register_toolchains()
python_register_toolchains(
name = "python%s" % VERSIONS["python"].replace(".", "_"),
python_version = VERSIONS["python"].replace("-", "_"),
)
65 changes: 65 additions & 0 deletions versions.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

VERSIONS = {
"aspect_bazel_lib": {
"type": "github_archive",
"repo": "aspect-build/bazel-lib",
"version": "2.16.0",
"sha256": "092f841dd9ea8e736ea834f304877a25190a762d0f0a6c8edac9f94aac8bbf16",
"strip_prefix": "bazel-lib-{version}",
"url": "https://github.com/{repo}/archive/v{version}.tar.gz",
},

"bazel_skylib": {
"type": "github_archive",
"repo": "bazelbuild/bazel-skylib",
"version": "1.4.2",
"sha256": "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
"url": "https://github.com/{repo}/releases/download/{version}/bazel-skylib-{version}.tar.gz",
},

"envoy": {
"type": "github_archive",
"repo": "envoyproxy/envoy",
"version": "60c29b959217d66ddb54732df78e45ec767df427",
"sha256": "f2b3dec8eb49ab235ca3c60c60a6ea4b1bd58cc4f8ea9302f7bae817eb472d88",
"urls": ["https://github.com/{repo}/archive/{version}.tar.gz"],
"strip_prefix": "envoy-{version}",
},

"envoy_toolshed": {
"type": "github_archive",
"repo": "envoyproxy/toolshed",
"version": "0.3.3",
"sha256": "1ac69d5b1cbc138f779fc3858f06a6777455136260e1144010f0b51880f69814",
"urls": ["https://github.com/{repo}/archive/bazel-v{version}.tar.gz"],
"patch_args": ["-p1"],
"strip_prefix": "toolshed-bazel-v{version}/bazel",
},

"rules_python": {
"type": "github_archive",
"repo": "bazelbuild/rules_python",
"version": "1.4.1",
"sha256": "9f9f3b300a9264e4c77999312ce663be5dee9a56e361a1f6fe7ec60e1beef9a3",
"url": "https://github.com/{repo}/releases/download/{version}/{name}-{version}.tar.gz",
"strip_prefix": "{name}-{version}",
},

"rules_foreign_cc": {
"type": "github_archive",
"repo": "bazelbuild/rules_foreign_cc",
"version": "0.14.0",
"sha256": "e0f0ebb1a2223c99a904a565e62aa285bf1d1a8aeda22d10ea2127591624866c",
"url": "https://github.com/{repo}/releases/download/{version}/{name}-{version}.tar.gz",
"strip_prefix": "{name}-{version}",
},

"toolchains_llvm": {
"type": "github_archive",
"repo": "bazel-contrib/toolchains_llvm",
"version": "1.4.0",
"sha256": "fded02569617d24551a0ad09c0750dc53a3097237157b828a245681f0ae739f8",
"url": "https://github.com/{repo}/releases/download/v{version}/{name}-v{version}.tar.gz",
"strip_prefix": "{name}-v{version}",
},
}
8 changes: 8 additions & 0 deletions wasm/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
licenses(["notice"]) # Apache 2

pkg_tar(
name = "modules",
deps = [
"//wasm/http-hello-world:module",
],
)
23 changes: 23 additions & 0 deletions wasm/http-hello-world/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@envoy//bazel/wasm:wasm.bzl", "envoy_wasm_cc_binary")

licenses(["notice"]) # Apache 2

exports_files(["module.rst", "module.yaml"])

envoy_wasm_cc_binary(
name = "hello.wasm",
srcs = ["hello.cc"],
)

filegroup(
name = "files",
srcs = glob(["**/*"], exclude = ["module.rst", "module.yaml", "BUILD"]),
visibility = ["//visibility:public"],
)

alias(
name = "module",
actual = ":hello.wasm",
visibility = ["//visibility:public"],
)
91 changes: 91 additions & 0 deletions wasm/http-hello-world/hello.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// NOLINT(namespace-envoy)
#include <string>
#include <string_view>
#include <unordered_map>

#include "proxy_wasm_intrinsics.h"

class ExampleRootContext : public RootContext {
public:
explicit ExampleRootContext(uint32_t id, std::string_view root_id) : RootContext(id, root_id) {}

bool onStart(size_t) override;
bool onConfigure(size_t) override;
void onTick() override;
};

class ExampleContext : public Context {
public:
explicit ExampleContext(uint32_t id, RootContext* root) : Context(id, root) {}

void onCreate() override;
FilterHeadersStatus onRequestHeaders(uint32_t headers, bool end_of_stream) override;
FilterDataStatus onRequestBody(size_t body_buffer_length, bool end_of_stream) override;
FilterHeadersStatus onResponseHeaders(uint32_t headers, bool end_of_stream) override;
FilterDataStatus onResponseBody(size_t body_buffer_length, bool end_of_stream) override;
void onDone() override;
void onLog() override;
void onDelete() override;
};
static RegisterContextFactory register_ExampleContext(CONTEXT_FACTORY(ExampleContext),
ROOT_FACTORY(ExampleRootContext),
"my_root_id");

bool ExampleRootContext::onStart(size_t) {
LOG_TRACE("onStart");
return true;
}

bool ExampleRootContext::onConfigure(size_t) {
LOG_TRACE("onConfigure");
proxy_set_tick_period_milliseconds(1000); // 1 sec
return true;
}

void ExampleRootContext::onTick() { LOG_TRACE("onTick"); }

void ExampleContext::onCreate() { LOG_WARN(std::string("onCreate " + std::to_string(id()))); }

FilterHeadersStatus ExampleContext::onRequestHeaders(uint32_t, bool) {
LOG_DEBUG(std::string("onRequestHeaders ") + std::to_string(id()));
auto result = getRequestHeaderPairs();
auto pairs = result->pairs();
LOG_INFO(std::string("headers: ") + std::to_string(pairs.size()));
for (auto& p : pairs) {
LOG_INFO(std::string(p.first) + std::string(" -> ") + std::string(p.second));
}
return FilterHeadersStatus::Continue;
}

FilterHeadersStatus ExampleContext::onResponseHeaders(uint32_t, bool) {
LOG_DEBUG(std::string("onResponseHeaders ") + std::to_string(id()));
auto result = getResponseHeaderPairs();
auto pairs = result->pairs();
LOG_INFO(std::string("headers: ") + std::to_string(pairs.size()));
for (auto& p : pairs) {
LOG_INFO(std::string(p.first) + std::string(" -> ") + std::string(p.second));
}
addResponseHeader("X-Wasm-custom", "FOO");
replaceResponseHeader("content-type", "text/plain; charset=utf-8");
removeResponseHeader("content-length");
return FilterHeadersStatus::Continue;
}

FilterDataStatus ExampleContext::onRequestBody(size_t body_buffer_length,
bool /* end_of_stream */) {
auto body = getBufferBytes(WasmBufferType::HttpRequestBody, 0, body_buffer_length);
LOG_ERROR(std::string("onRequestBody ") + std::string(body->view()));
return FilterDataStatus::Continue;
}

FilterDataStatus ExampleContext::onResponseBody(size_t body_buffer_length,
bool /* end_of_stream */) {
setBuffer(WasmBufferType::HttpResponseBody, 0, body_buffer_length, "Hello, world\n");
return FilterDataStatus::Continue;
}

void ExampleContext::onDone() { LOG_WARN(std::string("onDone " + std::to_string(id()))); }

void ExampleContext::onLog() { LOG_WARN(std::string("onLog " + std::to_string(id()))); }

void ExampleContext::onDelete() { LOG_WARN(std::string("onDelete " + std::to_string(id()))); }
14 changes: 14 additions & 0 deletions wasm/http-hello-world/module.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Download
--------


Running
-------


Configuration
-------------


Building
--------
Loading
Loading