Skip to content

feat(connections): connect through a Unix socket, locally or over the SSH tunnel (#1002) - #1250

Open
markankamaransheogarat-sys wants to merge 5 commits into
TabularisDB:mainfrom
markankamaransheogarat-sys:feat/unix-socket-connections
Open

markankamaransheogarat-sys wants to merge 5 commits into
TabularisDB:mainfrom
markankamaransheogarat-sys:feat/unix-socket-connections

Conversation

@markankamaransheogarat-sys

Copy link
Copy Markdown
Contributor

Closes #1002.

This is a fresh PR from current main, as agreed in #1246. It ports the design of #492 (@debba) and adds the #1002 extras on top. It supersedes both:

Commits

  1. feat(connections): Unix socket support… (author: @debba). The feat(connections): Unix socket support — dialed locally or through the SSH tunnel #492 changes, ported. While porting I adapted them to what main has gained since:
    • SshTunnel::new_with_tcp_override (SSH-scope proxy) now takes the forward destination instead of a remote host/port, so a socket can be reached through a proxied bastion too.
    • The AWS SSM tunnel (added since) clears the socket path like the K8s tunnel does, and a direct socket connection skips the database-scope proxy.
    • build_postgres_configurations returns Result on main. The socket branch is #[cfg(unix)], since tokio_postgres has no host_path/Host::Unix on Windows, and Windows gets a clear error.
    • build_mysql_options keeps main's IAM/cleartext rules and adds the socket endpoint with TLS forced off.
    • The endpoint selector sits in main's form next to the plugin host/port field overrides.
  2. feat(i18n): … pt-BR and zh: the two locales added after feat(connections): Unix socket support — dialed locally or through the SSH tunnel #492.
  3. feat(connections): import ?socket=, hide the local socket on Windows…:
    • mysql://user@host/db?socket=/path imports as a socket connection.
    • The local socket endpoint is hidden on Windows (hasUnixSockets). A socket reached through SSH stays available there, because the SSH server dials it.
    • AWS IAM is rejected over a local socket.
    • More tests.

Behaviour

MySQL / MariaDB PostgreSQL
no tunnel MySqlConnectOptions::socket, TLS off, SSL files ignored, cleartext plugin allowed, IAM rejected host_path(dir) + port parsed from .s.PGSQL.<port> (a directory also works), TLS off
SSH tunnel direct-streamlocal@openssh.com (russh) / ssh -L port:/path (system ssh); the driver dials the forwarded local port same
K8s / SSM tunnel socket ignored and cleared (TCP-only forwards) same
Windows local socket hidden in the UI and rejected by the backend; SSH-forwarded socket works same

The socket path shows up in connection labels instead of host:port. Ad-hoc pool keys use socket:<path> as the endpoint.

Tests

  • Rust: the feat(connections): Unix socket support — dialed locally or through the SSH tunnel #492 tests (forward destination, tunnel params, local socket in MySQL/Postgres options, Postgres path splitting, pool keys), plus IAM rejection and a Windows rejection test.
    • The tests that dial a socket are #[cfg(unix)], the Windows one is #[cfg(windows)], and both kinds run in CI.
    • Locally: socket 12, ssh_tunnel 25, pool_manager 94 passed. The full lib has 1938 passed; the 5 Windows-only path tests also fail on main.
  • Vitest: the feat(connections): Unix socket support — dialed locally or through the SSH tunnel #492 tests (unixSocketPathIssue, effectiveLocalSocketPath, labels, validation, the endpoint switch in the modal), plus ?socket= parsing and hasUnixSockets.
    • Full suite: 402 files / 6892 tests.
  • pnpm lint (eslint, prettier --check, theme tokens) and tsc -b are clean. Rustfmt is clean on the changed code; the remaining cargo fmt --check diffs are already on main.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QF7qKtRn5r6CrdDoU7ZmvY

debba and others added 3 commits October 21, 2026 21:49
… SSH tunnel

Port of TabularisDB#492 onto current main. A single optional `unix_socket_path` on
the connection: dialed locally by the MySQL and PostgreSQL drivers
instead of host:port, or by the SSH server (direct-streamlocal / ssh -L
port:/path) when the tunnel is enabled. Gated by the new `unix_socket`
driver capability; the Kubernetes tunnel ignores it.

Adapted while porting (markankamaransheogarat-sys):
- SshTunnel::new_with_tcp_override (SSH-scope proxy) takes the forward
  destination instead of remote host/port, so the proxy keeps working
- the AWS SSM tunnel, added since, clears the socket path like K8s
- a direct socket connection skips the database-scope proxy
- build_postgres_configurations returns Result on main; the socket branch
  is unix-only (tokio_postgres has no host_path on Windows) and Windows
  gets a clear error, as for MySQL
- build_mysql_options keeps main's IAM/cleartext rules and adds the
  socket as an endpoint with TLS forced off
- the UI is placed in main's connection form next to the plugin
  host/port field overrides

Co-Authored-By: markankamaransheogarat-sys <279850453+markankamaransheogarat-sys@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF7qKtRn5r6CrdDoU7ZmvY
The two locales were added after TabularisDB#492 was written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF7qKtRn5r6CrdDoU7ZmvY
… more socket tests (TabularisDB#1002)

On top of the TabularisDB#492 port, the parts of TabularisDB#1002 it did not cover:
- mysql://user@host/db?socket=/path connection strings import as a
  socket connection (unix_socket_path)
- the local socket endpoint is hidden on Windows (hasUnixSockets); a
  socket reached through the SSH tunnel stays available there, since the
  SSH server dials it, and the backend rejects a local socket on Windows
  with a clear error for MySQL and PostgreSQL
- AWS IAM authentication is rejected over a local socket
- tests: parser (?socket=, percent-encoding, blank, other drivers),
  hasUnixSockets, IAM rejection, Windows rejection

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF7qKtRn5r6CrdDoU7ZmvY
Comment thread src/utils/connections.ts
* @param params - Connection parameters (any object carrying the three fields)
* @returns The trimmed socket path, or null when none applies
*/
/**

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.

WARNING: hasUnixSockets was inserted between the effectiveLocalSocketPath JSDoc and its function

The doc block above (lines 181-188, "The local Unix socket path in effect for a connection...") now sits directly before the hasUnixSockets JSDoc, so effectiveLocalSocketPath (below hasUnixSockets) has no documentation and an orphaned doc block precedes an unrelated function. Move hasUnixSockets (with its JSDoc) above the effectiveLocalSocketPath doc block, or below effectiveLocalSocketPath.

Comment thread src/utils/connections.ts Outdated

const socketPath = effectiveLocalSocketPath(params);
if (socketPath) {
return `${socketPath}/${params.database}`;

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.

SUGGESTION: Socket display string reads as a filesystem path

${socketPath}/${params.database} produces e.g. /tmp/mysql.sock/mydb, which looks like a path inside the socket file. connectionSubtitle uses socketPath · db for the same case. Consider a distinct, unambiguous format (e.g. socket:/tmp/mysql.sock/mydb) so the label is not mistaken for a path and stays consistent with the pool key's socket:<path> convention.

Comment thread src/utils/connectionStringParser.ts Outdated
// `mysql://root@localhost/db?socket=/tmp/mysql.sock`: the socket replaces
// host:port (the host is kept so the form can switch back).
const unix_socket_path =
resolved.id === 'mysql' ? url.searchParams.get('socket')?.trim() || undefined : undefined;

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.

SUGGESTION: ?socket= import is hardcoded to the driver id mysql

resolved.id === 'mysql' ignores ?socket= for any other MySQL-dialect or unix_socket-capable driver that owns the mysql/mariadb scheme (e.g. a MariaDB plugin), even though the rest of the PR gates the feature on the unix_socket capability. .rules/plugins.md asks for capabilities over driver ids; consider checking the driver's unix_socket capability / sql_dialect === 'mysql' here (the modal already does this at importingMysql).

connection_uri_in_keychain: false,
// `?socket=` switches the form to the socket endpoint; a string
// without it goes back to host and port.
unix_socket_path: parsed.unix_socket_path,

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.

WARNING: Imported ?socket= can be saved while the socket UI is hidden (Windows)

On Windows hasUnixSockets() is false, so canUseSocket/socketMode are false (unless SSH is on) and the host/port inputs are shown, but this line still writes the imported unix_socket_path into formData. It is then persisted and sent to the backend, where local_unix_socket_path() is set and build_mysql_options returns "Unix socket connections are not supported on Windows" - with no visible field the user can edit to fix it, and host/port are silently ignored. Drop the parsed socket when !hasUnixSockets() (and no SSH), or clear unix_socket_path when the socket endpoint is not selectable.

Comment thread src/i18n/locales/en.json Outdated
"socketPathForwardActive": "The SSH server connects to this socket instead of Host and Port. A database on a socket cannot negotiate TLS, so it is turned off; the SSH tunnel still encrypts the whole path.",
"socketPathNotAbsolute": "Enter an absolute path, as it appears on the machine that connects to the socket.",
"socketPathDirectory": "Point at the socket file itself, not the directory holding it.",
"socketPathTunnel": "Not used while a Kubernetes tunnel is enabled.",

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.

SUGGESTION: newConnection.socketPathTunnel is never used

The key is added to all 11 locales but nothing in src/ references it (the endpoint selector is hidden while K8s is enabled, so the message is never rendered). Either render it where the socket is ignored or drop the key from every locale.

@kilo-code-bot

kilo-code-bot Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (16 files in this increment)
  • src/components/modals/NewConnectionModal.tsx - imported ?socket= is now only applied when the socket field is available
  • src/utils/connectionStringParser.ts - ?socket= import now follows the unix_socket capability instead of the mysql id
  • src/utils/connections.ts - JSDoc restored to effectiveLocalSocketPath; socket display string is now path (db)
  • src/i18n/locales/*.json (11 files) - unused newConnection.socketPathTunnel removed
  • tests/utils/connectionStringParser.test.ts, tests/utils/connections.test.ts - updated and extended for the changes above

Notes: The latest commit resolves all five earlier findings, and the changed code raises no new issues. No code was run (read-only mode).

Previous Review Summaries (2 snapshots, latest commit 96af7ee)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 96af7ee)

Status: 5 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 3
Issue Details (click to expand)

WARNING

File Line Issue
src/utils/connections.ts 189 hasUnixSockets was inserted between the effectiveLocalSocketPath JSDoc and its function, leaving that function undocumented and an orphaned doc block before an unrelated one
src/components/modals/NewConnectionModal.tsx 2587 An imported ?socket= is written to the form even where the socket UI is hidden (Windows without SSH). It is saved and the backend then rejects it, with no visible field to fix

SUGGESTION

File Line Issue
src/utils/connections.ts 232 formatConnectionString renders a socket as /path/to.sock/db, which reads like a path inside the socket file
src/utils/connectionStringParser.ts 380 ?socket= import is gated on the hardcoded id mysql, not on the unix_socket capability or MySQL dialect
src/i18n/locales/en.json 1312 newConnection.socketPathTunnel is added to all locales but never used
Files Reviewed (1 file in this increment)
  • src/components/modals/NewConnectionModal.tsx - 1 issue (carried forward)

Notes: The latest commit only swaps text-amber-500 for the text-accent-warning token on the socket path hints and raises no new issues. The four earlier findings in unchanged files were re-checked against current code and are still present. No code was run (read-only mode).

Fix these issues in Kilo Cloud

Previous review (commit 5f47447)

Status: 5 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 3
Issue Details (click to expand)

WARNING

File Line Issue
src/utils/connections.ts 189 hasUnixSockets was inserted between the effectiveLocalSocketPath JSDoc and its function, leaving that function undocumented and an orphaned doc block before an unrelated one
src/components/modals/NewConnectionModal.tsx 2587 An imported ?socket= is written to the form even where the socket UI is hidden (Windows without SSH). It is saved and the backend then rejects it, with no visible field to fix

SUGGESTION

File Line Issue
src/utils/connections.ts 232 formatConnectionString renders a socket as /path/to.sock/db, which reads like a path inside the socket file
src/utils/connectionStringParser.ts 380 ?socket= import is gated on the hardcoded id mysql, not on the unix_socket capability or MySQL dialect
src/i18n/locales/en.json 1312 newConnection.socketPathTunnel is added to all locales but never used
Files Reviewed (33 files)
  • src-tauri/src/commands.rs
  • src-tauri/src/drivers/driver_trait.rs
  • src-tauri/src/drivers/mysql/mod.rs
  • src-tauri/src/drivers/postgres/mod.rs
  • src-tauri/src/drivers/sqlite/mod.rs
  • src-tauri/src/models.rs
  • src-tauri/src/plugins/driver.rs
  • src-tauri/src/pool_manager.rs
  • src-tauri/src/pool_manager_tests.rs
  • src-tauri/src/ssh_tunnel.rs
  • src-tauri/tests/postgres_integration/parity.rs
  • src/components/modals/NewConnectionModal.tsx - 1 issue
  • src/contexts/DatabaseContext.ts
  • src/i18n/locales/*.json (11 locales) - 1 issue
  • src/types/plugins.ts
  • src/utils/connectionStringParser.ts - 1 issue
  • src/utils/connections.ts - 2 issues
  • src/utils/credentials.ts
  • tests/components/modals/NewConnectionModal.test.tsx
  • tests/utils/connectionStringParser.test.ts
  • tests/utils/connections.test.ts

Notes: Rust changes were reviewed by reading only; no tests were run (read-only mode). SSH, K8s and SSM tunnels clear the socket path before the drivers see it, and the pool key and driver options use local_unix_socket_path() consistently.

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-5.5 · Input: 248 · Output: 1.4K · Cached: 197.3K

Review guidance: REVIEW.md from base branch main

@markankamaransheogarat-sys markankamaransheogarat-sys changed the title feat(connections): Unix socket support, locally and through the SSH tunnel (#1002) feat(connections): connect through a Unix socket, locally or over the SSH tunnel (#1002) Oct 21, 2026
…abularisDB#1002)

- keep effectiveLocalSocketPath's JSDoc on the function it documents
- do not import ?socket= where the socket field is hidden (Windows without SSH)
- show a socket connection as `path (db)` instead of `path/db`
- gate ?socket= on the unix_socket capability instead of the driver id
- drop the unused socketPathTunnel string from every locale

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QF7qKtRn5r6CrdDoU7ZmvY

This branch has not been deployed

No deployments
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.

[Feat]: MySQL / MariaDB connection through a local Unix socket

2 participants