diff --git a/.agents/skills/onboard-team-area/SKILL.md b/.agents/skills/onboard-team-area/SKILL.md
index c7bc9165147..0edce8d66b7 100644
--- a/.agents/skills/onboard-team-area/SKILL.md
+++ b/.agents/skills/onboard-team-area/SKILL.md
@@ -60,5 +60,5 @@ No `.nextchanges/` entry; this is ownership/config only. Write the PR using the
## Experimental vs stable, and graduation
-- **Experimental** — code under `experimental//`, tests under `acceptance/experimental//`. Register it under the hidden parent in `cmd/experimental/experimental.go`, or top-level in `cmd/cmd.go` with `Hidden: true` (as `ssh` does). Experimental commands still ship enabled in every release; `Hidden` only removes them from `--help`, it does not gate or compile them out. No `.nextchanges/` entries while experimental. To hand a build to testers, push a `bugbash-` branch (auto-builds a snapshot) and share the `internal/bugbash/exec.sh` one-liner.
+- **Experimental** — code under `experimental//`, tests under `acceptance/experimental//`. Register it under the hidden parent in `cmd/experimental/experimental.go`, or top-level in `cmd/cmd.go` with `Hidden: true` (as `sandbox` does). Experimental commands still ship enabled in every release; `Hidden` only removes them from `--help`, it does not gate or compile them out. No `.nextchanges/` entries while experimental. To hand a build to testers, push a `bugbash-` branch (auto-builds a snapshot) and share the `internal/bugbash/exec.sh` one-liner.
- **Graduating to stable** — `git mv` the feature-complete commands to `cmd//` + `libs//`, register them top-level in `cmd/cmd.go`, keep the old `experimental` paths as deprecated cobra aliases (`sub.Hidden = true`, `sub.Deprecated = '...'`), add OWNERS rules for the new stable paths, and add a `.nextchanges/` entry. See `experimental/aitools` graduating to top-level `aitools` (PR #4917) as the worked example.
diff --git a/.agents/skills/pr-checklist/SKILL.md b/.agents/skills/pr-checklist/SKILL.md
index 7da1560a156..0fbdf7f5fb6 100644
--- a/.agents/skills/pr-checklist/SKILL.md
+++ b/.agents/skills/pr-checklist/SKILL.md
@@ -23,9 +23,9 @@ Before submitting a PR, run these commands to match what CI checks. CI uses the
# 5. If you changed files in python/:
./task pydabs-codegen pydabs-test pydabs-lint pydabs-docs
-# 6. If you changed cmd/aitools/, libs/aitools/, experimental/aitools/, or experimental/ssh/:
+# 6. If you changed cmd/aitools/, libs/aitools/, experimental/aitools/, or cmd/ssh/:
./task test-exp-aitools # only if aitools code changed (top-level or experimental)
-./task test-exp-ssh # only if ssh code changed
+./task test-ssh # only if ssh code changed
```
## Final cleanup scan
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index b4c5238326b..88093ed8e62 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -245,14 +245,14 @@ jobs:
run: |
go tool -modfile=tools/task/go.mod task test-exp-aitools
- test-exp-ssh:
+ test-ssh:
needs:
- cleanups
- testmask
# Only run if the target is in the list of targets from testmask
- if: ${{ contains(fromJSON(needs.testmask.outputs.targets), 'test-exp-ssh') }}
- name: "task test-exp-ssh (${{matrix.os.name}})"
+ if: ${{ contains(fromJSON(needs.testmask.outputs.targets), 'test-ssh') }}
+ name: "task test-ssh (${{matrix.os.name}})"
runs-on: ${{ matrix.os.runner }}
defaults:
@@ -291,7 +291,7 @@ jobs:
- name: Setup build environment
uses: ./.github/actions/setup-build-environment
with:
- cache-key: test-exp-ssh
+ cache-key: test-ssh
# The ssh acceptance test drives a real sshd behind the tunnel; the runner
# ships only the client. Install it on Linux (the OS the test is gated to);
@@ -302,7 +302,7 @@ jobs:
- name: Run tests
run: |
- go tool -modfile=tools/task/go.mod task test-exp-ssh
+ go tool -modfile=tools/task/go.mod task test-ssh
test-pipelines:
needs:
@@ -421,7 +421,7 @@ jobs:
needs:
- test
- test-exp-aitools
- - test-exp-ssh
+ - test-ssh
- test-pipelines
- test-sandbox
@@ -504,7 +504,7 @@ jobs:
- name: Generate GitHub App Token (check runs)
if: >-
(github.event_name == 'merge_group') ||
- (github.event_name == 'pull_request' && !contains(fromJSON(needs.testmask.outputs.targets), 'test') && !contains(fromJSON(needs.testmask.outputs.targets), 'test-exp-ssh'))
+ (github.event_name == 'pull_request' && !contains(fromJSON(needs.testmask.outputs.targets), 'test') && !contains(fromJSON(needs.testmask.outputs.targets), 'test-ssh'))
id: generate-check-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
@@ -517,7 +517,7 @@ jobs:
# Skip integration tests if the primary "test" target is not triggered by this change.
# Use Checks API (not Statuses API) to match the required "Integration Tests" check.
- name: Skip integration tests (pull request)
- if: ${{ github.event_name == 'pull_request' && !contains(fromJSON(needs.testmask.outputs.targets), 'test') && !contains(fromJSON(needs.testmask.outputs.targets), 'test-exp-ssh') }}
+ if: ${{ github.event_name == 'pull_request' && !contains(fromJSON(needs.testmask.outputs.targets), 'test') && !contains(fromJSON(needs.testmask.outputs.targets), 'test-ssh') }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.generate-check-token.outputs.token }}
@@ -563,7 +563,7 @@ jobs:
- testmask
if: >-
- (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && (contains(fromJSON(needs.testmask.outputs.targets), 'test') || contains(fromJSON(needs.testmask.outputs.targets), 'test-exp-ssh'))) ||
+ (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && (contains(fromJSON(needs.testmask.outputs.targets), 'test') || contains(fromJSON(needs.testmask.outputs.targets), 'test-ssh'))) ||
(github.event_name == 'push')
runs-on:
diff --git a/.nextchanges/cli/ssh-out-of-experimental.md b/.nextchanges/cli/ssh-out-of-experimental.md
new file mode 100644
index 00000000000..2463e4f97b2
--- /dev/null
+++ b/.nextchanges/cli/ssh-out-of-experimental.md
@@ -0,0 +1 @@
+The `databricks ssh` command group is no longer experimental and now appears in `databricks --help`.
diff --git a/Taskfile.yml b/Taskfile.yml
index 8ed24ad0f60..201cd1c48d9 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -7,7 +7,7 @@ vars:
# Pinned ruff (linter + formatter). Keep in sync with the version in
# .github/workflows/check.yml and python/Taskfile.yml.
RUFF: uvx ruff@0.15.17
- TEST_PACKAGES: ./acceptance/internal ./libs/... ./internal/... ./cmd/... ./bundle/... ./experimental/ssh/... .
+ TEST_PACKAGES: ./acceptance/internal ./libs/... ./internal/... ./cmd/... ./bundle/... .
ACCEPTANCE_TEST_FILTER: ""
# Single brace-expansion glob covering every //go:embed target in the repo,
# computed by grepping `//go:embed` directives. Evaluated lazily by Task so
@@ -675,10 +675,10 @@ tasks:
--packages ./acceptance/... \
-- -timeout=${LOCAL_TIMEOUT:-60m} -run "TestAccept/(apps|experimental/aitools)"
- test-exp-ssh:
- desc: Run experimental SSH unit and acceptance tests
+ test-ssh:
+ desc: Run SSH unit and acceptance tests
sources:
- - experimental/ssh/**
+ - cmd/ssh/**
- acceptance/ssh/**
- "{{.EMBED_SOURCES}}"
cmds:
@@ -686,7 +686,7 @@ tasks:
{{.GO_TOOL}} gotestsum \
--format ${GOTESTSUM_FORMAT:-pkgname-and-test-fails} \
--no-summary=skipped \
- --packages ./experimental/ssh/... \
+ --packages ./cmd/ssh/... \
-- -timeout=${LOCAL_TIMEOUT:-60m}
- |
{{.GO_TOOL}} gotestsum \
diff --git a/acceptance/help/output.txt b/acceptance/help/output.txt
index 266e1227c48..539163382e9 100644
--- a/acceptance/help/output.txt
+++ b/acceptance/help/output.txt
@@ -183,6 +183,7 @@ Additional Commands:
help Help about any command
labs Manage Databricks Labs installations
quickstart Print an introduction to the Databricks CLI
+ ssh Connect to your Databricks compute and workspace via SSH
version Retrieve information about the current version of this CLI
Flags:
diff --git a/acceptance/ssh/connect-serverless-cpu/script b/acceptance/ssh/connect-serverless-cpu/script
index 40bbb6debc2..85b0e6e73f0 100644
--- a/acceptance/ssh/connect-serverless-cpu/script
+++ b/acceptance/ssh/connect-serverless-cpu/script
@@ -9,7 +9,7 @@ if [ -n "${CLOUD_ENV:-}" ]; then
else
# Local: the test server backs the /ssh websocket with a real sshd, so this
# asserts the bootstrap job plus a full handshake over the tunnel. Skip when
- # sshd is absent (only task test-exp-ssh provisions it).
+ # sshd is absent (only task test-ssh provisions it).
if [ -z "$(command -v sshd || ls /usr/sbin/sshd /usr/local/sbin/sshd /sbin/sshd 2>/dev/null)" ]; then
echo "SKIP_TEST sshd (openssh-server) not installed"
exit 0
diff --git a/acceptance/ssh/connect-serverless-gpu/script b/acceptance/ssh/connect-serverless-gpu/script
index 0943ec9d2b7..9e53e8f7a38 100644
--- a/acceptance/ssh/connect-serverless-gpu/script
+++ b/acceptance/ssh/connect-serverless-gpu/script
@@ -18,7 +18,7 @@ if [ -n "${CLOUD_ENV:-}" ]; then
else
# No compute locally: the test server backs the driver-proxy /ssh websocket with a
# real sshd, so this one run asserts both the bootstrap job and a full handshake +
- # remote exec over the ws:// tunnel. Needs sshd (only task test-exp-ssh provisions
+ # remote exec over the ws:// tunnel. Needs sshd (only task test-ssh provisions
# it); the test server probes the same way, so skip where it's absent.
if [ -z "$(command -v sshd || ls /usr/sbin/sshd /usr/local/sbin/sshd /sbin/sshd 2>/dev/null)" ]; then
echo "SKIP_TEST sshd (openssh-server) not installed"
diff --git a/acceptance/ssh/connect-serverless-gpu/test.toml b/acceptance/ssh/connect-serverless-gpu/test.toml
index 9ab5c69e8a2..6612907c32b 100644
--- a/acceptance/ssh/connect-serverless-gpu/test.toml
+++ b/acceptance/ssh/connect-serverless-gpu/test.toml
@@ -11,7 +11,7 @@ Ignore = [
]
# Linux-only: the local run drives a real sshd, reliable only there (and where
-# task test-exp-ssh provisions it). Absent GOOS keys default to enabled, so the
+# task test-ssh provisions it). Absent GOOS keys default to enabled, so the
# other OSes must be disabled explicitly.
GOOS.linux = true
GOOS.darwin = false
diff --git a/acceptance/ssh/connection/script b/acceptance/ssh/connection/script
index c69babb6dd0..d8becdbadcd 100644
--- a/acceptance/ssh/connection/script
+++ b/acceptance/ssh/connection/script
@@ -18,7 +18,7 @@ if [ -n "${CLOUD_ENV:-}" ]; then
else
# No compute locally: the test server backs the driver-proxy /ssh websocket with a
# real sshd, so this one run asserts both the bootstrap job and a full handshake +
- # remote exec over the ws:// tunnel. Needs sshd (only task test-exp-ssh provisions
+ # remote exec over the ws:// tunnel. Needs sshd (only task test-ssh provisions
# it); the test server probes the same way, so skip where it's absent.
if [ -z "$(command -v sshd || ls /usr/sbin/sshd /usr/local/sbin/sshd /sbin/sshd 2>/dev/null)" ]; then
echo "SKIP_TEST sshd (openssh-server) not installed"
diff --git a/acceptance/ssh/connection/test.toml b/acceptance/ssh/connection/test.toml
index 3f67650471d..c9eef1892a7 100644
--- a/acceptance/ssh/connection/test.toml
+++ b/acceptance/ssh/connection/test.toml
@@ -12,7 +12,7 @@ Ignore = [
]
# Linux-only: the local run drives a real sshd, reliable only there (and where
-# task test-exp-ssh provisions it). Absent GOOS keys default to enabled, so the
+# task test-ssh provisions it). Absent GOOS keys default to enabled, so the
# other OSes must be disabled explicitly.
GOOS.linux = true
GOOS.darwin = false
diff --git a/cmd/cmd.go b/cmd/cmd.go
index a2c3280b940..54b15ea7c57 100644
--- a/cmd/cmd.go
+++ b/cmd/cmd.go
@@ -6,7 +6,7 @@ import (
aitoolscmd "github.com/databricks/cli/cmd/aitools"
"github.com/databricks/cli/cmd/psql"
- ssh "github.com/databricks/cli/experimental/ssh/cmd"
+ "github.com/databricks/cli/cmd/ssh"
"github.com/databricks/cli/cmd/account"
"github.com/databricks/cli/cmd/api"
diff --git a/experimental/ssh/CLAUDE.md b/cmd/ssh/CLAUDE.md
similarity index 98%
rename from experimental/ssh/CLAUDE.md
rename to cmd/ssh/CLAUDE.md
index 222439b1f69..f7fb8ceb5a9 100644
--- a/experimental/ssh/CLAUDE.md
+++ b/cmd/ssh/CLAUDE.md
@@ -1,4 +1,4 @@
-# Working on `experimental/ssh`
+# Working on `cmd/ssh`
This file provides guidance to AI assistants working on the SSH tunnel. See the
repository root `CLAUDE.md` for project-wide rules.
diff --git a/experimental/ssh/FAILURE_MODES.md b/cmd/ssh/FAILURE_MODES.md
similarity index 99%
rename from experimental/ssh/FAILURE_MODES.md
rename to cmd/ssh/FAILURE_MODES.md
index 717de265b1b..973038633eb 100644
--- a/experimental/ssh/FAILURE_MODES.md
+++ b/cmd/ssh/FAILURE_MODES.md
@@ -154,5 +154,5 @@ The proxy-layer behaviors have unit tests that don't need a cluster:
(state message, error trace, run-page URL) using SDK mocks.
```shell
-go test ./experimental/ssh/...
+go test ./cmd/ssh/...
```
diff --git a/experimental/ssh/README.md b/cmd/ssh/README.md
similarity index 100%
rename from experimental/ssh/README.md
rename to cmd/ssh/README.md
diff --git a/experimental/ssh/bench.sh b/cmd/ssh/bench.sh
similarity index 94%
rename from experimental/ssh/bench.sh
rename to cmd/ssh/bench.sh
index 466e2104c07..583b82d5440 100755
--- a/experimental/ssh/bench.sh
+++ b/cmd/ssh/bench.sh
@@ -3,7 +3,7 @@
# SSH Tunnel Performance Test Script
# Usage:
# 1. Setup ssh config: ./cli ssh setup --cluster --name
-# 2. Run: ./experimental/ssh/bench.sh [ssh-tunnel-binary-path] [profile]
+# 2. Run: ./cmd/ssh/bench.sh [ssh-tunnel-binary-path] [profile]
set -e
diff --git a/experimental/ssh/cmd/connect.go b/cmd/ssh/connect.go
similarity index 99%
rename from experimental/ssh/cmd/connect.go
rename to cmd/ssh/connect.go
index 7502d70f560..aec55e7ad3a 100644
--- a/experimental/ssh/cmd/connect.go
+++ b/cmd/ssh/connect.go
@@ -4,7 +4,7 @@ import (
"time"
"github.com/databricks/cli/cmd/root"
- "github.com/databricks/cli/experimental/ssh/internal/client"
+ "github.com/databricks/cli/cmd/ssh/internal/client"
"github.com/databricks/cli/libs/cmdctx"
"github.com/spf13/cobra"
)
diff --git a/experimental/ssh/cmd/constants.go b/cmd/ssh/constants.go
similarity index 100%
rename from experimental/ssh/cmd/constants.go
rename to cmd/ssh/constants.go
diff --git a/experimental/ssh/internal/client/client.go b/cmd/ssh/internal/client/client.go
similarity index 99%
rename from experimental/ssh/internal/client/client.go
rename to cmd/ssh/internal/client/client.go
index 031bbd4d7af..1efeb2ec9f3 100644
--- a/experimental/ssh/internal/client/client.go
+++ b/cmd/ssh/internal/client/client.go
@@ -20,11 +20,11 @@ import (
"syscall"
"time"
- "github.com/databricks/cli/experimental/ssh/internal/keys"
- "github.com/databricks/cli/experimental/ssh/internal/proxy"
- "github.com/databricks/cli/experimental/ssh/internal/sshconfig"
- "github.com/databricks/cli/experimental/ssh/internal/vscode"
- sshWorkspace "github.com/databricks/cli/experimental/ssh/internal/workspace"
+ "github.com/databricks/cli/cmd/ssh/internal/keys"
+ "github.com/databricks/cli/cmd/ssh/internal/proxy"
+ "github.com/databricks/cli/cmd/ssh/internal/sshconfig"
+ "github.com/databricks/cli/cmd/ssh/internal/vscode"
+ sshWorkspace "github.com/databricks/cli/cmd/ssh/internal/workspace"
"github.com/databricks/cli/internal/build"
"github.com/databricks/cli/libs/auth"
"github.com/databricks/cli/libs/cmdio"
diff --git a/experimental/ssh/internal/client/client_internal_test.go b/cmd/ssh/internal/client/client_internal_test.go
similarity index 99%
rename from experimental/ssh/internal/client/client_internal_test.go
rename to cmd/ssh/internal/client/client_internal_test.go
index cb47cd71bb8..ad553bcf08c 100644
--- a/experimental/ssh/internal/client/client_internal_test.go
+++ b/cmd/ssh/internal/client/client_internal_test.go
@@ -11,7 +11,7 @@ import (
"testing"
"time"
- "github.com/databricks/cli/experimental/ssh/internal/sshconfig"
+ "github.com/databricks/cli/cmd/ssh/internal/sshconfig"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/telemetry/protos"
"github.com/databricks/databricks-sdk-go/experimental/mocks"
diff --git a/experimental/ssh/internal/client/client_test.go b/cmd/ssh/internal/client/client_test.go
similarity index 99%
rename from experimental/ssh/internal/client/client_test.go
rename to cmd/ssh/internal/client/client_test.go
index 09fd1067d4f..8e0c27cb5db 100644
--- a/experimental/ssh/internal/client/client_test.go
+++ b/cmd/ssh/internal/client/client_test.go
@@ -7,7 +7,7 @@ import (
"testing"
"time"
- "github.com/databricks/cli/experimental/ssh/internal/client"
+ "github.com/databricks/cli/cmd/ssh/internal/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
diff --git a/experimental/ssh/internal/client/policy_internal_test.go b/cmd/ssh/internal/client/policy_internal_test.go
similarity index 100%
rename from experimental/ssh/internal/client/policy_internal_test.go
rename to cmd/ssh/internal/client/policy_internal_test.go
diff --git a/experimental/ssh/internal/client/releases.go b/cmd/ssh/internal/client/releases.go
similarity index 99%
rename from experimental/ssh/internal/client/releases.go
rename to cmd/ssh/internal/client/releases.go
index 141b4def5fd..23f4b2e020a 100644
--- a/experimental/ssh/internal/client/releases.go
+++ b/cmd/ssh/internal/client/releases.go
@@ -15,7 +15,7 @@ import (
"syscall"
"time"
- "github.com/databricks/cli/experimental/ssh/internal/workspace"
+ "github.com/databricks/cli/cmd/ssh/internal/workspace"
"github.com/databricks/cli/libs/filer"
"github.com/databricks/cli/libs/log"
"github.com/databricks/databricks-sdk-go"
diff --git a/experimental/ssh/internal/client/releases_test.go b/cmd/ssh/internal/client/releases_test.go
similarity index 100%
rename from experimental/ssh/internal/client/releases_test.go
rename to cmd/ssh/internal/client/releases_test.go
diff --git a/experimental/ssh/internal/client/ssh-server-bootstrap.py b/cmd/ssh/internal/client/ssh-server-bootstrap.py
similarity index 100%
rename from experimental/ssh/internal/client/ssh-server-bootstrap.py
rename to cmd/ssh/internal/client/ssh-server-bootstrap.py
diff --git a/experimental/ssh/internal/client/submit_internal_test.go b/cmd/ssh/internal/client/submit_internal_test.go
similarity index 100%
rename from experimental/ssh/internal/client/submit_internal_test.go
rename to cmd/ssh/internal/client/submit_internal_test.go
diff --git a/experimental/ssh/internal/client/websockets.go b/cmd/ssh/internal/client/websockets.go
similarity index 100%
rename from experimental/ssh/internal/client/websockets.go
rename to cmd/ssh/internal/client/websockets.go
diff --git a/experimental/ssh/internal/client/websockets_test.go b/cmd/ssh/internal/client/websockets_test.go
similarity index 100%
rename from experimental/ssh/internal/client/websockets_test.go
rename to cmd/ssh/internal/client/websockets_test.go
diff --git a/experimental/ssh/internal/fileutil/backup.go b/cmd/ssh/internal/fileutil/backup.go
similarity index 100%
rename from experimental/ssh/internal/fileutil/backup.go
rename to cmd/ssh/internal/fileutil/backup.go
diff --git a/experimental/ssh/internal/fileutil/backup_test.go b/cmd/ssh/internal/fileutil/backup_test.go
similarity index 97%
rename from experimental/ssh/internal/fileutil/backup_test.go
rename to cmd/ssh/internal/fileutil/backup_test.go
index 7101fd3afc0..e7825ad9dc6 100644
--- a/experimental/ssh/internal/fileutil/backup_test.go
+++ b/cmd/ssh/internal/fileutil/backup_test.go
@@ -7,7 +7,7 @@ import (
"runtime"
"testing"
- "github.com/databricks/cli/experimental/ssh/internal/fileutil"
+ "github.com/databricks/cli/cmd/ssh/internal/fileutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
diff --git a/experimental/ssh/internal/keys/keys.go b/cmd/ssh/internal/keys/keys.go
similarity index 100%
rename from experimental/ssh/internal/keys/keys.go
rename to cmd/ssh/internal/keys/keys.go
diff --git a/experimental/ssh/internal/keys/keys_test.go b/cmd/ssh/internal/keys/keys_test.go
similarity index 97%
rename from experimental/ssh/internal/keys/keys_test.go
rename to cmd/ssh/internal/keys/keys_test.go
index 68054311f8c..b753d477b80 100644
--- a/experimental/ssh/internal/keys/keys_test.go
+++ b/cmd/ssh/internal/keys/keys_test.go
@@ -5,7 +5,7 @@ import (
"path/filepath"
"testing"
- "github.com/databricks/cli/experimental/ssh/internal/keys"
+ "github.com/databricks/cli/cmd/ssh/internal/keys"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
diff --git a/experimental/ssh/internal/keys/secrets.go b/cmd/ssh/internal/keys/secrets.go
similarity index 100%
rename from experimental/ssh/internal/keys/secrets.go
rename to cmd/ssh/internal/keys/secrets.go
diff --git a/experimental/ssh/internal/proxy/client.go b/cmd/ssh/internal/proxy/client.go
similarity index 100%
rename from experimental/ssh/internal/proxy/client.go
rename to cmd/ssh/internal/proxy/client.go
diff --git a/experimental/ssh/internal/proxy/client_server_test.go b/cmd/ssh/internal/proxy/client_server_test.go
similarity index 100%
rename from experimental/ssh/internal/proxy/client_server_test.go
rename to cmd/ssh/internal/proxy/client_server_test.go
diff --git a/experimental/ssh/internal/proxy/connections.go b/cmd/ssh/internal/proxy/connections.go
similarity index 100%
rename from experimental/ssh/internal/proxy/connections.go
rename to cmd/ssh/internal/proxy/connections.go
diff --git a/experimental/ssh/internal/proxy/connections_test.go b/cmd/ssh/internal/proxy/connections_test.go
similarity index 100%
rename from experimental/ssh/internal/proxy/connections_test.go
rename to cmd/ssh/internal/proxy/connections_test.go
diff --git a/experimental/ssh/internal/proxy/keepalive_test.go b/cmd/ssh/internal/proxy/keepalive_test.go
similarity index 100%
rename from experimental/ssh/internal/proxy/keepalive_test.go
rename to cmd/ssh/internal/proxy/keepalive_test.go
diff --git a/experimental/ssh/internal/proxy/proxy.go b/cmd/ssh/internal/proxy/proxy.go
similarity index 100%
rename from experimental/ssh/internal/proxy/proxy.go
rename to cmd/ssh/internal/proxy/proxy.go
diff --git a/experimental/ssh/internal/proxy/proxy_test.go b/cmd/ssh/internal/proxy/proxy_test.go
similarity index 100%
rename from experimental/ssh/internal/proxy/proxy_test.go
rename to cmd/ssh/internal/proxy/proxy_test.go
diff --git a/experimental/ssh/internal/proxy/server.go b/cmd/ssh/internal/proxy/server.go
similarity index 100%
rename from experimental/ssh/internal/proxy/server.go
rename to cmd/ssh/internal/proxy/server.go
diff --git a/experimental/ssh/internal/server/jupyter-init.py b/cmd/ssh/internal/server/jupyter-init.py
similarity index 100%
rename from experimental/ssh/internal/server/jupyter-init.py
rename to cmd/ssh/internal/server/jupyter-init.py
diff --git a/experimental/ssh/internal/server/logs.go b/cmd/ssh/internal/server/logs.go
similarity index 100%
rename from experimental/ssh/internal/server/logs.go
rename to cmd/ssh/internal/server/logs.go
diff --git a/experimental/ssh/internal/server/logs_test.go b/cmd/ssh/internal/server/logs_test.go
similarity index 100%
rename from experimental/ssh/internal/server/logs_test.go
rename to cmd/ssh/internal/server/logs_test.go
diff --git a/experimental/ssh/internal/server/server.go b/cmd/ssh/internal/server/server.go
similarity index 98%
rename from experimental/ssh/internal/server/server.go
rename to cmd/ssh/internal/server/server.go
index 4356700d87d..5f561cb2737 100644
--- a/experimental/ssh/internal/server/server.go
+++ b/cmd/ssh/internal/server/server.go
@@ -17,8 +17,8 @@ import (
"path/filepath"
"time"
- "github.com/databricks/cli/experimental/ssh/internal/proxy"
- "github.com/databricks/cli/experimental/ssh/internal/workspace"
+ "github.com/databricks/cli/cmd/ssh/internal/proxy"
+ "github.com/databricks/cli/cmd/ssh/internal/workspace"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/log"
"github.com/databricks/databricks-sdk-go"
diff --git a/experimental/ssh/internal/server/server_test.go b/cmd/ssh/internal/server/server_test.go
similarity index 100%
rename from experimental/ssh/internal/server/server_test.go
rename to cmd/ssh/internal/server/server_test.go
diff --git a/experimental/ssh/internal/server/sshd.go b/cmd/ssh/internal/server/sshd.go
similarity index 98%
rename from experimental/ssh/internal/server/sshd.go
rename to cmd/ssh/internal/server/sshd.go
index 01fd0e3cdb0..bcf5893df2e 100644
--- a/experimental/ssh/internal/server/sshd.go
+++ b/cmd/ssh/internal/server/sshd.go
@@ -12,7 +12,7 @@ import (
"strconv"
"strings"
- "github.com/databricks/cli/experimental/ssh/internal/keys"
+ "github.com/databricks/cli/cmd/ssh/internal/keys"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/log"
"github.com/databricks/databricks-sdk-go"
diff --git a/experimental/ssh/internal/server/sshd_test.go b/cmd/ssh/internal/server/sshd_test.go
similarity index 100%
rename from experimental/ssh/internal/server/sshd_test.go
rename to cmd/ssh/internal/server/sshd_test.go
diff --git a/experimental/ssh/internal/setup/setup.go b/cmd/ssh/internal/setup/setup.go
similarity index 95%
rename from experimental/ssh/internal/setup/setup.go
rename to cmd/ssh/internal/setup/setup.go
index 286ab7be7a7..d98a6d7d947 100644
--- a/experimental/ssh/internal/setup/setup.go
+++ b/cmd/ssh/internal/setup/setup.go
@@ -6,9 +6,9 @@ import (
"fmt"
"time"
- sshclient "github.com/databricks/cli/experimental/ssh/internal/client"
- "github.com/databricks/cli/experimental/ssh/internal/keys"
- "github.com/databricks/cli/experimental/ssh/internal/sshconfig"
+ sshclient "github.com/databricks/cli/cmd/ssh/internal/client"
+ "github.com/databricks/cli/cmd/ssh/internal/keys"
+ "github.com/databricks/cli/cmd/ssh/internal/sshconfig"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/compute"
diff --git a/experimental/ssh/internal/setup/setup_test.go b/cmd/ssh/internal/setup/setup_test.go
similarity index 99%
rename from experimental/ssh/internal/setup/setup_test.go
rename to cmd/ssh/internal/setup/setup_test.go
index 9b3267c6b62..d7e4662f553 100644
--- a/experimental/ssh/internal/setup/setup_test.go
+++ b/cmd/ssh/internal/setup/setup_test.go
@@ -8,7 +8,7 @@ import (
"testing"
"time"
- "github.com/databricks/cli/experimental/ssh/internal/client"
+ "github.com/databricks/cli/cmd/ssh/internal/client"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/experimental/mocks"
diff --git a/experimental/ssh/internal/sshconfig/sshconfig.go b/cmd/ssh/internal/sshconfig/sshconfig.go
similarity index 99%
rename from experimental/ssh/internal/sshconfig/sshconfig.go
rename to cmd/ssh/internal/sshconfig/sshconfig.go
index fbbf3b42fee..cc900115da4 100644
--- a/experimental/ssh/internal/sshconfig/sshconfig.go
+++ b/cmd/ssh/internal/sshconfig/sshconfig.go
@@ -9,7 +9,7 @@ import (
"path/filepath"
"strings"
- "github.com/databricks/cli/experimental/ssh/internal/fileutil"
+ "github.com/databricks/cli/cmd/ssh/internal/fileutil"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/env"
)
diff --git a/experimental/ssh/internal/sshconfig/sshconfig_test.go b/cmd/ssh/internal/sshconfig/sshconfig_test.go
similarity index 100%
rename from experimental/ssh/internal/sshconfig/sshconfig_test.go
rename to cmd/ssh/internal/sshconfig/sshconfig_test.go
diff --git a/experimental/ssh/internal/vscode/run.go b/cmd/ssh/internal/vscode/run.go
similarity index 100%
rename from experimental/ssh/internal/vscode/run.go
rename to cmd/ssh/internal/vscode/run.go
diff --git a/experimental/ssh/internal/vscode/run_test.go b/cmd/ssh/internal/vscode/run_test.go
similarity index 100%
rename from experimental/ssh/internal/vscode/run_test.go
rename to cmd/ssh/internal/vscode/run_test.go
diff --git a/experimental/ssh/internal/vscode/settings.go b/cmd/ssh/internal/vscode/settings.go
similarity index 99%
rename from experimental/ssh/internal/vscode/settings.go
rename to cmd/ssh/internal/vscode/settings.go
index 5b4a0bc34fc..29448c1fc75 100644
--- a/experimental/ssh/internal/vscode/settings.go
+++ b/cmd/ssh/internal/vscode/settings.go
@@ -11,7 +11,7 @@ import (
"runtime"
"strings"
- "github.com/databricks/cli/experimental/ssh/internal/fileutil"
+ "github.com/databricks/cli/cmd/ssh/internal/fileutil"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/log"
diff --git a/experimental/ssh/internal/vscode/settings_test.go b/cmd/ssh/internal/vscode/settings_test.go
similarity index 99%
rename from experimental/ssh/internal/vscode/settings_test.go
rename to cmd/ssh/internal/vscode/settings_test.go
index 9ec36ec7364..e8e054aa265 100644
--- a/experimental/ssh/internal/vscode/settings_test.go
+++ b/cmd/ssh/internal/vscode/settings_test.go
@@ -9,7 +9,7 @@ import (
"runtime"
"testing"
- "github.com/databricks/cli/experimental/ssh/internal/fileutil"
+ "github.com/databricks/cli/cmd/ssh/internal/fileutil"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/env"
"github.com/stretchr/testify/assert"
diff --git a/experimental/ssh/internal/workspace/workspace.go b/cmd/ssh/internal/workspace/workspace.go
similarity index 100%
rename from experimental/ssh/internal/workspace/workspace.go
rename to cmd/ssh/internal/workspace/workspace.go
diff --git a/experimental/ssh/cmd/server.go b/cmd/ssh/server.go
similarity index 98%
rename from experimental/ssh/cmd/server.go
rename to cmd/ssh/server.go
index 3675a4a7fe8..85e56c9001b 100644
--- a/experimental/ssh/cmd/server.go
+++ b/cmd/ssh/server.go
@@ -4,7 +4,7 @@ import (
"time"
"github.com/databricks/cli/cmd/root"
- "github.com/databricks/cli/experimental/ssh/internal/server"
+ "github.com/databricks/cli/cmd/ssh/internal/server"
"github.com/databricks/cli/libs/cmdctx"
"github.com/spf13/cobra"
)
diff --git a/experimental/ssh/cmd/setup.go b/cmd/ssh/setup.go
similarity index 97%
rename from experimental/ssh/cmd/setup.go
rename to cmd/ssh/setup.go
index ff67501445e..5478ea11d49 100644
--- a/experimental/ssh/cmd/setup.go
+++ b/cmd/ssh/setup.go
@@ -4,7 +4,7 @@ import (
"time"
"github.com/databricks/cli/cmd/root"
- "github.com/databricks/cli/experimental/ssh/internal/setup"
+ "github.com/databricks/cli/cmd/ssh/internal/setup"
"github.com/databricks/cli/libs/cmdctx"
"github.com/spf13/cobra"
)
diff --git a/experimental/ssh/cmd/ssh.go b/cmd/ssh/ssh.go
similarity index 87%
rename from experimental/ssh/cmd/ssh.go
rename to cmd/ssh/ssh.go
index 9939d2f7050..ae73d5251a2 100644
--- a/experimental/ssh/cmd/ssh.go
+++ b/cmd/ssh/ssh.go
@@ -6,9 +6,8 @@ import (
func New() *cobra.Command {
cmd := &cobra.Command{
- Use: "ssh",
- Short: "Connect to your Databricks compute and workspace via SSH",
- Hidden: true,
+ Use: "ssh",
+ Short: "Connect to your Databricks compute and workspace via SSH",
Long: `Connect to your Databricks compute and workspace via SSH.
Common workflows:
diff --git a/libs/process/group.go b/libs/process/group.go
index 24b3e289dd0..309a8cb8fca 100644
--- a/libs/process/group.go
+++ b/libs/process/group.go
@@ -4,6 +4,6 @@ import "time"
// processGroupGracePeriod bounds how long WithProcessGroup waits after the
// context is cancelled before escalating to SIGKILL. It mirrors the 10s grace
-// period used elsewhere for subprocess termination (see experimental/ssh). It is
+// period used elsewhere for subprocess termination (see cmd/ssh). It is
// a var, not a const, only so the escalation test can shorten it.
var processGroupGracePeriod = 10 * time.Second
diff --git a/libs/testserver/ssh.go b/libs/testserver/ssh.go
index 0cb7eef8846..1a8f9dff408 100644
--- a/libs/testserver/ssh.go
+++ b/libs/testserver/ssh.go
@@ -29,7 +29,7 @@ func sshTunnelRemoteUser() string {
}
// sshClientPublicKeySecretKey is the secret the CLI stores its authorized public key
-// under (mirrors clientPublicKeyName in experimental/ssh); sshd authorizes it below.
+// under (mirrors clientPublicKeyName in cmd/ssh); sshd authorizes it below.
const sshClientPublicKeySecretKey = "client-public-key"
var sshTunnelUpgrader = websocket.Upgrader{}
diff --git a/ruff.toml b/ruff.toml
index db6ffa98604..c9a97b217ed 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -64,5 +64,5 @@ exclude = [
[lint.per-file-ignores]
# dbutils and spark are injected into the global namespace by the Databricks
# runtime where these scripts execute; they are never imported.
-"experimental/ssh/internal/client/ssh-server-bootstrap.py" = ["F821"]
+"cmd/ssh/internal/client/ssh-server-bootstrap.py" = ["F821"]
"acceptance/dbr_runner.py" = ["F821"]
diff --git a/tools/testmask/targets.go b/tools/testmask/targets.go
index bb0dcbfe1bf..d7064394a4d 100644
--- a/tools/testmask/targets.go
+++ b/tools/testmask/targets.go
@@ -14,7 +14,7 @@ import (
// trigger set for their corresponding CI job of the same name.
var ciTargets = []string{
"test-exp-aitools",
- "test-exp-ssh",
+ "test-ssh",
"test-pipelines",
"test-sandbox",
}
diff --git a/tools/testmask/targets_test.go b/tools/testmask/targets_test.go
index b2b058fc59d..07e34056f4f 100644
--- a/tools/testmask/targets_test.go
+++ b/tools/testmask/targets_test.go
@@ -17,12 +17,12 @@ func TestGetTargets(t *testing.T) {
targets []string
}{
{
- name: "experimental_ssh",
+ name: "ssh",
files: []string{
- "experimental/ssh/main.go",
- "experimental/ssh/lib/server.go",
+ "cmd/ssh/main.go",
+ "cmd/ssh/lib/server.go",
},
- targets: []string{"test-exp-ssh"},
+ targets: []string{"test-ssh"},
},
{
name: "pipelines",
@@ -59,29 +59,29 @@ func TestGetTargets(t *testing.T) {
files: []string{
"go.mod",
},
- targets: []string{"test", "test-exp-aitools", "test-exp-ssh", "test-pipelines", "test-sandbox"},
+ targets: []string{"test", "test-exp-aitools", "test-pipelines", "test-sandbox", "test-ssh"},
},
{
name: "go_sum_triggers_all",
files: []string{
"go.sum",
},
- targets: []string{"test", "test-exp-aitools", "test-exp-ssh", "test-pipelines", "test-sandbox"},
+ targets: []string{"test", "test-exp-aitools", "test-pipelines", "test-sandbox", "test-ssh"},
},
{
name: "go_mod_with_other_files_triggers_all",
files: []string{
- "experimental/ssh/main.go",
+ "cmd/ssh/main.go",
"go.mod",
},
- targets: []string{"test", "test-exp-aitools", "test-exp-ssh", "test-pipelines", "test-sandbox"},
+ targets: []string{"test", "test-exp-aitools", "test-pipelines", "test-sandbox", "test-ssh"},
},
{
name: "setup_build_environment_triggers_all",
files: []string{
".github/actions/setup-build-environment/action.yml",
},
- targets: []string{"test", "test-exp-aitools", "test-exp-ssh", "test-pipelines", "test-sandbox"},
+ targets: []string{"test", "test-exp-aitools", "test-pipelines", "test-sandbox", "test-ssh"},
},
{
name: "empty_files",