istio: Wasm local filename extensions never unloaded when EnvoyFilter deleted

I suspect this is an Envoy bug. I am reporting it here because I can recreate the problem in a few lines with an EnvoyFilter. I don’t know Envoy will enough to reproduce w/o Istio.

wasm-unload.zip

To reproduce:

unzip wasm-unload.zip
# heartbeat.wasm is my own AssemblyScript plugin compiled with <https://github.com/solo-io/proxy-runtime>
kubectl create configmap new-filter --from-file=new-filter.wasm=heartbeat.wasm
# Deploy a pod in an auto-injected namespace
kubectl apply -f httpbin-sidecar-wasm.yaml
# Create an EnvoyFilter with workload selector `app=httpbin`
kubectl apply -f httpbin-ef.yaml
# Note that if you check :15000/config_dump at this point, "new-filter.wasm" is referenced in six places.
# (That could be my EnvoyFilter, I didn't research it exactly how it attached.)
kubectl logs deployment/httpbin -c istio-proxy -f
# heartbeat.wasm calls calls `proxy_set_tick_period_milliseconds` to be woken up every 10 seconds
# Note that `proxy_on_vm_start` must have been called three times, every 10 seconds it logs three times
# (Why not six times?  I don't know.)
kubectl delete -f httpbin-ef.yaml

At this point, kubectl exec service/httpbin -c istio-proxy -- curl localhost:15000/config_dump references “new-filter.wasm” ZERO times. Yet according to kubectl logs deployment/httpbin -c istio-proxy -f every 10 seconds it is still logging three times.

I also expected ABI proxy_on_done to be called by Envoy and my WASM to log something, but the log never appeared.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (10 by maintainers)

Most upvoted comments

@yuval-k The name in the filter config does not have to be a well known name. The typed config decides which filter is used.

@yuval-k Here is my source code:

add-header-and-tick.ts.txt

This code doesn’t do anything useful. I wrote it to get an understanding of the lifecycle events that a filter might experience. There may be some errors – for example, I defined an onDone() and onComplete() for both my Context and my RootContext, because I was uncertain if the system would call both, and in what order. (Currently it is calling neither).