Skip to content

Commit 74caeb0

Browse files
committed
Phase 1 complete: load + execute Wasm modules from VCL
- Rust test module (get_constant, add_numbers, on_request_allow/block) - 4 passing VTC tests: basic load, allow/block decisions, error handling - Fixed build: vcc_if.h naming, vwasm_ prefix to avoid Wasmtime symbol clash - Dockerfile with Varnish 7.5 + Wasmtime 25 + Rust toolchain - LD_LIBRARY_PATH for runtime Wasmtime shared library resolution
1 parent efad368 commit 74caeb0

18 files changed

Lines changed: 233 additions & 40 deletions

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ Makefile
2929
Makefile.in
3030

3131
# VMOD generated
32-
src/vcc_wasm_if.c
33-
src/vcc_wasm_if.h
32+
src/vcc_if.c
33+
src/vcc_if.h
3434

3535
# IDE
3636
.vscode/

Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ RUN apt-get update && apt-get install -y \
1515
curl \
1616
ca-certificates \
1717
gnupg \
18+
xz-utils \
1819
&& rm -rf /var/lib/apt/lists/*
1920

2021
# Install Varnish from official repo
@@ -33,11 +34,25 @@ RUN ARCH=$(dpkg --print-architecture) \
3334
&& ln -s /opt/wasmtime-v${WASMTIME_VERSION}-${WASMTIME_ARCH}-linux-c-api /opt/wasmtime
3435

3536
ENV WASMTIME_DIR=/opt/wasmtime
37+
ENV LD_LIBRARY_PATH=/opt/wasmtime/lib
38+
39+
# Install Rust (for building test Wasm modules)
40+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \
41+
&& . "$HOME/.cargo/env" \
42+
&& rustup target add wasm32-unknown-unknown
43+
44+
ENV PATH="/root/.cargo/bin:${PATH}"
3645

3746
WORKDIR /src
3847

3948
COPY . .
4049

50+
# Build the test Wasm module
51+
RUN cd examples/rust && cargo build --release \
52+
&& mkdir -p /src/tests/wasm \
53+
&& cp target/wasm32-unknown-unknown/release/test_module.wasm /src/tests/wasm/
54+
55+
# Build the VMOD
4156
RUN chmod +x autogen.sh \
4257
&& ./autogen.sh \
4358
&& ./configure --with-wasmtime=${WASMTIME_DIR} \

Makefile.am

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ check-local:
1212
@if test -n "$(VARNISHTEST)"; then \
1313
for t in $(srcdir)/tests/*.vtc; do \
1414
echo "Running $$t..."; \
15-
$(VARNISHTEST) -Dvmod_wasm="$(abs_top_builddir)/src/.libs/libvmod_wasm.so" $$t || exit 1; \
15+
$(VARNISHTEST) \
16+
-Dvmod_wasm="$(abs_top_builddir)/src/.libs/libvmod_wasm.so" \
17+
-Dwasm_module="$(abs_top_srcdir)/tests/wasm/test_module.wasm" \
18+
$$t || exit 1; \
1619
done; \
1720
else \
1821
echo "WARNING: varnishtest not found, skipping VTC tests"; \

autogen.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Bootstrap the autotools build system
33
set -e
44

5+
mkdir -p m4
6+
libtoolize --force --copy
57
aclocal -I m4
68
autoheader
79
automake --add-missing --foreign

examples/rust/.cargo/config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "wasm32-unknown-unknown"

examples/rust/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/rust/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "test-module"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[profile.release]
10+
opt-level = "s"
11+
lto = true

examples/rust/src/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// Minimal test Wasm module for vmod-wasm Phase 1 testing.
2+
///
3+
/// Exports simple functions that the VMOD can call to verify
4+
/// basic load + execute functionality.
5+
6+
/// Returns a constant (42) — simplest possible test.
7+
#[no_mangle]
8+
pub extern "C" fn get_constant() -> i32 {
9+
42
10+
}
11+
12+
/// Adds two hardcoded numbers — verifies the runtime works.
13+
#[no_mangle]
14+
pub extern "C" fn add_numbers() -> i32 {
15+
17 + 25
16+
}
17+
18+
/// Simulates an "allow" decision (return 0 = allow).
19+
#[no_mangle]
20+
pub extern "C" fn on_request_allow() -> i32 {
21+
0
22+
}
23+
24+
/// Simulates a "block" decision (return 403 = block).
25+
#[no_mangle]
26+
pub extern "C" fn on_request_block() -> i32 {
27+
403
28+
}

src/Makefile.am

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AM_CFLAGS = $(VARNISHAPI_CFLAGS) $(WASMTIME_CFLAGS)
1+
AM_CFLAGS = $(VARNISHAPI_CFLAGS) $(WASMTIME_CFLAGS) -I$(top_builddir)/src
22

33
vmoddir = $(VMOD_DIR)
44
vmod_LTLIBRARIES = libvmod_wasm.la
@@ -18,12 +18,12 @@ libvmod_wasm_la_LIBADD = $(VARNISHAPI_LIBS) $(WASMTIME_LIBS)
1818

1919
# Generate VMOD interface from .vcc
2020
nodist_libvmod_wasm_la_SOURCES = \
21-
vcc_wasm_if.c \
22-
vcc_wasm_if.h
21+
vcc_if.c \
22+
vcc_if.h
2323

24-
vcc_wasm_if.c vcc_wasm_if.h: vmod_wasm.vcc
25-
$(PYTHON) $(VMODTOOL) $(srcdir)/vmod_wasm.vcc
24+
vcc_if.c vcc_if.h: vmod_wasm.vcc
25+
$(VMODTOOL) $(srcdir)/vmod_wasm.vcc
2626

27-
BUILT_SOURCES = vcc_wasm_if.c vcc_wasm_if.h
27+
BUILT_SOURCES = vcc_if.c vcc_if.h
2828
CLEANFILES = $(BUILT_SOURCES)
2929
EXTRA_DIST = vmod_wasm.vcc

src/vmod_wasm.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@
2929
#include "cache/cache.h"
3030
#include "vcl.h"
3131

32-
#include "vcc_wasm_if.h"
32+
#include "vcc_if.h"
3333
#include "wasm_engine.h"
3434

3535
#define VMOD_WASM_VERSION "0.1.0"
3636

3737
/* Global Wasm engine — shared across all VCL instances and threads */
38-
static struct wasm_engine *wasm_engine_global = NULL;
38+
static struct vwasm_engine *vwasm_engine_global = NULL;
3939
static pthread_mutex_t engine_mtx = PTHREAD_MUTEX_INITIALIZER;
4040

