Skip to content

Commit 3f43202

Browse files
authored
Internalize dead sbx-manager exports (#6429)
* Initial plan * refactor: internalize sbx-manager test-only helpers --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 14a64fc commit 3f43202

3 files changed

Lines changed: 35 additions & 29 deletions

File tree

src/container-runtime.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { resolveDockerRuntime, runtimeNeedsStaticDns, runtimeUsesComposeAgent, runtimeUsesIptables, isGvisorRuntime } from './container-runtime';
2-
import { sanitizeEnvForSbx } from './sbx-manager';
2+
import { testHelpers } from './sbx-manager';
3+
4+
const { sanitizeEnvForSbx } = testHelpers;
35

46
describe('container-runtime', () => {
57
describe('resolveDockerRuntime', () => {

src/sbx-manager.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import {
33
execInSandbox,
44
isSbxAvailable,
55
removeSandbox,
6-
restoreHomeCredentials,
7-
sanitizeEnvForSbx,
8-
withLocalBinOnPath,
96
SBX_DEFAULT_NAME,
7+
testHelpers,
108
} from './sbx-manager';
119
import * as fs from 'fs';
1210
import { mockExecaFn } from './test-helpers/mock-execa.test-utils';
1311
import { logger } from './logger';
1412

13+
const { restoreHomeCredentials, sanitizeEnvForSbx, withLocalBinOnPath } = testHelpers;
14+
1515
// eslint-disable-next-line @typescript-eslint/no-require-imports
1616
jest.mock('execa', () => require('./test-helpers/mock-execa.test-utils').execaMockFactory());
1717
// eslint-disable-next-line @typescript-eslint/no-require-imports

src/sbx-manager.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,32 +52,12 @@ const SECRET_ENV_PATTERNS = [
5252
/** Default sandbox name (single-sandbox-per-run model). */
5353
export const SBX_DEFAULT_NAME = `${SBX_NAME_PREFIX}-${process.pid}`;
5454

55-
export interface SbxConfig {
56-
/** Sandbox name (defaults to `awf-agent-<pid>`). */
57-
name?: string;
58-
/** Workspace directory to mount into the sandbox. */
59-
workspaceDir: string;
60-
/** Squid proxy IP for DOCKER_SANDBOXES_PROXY. */
61-
squidIp: string;
62-
/** Squid proxy port (default 3128). */
63-
squidPort?: number;
64-
/** Additional workspace mounts (read-only paths). */
65-
extraMounts?: string[];
66-
}
67-
68-
export interface SbxExecOptions {
69-
timeoutMinutes?: number;
70-
workDir?: string;
71-
environment?: Record<string, string>;
72-
tty?: boolean;
73-
}
74-
7555
/**
7656
* Strips secret-bearing env vars from process.env so they never reach
7757
* the sbx CLI or the sandbox interior. Returns a shallow copy with
7858
* only non-secret entries plus any explicit overrides.
7959
*/
80-
export function sanitizeEnvForSbx(
60+
function sanitizeEnvForSbx(
8161
overrides: Record<string, string> = {},
8262
): Record<string, string | undefined> {
8363
const clean: Record<string, string | undefined> = {};
@@ -157,7 +137,7 @@ function scrubHomeCredentials(homePath: string): void {
157137
* MUST run only after the sandbox is removed, because the home dirs are live
158138
* mounts — restoring while the VM is running would re-expose the secrets.
159139
*/
160-
export function restoreHomeCredentials(): void {
140+
function restoreHomeCredentials(): void {
161141
for (const { original, backup } of scrubbedCredentials) {
162142
try {
163143
if (fs.existsSync(backup)) {
@@ -186,7 +166,18 @@ export function restoreHomeCredentials(): void {
186166
* Creates a Docker sbx sandbox with workspace mounts.
187167
* Sets `DOCKER_SANDBOXES_PROXY` to chain all egress through AWF's Squid.
188168
*/
189-
export async function createSandbox(config: SbxConfig): Promise<string> {
169+
export async function createSandbox(config: {
170+
/** Sandbox name (defaults to `awf-agent-<pid>`). */
171+
name?: string;
172+
/** Workspace directory to mount into the sandbox. */
173+
workspaceDir: string;
174+
/** Squid proxy IP for DOCKER_SANDBOXES_PROXY. */
175+
squidIp: string;
176+
/** Squid proxy port (default 3128). */
177+
squidPort?: number;
178+
/** Additional workspace mounts (read-only paths). */
179+
extraMounts?: string[];
180+
}): Promise<string> {
190181
const name = config.name || SBX_DEFAULT_NAME;
191182
const squidPort = config.squidPort || 3128;
192183
const proxyUrl = `http://${config.squidIp}:${squidPort}`;
@@ -356,18 +347,31 @@ export async function createSandbox(config: SbxConfig): Promise<string> {
356347
* resolvable by name. `$HOME` resolves to the injected HOME (getRealUserHome),
357348
* which matches the wholesale-mounted home tool dirs.
358349
*/
359-
export function withLocalBinOnPath(command: string): string {
350+
function withLocalBinOnPath(command: string): string {
360351
return `export PATH="$HOME/.local/bin\${PATH:+:$PATH}"; ${command}`;
361352
}
362353

354+
/** @internal Exposed for unit tests only. */
355+
// ts-prune-ignore-next
356+
export const testHelpers = {
357+
sanitizeEnvForSbx,
358+
restoreHomeCredentials,
359+
withLocalBinOnPath,
360+
};
361+
363362
/**
364363
* Executes a command inside the sandbox, streaming stdout/stderr.
365364
* Returns the exit code of the command.
366365
*/
367366
export async function execInSandbox(
368367
name: string,
369368
command: string,
370-
options?: SbxExecOptions,
369+
options?: {
370+
timeoutMinutes?: number;
371+
workDir?: string;
372+
environment?: Record<string, string>;
373+
tty?: boolean;
374+
},
371375
): Promise<{ exitCode: number }> {
372376
logger.info(`Executing in sandbox "${name}": ${command}`);
373377

0 commit comments

Comments
 (0)