67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
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...)
|
|
}
|