4141
/*
@@ -44,25 +44,25 @@ static pthread_mutex_t engine_mtx = PTHREAD_MUTEX_INITIALIZER;
4444
* DISCARD: destroy the Wasm engine
4545
*/
4646
int v_matchproto_(vmod_event_f)
47-
vmod_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
47+
vmod_vmod_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
4848
{
4949
(void)priv;
5050

5151
switch (e) {
5252
case VCL_EVENT_LOAD:
5353
AZ(pthread_mutex_lock(&engine_mtx));
54-
if (wasm_engine_global == NULL)
55-
wasm_engine_global = wasm_engine_new();
54+
if (vwasm_engine_global == NULL)
55+
vwasm_engine_global = vwasm_engine_new();
5656
AZ(pthread_mutex_unlock(&engine_mtx));
57-
if (wasm_engine_global == NULL)
57+
if (vwasm_engine_global == NULL)
5858
return (-1);
5959
return (0);
6060

6161
case VCL_EVENT_DISCARD:
6262
AZ(pthread_mutex_lock(&engine_mtx));
63-
if (wasm_engine_global != NULL) {
64-
wasm_engine_destroy(&wasm_engine_global);
65-
wasm_engine_global = NULL;
63+
if (vwasm_engine_global != NULL) {
64+
vwasm_engine_destroy(&vwasm_engine_global);
65+
vwasm_engine_global = NULL;
6666
}
6767
AZ(pthread_mutex_unlock(&engine_mtx));
6868
return (0);
@@ -90,9 +90,9 @@ vmod_load(VRT_CTX, VCL_STRING name, VCL_STRING path)
9090
return;
9191
}
9292

93-
AN(wasm_engine_global);
93+
AN(vwasm_engine_global);
9494

95-
if (wasm_engine_load_module(wasm_engine_global, name, path) != 0) {
95+
if (vwasm_engine_load_module(vwasm_engine_global, name, path) != 0) {
9696
VRT_fail(ctx, "wasm.load(): failed to load module '%s' from '%s'",
9797
name, path);
9898
}
@@ -116,10 +116,10 @@ vmod_execute(VRT_CTX, VCL_STRING name, VCL_STRING function)
116116
return (-1);
117117
}
118118

119-
AN(wasm_engine_global);
119+
AN(vwasm_engine_global);
120120

121121
int result = 0;
122-
if (wasm_engine_call(wasm_engine_global, ctx, name, function, &result) != 0) {
122+
if (vwasm_engine_call(vwasm_engine_global, ctx, name, function, &result) != 0) {
123123
VSLb(ctx->vsl, SLT_Error,
124124
"wasm.execute(): failed to call '%s' in module '%s'",
125125
function, name);

0 commit comments

Comments
 (0)