Enhance Config and Manager for Container Path Management
- Added ContainerWorkDir and ContainerIPCSocket fields to the Config struct for better container path configuration. - Updated DefaultConfig to initialize new fields with default values. - Modified the Manager to apply defaults for container paths and utilize them in container creation and execution methods, improving flexibility and reliability in container management.
This commit is contained in:
parent
1ece4b0f48
commit
0394727f29
2 changed files with 59 additions and 14 deletions
|
|
@ -16,16 +16,22 @@ type Config struct {
|
|||
IdleTimeout time.Duration `json:"idle_timeout,omitempty"` // Idle timeout before stopping container
|
||||
MaxMemory string `json:"max_memory,omitempty"` // Memory limit, e.g., "2g"
|
||||
MaxCPU float64 `json:"max_cpu,omitempty"` // CPU limit, e.g., 1.0
|
||||
|
||||
// Container internal paths
|
||||
ContainerWorkDir string `json:"container_workdir,omitempty"` // Container working directory, default: /workspace
|
||||
ContainerIPCSocket string `json:"container_ipc_socket,omitempty"` // Container IPC socket path, default: /tmp/yao.sock
|
||||
}
|
||||
|
||||
// DefaultConfig returns a Config with default values
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Image: "yaoapp/sandbox-claude:latest",
|
||||
MaxContainers: 100,
|
||||
IdleTimeout: 30 * time.Minute,
|
||||
MaxMemory: "2g",
|
||||
MaxCPU: 1.0,
|
||||
Image: "yaoapp/sandbox-claude:latest",
|
||||
MaxContainers: 100,
|
||||
IdleTimeout: 30 * time.Minute,
|
||||
MaxMemory: "2g",
|
||||
MaxCPU: 1.0,
|
||||
ContainerWorkDir: "/workspace",
|
||||
ContainerIPCSocket: "/tmp/yao.sock",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,4 +97,17 @@ func (c *Config) Init(dataRoot string) {
|
|||
}
|
||||
// Invalid env value: keep existing/default value
|
||||
}
|
||||
|
||||
// Container internal paths
|
||||
if env := os.Getenv("YAO_SANDBOX_CONTAINER_WORKDIR"); env != "" {
|
||||
c.ContainerWorkDir = env
|
||||
} else if c.ContainerWorkDir == "" {
|
||||
c.ContainerWorkDir = "/workspace"
|
||||
}
|
||||
|
||||
if env := os.Getenv("YAO_SANDBOX_CONTAINER_IPC"); env != "" {
|
||||
c.ContainerIPCSocket = env
|
||||
} else if c.ContainerIPCSocket == "" {
|
||||
c.ContainerIPCSocket = "/tmp/yao.sock"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ func NewManager(config *Config) (*Manager, error) {
|
|||
config = DefaultConfig()
|
||||
}
|
||||
|
||||
// Apply defaults for missing container paths
|
||||
if config.ContainerWorkDir == "" {
|
||||
config.ContainerWorkDir = "/workspace"
|
||||
}
|
||||
if config.ContainerIPCSocket == "" {
|
||||
config.ContainerIPCSocket = "/tmp/yao.sock"
|
||||
}
|
||||
|
||||
// Initialize Docker client
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
|
|
@ -153,18 +161,23 @@ func (m *Manager) createContainer(ctx context.Context, userID, chatID string) (*
|
|||
containerConfig := &container.Config{
|
||||
Image: m.config.Image,
|
||||
Cmd: []string{"sleep", "infinity"},
|
||||
WorkingDir: "/workspace",
|
||||
WorkingDir: m.config.ContainerWorkDir,
|
||||
Env: []string{
|
||||
"YAO_IPC_SOCKET=/tmp/yao.sock",
|
||||
"YAO_IPC_SOCKET=" + m.config.ContainerIPCSocket,
|
||||
},
|
||||
}
|
||||
|
||||
// Host configuration
|
||||
// Host configuration - only mount IPC socket if it exists
|
||||
binds := []string{
|
||||
workspaceHost + ":" + m.config.ContainerWorkDir,
|
||||
}
|
||||
// Only mount IPC socket if the file exists (it's created by IPC manager)
|
||||
if _, err := os.Stat(ipcSocketHost); err == nil {
|
||||
binds = append(binds, ipcSocketHost+":"+m.config.ContainerIPCSocket)
|
||||
}
|
||||
|
||||
hostConfig := &container.HostConfig{
|
||||
Binds: []string{
|
||||
workspaceHost + ":/workspace",
|
||||
ipcSocketHost + ":/tmp/yao.sock",
|
||||
},
|
||||
Binds: binds,
|
||||
Resources: container.Resources{
|
||||
Memory: parseMemory(m.config.MaxMemory),
|
||||
NanoCPUs: int64(m.config.MaxCPU * 1e9),
|
||||
|
|
@ -342,7 +355,7 @@ func (m *Manager) Exec(ctx context.Context, name string, cmd []string, opts *Exe
|
|||
|
||||
// Default options
|
||||
if opts.WorkDir == "" {
|
||||
opts.WorkDir = "/workspace"
|
||||
opts.WorkDir = m.config.ContainerWorkDir
|
||||
}
|
||||
|
||||
// Create exec instance
|
||||
|
|
@ -544,9 +557,22 @@ func (m *Manager) WriteFile(ctx context.Context, name, path string, content []by
|
|||
// Ensure parent directory exists
|
||||
dir := filepath.Dir(path)
|
||||
if dir != "/" && dir != "." {
|
||||
if _, err := m.Exec(ctx, name, []string{"mkdir", "-p", dir}, nil); err != nil {
|
||||
result, err := m.Exec(ctx, name, []string{"mkdir", "-p", dir}, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create parent directory: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("mkdir failed with exit code %d: %s", result.ExitCode, result.Stdout)
|
||||
}
|
||||
|
||||
// Verify directory was created
|
||||
verifyResult, err := m.Exec(ctx, name, []string{"test", "-d", dir}, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to verify directory: %w", err)
|
||||
}
|
||||
if verifyResult.ExitCode != 0 {
|
||||
return fmt.Errorf("directory %s was not created", dir)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a tar archive with the file
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue