mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-09 21:00:56 -07:00
fix: address SandboxManager PR feedback
- docs: Update tools.sandbox configuration type to boolean | string | object - core: Add validation to ConfigSchema requiring a command when sandbox is enabled - core: Remove redundant sandbox defaulting logic from Config constructor - cli: Update LXC removeDevices exit listener to use spawnSync with SIGKILL to prevent hanging processes - core: Integrate NoopSandboxManager into ShellExecutionService to correctly utilize sanitized environment
This commit is contained in:
@@ -469,6 +469,15 @@ export const ConfigSchema = z.object({
|
||||
.optional(),
|
||||
image: z.string().optional(),
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
if (data.enabled && !data.command) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Sandbox command is required when sandbox is enabled',
|
||||
path: ['command'],
|
||||
});
|
||||
}
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
@@ -839,19 +848,7 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
this.embeddingModel =
|
||||
params.embeddingModel ?? DEFAULT_GEMINI_EMBEDDING_MODEL;
|
||||
this.fileSystemService = new StandardFileSystemService();
|
||||
this.sandbox = params.sandbox
|
||||
? {
|
||||
enabled: params.sandbox.enabled ?? false,
|
||||
allowedPaths: params.sandbox.allowedPaths ?? [],
|
||||
networkAccess: params.sandbox.networkAccess ?? false,
|
||||
command: params.sandbox.command,
|
||||
image: params.sandbox.image,
|
||||
}
|
||||
: {
|
||||
enabled: false,
|
||||
allowedPaths: [],
|
||||
networkAccess: false,
|
||||
};
|
||||
this.sandbox = params.sandbox;
|
||||
this.targetDir = path.resolve(params.targetDir);
|
||||
this.folderTrust = params.folderTrust ?? false;
|
||||
this.workspaceContext = new WorkspaceContext(this.targetDir, []);
|
||||
|
||||
@@ -26,10 +26,8 @@ import {
|
||||
serializeTerminalToObject,
|
||||
type AnsiOutput,
|
||||
} from '../utils/terminalSerializer.js';
|
||||
import {
|
||||
sanitizeEnvironment,
|
||||
type EnvironmentSanitizationConfig,
|
||||
} from './environmentSanitization.js';
|
||||
import { sanitizeEnvironment, type EnvironmentSanitizationConfig } from './environmentSanitization.js';
|
||||
import { NoopSandboxManager } from './sandboxManager.js';
|
||||
import { killProcessGroup } from '../utils/process-utils.js';
|
||||
const { Terminal } = pkg;
|
||||
|
||||
@@ -326,6 +324,15 @@ export class ShellExecutionService {
|
||||
shouldUseNodePty: boolean,
|
||||
shellExecutionConfig: ShellExecutionConfig,
|
||||
): Promise<ShellExecutionHandle> {
|
||||
const sandboxManager = new NoopSandboxManager();
|
||||
const { env: sanitizedEnv } = await sandboxManager.prepareCommand({
|
||||
command: commandToExecute,
|
||||
args: [],
|
||||
env: process.env,
|
||||
cwd,
|
||||
config: shellExecutionConfig,
|
||||
});
|
||||
|
||||
if (shouldUseNodePty) {
|
||||
const ptyInfo = await getPty();
|
||||
if (ptyInfo) {
|
||||
@@ -337,6 +344,7 @@ export class ShellExecutionService {
|
||||
abortSignal,
|
||||
shellExecutionConfig,
|
||||
ptyInfo,
|
||||
sanitizedEnv,
|
||||
);
|
||||
} catch (_e) {
|
||||
// Fallback to child_process
|
||||
@@ -695,6 +703,7 @@ export class ShellExecutionService {
|
||||
abortSignal: AbortSignal,
|
||||
shellExecutionConfig: ShellExecutionConfig,
|
||||
ptyInfo: PtyImplementation,
|
||||
sanitizedEnv: Record<string, string | undefined>,
|
||||
): Promise<ShellExecutionHandle> {
|
||||
if (!ptyInfo) {
|
||||
// This should not happen, but as a safeguard...
|
||||
@@ -724,10 +733,7 @@ export class ShellExecutionService {
|
||||
cols,
|
||||
rows,
|
||||
env: {
|
||||
...sanitizeEnvironment(
|
||||
process.env,
|
||||
shellExecutionConfig.sanitizationConfig,
|
||||
),
|
||||
...sanitizedEnv,
|
||||
GEMINI_CLI: '1',
|
||||
TERM: 'xterm-256color',
|
||||
PAGER: shellExecutionConfig.pager ?? 'cat',
|
||||
|
||||
Reference in New Issue
Block a user