Enhance Sandbox Configuration for CI and Testing

- Updated CI workflows to set the YAO_SANDBOX_CONTAINER_USER environment variable, ensuring proper user permissions during sandbox tests.
- Modified the Config struct to include ContainerUser, allowing for user specification in container execution.
- Improved test setup in config_test.go to clear conflicting environment variables, enhancing test reliability.
- Refactored manager_test.go to utilize the new getContainerUser function for consistent user handling across tests.
This commit is contained in:
Max 2026-01-29 20:13:40 +08:00
parent 68fd1919c0
commit b40cea6887
6 changed files with 29 additions and 2 deletions

View file

@ -889,7 +889,10 @@ jobs:
env:
YAO_SANDBOX_WORKSPACE: ${{ runner.temp }}/sandbox/workspace
YAO_SANDBOX_IPC: ${{ runner.temp }}/sandbox/ipc
run: make unit-test-sandbox
run: |
# Use runner's UID:GID to avoid permission issues
export YAO_SANDBOX_CONTAINER_USER="$(id -u):$(id -g)"
make unit-test-sandbox
- name: Codecov Report
uses: codecov/codecov-action@v4

View file

@ -659,7 +659,10 @@ jobs:
env:
YAO_SANDBOX_WORKSPACE: ${{ runner.temp }}/sandbox/workspace
YAO_SANDBOX_IPC: ${{ runner.temp }}/sandbox/ipc
run: make unit-test-sandbox
run: |
# Use runner's UID:GID to match host permissions
export YAO_SANDBOX_CONTAINER_USER="$(id -u):$(id -g)"
make unit-test-sandbox
- name: Codecov Report
uses: codecov/codecov-action@v4

View file

@ -20,6 +20,7 @@ type Config struct {
// 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
ContainerUser string `json:"container_user,omitempty"` // Container user, default: "" (use image default). Set to "0" for root.
}
// DefaultConfig returns a Config with default values
@ -110,4 +111,9 @@ func (c *Config) Init(dataRoot string) {
} else if c.ContainerIPCSocket == "" {
c.ContainerIPCSocket = "/tmp/yao.sock"
}
// Container user (for CI environments with UID mismatch)
if env := os.Getenv("YAO_SANDBOX_CONTAINER_USER"); env != "" {
c.ContainerUser = env
}
}

View file

@ -27,6 +27,10 @@ func TestDefaultConfig(t *testing.T) {
}
func TestConfigInit(t *testing.T) {
// Clear any existing environment variables that might interfere
os.Unsetenv("YAO_SANDBOX_WORKSPACE")
os.Unsetenv("YAO_SANDBOX_IPC")
// Test with dataRoot
cfg := &Config{}
cfg.Init("/tmp/yao-test")

View file

@ -162,6 +162,7 @@ func (m *Manager) createContainer(ctx context.Context, userID, chatID string) (*
Image: m.config.Image,
Cmd: []string{"sleep", "infinity"},
WorkingDir: m.config.ContainerWorkDir,
User: m.config.ContainerUser, // Empty string uses image default
Env: []string{
"YAO_IPC_SOCKET=" + m.config.ContainerIPCSocket,
},

View file

@ -40,6 +40,11 @@ func getTestDirs(prefix string) (string, string, string, error) {
return workspaceRoot, ipcDir, tmpDir, nil
}
// getContainerUser returns the container user from environment variable
func getContainerUser() string {
return os.Getenv("YAO_SANDBOX_CONTAINER_USER")
}
// skipIfNoDocker skips the test if Docker is not available
func skipIfNoDocker(t *testing.T) *Manager {
t.Helper()
@ -57,6 +62,7 @@ func skipIfNoDocker(t *testing.T) *Manager {
IdleTimeout: 1 * time.Minute,
MaxMemory: "512m",
MaxCPU: 0.5,
ContainerUser: getContainerUser(),
}
m, err := NewManager(cfg)
@ -545,6 +551,7 @@ func TestConcurrencyLimit(t *testing.T) {
IdleTimeout: 1 * time.Minute,
MaxMemory: "256m",
MaxCPU: 0.25,
ContainerUser: getContainerUser(),
}
m, err := NewManager(cfg)
@ -674,6 +681,7 @@ func TestCleanup(t *testing.T) {
IdleTimeout: 100 * time.Millisecond, // Very short for testing
MaxMemory: "256m",
MaxCPU: 0.25,
ContainerUser: getContainerUser(),
}
m, err := NewManager(cfg)
@ -748,6 +756,7 @@ func TestManagerWithYaoApp(t *testing.T) {
IdleTimeout: 5 * time.Minute,
MaxMemory: "1g",
MaxCPU: 1.0,
ContainerUser: getContainerUser(),
}
m, err := NewManager(cfg)
@ -836,6 +845,7 @@ func TestEnsureImageAutoPull(t *testing.T) {
IdleTimeout: 1 * time.Minute,
MaxMemory: "128m",
MaxCPU: 0.25,
ContainerUser: getContainerUser(),
}
m, err := NewManager(cfg)