Skip to content

perf: store extension server resources centrally - #10071

Merged
zhaohuabing merged 3 commits into
envoyproxy:mainfrom
zirain:perf/extensionserver
Sep 24, 2026
Merged

zhaohuabing merged 3 commits into
envoyproxy:mainfrom
zirain:perf/extensionserver

Conversation

@zirain

@zirain zirain commented Sep 22, 2026

Copy link
Copy Markdown
Member

fixes: #10065

Signed-off-by: zirain <zirain2009@gmail.com>
@zirain
zirain requested a review from a team as a code owner September 22, 2026 10:30
@netlify

netlify Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit f27ab92
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6ab321e262ef8b0008ebe4cd
😎 Deploy Preview https://deploy-preview-10071--cerulean-figolla-1f9435.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.59155% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 81.34%. Comparing base (3ec9a01) to head (f27ab92).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
internal/gatewayapi/helpers.go 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #10071      +/-   ##
==========================================
+ Coverage   81.31%   81.34%   +0.02%     
==========================================
  Files         264      265       +1     
  Lines       40994    41050      +56     
==========================================
+ Hits        33336    33393      +57     
+ Misses       7657     7656       -1     
  Partials        1        1              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

guydc
guydc previously approved these changes Sep 23, 2026

@guydc guydc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall LGTM, maybe tests for policy/filter mixing on the same route can be added.

Comment thread internal/gatewayapi/extensionserverpolicy.go Outdated
Signed-off-by: zirain <zirain2009@gmail.com>
Signed-off-by: zirain <zirain2009@gmail.com>

@guydc guydc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@zirain zirain added this to the v1.10.0-rc.1 Release milestone Sep 23, 2026
@zirain
zirain requested a review from a team September 23, 2026 23:32

@zhaohuabing zhaohuabing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM. Thanks!

@zhaohuabing
zhaohuabing merged commit 0fdeba7 into envoyproxy:main Sep 24, 2026
73 of 75 checks passed
@zirain
zirain deleted the perf/extensionserver branch September 24, 2026 02:03
@vvoytovych

Copy link
Copy Markdown

Thank you for this change. We run Envoy Gateway with mergeGateways and extension server policies, and it removes most of our controller's memory.

On a copy of our objects (a few hundred merged Gateways, 766 listeners, about 100 Gateway-targeted policies), three runs each:

build controller live heap at rest
the parent of this PR (3b211d29) 912 MiB
this PR (0fdeba79) 74 MiB

The peak after a policy change fell from about 1.9 GiB to 0.25 GiB (process RSS). Before this change, 90% of our heap at rest was copies of these policies in listener ExtensionRefs.

Could this be cherry-picked into release-v1.9 and release-v1.8? #10072 is already labelled for both.

The attachment of these policies to every merged listener is a separate bug: #10097, fixed in #10099.

@zirain

zirain commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

@vvoytovych add this to 1.9.2 and 1.8.5

@vvoytovych

Copy link
Copy Markdown

Thank you! One note for the v1.8.5 pick, from a trial on our side. On release/v1.8 it conflicts in 16 files. On release/v1.9 the pick is clean.
I would recommend to focus on 1.9 only.

