prepare for multi-platform support

This commit is contained in:
criyle 2020-04-24 22:34:50 -04:00
parent 6a9c90cafb
commit 35b0d100ab
9 changed files with 148 additions and 114 deletions

View File

@ -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

View File

@ -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,
}
}

View File

@ -0,0 +1,4 @@
package main
func initEnvPool() {
}

View 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,
}
}

View File

@ -0,0 +1,6 @@
// +build !windows,!linux,!darwin
package main
func initEnvPool() {
}

View File

@ -0,0 +1,4 @@
package main
func initEnvPool() {
}

View File

@ -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
}

View 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
}