Skip to content

feat!: remove the bundled SSH tunnel in favour of the erpl_tunnel extension - #119

Merged
jrosskopf merged 3 commits into
masterfrom
claude/remove-bundled-tunnel
Aug 22, 2026
Merged

feat!: remove the bundled SSH tunnel in favour of the erpl_tunnel extension#119
jrosskopf merged 3 commits into
masterfrom
claude/remove-bundled-tunnel

Conversation

@jrosskopf

@jrosskopf jrosskopf commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

erpl bundled an SSH tunnel in tunnel/. It is superseded by erpl-tunnel, which does strictly more. Full analysis in TUNNEL_REMOVAL_PLAN.md.

Nothing is lost

bundled tunnel/ erpl-tunnel
tunnel_create, tunnel_close, tunnel_close_all, tunnels() yes yes
ssh_tunnel secret 7 params same type name + alias, all 7, plus mesh params
Reverse tunnels, tunnel_peers, tunnel_self, mesh backends, bind_all yes
Published platforms only inside the erpl bundle get.erpl.io since 2026-07-26, including linux_arm64

erpl_rfc never depended on the tunnel in either direction — it is a plain port forwarder.

This is a bug fix, not just cleanup

While erpl bundled its own tunnel it silently shadowed the dedicated extension. Demonstrated against real artifacts:

LOAD erpl;
INSTALL '<erpl-tunnel>'; LOAD erpl_tunnel;   -- succeeds. No error, no warning.
SELECT function_name FROM duckdb_functions() WHERE function_name LIKE 'tunnel%';
-- tunnel_close, tunnel_create        ← only the old ones

The name was already claimed, so the second LOAD was a no-op. Nobody with erpl installed could migrate. Freeing the name is why the stubs live in erpl_rfc rather than in a surviving erpl_tunnel.

What remains

A stub per moved function, raising a message that names the extension, the two-line install, and the repo. Each carries the original named parameters so a realistic call reaches the message rather than a signature error.

The ssh_tunnel secret type is deliberately not registered — RegisterSecretType throws on a duplicate, which would make LOAD erpl_tunnel fail outright.

Stubs register only when the name is absent, so LOAD erpl_tunnel then LOAD erpl cannot displace a working implementation.

⚠️ Merge DataZooDE/erpl-tunnel#5 and release it first

Testing found the stubs would otherwise break the migration they advertise:

LOAD erpl_tunnel → Invalid Input Error: "Pragma Function with name "tunnel_create" already exists!"

RegisterFunction(PragmaFunction) and the CreateTableFunctionInfo overload leave on_conflict at ERROR_ON_CONFLICT. Fixing only the pragmas moved the abort to the tunnels table function and left the extension half-registered (loaded = false, tunnel_peers/tunnel_self missing) — which looks like success unless you count the functions. erpl-tunnel#5 makes those registrations replace instead.

Both load orders are now verified end-to-end: all nine functions present, real implementation serving, PRAGMA tunnel_close_all returns "All tunnels closed successfully".

Also

  • libssh2 dropped from rfc/vcpkg.json; nothing else used it.
  • sql_tests_tunnel and its docker-compose SSH mock removed.
  • Trampoline no longer embeds/extracts/loads erpl_tunnel on any platform.
  • Released bundle: 290 MB → 242 MB.

Testing

rfc 28/28 and odp 24/24 on both RFC backends; smoke test green; BICS running.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…ension

erpl bundled an SSH tunnel in tunnel/. It is superseded by erpl-tunnel, which
does strictly more -- reverse tunnels, Tailscale and NetBird backends, peer
discovery -- and has published to get.erpl.io since 2026-07-26 on more platforms
than erpl itself ships, linux_arm64 included. Nothing is lost: the secret type
is the same ssh_tunnel with a superset of parameters, and every function erpl
had exists there. erpl_rfc never depended on the tunnel in either direction.

This is a bug fix as much as a cleanup. While erpl bundled its own, it silently
SHADOWED the dedicated extension: the name erpl_tunnel was already claimed, so
`INSTALL erpl_tunnel; LOAD erpl_tunnel;` succeeded, changed nothing, and left
the caller on the weaker implementation with no error. Nobody with erpl
installed could migrate. Freeing the name is what unblocks them, and is why the
stubs live in erpl_rfc rather than in a surviving erpl_tunnel extension.

What remains is a stub per moved function -- tunnel_create, tunnel_close,
tunnel_close_all, tunnels() -- raising a message that names the extension, the
two-line install, and the repository. Each carries the original named
parameters, so a realistic call reaches the message instead of a signature
error. The ssh_tunnel secret type is deliberately NOT registered: RegisterSecretType
throws on a duplicate, which would make LOAD erpl_tunnel fail outright.

The stubs register only when the name is absent, so `LOAD erpl_tunnel` followed
by `LOAD erpl` cannot displace a working implementation. Both orders are tested
against a real erpl_tunnel build; both end with all nine functions present and
the real implementation serving them. That needs erpl-tunnel's
replace-on-conflict fix -- without it the reverse order aborts the LOAD, which
is the migration path the stub message itself recommends.

Also drops libssh2 from rfc/vcpkg.json (nothing else used it), sql_tests_tunnel
and its docker-compose SSH mock, and the trampoline's embed/extract/load of
erpl_tunnel on all three platforms. The released bundle goes from 290 MB to
242 MB.

Suites after the change: rfc 28/28 and odp 24/24 on both RFC backends, smoke
test green.
The plan recorded that duplicate names do not throw and that last registration
wins. That came from a probe against the statically linked debug build, where
extensions register through a different path, and it does not hold for real
loadable extensions: LOAD erpl_tunnel aborts on the first name erpl's stubs
already hold.

Records what the real test showed, the half-registered state that fixing only
the pragmas produces, the companion erpl-tunnel PR, and the release ordering it
imposes.
The Windows smoke test failed with 'Error during extraction: Failed to find
resource: LIBSSH2'. Dropping libssh2 from rfc/vcpkg.json with the bundled SSH
tunnel means vcpkg no longer builds it, so attach_vcpkg_dlls_as_resources -- which
globs whatever vcpkg produced -- had nothing to attach, while the extraction side
still asked for it by name. zlib1.dll goes the same way; it was only there as a
libssh2 dependency.

The underlying trap is that the attach side globs and the extract side is a
hardcoded list, so the two can drift silently and a missing resource fails the
whole extraction rather than just that file. Noted in a comment at the list.

Caught by CI: Linux and macOS never see this path, and the release build links
fine -- only the Windows smoke test exercises resource extraction.
@jrosskopf
jrosskopf merged commit d3b683e into master Aug 22, 2026
53 checks passed
@jrosskopf
jrosskopf deleted the claude/remove-bundled-tunnel branch August 22, 2026 05:33
jrosskopf added a commit that referenced this pull request Aug 22, 2026
Covers both features that landed since v2026.08.19: the runtime-selectable RFC
backend (#118), which had no changelog entry at all, and the removal of the
bundled SSH tunnel (#119).

Also bumps the two version constants to match the tag. Both carry a "bump on
release" comment and both had drifted -- telemetry's kProductVersion still said
2026.07.02 and the feedback banner 2026.07.24, so every event and banner since
has been stamped with a version that was never released.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant