mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-12 22:14:22 +00:00
fix(cliproxy): add session check on delete and atomic settings writes
- Block variant deletion when CLIProxy has active sessions - Use temp file + rename pattern for atomic settings writes - Prevents partial writes on crash/interruption
This commit is contained in:
1 parent
6ff17d8480
commit
74868972dd
2 files changed
+26
-9
No files matched your search
@@ -15,7 +15,7 @@ import { loadOrCreateUnifiedConfig } from '../../config/unified-config-loader';
|
|||||||
import { DEFAULT_BACKEND } from '../platform-detector';
|
import { DEFAULT_BACKEND } from '../platform-detector';
|
||||||
import { isUnifiedMode } from '../../config/unified-config-loader';
|
import { isUnifiedMode } from '../../config/unified-config-loader';
|
||||||
import { deleteConfigForPort } from '../config-generator';
|
import { deleteConfigForPort } from '../config-generator';
|
||||||
import { deleteSessionLockForPort } from '../session-tracker';
|
import { hasActiveSessions, deleteSessionLockForPort } from '../session-tracker';
|
||||||
import { warn } from '../../utils/ui';
|
import { warn } from '../../utils/ui';
|
||||||
import {
|
import {
|
||||||
createSettingsFile,
|
createSettingsFile,
|
||||||
@@ -154,6 +154,22 @@ export function createVariant(
|
|||||||
*/
|
*/
|
||||||
export function removeVariant(name: string): VariantOperationResult {
|
export function removeVariant(name: string): VariantOperationResult {
|
||||||
try {
|
try {
|
||||||
|
// First check if variant exists and has active sessions
|
||||||
|
const variants = listVariantsFromConfig();
|
||||||
|
const existingVariant = variants[name];
|
||||||
|
|
||||||
|
if (!existingVariant) {
|
||||||
|
return { success: false, error: `Variant '${name}' not found` };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for active sessions on this variant's port before deletion
|
||||||
|
if (existingVariant.port && hasActiveSessions(existingVariant.port)) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: `Cannot delete variant '${name}': CLIProxy is running with active sessions. Stop the session first.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let variant: VariantConfig | null;
|
let variant: VariantConfig | null;
|
||||||
|
|
||||||
if (isUnifiedMode()) {
|
if (isUnifiedMode()) {
|
||||||
@@ -179,11 +195,7 @@ export function removeVariant(name: string): VariantOperationResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variant) {
|
return { success: true, variant: variant ?? undefined };
|
||||||
return { success: false, error: `Variant '${name}' not found` };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, variant };
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { success: false, error: (error as Error).message };
|
return { success: false, error: (error as Error).message };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,10 +63,13 @@ function ensureDir(dir: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write settings file atomically
|
* Write settings file atomically using temp file + rename.
|
||||||
|
* The renameSync is atomic on POSIX systems, preventing partial writes on crash.
|
||||||
*/
|
*/
|
||||||
function writeSettings(filePath: string, settings: SettingsFile): void {
|
function writeSettings(filePath: string, settings: SettingsFile): void {
|
||||||
fs.writeFileSync(filePath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
const tempPath = `${filePath}.tmp.${process.pid}`;
|
||||||
|
fs.writeFileSync(tempPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
||||||
|
fs.renameSync(tempPath, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -248,7 +251,9 @@ export function updateSettingsModel(settingsPath: string, model: string): void {
|
|||||||
delete (settings.env as unknown as Record<string, string>).ANTHROPIC_MODEL;
|
delete (settings.env as unknown as Record<string, string>).ANTHROPIC_MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(resolvedPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
const tempPath = `${resolvedPath}.tmp.${process.pid}`;
|
||||||
|
fs.writeFileSync(tempPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
||||||
|
fs.renameSync(tempPath, resolvedPath);
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore errors - settings file may be invalid
|
// Ignore errors - settings file may be invalid
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user