mirror of
https://github.com/criyle/go-judge.git
synced 2025-09-26 22:39:12 +08:00
prepare for multi-platform support
This commit is contained in:
parent
6a9c90cafb
commit
35b0d100ab
@ -5,14 +5,7 @@ import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/criyle/go-judge/pkg/pool"
|
||||
"github.com/criyle/go-sandbox/container"
|
||||
"github.com/criyle/go-sandbox/pkg/cgroup"
|
||||
"github.com/criyle/go-sandbox/pkg/forkexec"
|
||||
)
|
||||
|
||||
type initParameter struct {
|
||||
@ -53,42 +46,7 @@ func Init(i *C.char) C.int {
|
||||
os.MkdirAll(ip.Dir, 0755)
|
||||
fs = newFileLocalStore(ip.Dir)
|
||||
}
|
||||
|
||||
root, err := ioutil.TempDir("", "dm")
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
mb, err := parseMountConfig(ip.MountConf)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return -1
|
||||
}
|
||||
mb = getDefaultMount()
|
||||
}
|
||||
m, err := mb.Build(true)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
unshareFlags := uintptr(forkexec.UnshareFlags)
|
||||
if ip.NetShare {
|
||||
unshareFlags ^= syscall.CLONE_NEWNET
|
||||
}
|
||||
|
||||
b := &container.Builder{
|
||||
Root: root,
|
||||
Mounts: m,
|
||||
CloneFlags: unshareFlags,
|
||||
ExecFile: ip.CInitPath,
|
||||
}
|
||||
cgb, err := cgroup.NewBuilder("executorserver").WithCPUAcct().WithMemory().WithPids().FilterByEnv()
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
cgroupPool := pool.NewFakeCgroupPool(cgb)
|
||||
envPool = pool.NewEnvPool(b, cgroupPool)
|
||||
initEnvPool()
|
||||
|
||||
startWorkers()
|
||||
return 0
|
||||
|
@ -4,17 +4,10 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
|
||||
"github.com/criyle/go-judge/pkg/envexec"
|
||||
"github.com/criyle/go-judge/pkg/pool"
|
||||
"github.com/criyle/go-sandbox/container"
|
||||
"github.com/criyle/go-sandbox/pkg/cgroup"
|
||||
"github.com/criyle/go-sandbox/pkg/forkexec"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -34,10 +27,6 @@ var (
|
||||
printLog = log.Println
|
||||
)
|
||||
|
||||
func init() {
|
||||
container.Init()
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
@ -51,46 +40,7 @@ func main() {
|
||||
printLog = func(v ...interface{}) {}
|
||||
}
|
||||
|
||||
root, err := ioutil.TempDir("", "dm")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Created tmp dir for container root at:", root)
|
||||
|
||||
mb, err := parseMountConfig(*mountConf)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Use the default container mount")
|
||||
mb = getDefaultMount()
|
||||
}
|
||||
m, err := mb.Build(true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Created container mount at:", mb)
|
||||
|
||||
unshareFlags := uintptr(forkexec.UnshareFlags)
|
||||
if *netShare {
|
||||
unshareFlags ^= syscall.CLONE_NEWNET
|
||||
}
|
||||
|
||||
b := &container.Builder{
|
||||
Root: root,
|
||||
Mounts: m,
|
||||
CredGenerator: newCredGen(),
|
||||
Stderr: true,
|
||||
CloneFlags: unshareFlags,
|
||||
}
|
||||
cgb, err := cgroup.NewBuilder("executorserver").WithCPUAcct().WithMemory().WithPids().FilterByEnv()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Created cgroup builder with:", cgb)
|
||||
|
||||
cgroupPool := pool.NewFakeCgroupPool(cgb)
|
||||
envPool = pool.NewEnvPool(b, cgroupPool)
|
||||
initEnvPool()
|
||||
|
||||
printLog("Starting worker with parallism", *parallism)
|
||||
startWorkers()
|
||||
@ -114,19 +64,3 @@ func main() {
|
||||
printLog("Starting http server at", *addr)
|
||||
r.Run(*addr)
|
||||
}
|
||||
|
||||
type credGen struct {
|
||||
cur uint32
|
||||
}
|
||||
|
||||
func newCredGen() *credGen {
|
||||
return &credGen{cur: 10000}
|
||||
}
|
||||
|
||||
func (c *credGen) Get() syscall.Credential {
|
||||
n := atomic.AddUint32(&c.cur, 1)
|
||||
return syscall.Credential{
|
||||
Uid: n,
|
||||
Gid: n,
|
||||
}
|
||||
}
|
||||
|
4
cmd/executorserver/main_darwin.go
Normal file
4
cmd/executorserver/main_darwin.go
Normal file
@ -0,0 +1,4 @@
|
||||
package main
|
||||
|
||||
func initEnvPool() {
|
||||
}
|
77
cmd/executorserver/main_linux.go
Normal file
77
cmd/executorserver/main_linux.go
Normal file
@ -0,0 +1,77 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
|
||||
"github.com/criyle/go-judge/pkg/pool"
|
||||
"github.com/criyle/go-sandbox/container"
|
||||
"github.com/criyle/go-sandbox/pkg/cgroup"
|
||||
"github.com/criyle/go-sandbox/pkg/forkexec"
|
||||
)
|
||||
|
||||
func init() {
|
||||
container.Init()
|
||||
}
|
||||
|
||||
func initEnvPool() {
|
||||
root, err := ioutil.TempDir("", "executorserver")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Created tmp dir for container root at:", root)
|
||||
|
||||
mb, err := parseMountConfig(*mountConf)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Use the default container mount")
|
||||
mb = getDefaultMount()
|
||||
}
|
||||
m, err := mb.Build(true)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Created container mount at:", mb)
|
||||
|
||||
unshareFlags := uintptr(forkexec.UnshareFlags)
|
||||
if *netShare {
|
||||
unshareFlags ^= syscall.CLONE_NEWNET
|
||||
}
|
||||
|
||||
b := &container.Builder{
|
||||
Root: root,
|
||||
Mounts: m,
|
||||
CredGenerator: newCredGen(),
|
||||
Stderr: true,
|
||||
CloneFlags: unshareFlags,
|
||||
}
|
||||
cgb, err := cgroup.NewBuilder("executorserver").WithCPUAcct().WithMemory().WithPids().FilterByEnv()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
printLog("Created cgroup builder with:", cgb)
|
||||
|
||||
cgroupPool := pool.NewFakeCgroupPool(cgb)
|
||||
envPool = pool.NewEnvPool(b, cgroupPool)
|
||||
}
|
||||
|
||||
type credGen struct {
|
||||
cur uint32
|
||||
}
|
||||
|
||||
func newCredGen() *credGen {
|
||||
return &credGen{cur: 10000}
|
||||
}
|
||||
|
||||
func (c *credGen) Get() syscall.Credential {
|
||||
n := atomic.AddUint32(&c.cur, 1)
|
||||
return syscall.Credential{
|
||||
Uid: n,
|
||||
Gid: n,
|
||||
}
|
||||
}
|
6
cmd/executorserver/main_others.go
Normal file
6
cmd/executorserver/main_others.go
Normal file
@ -0,0 +1,6 @@
|
||||
// +build !windows,!linux,!darwin
|
||||
|
||||
package main
|
||||
|
||||
func initEnvPool() {
|
||||
}
|
4
cmd/executorserver/main_windows.go
Normal file
4
cmd/executorserver/main_windows.go
Normal file
@ -0,0 +1,4 @@
|
||||
package main
|
||||
|
||||
func initEnvPool() {
|
||||
}
|
@ -3,12 +3,16 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var errNotImplemented = errors.New("Memfile open is not defined on this platform")
|
||||
|
||||
func (m *memFile) Open() (*os.File, error) {
|
||||
return nil, errNotImplemented
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go func() {
|
||||
w.Write(m.content)
|
||||
}()
|
||||
return r, nil
|
||||
}
|
||||
|
47
pkg/envexec/file_util_others.go
Normal file
47
pkg/envexec/file_util_others.go
Normal file
@ -0,0 +1,47 @@
|
||||
// +build !linux
|
||||
|
||||
package envexec
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func copyDir(src *os.File, dst string) error {
|
||||
// make sure dir exists
|
||||
os.MkdirAll(dst, 0777)
|
||||
newDir, err := os.Open(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer newDir.Close()
|
||||
|
||||
dir := src
|
||||
names, err := dir.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range names {
|
||||
if copyDirFile(src.Name(), dst, n); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyDirFile(src, dst, name string) error {
|
||||
s, err := os.Open(path.Join(src, name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := os.OpenFile(path.Join(dst, name), os.O_WRONLY, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(t, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user