kkk777-7 added a commit that referenced this pull request Sep 28, 2026
* fix(luavalidator): block getfenv/setfenv/newproxy/module in the Lua security sandbox (#9743)

* fix(luavalidator): block getfenv/setfenv/newproxy/module in the Lua sandbox

getfenv/setfenv/newproxy/module were not in the blocklist. getfenv(0)
returns the global table regardless of `_G = nil`, so that line's comment
is inaccurate. No escape is reachable today (io/os originals stay in
upvalues, debug is nil), so this is defense-in-depth.

Signed-off-by: kanywst <niwatakuma@icloud.com>

* docs: add release note for Lua sandbox env hardening

Signed-off-by: kanywst <niwatakuma@icloud.com>

* docs: note the Lua sandbox hardening as a breaking change

Signed-off-by: kanywst <niwatakuma@icloud.com>

---------

Signed-off-by: kanywst <niwatakuma@icloud.com>
Co-authored-by: Rudrakh Panigrahi <rudrakh97@gmail.com>

* fix(ratelimit): apply priorityClassName to the rate limit pod (#9898)

rateLimitDeployment.pod.priorityClassName was accepted in EnvoyGateway
config but never copied onto the managed Deployment pod spec, so the
rate limit pod ignored the configured PriorityClass. Set it the same
way the proxy Deployment already does.

Fixes #9897

Signed-off-by: Vijay Pal <vijay.pal@nutanix.com>

* fix: apply maxDynamicDescriptors at route level (#9974)

* fix: apply maxDynamicDescriptors at route level

Envoy Gateway sets max_dynamic_descriptors to 10000 only on the HCM-level
local_ratelimit filter, which carries no descriptors. The real configuration
lives in each route's typed_per_filter_config, and Envoy resolves that
per-route config as a whole without inheriting anything from the HCM filter,
so every route-level limiter fell back to Envoy's default of 20.

A Distinct rule (per client IP, per header value, per query parameter)
therefore tracked only the 20 most recently seen values: the 21st evicted
the oldest bucket, and an evicted client came back with a full bucket. That
made per-client limits on a public listener a coarse layer rather than a
bound.

Set the same limit on the route-level config, where the wildcard
descriptors actually live, and share the constant between both sites.

Signed-off-by: Andreea Popescu <andreea.popescu@pidginhost.com>

* test(ratelimit): cover and document dynamic bucket retention

Signed-off-by: Andreea Popescu <andreea.popescu@pidginhost.com>

* chore: number the local rate limit release note

Signed-off-by: Andreea Popescu <andreea.popescu@pidginhost.com>

* test(ratelimit): pin the limiter headers on 429

CompareRoundTrip compares response headers only for 200 and 204, so the
retention subtest's final 429 was attributed by status alone. Assert
x-ratelimit-limit and x-ratelimit-remaining on the captured response to
tie the rejection to the original user's exhausted bucket.

Also reword the constant's comment: the capacity applies per wildcard
descriptor in each route configuration, and entries are allocated on
demand.

Signed-off-by: Andreea Popescu <andreea.popescu@pidginhost.com>

---------

Signed-off-by: Andreea Popescu <andreea.popescu@pidginhost.com>
Co-authored-by: zirain <zirain2009@gmail.com>

* fix(translator): match SNI on every TCP filter chain (#10011)

* Revert "fix(tcp): add SNI-based filter chain matching for TLS passthrough empty routes (#8521)"

This reverts commit c11f0c2.

emitting identical EmptyCluster filter chains -- by collapsing the placeholder
chains into a single shared one, rather than by giving them distinct matchers.
Collapsing only helps against another placeholder: it does nothing when the
colliding chain belongs to a different listener, which is why #9341 and #9516
still reproduce. Its own commit message describes adding SNI matching, but the
merged change carries none.

Restore the per-listener empty route. The commits that follow add the SNI match
the placeholder chains actually need, which keeps them unique on their own.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix(translator): match SNI on every TCP filter chain

Filter chains on a shared xDS listener must each have a distinct match or
Envoy rejects the listener and stops accepting updates to it. Placeholder
chains for route-less listeners had no match at all, so one sharing a port
with a wildcard HTTPS listener produced two `{}` matchers and a NACK.

Carry the Gateway listener hostname on the TCP IR listener, for TLS protocol
listeners only since TCP ignores hostnames, and resolve the SNI once in
addXdsTCPFilterChain, falling back to that hostname whenever the route carries
none of its own. Every TCP filter chain is then matched the same way and the
placeholder needs no special case.

Reinstate the #7866 regression test dropped by the revert, with each listener
given a distinct hostname -- listeners sharing a port with identical hostnames
are rejected with HostnameConflict before translation, so this is what the
Gateway API layer actually emits. It now asserts three chains with three
distinct serverNames rather than one shared chain.

Co-authored-by: Florian Wiegand <36593900+wiegandf@users.noreply.github.com>
Signed-off-by: Florian Wiegand <36593900+wiegandf@users.noreply.github.com>
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* clean up

Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix(translator): name the placeholder filter chain after its listener

The placeholder chain for a route-less TCP listener was named after the
EmptyCluster it points at, which reads as a cluster in a config dump and
goes stale if the placeholder ever targets something else. Name it after
the listener that owns it instead, with a /no-routes suffix saying why
the chain exists.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* test: include SNI hostname in merged gateway fixture

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>

---------

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>
Signed-off-by: Florian Wiegand <36593900+wiegandf@users.noreply.github.com>
Co-authored-by: Florian Wiegand <36593900+wiegandf@users.noreply.github.com>

* fix(gatewayapi): conflict HTTPS and TLS listeners sharing a hostname when gateways are merged (#10013)

validateConflictedMergedListeners keys on the listener protocol verbatim, so an
HTTPS listener and a TLS listener on the same port with the same hostname land in
different buckets and are both accepted. They cannot both be served: listeners
sharing a port are told apart by SNI, and here the SNI is the same. Envoy ends up
with two filter chains carrying an identical server_names match and rejects the
listener, along with every update to it that follows.

Key on the protocol class instead, which puts HTTPS and TLS together, so the
second listener is marked Conflicted with HostnameConflict. This is what
validateConflictedHostnameListeners already does within a single Gateway;
merged Gateways were the only path that skipped the check.

Also route the conflict through setConflictedConditions rather than setting the
condition directly. Every other conflict path already uses it, and it is what
sets Accepted=False and Programmed=False on a ListenerSet listener -- without it
a conflicted ListenerSet entry reports no Accepted condition at all and a generic
ListenersNotValid reason for Programmed.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix: scope merged cluster settings by backend protocol (#10016)

* fix: scope merged cluster settings by backend protocol

Signed-off-by: kkk777-7 <kota.kimura0725@gmail.com>

* rename release note

Signed-off-by: kkk777-7 <kota.kimura0725@gmail.com>

---------

Signed-off-by: kkk777-7 <kota.kimura0725@gmail.com>

* fix: marshal xDS typed_config deterministically to avoid equivalent-resource churn (#10019)

* fix: marshal xDS typed_config deterministically to avoid equivalent-resource churn

ToAnyWithValidation wrapped every filter typed_config via anypb.New, which uses
the default non-deterministic marshaler. Proto map fields (an access log's
json_format, JWT providers, filter metadata) then serialize in a random key
order on each translation, so semantically unchanged resources are emitted with
different bytes and republished on every reconcile.

Marshal deterministically via anypb.MarshalFrom so map keys serialize in a stable
order. Add a regression test, since the golden xDS tests compare protojson output
(which re-sorts map keys) and cannot catch this.

Signed-off-by: nguyenptk <nguyenptk@gmail.com>

* docs: add release note for deterministic xDS marshaling fix

Signed-off-by: nguyenptk <nguyenptk@gmail.com>

---------

Signed-off-by: nguyenptk <nguyenptk@gmail.com>

* fix: accept equal-preference cipher groups in TLS settings (#10050)

The cipher validation added in v1.8.0 compares each entry of the cipher
list against the set of supported cipher names as a whole string. That
rejects BoringSSL equal-preference groups such as
"[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]", which
Envoy accepts and which let the client's own preference break the tie
between equally preferred ciphers. This includes the default cipher list
documented on the ciphers field itself, so copying the documented
defaults into a ClientTrafficPolicy left it not accepted.

Unwrap group entries and validate each member, rejecting malformed
groups (unclosed, empty, nested) and a separator used outside a group.

Fixes #9679

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>
Co-authored-by: zirain <zirain2009@gmail.com>

* fix(gatewayapi): allow consistent hash with merge backends (#10052)

* feat(gatewayapi): allow consistent hash with merge backends

Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix: refresh consistent hash merge fixtures and cleanup

Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix: clarify consistent hash merge regression coverage and release note

Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* chore: remove unused BTPLoadBalancerIndex

The gateway-level ConsistentHash check in weightedRuleBackendsMustBeInOneCluster
was its only consumer, and that check is gone now that consistent hashing works
with merged backends.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* test(xds): cover consistent hash with merged backend clusters

Feed the IR from the gatewayapi mergebackends consistent-hash fixture through
the xDS translator, checking that shared clusters get the Maglev policy and
hash config and the weighted route keeps its hash policy with use_hash_policy.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

---------

Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>

* perf: store extension server resources centrally (#10071)

* perf: store extension server resources centrally

Signed-off-by: zirain <zirain2009@gmail.com>

* nit

Signed-off-by: zirain <zirain2009@gmail.com>

* more tests

Signed-off-by: zirain <zirain2009@gmail.com>

---------

Signed-off-by: zirain <zirain2009@gmail.com>

* perf: store upstream CA bundles once per gateway (#10072)

* perf: share immutable TLS certificate bytes across IR copies

A heap profile of a gateway whose backends validate against a shared CA had
4.75 GB of a 7.45 GB live heap in duplicated certificate bytes. Two multipliers
stack: every DestinationSetting gets its own copy of the CA bundle, and the
watchable map deep copies the whole ir.Xds once per store and once per
subscriber, so each bundle was held once per destination per copy.

The bytes are already immutable once translation has produced them. The
translator aliases them straight out of the Secret, and the xDS translator only
reads them into protobuf InlineBytes, so the copy in the generated deep-copy
functions bought nothing.

Hand-write DeepCopyInto for TLSCACertificate, TLSCertificate and TLSCrl so a
copy shares those slices. controller-gen omits a generated DeepCopyInto when the
type already has one, so the generated DeepCopy wrappers and every caller stay
as they are. Intern the assembled CA bundle per translation so destinations
referencing the same CA share one backing array as well.

Deep copying an IR with 1000 destinations sharing a 22KB CA bundle drops from
25.6 MB and 2.7 ms to 1.1 MB and 0.27 ms. Translation allocation on the same
shape drops about 29%.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* polish

Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* test: build the benchmark CA bundle instead of pasting it

The bundle was one certificate repeated twenty times inline in the ConfigMap
YAML, which cost about 400 unreadable lines and defined the bundle twice, so
nothing kept the translation benchmark and the deep-copy benchmark measuring
the same bytes. Build it from a single constant instead.

Also name the release note after the PR rather than the issue.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* perf: store upstream CA bundles centrally instead of sharing their memory

Sharing the certificate bytes between IR copies kept the deep copy at the
watchable boundary from duplicating them, but it also meant a byte slice reachable
from several snapshots at once, which is harder to reason about and leaves an
append on one copy visible to another. Store the bundles centrally instead, the
way extension server resources are stored, so each copy stays self-contained.

Xds.CACertificates holds one CACertificateEntry per distinct bundle, addressed by
a digest of its bytes, and TLSCACertificate carries that digest rather than its own
copy. A reference keeps its own Name, so the xDS secret name is unchanged and
Envoy sees exactly what it saw before. Where no gateway IR is in scope to register
against, such as the ext service and telemetry paths, the bytes stay on the
reference and resolution falls back to them.

Addressing by content rather than by the owning policy matters because
BackendTLSPolicy cannot reference across namespaces, so a cluster trusting one
corporate CA is forced to copy it per namespace. Keying on the policy would leave
every one of those copies in place.

Deep copying an IR with 1000 destinations, each with its own policy trusting the
same CA, drops from 25.6 MB and 2.1 ms to 1.1 MB and 0.28 ms.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix: use the full digest to content-address CA bundles

The digest was cut to its first 64 bits, and a match reused the existing entry
without comparing the bytes behind it. Two bundles on one gateway sharing that
prefix would silently give the second destination the first bundle as its trusted
CA. A gateway can carry bundles from tenants that do not trust each other, so the
truncation is not worth the shorter name.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* fix: key the resolved CA cache by the resource, not its secret name

A Backend and a BackendTLSPolicy both name their CA secret <name>/<namespace>-ca,
so one of each sharing a name in a namespace produced the same cache key. The
cache was also written from the merged config, which cannot tell which of the two
the CA came from. A route to the Backend translated first therefore let the policy
skip reading its own refs and adopt the Backend's CA.

Key the cache by the resource's kind, namespace and name instead, and write it
where the CA is resolved rather than after the merge. Cache the digest rather than
the entry, so a destination rejected before its bundle is registered leaves nothing
for a later lookup to reuse.

The Backend path now takes the same shortcut the policy path already had, which is
what makes the kind in the key meaningful.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

---------

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>
Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: zirain <zirain2009@gmail.com>

* fix(translator): compute GeoIP header removals once per listener (#10107)

* [envoy-gateway] Reuse listener GeoIP header removals [ci changed_files]

Signed-off-by: Cooper Gamble <cooper@openai.com>

* [envoy-gateway] Add GeoIP translation performance release note [ci changed_files]

Signed-off-by: Cooper Gamble <cooper@openai.com>

---------

Signed-off-by: Cooper Gamble <cooper@openai.com>
Co-authored-by: zirain <zirain2009@gmail.com>

* fix: count UDP proxy sessions in shutdown drain (#10110)

fix: count UDP proxy sessions in shutdown drain (#10109)

The shutdown manager only summed listener downstream_cx_active, which
never includes UDP proxy sessions, so a UDP-only proxy exited as soon as
the minimum drain period passed. Also count udp.*.downstream_sess_active.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* test: regenerate the merged consistent-hash cluster golden (#10115)

Marking merged backend clusters as route clusters stopped them carrying a
cluster-level hash policy, since a route cluster gets its hash policy from the
route action instead. The golden was not regenerated at the time, so
TestTranslateXds and gen-check fail on main.

Consistent hashing is unaffected: the route still carries the source IP hash
policy and both clusters keep their maglev load balancing policy.

Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>

* [cooper-09] fix(jsonpatch): batch JSONPath matches (#10118)

* [envoy-gateway] Batch JSONPath matches in one apply [ci changed_files]

Signed-off-by: Cooper Gamble <cooper@openai.com>

* fix: generate testdata

Signed-off-by: kkk777-7 <kota.kimura0725@gmail.com>

* fix: security fixes (#10130)

* security fix: GHSA-gmx8-fhfh-mgjx (#35)

Signed-off-by: Guy Daich <guy.daich@sap.com>

* fix: check for nil pod-name key in Token Review extra field (#41)

Signed-off-by: Karol Szwaj <karol.szwaj@gmail.com>
Co-authored-by: Karol Szwaj <karol.szwaj@gmail.com>

* fix: allow to disable EnvoyProxy patch with RuntimeFlag (#37)

Signed-off-by: zirain <zirain2009@gmail.com>

* fix: a panic during shutdown (#33)

Signed-off-by: zirain <zirain2009@gmail.com>

* release notes

Signed-off-by: zirain <zirain2009@gmail.com>

* fix PR number

Signed-off-by: zirain <zirain2009@gmail.com>

---------

Signed-off-by: Guy Daich <guy.daich@sap.com>
Signed-off-by: Karol Szwaj <karol.szwaj@gmail.com>
Signed-off-by: zirain <zirain2009@gmail.com>
Co-authored-by: Guy Daich <guy.daich@sap.com>
Co-authored-by: Karol Szwaj <karol.szwaj@gmail.com>

* add: envoy proxy warn condition

Signed-off-by: kkk777-7 <kota.kimura0725@gmail.com>

---------

Signed-off-by: kanywst <niwatakuma@icloud.com>
Signed-off-by: Vijay Pal <vijay.pal@nutanix.com>
Signed-off-by: Andreea Popescu <andreea.popescu@pidginhost.com>
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Signed-off-by: Huabing (Robin) Zhao <huabing@tetrate.io>
Signed-off-by: Florian Wiegand <36593900+wiegandf@users.noreply.github.com>
Signed-off-by: kkk777-7 <kota.kimura0725@gmail.com>
Signed-off-by: nguyenptk <nguyenptk@gmail.com>
Signed-off-by: zirain <zirain2009@gmail.com>
Signed-off-by: Cooper Gamble <cooper@openai.com>
Signed-off-by: Guy Daich <guy.daich@sap.com>
Signed-off-by: Karol Szwaj <karol.szwaj@gmail.com>
Co-authored-by: kt <kanywst12@gmail.com>
Co-authored-by: Rudrakh Panigrahi <rudrakh97@gmail.com>
Co-authored-by: Vijaypal(NAI) <vijay.pal@nutanix.com>
Co-authored-by: andreeapid <andreea.popescu@pidginhost.com>
Co-authored-by: zirain <zirain2009@gmail.com>
Co-authored-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
Co-authored-by: Florian Wiegand <36593900+wiegandf@users.noreply.github.com>
Co-authored-by: Nguyên (Harry) <nguyenptk@gmail.com>
Co-authored-by: cooper-oai <cooper@openai.com>
Co-authored-by: Guy Daich <guy.daich@sap.com>
Co-authored-by: Karol Szwaj <karol.szwaj@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

store extension server resources centrally

4 participants