package sandbox import ( "bytes" "fmt" "os/exec" "runtime" "sync" "github.com/ssgo/log" ) var runtimeLocks sync.Map // 锁管理 func getRuntimeLock(language, typ, name string) *sync.Mutex { l, _ := runtimeLocks.LoadOrStore(language+":"+typ+":"+name, &sync.Mutex{}) return l.(*sync.Mutex) } type RuntimeConfig struct { Root string HttpProxy string Mirror string } type RuntimeSandboxConfig struct { StartCmd string Envs map[string]string } type Runtime struct { Check func(runtimePath, venvPath, projectPath string, uid, gid int, cfg *RuntimeConfig) (*RuntimeSandboxConfig, error) } var runtimeList = make(map[string]*Runtime) var runtimeListLock sync.RWMutex func RegisterRuntime(name string, rt *Runtime) { runtimeListLock.Lock() defer runtimeListLock.Unlock() runtimeList[name] = rt } func RunCmdWithEnv(envs map[string]string, cmdDir string, uid, gid int, name string, args ...string) (string, error) { cmd := exec.Command(name, args...) cmd.Dir = cmdDir for k, v := range envs { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v)) } var out bytes.Buffer cmd.Stdout = &out cmd.Stderr = &out if runtime.GOOS == "linux" && uid > 0 { applyCredential(cmd, uid, gid) } err := cmd.Run() if err != nil { log.DefaultLogger.Error("[Sandbox] RunCmd failed "+err.Error(), "name", name, "args", args) } return out.String(), err } func RunCmd(cmdDir string, uid, gid int, name string, args ...string) (string, error) { return RunCmdWithEnv(nil, cmdDir, uid, gid, name, args...) }