@dbx-tools/lakebox 0.9.131 → 0.9.132
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -20
- package/index.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,48 +2,146 @@
|
|
|
2
2
|
|
|
3
3
|
Connect to, provision, and run commands on Databricks Lakeboxes.
|
|
4
4
|
|
|
5
|
-
The package provides the Lakebox REST client, lifecycle convergence, and a
|
|
6
|
-
verified SSH session with pooled native OpenSSH or ssh2 command and forwarding
|
|
7
|
-
transport. It has no AppKit, React, or Lakebase dependency. User accounts,
|
|
8
|
-
resource identity, and services belong to `@dbx-tools/appkit-lakebox`.
|
|
9
|
-
|
|
10
5
|
## Provision a Lakebox
|
|
11
6
|
|
|
12
7
|
```ts
|
|
8
|
+
import { client as authClient } from "@dbx-tools/auth";
|
|
13
9
|
import { LakeboxClient } from "@dbx-tools/lakebox/rest";
|
|
14
10
|
import { ensureLakeboxRunning } from "@dbx-tools/lakebox/lifecycle";
|
|
15
11
|
|
|
16
|
-
const
|
|
12
|
+
const auth = await authClient.createAuthClient({ profile: "MY-PROFILE" });
|
|
13
|
+
const api = new LakeboxClient({
|
|
14
|
+
host: auth.host,
|
|
15
|
+
...(auth.workspaceId ? { workspaceId: auth.workspaceId } : {}),
|
|
16
|
+
authenticate: async (headers) => {
|
|
17
|
+
for (const [name, value] of Object.entries(await auth.headers())) {
|
|
18
|
+
headers.set(name, value);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
});
|
|
17
22
|
const entry = await api.create();
|
|
18
23
|
await api.setIdleTimeout(entry.sandboxId, 3_600);
|
|
19
24
|
const running = await ensureLakeboxRunning(api, entry);
|
|
20
25
|
```
|
|
21
26
|
|
|
22
27
|
`LakeboxClient` accepts any credential object with `host` and
|
|
23
|
-
`authenticate(headers)
|
|
24
|
-
`WorkspaceClient.config
|
|
28
|
+
`authenticate(headers)`. AppKit and the Databricks SDK
|
|
29
|
+
`WorkspaceClient.config` satisfy this contract directly. The example adapts
|
|
30
|
+
`@dbx-tools/auth` for an explicit local profile. Use the app service principal
|
|
31
|
+
for lifecycle calls in a Databricks App.
|
|
32
|
+
|
|
33
|
+
## Connect and run a command
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
Create or load an SSH key, register it with the workspace, verify the gateway
|
|
36
|
+
host key, and close the session when work finishes:
|
|
27
37
|
|
|
28
38
|
```ts
|
|
39
|
+
import { SshKeyStore } from "@dbx-tools/lakebox/key-store";
|
|
40
|
+
import type { LakeboxClient, LakeboxEntry } from "@dbx-tools/lakebox/rest";
|
|
29
41
|
import { SshSession } from "@dbx-tools/lakebox/session";
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const
|
|
43
|
+
export async function runCommand(
|
|
44
|
+
api: LakeboxClient,
|
|
45
|
+
running: LakeboxEntry,
|
|
46
|
+
user: { name: string; home: string },
|
|
47
|
+
): Promise<void> {
|
|
48
|
+
const owner = "my-service";
|
|
49
|
+
const keys = new SshKeyStore();
|
|
50
|
+
const key = await keys.ensureRegistered(api, owner);
|
|
51
|
+
const gatewayHost = running.gatewayHost ?? key.gatewayHost;
|
|
52
|
+
if (!gatewayHost) {
|
|
53
|
+
throw new Error("The Lakebox API did not return an SSH gateway host");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const gatewayPort = 2_222;
|
|
57
|
+
const scope = await api.workspaceScope();
|
|
58
|
+
const knownHost = await keys.knownHost(scope, owner, gatewayHost, gatewayPort);
|
|
59
|
+
const session = new SshSession({
|
|
60
|
+
host: gatewayHost,
|
|
61
|
+
port: gatewayPort,
|
|
62
|
+
username: running.sandboxId,
|
|
63
|
+
privateKey: key.privateKey,
|
|
64
|
+
privateKeyPath: key.privateKeyPath,
|
|
65
|
+
knownHostsPath: keys.knownHostsPath(scope, owner, gatewayHost, gatewayPort),
|
|
66
|
+
connectTimeoutMs: 30_000,
|
|
67
|
+
sshTransport: "auto",
|
|
68
|
+
ssh2Patch: "auto",
|
|
69
|
+
...(knownHost ? { knownHost } : {}),
|
|
70
|
+
rememberHost: (fingerprint, hostKey) =>
|
|
71
|
+
keys.rememberHost(scope, owner, gatewayHost, gatewayPort, fingerprint, hostKey),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
await session.connect();
|
|
76
|
+
const command = session.execute("sh", ["-lc", "uname -a"], {
|
|
77
|
+
user,
|
|
78
|
+
timeoutMs: 30_000,
|
|
79
|
+
});
|
|
80
|
+
const result = await command.result;
|
|
81
|
+
if (!result.success) {
|
|
82
|
+
throw new Error(result.stderr || `Command exited with ${result.exitCode}`);
|
|
83
|
+
}
|
|
84
|
+
} finally {
|
|
85
|
+
await session.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
37
88
|
```
|
|
38
89
|
|
|
39
90
|
Every command clears inherited Databricks credentials and SSH agent variables
|
|
40
|
-
before
|
|
41
|
-
|
|
91
|
+
before it runs. `execute()` returns a live `SshCommand`. Its `stdout` and
|
|
92
|
+
`stderr` fields are async iterables, awaiting the command returns its numeric
|
|
93
|
+
exit code, and `result` returns captured output and timing metadata.
|
|
94
|
+
|
|
95
|
+
The low-level package doesn't create Linux users. Pass an account that already
|
|
96
|
+
exists on the Lakebox. `@dbx-tools/appkit-lakebox` creates and isolates
|
|
97
|
+
application user accounts before it runs their commands.
|
|
98
|
+
|
|
99
|
+
`forwardOut(host, port)` opens a forwarded TCP stream through a separate pool.
|
|
100
|
+
Long-lived HTTP and WebSocket streams don't consume the warm command
|
|
42
101
|
connection.
|
|
43
102
|
|
|
103
|
+
## Stop or delete a Lakebox
|
|
104
|
+
|
|
105
|
+
Use lifecycle convergence when you need to wait for a terminal state:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { ensureLakeboxStopped } from "@dbx-tools/lakebox/lifecycle";
|
|
109
|
+
import type { LakeboxClient, LakeboxEntry } from "@dbx-tools/lakebox/rest";
|
|
110
|
+
|
|
111
|
+
export async function stopAndDelete(api: LakeboxClient, running: LakeboxEntry): Promise<void> {
|
|
112
|
+
const stopped = await ensureLakeboxStopped(api, running);
|
|
113
|
+
await api.delete(stopped.sandboxId);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`stop()` preserves the persistent Lakebox filesystem. `delete()` permanently
|
|
118
|
+
removes the Lakebox and its data.
|
|
119
|
+
|
|
44
120
|
## Configuration
|
|
45
121
|
|
|
46
|
-
| Field
|
|
47
|
-
|
|
|
122
|
+
| Field | Values | Default |
|
|
123
|
+
| -------------- | ------------------------- | ----------------------------------------- |
|
|
48
124
|
| `sshTransport` | `auto`, `openssh`, `ssh2` | `auto` prefers native OpenSSH with SOCKS5 |
|
|
49
|
-
| `ssh2Patch`
|
|
125
|
+
| `ssh2Patch` | `auto`, `true`, `false` | `auto` patches only in development |
|
|
126
|
+
|
|
127
|
+
`SshSessionOptions` also requires the gateway host and port, Lakebox ID as the
|
|
128
|
+
SSH username, private key material, key and known-host paths, and a connection
|
|
129
|
+
timeout. `SshKeyStore` stores keys and gateway fingerprints under
|
|
130
|
+
`~/.dbx-tools/lakebox` unless you pass another root.
|
|
131
|
+
|
|
132
|
+
## Understand lifecycle and transport limits
|
|
133
|
+
|
|
134
|
+
- `ensureLakeboxRunning()` and `ensureLakeboxStopped()` poll for up to five
|
|
135
|
+
minutes.
|
|
136
|
+
- The REST client doesn't map users, persist app resource identity, or manage
|
|
137
|
+
services. Use [@dbx-tools/appkit-lakebox](../appkit-lakebox/README.md) for
|
|
138
|
+
those application-level capabilities.
|
|
139
|
+
- The command pool keeps one tested connection warm and grows to 10
|
|
140
|
+
connections. Forwarding uses a separate pool with no minimum.
|
|
141
|
+
- Each borrowed SSH resource handles one operation and is destroyed after that
|
|
142
|
+
command or forwarded stream. A failed forwarding open retries once with a new
|
|
143
|
+
resource. Established streams and commands aren't replayed.
|
|
144
|
+
- `auto` selects native OpenSSH when it is available and selects ssh2
|
|
145
|
+
otherwise. It doesn't switch transports after a runtime failure.
|
|
146
|
+
- `close()` cancels active commands, closes transport pools, and waits for an
|
|
147
|
+
in-progress connection attempt to settle.
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/lakebox";
|
|
6
|
-
export const PACKAGE_VERSION = "0.9.
|
|
6
|
+
export const PACKAGE_VERSION = "0.9.132";
|
|
7
7
|
export * as keyStore from "./src/key-store.ts";
|
|
8
8
|
export * as lifecycle from "./src/lifecycle.ts";
|
|
9
9
|
export * as rest from "./src/rest.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const PACKAGE_IDENTIFIER = "@dbx-tools/lakebox";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.9.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.9.132";
|
|
3
3
|
export * as keyStore from "./src/key-store.ts";
|
|
4
4
|
export * as lifecycle from "./src/lifecycle.ts";
|
|
5
5
|
export * as rest from "./src/rest.ts";
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Regenerated from the exporting modules in ./src.
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/lakebox";
|
|
5
|
-
export const PACKAGE_VERSION = "0.9.
|
|
5
|
+
export const PACKAGE_VERSION = "0.9.132";
|
|
6
6
|
export * as keyStore from "./src/key-store.js";
|
|
7
7
|
export * as lifecycle from "./src/lifecycle.js";
|
|
8
8
|
export * as rest from "./src/rest.js";
|
|
@@ -12,4 +12,4 @@ export { SshKeyStore } from "./src/key-store.js";
|
|
|
12
12
|
export { LakeboxEntrySchema, LakeboxSshKeySchema, LakeboxApiError, LakeboxClient } from "./src/rest.js";
|
|
13
13
|
export { SshSession } from "./src/session.js";
|
|
14
14
|
export { SshTransportModeSchema, Ssh2PatchModeSchema } from "./src/transport.js";
|
|
15
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxvQkFBb0IsQ0FBQztBQUN2RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxRQUFRLE1BQU0sb0JBQW9CLENBQUM7QUFDL0MsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXhHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU5QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvbGFrZWJveFwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjEzMlwiO1xuZXhwb3J0ICogYXMga2V5U3RvcmUgZnJvbSBcIi4vc3JjL2tleS1zdG9yZS50c1wiO1xuZXhwb3J0ICogYXMgbGlmZWN5Y2xlIGZyb20gXCIuL3NyYy9saWZlY3ljbGUudHNcIjtcbmV4cG9ydCAqIGFzIHJlc3QgZnJvbSBcIi4vc3JjL3Jlc3QudHNcIjtcbmV4cG9ydCAqIGFzIHNlc3Npb24gZnJvbSBcIi4vc3JjL3Nlc3Npb24udHNcIjtcbmV4cG9ydCAqIGFzIHRyYW5zcG9ydCBmcm9tIFwiLi9zcmMvdHJhbnNwb3J0LnRzXCI7XG5leHBvcnQgeyBTc2hLZXlTdG9yZSB9IGZyb20gXCIuL3NyYy9rZXktc3RvcmUudHNcIjtcbmV4cG9ydCB7IExha2Vib3hFbnRyeVNjaGVtYSwgTGFrZWJveFNzaEtleVNjaGVtYSwgTGFrZWJveEFwaUVycm9yLCBMYWtlYm94Q2xpZW50IH0gZnJvbSBcIi4vc3JjL3Jlc3QudHNcIjtcbmV4cG9ydCB0eXBlIHsgTGFrZWJveEVudHJ5LCBMYWtlYm94U3NoS2V5LCBMYWtlYm94QXV0aCB9IGZyb20gXCIuL3NyYy9yZXN0LnRzXCI7XG5leHBvcnQgeyBTc2hTZXNzaW9uIH0gZnJvbSBcIi4vc3JjL3Nlc3Npb24udHNcIjtcbmV4cG9ydCB0eXBlIHsgU3NoU2Vzc2lvbk9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvc2Vzc2lvbi50c1wiO1xuZXhwb3J0IHsgU3NoVHJhbnNwb3J0TW9kZVNjaGVtYSwgU3NoMlBhdGNoTW9kZVNjaGVtYSB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbmV4cG9ydCB0eXBlIHsgU3NoVHJhbnNwb3J0TW9kZSwgU3NoMlBhdGNoTW9kZSB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
|
package/package.json
CHANGED
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"vitest": "3.2.4"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@dbx-tools/core": "^0.9.
|
|
29
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
30
|
-
"@dbx-tools/shared-lakebox": "^0.9.
|
|
28
|
+
"@dbx-tools/core": "^0.9.132",
|
|
29
|
+
"@dbx-tools/shared-core": "^0.9.132",
|
|
30
|
+
"@dbx-tools/shared-lakebox": "^0.9.132",
|
|
31
31
|
"generic-pool": "^3.9.0",
|
|
32
32
|
"socks": "^2.8.10",
|
|
33
33
|
"ssh2": "^1.17.0",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"./package.json": "./package.json"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"version": "0.9.
|
|
74
|
+
"version": "0.9.132",
|
|
75
75
|
"types": "./lib/index.d.ts",
|
|
76
76
|
"dbxToolsConfig": {
|
|
77
77
|
"tags": [
|