refactor(*): replace path with file path and normalize error messages

This commit is contained in:
criyle 2025-05-25 22:19:42 -04:00
parent cf2e097a6b
commit 86b85d8556
19 changed files with 297 additions and 61 deletions

View File

@ -71,7 +71,7 @@ func (e *execServer) FileList(c context.Context, n *emptypb.Empty) (*pb.FileList
func (e *execServer) FileGet(c context.Context, f *pb.FileID) (*pb.FileContent, error) { func (e *execServer) FileGet(c context.Context, f *pb.FileID) (*pb.FileContent, error) {
name, file := e.fs.Get(f.GetFileID()) name, file := e.fs.Get(f.GetFileID())
if file == nil { if file == nil {
return nil, status.Errorf(codes.NotFound, "file %v not found", f.GetFileID()) return nil, status.Errorf(codes.NotFound, "file not found: %q", f.GetFileID())
} }
r, err := envexec.FileToReader(file) r, err := envexec.FileToReader(file)
if err != nil { if err != nil {
@ -111,7 +111,7 @@ func (e *execServer) FileAdd(c context.Context, fc *pb.FileContent) (*pb.FileID,
func (e *execServer) FileDelete(c context.Context, f *pb.FileID) (*emptypb.Empty, error) { func (e *execServer) FileDelete(c context.Context, f *pb.FileID) (*emptypb.Empty, error) {
ok := e.fs.Remove(f.GetFileID()) ok := e.fs.Remove(f.GetFileID())
if !ok { if !ok {
return nil, status.Errorf(codes.NotFound, "file id does not exists for %v", f.GetFileID()) return nil, status.Errorf(codes.NotFound, "file id does not exists: %q", f.GetFileID())
} }
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }
@ -241,10 +241,10 @@ func convertPBFile(c *pb.Request_File, srcPrefix []string) (worker.CmdFile, erro
if len(srcPrefix) > 0 { if len(srcPrefix) > 0 {
ok, err := model.CheckPathPrefixes(c.Local.GetSrc(), srcPrefix) ok, err := model.CheckPathPrefixes(c.Local.GetSrc(), srcPrefix)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("check path prefixes: %w", err)
} }
if !ok { if !ok {
return nil, fmt.Errorf("file (%s) does not under (%s)", c.Local.GetSrc(), srcPrefix) return nil, fmt.Errorf("file outside of prefix: %q, %q", c.Local.GetSrc(), srcPrefix)
} }
} }
return &worker.LocalFile{Src: c.Local.GetSrc()}, nil return &worker.LocalFile{Src: c.Local.GetSrc()}, nil
@ -255,7 +255,7 @@ func convertPBFile(c *pb.Request_File, srcPrefix []string) (worker.CmdFile, erro
case *pb.Request_File_Pipe: case *pb.Request_File_Pipe:
return &worker.Collector{Name: c.Pipe.GetName(), Max: envexec.Size(c.Pipe.GetMax()), Pipe: c.Pipe.GetPipe()}, nil return &worker.Collector{Name: c.Pipe.GetName(), Max: envexec.Size(c.Pipe.GetMax()), Pipe: c.Pipe.GetPipe()}, nil
} }
return nil, fmt.Errorf("request file type not supported yet %v", c) return nil, fmt.Errorf("request file type not supported: %T", c)
} }
func convertCopyOut(copyOut []*pb.Request_CmdCopyOutFile) []worker.CmdCopyOutFile { func convertCopyOut(copyOut []*pb.Request_CmdCopyOutFile) []worker.CmdCopyOutFile {

View File

@ -12,7 +12,7 @@ import (
"net/http/pprof" "net/http/pprof"
"os" "os"
"os/signal" "os/signal"
"path" "path/filepath"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"strings" "strings"
@ -465,7 +465,7 @@ func newFilsStore(conf *config.Config) (filestore.FileStore, func() error) {
conf.Dir = os.TempDir() conf.Dir = os.TempDir()
} }
var err error var err error
conf.Dir = path.Join(conf.Dir, "go-judge") conf.Dir = filepath.Join(conf.Dir, "go-judge")
err = os.Mkdir(conf.Dir, os.ModePerm) err = os.Mkdir(conf.Dir, os.ModePerm)
if err != nil && !errors.Is(err, os.ErrExist) { if err != nil && !errors.Is(err, os.ErrExist) {
logger.Fatal("Failed to create file store default dir", zap.Error(err)) logger.Fatal("Failed to create file store default dir", zap.Error(err))

View File

@ -1,7 +1,7 @@
package main package main
import ( import (
"path" "path/filepath"
"time" "time"
"github.com/criyle/go-judge/cmd/go-judge/config" "github.com/criyle/go-judge/cmd/go-judge/config"
@ -89,7 +89,7 @@ func initCgroupMetrics(conf *config.Config, param map[string]any) {
} }
// current cgroup is xxx/api, get the dir // current cgroup is xxx/api, get the dir
prefix = path.Dir(prefix) prefix = filepath.Dir(prefix)
control, err := cgroup.GetAvailableControllerWithPrefix(prefix) control, err := cgroup.GetAvailableControllerWithPrefix(prefix)
if err != nil { if err != nil {
return return
@ -107,7 +107,7 @@ func initCgroupMetrics(conf *config.Config, param map[string]any) {
} }
newCgroupMetrics(apiCg, "controller") newCgroupMetrics(apiCg, "controller")
containersCg, err := cgroup.New(path.Join(prefix, "containers"), control) containersCg, err := cgroup.New(filepath.Join(prefix, "containers"), control)
if err != nil { if err != nil {
return return
} }

View File

@ -97,6 +97,10 @@ func (s Status) MarshalJSON() ([]byte, error) {
// UnmarshalJSON convert string into status // UnmarshalJSON convert string into status
func (s *Status) UnmarshalJSON(b []byte) error { func (s *Status) UnmarshalJSON(b []byte) error {
str := string(b) str := string(b)
if len(str) < 2 || str[0] != '"' || str[len(str)-1] != '"' {
return fmt.Errorf("invalid status string: %s", str)
}
// remove quotes
v, err := envexec.StringToStatus(str[1 : len(str)-1]) v, err := envexec.StringToStatus(str[1 : len(str)-1])
if err != nil { if err != nil {
return err return err
@ -361,7 +365,7 @@ func convertCmdFile(f *CmdFile, srcPrefix []string) (worker.CmdFile, error) {
case f.Max != nil && f.Name != nil: case f.Max != nil && f.Name != nil:
return &worker.Collector{Name: *f.Name, Max: envexec.Size(*f.Max), Pipe: f.Pipe}, nil return &worker.Collector{Name: *f.Name, Max: envexec.Size(*f.Max), Pipe: f.Pipe}, nil
default: default:
return nil, fmt.Errorf("file is not valid for cmd") return nil, fmt.Errorf("file type is not valid for cmd: %v", f)
} }
} }

View File

@ -0,0 +1,229 @@
package model
import (
"encoding/json"
"os"
"path/filepath"
"testing"
"time"
"github.com/criyle/go-judge/worker"
)
func TestStatus_MarshalUnmarshalJSON(t *testing.T) {
type wrap struct {
Status Status `json:"status"`
}
orig := wrap{Status: 1}
data, err := json.Marshal(orig)
if err != nil {
t.Fatalf("Marshal error: %v", err)
}
var got wrap
if err := json.Unmarshal(data, &got); err != nil {
t.Fatalf("Unmarshal error: %v", err)
}
if got.Status != orig.Status {
t.Errorf("got %v, want %v", got.Status, orig.Status)
}
}
func TestStatus_UnmarshalJSON_Invalid(t *testing.T) {
var s Status
err := s.UnmarshalJSON([]byte(`"not_a_status"`))
if err == nil {
t.Error("expected error for invalid status string")
}
}
func TestConvertCopyOut(t *testing.T) {
in := []string{"foo.txt", "bar.txt?"}
out := convertCopyOut(in)
if len(out) != 2 {
t.Fatalf("expected 2, got %d", len(out))
}
if out[0].Name != "foo.txt" || out[0].Optional {
t.Errorf("unexpected: %+v", out[0])
}
if out[1].Name != "bar.txt" || !out[1].Optional {
t.Errorf("unexpected: %+v", out[1])
}
}
func TestCheckPathPrefixes(t *testing.T) {
tmp := t.TempDir()
abs := filepath.Join(tmp, "file.txt")
os.WriteFile(abs, []byte("x"), 0644)
ok, err := CheckPathPrefixes(abs, []string{tmp})
if err != nil {
t.Fatalf("CheckPathPrefixes error: %v", err)
}
if !ok {
t.Errorf("expected true for prefix match")
}
ok, err = CheckPathPrefixes(abs, []string{"/not/a/prefix"})
if err != nil {
t.Fatalf("CheckPathPrefixes error: %v", err)
}
if ok {
t.Errorf("expected false for non-matching prefix")
}
}
func TestConvertCmdFile_Local(t *testing.T) {
src := "/tmp/foo"
f := &CmdFile{Src: &src}
_, err := convertCmdFile(f, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
}
func TestConvertCmdFile_Content(t *testing.T) {
content := "abc"
f := &CmdFile{Content: &content}
cf, err := convertCmdFile(f, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if cf == nil {
t.Error("expected non-nil CmdFile")
}
}
func TestConvertCmdFile_FileID(t *testing.T) {
id := "id"
f := &CmdFile{FileID: &id}
cf, err := convertCmdFile(f, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if cf == nil {
t.Error("expected non-nil CmdFile")
}
}
func TestConvertCmdFile_Collector(t *testing.T) {
name := "out"
max := int64(123)
f := &CmdFile{Name: &name, Max: &max}
cf, err := convertCmdFile(f, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if cf == nil {
t.Error("expected non-nil CmdFile")
}
}
func TestConvertCmdFile_Invalid(t *testing.T) {
f := &CmdFile{}
_, err := convertCmdFile(f, nil)
if err == nil {
t.Error("expected error for invalid CmdFile")
}
}
func TestResult_String(t *testing.T) {
r := Result{
Status: 1,
ExitStatus: 0,
Error: "",
Time: uint64(time.Second),
RunTime: uint64(time.Second),
Memory: 1024,
Files: map[string]string{"foo": "bar"},
}
s := r.String()
if s == "" {
t.Error("expected non-empty string")
}
}
func TestConvertPipe(t *testing.T) {
p := PipeMap{
In: PipeIndex{Index: 1, Fd: 2},
Out: PipeIndex{Index: 3, Fd: 4},
Name: "pipe",
Max: 100,
Proxy: true,
}
wp := convertPipe(p)
if wp.In.Index != 1 || wp.Out.Fd != 4 || wp.Name != "pipe" || wp.Limit != 100 {
t.Errorf("unexpected convertPipe result: %+v", wp)
}
}
func TestConvertRequest_Basic(t *testing.T) {
src := "/tmp/foo"
content := "abc"
fileID := "id"
name := "out"
max := int64(123)
copyOut := []string{"result.txt", "log.txt?"}
req := &Request{
Cmd: []Cmd{{
Args: []string{"echo", "hello"},
Files: []*CmdFile{{Src: &src}, {Content: &content}, {FileID: &fileID}, {Name: &name, Max: &max}},
CopyOut: copyOut,
CPULimit: uint64(1000 * time.Millisecond),
MemoryLimit: 1024,
}},
}
workerReq, err := ConvertRequest(req, []string{"/tmp"})
if err != nil {
t.Fatalf("ConvertRequest error: %v", err)
}
if len(workerReq.Cmd[0].Files) != 4 {
t.Errorf("expected 4 files, got %d", len(workerReq.Cmd[0].Files))
}
if len(workerReq.Cmd[0].CopyOut) != 2 {
t.Errorf("expected 2 copyOut, got %d", len(workerReq.Cmd[0].CopyOut))
}
if workerReq.Cmd[0].CPULimit != 1000*time.Millisecond {
t.Errorf("unexpected CPULimit: %v", workerReq.Cmd[0].CPULimit)
}
if workerReq.Cmd[0].MemoryLimit != 1024 {
t.Errorf("unexpected MemoryLimit: %v", workerReq.Cmd[0].MemoryLimit)
}
}
func TestConvertRequest_InvalidFile(t *testing.T) {
req := &Request{
Cmd: []Cmd{
{
Files: []*CmdFile{{}}, // invalid
},
},
}
_, err := ConvertRequest(req, nil)
if err == nil {
t.Error("expected error for invalid CmdFile")
}
}
func TestConvertResponse_Basic(t *testing.T) {
res := worker.Response{
Results: []worker.Result{{
Status: 1,
ExitStatus: 0,
Error: "",
Time: 1000 * time.Millisecond,
RunTime: 900 * time.Millisecond,
Memory: 2048,
ProcPeak: 2,
Files: map[string]*os.File{},
FileError: []worker.FileError{{Name: "foo", Type: 1, Message: "err"}},
}},
}
resp, _ := ConvertResponse(res, false)
if resp.Results[0].Status != 1 {
t.Errorf("unexpected Status: %v", resp.Results[0].Status)
}
if resp.Results[0].Time != uint64(1000*time.Millisecond) {
t.Errorf("unexpected Time: %v", resp.Results[0].Time)
}
if len(resp.Results[0].FileError) != 1 {
t.Errorf("unexpected FileError: %+v", resp.Results[0].FileError)
}
}

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"mime" "mime"
"net/http" "net/http"
"path" "path/filepath"
"github.com/criyle/go-judge/envexec" "github.com/criyle/go-judge/envexec"
"github.com/criyle/go-judge/filestore" "github.com/criyle/go-judge/filestore"
@ -82,7 +82,7 @@ func (f *fileHandle) fileIDGet(c *gin.Context) {
c.AbortWithStatus(http.StatusNotFound) c.AbortWithStatus(http.StatusNotFound)
return return
} }
typ := mime.TypeByExtension(path.Ext(name)) typ := mime.TypeByExtension(filepath.Ext(name))
c.Header("Content-Type", typ) c.Header("Content-Type", typ)
fi, ok := file.(*envexec.FileInput) // fast path fi, ok := file.(*envexec.FileInput) // fast path

View File

@ -2,15 +2,16 @@ package restexecutor
import ( import (
"bytes" "bytes"
"github.com/criyle/go-judge/filestore"
"github.com/gin-gonic/gin"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
"path" "path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/criyle/go-judge/filestore"
"github.com/gin-gonic/gin"
) )
func TestFilePost(t *testing.T) { func TestFilePost(t *testing.T) {
@ -65,7 +66,7 @@ func TestFilePost(t *testing.T) {
fileID = fileID[1 : len(fileID)-1] fileID = fileID[1 : len(fileID)-1]
// Check if the file is stored correctly // Check if the file is stored correctly
filePath := path.Join(tempDir, fileID) filePath := filepath.Join(tempDir, fileID)
_, err = os.Stat(filePath) _, err = os.Stat(filePath)
if os.IsNotExist(err) { if os.IsNotExist(err) {
t.Fatalf("File should exist in the storage: %v", err) t.Fatalf("File should exist in the storage: %v", err)
@ -116,7 +117,7 @@ func TestFileGet(t *testing.T) {
// Create files in the temporary directory // Create files in the temporary directory
for _, file := range filesToCreate { for _, file := range filesToCreate {
filePath := path.Join(tempDir, file.Name) filePath := filepath.Join(tempDir, file.Name)
err := CreateFileWithContent(filePath, file.Content) err := CreateFileWithContent(filePath, file.Content)
if err != nil { if err != nil {
t.Fatalf("Failed to create file: %v", err) t.Fatalf("Failed to create file: %v", err)
@ -158,7 +159,7 @@ func TestFileIDGet(t *testing.T) {
// Create a test file // Create a test file
testFileName := "test.py" testFileName := "test.py"
testFilePath := path.Join(tempDir, testFileName) testFilePath := filepath.Join(tempDir, testFileName)
err := CreateFileWithContent(testFilePath, "print(58 - 7 * 3)") err := CreateFileWithContent(testFilePath, "print(58 - 7 * 3)")
if err != nil { if err != nil {
t.Fatalf("Failed to create test file: %v", err) t.Fatalf("Failed to create test file: %v", err)
@ -182,7 +183,7 @@ func TestFileIDGet(t *testing.T) {
t.Fatalf("Expected status %d, got %d", http.StatusOK, w.Code) t.Fatalf("Expected status %d, got %d", http.StatusOK, w.Code)
} }
bodyBytes, err := os.ReadFile(path.Join(tempDir, fileID)) bodyBytes, err := os.ReadFile(filepath.Join(tempDir, fileID))
if err != nil { if err != nil {
t.Fatalf("Failed to read response body: %v", err) t.Fatalf("Failed to read response body: %v", err)
} }
@ -206,7 +207,7 @@ func TestFileIDDelete(t *testing.T) {
// Create a test file // Create a test file
testFileName := "test.py" testFileName := "test.py"
testFilePath := path.Join(tempDir, testFileName) testFilePath := filepath.Join(tempDir, testFileName)
err := CreateFileWithContent(testFilePath, "print(58 - 7 * 3)") err := CreateFileWithContent(testFilePath, "print(58 - 7 * 3)")
if err != nil { if err != nil {
t.Fatalf("Failed to create test file: %v", err) t.Fatalf("Failed to create test file: %v", err)
@ -231,7 +232,7 @@ func TestFileIDDelete(t *testing.T) {
} }
// Check if the file is deleted from the storage // Check if the file is deleted from the storage
if _, err := os.Stat(path.Join(tempDir, fileID)); !os.IsNotExist(err) { if _, err := os.Stat(filepath.Join(tempDir, fileID)); !os.IsNotExist(err) {
t.Fatalf("Expected file to be deleted, but it still exists") t.Fatalf("Expected file to be deleted, but it still exists")
} }
} }

View File

@ -12,8 +12,9 @@ import (
) )
var ( var (
_ worker.CmdFile = &fileStreamIn{} _ worker.CmdFile = &fileStreamIn{}
_ worker.CmdFile = &fileStreamOut{} _ worker.CmdFile = &fileStreamOut{}
_ envexec.ReaderTTY = &fileStreamInReader{}
) )
type fileStreamIn struct { type fileStreamIn struct {

View File

@ -77,7 +77,7 @@ func (h *wsHandle) handleWS(c *gin.Context) {
} }
r, err := model.ConvertRequest(&req.Request, h.srcPrefix) r, err := model.ConvertRequest(&req.Request, h.srcPrefix)
if err != nil { if err != nil {
return fmt.Errorf("ws convert error: %v", err) return fmt.Errorf("ws convert error: %w", err)
} }
ctx, cancel := context.WithCancel(baseCtx) ctx, cancel := context.WithCancel(baseCtx)
@ -90,7 +90,7 @@ func (h *wsHandle) handleWS(c *gin.Context) {
}: }:
} }
cancel() cancel()
h.logger.Debug("ws request error: %v", zap.Error(err)) h.logger.Debug("ws request error", zap.Error(err))
return nil return nil
} }
@ -171,7 +171,7 @@ func (h *wsHandle) handleWS(c *gin.Context) {
case r := <-resultCh: case r := <-resultCh:
conn.SetWriteDeadline(time.Now().Add(writeWait)) conn.SetWriteDeadline(time.Now().Add(writeWait))
if err := conn.WriteJSON(r); err != nil { if err := conn.WriteJSON(r); err != nil {
h.logger.Info("ws write error:", zap.Error(err)) h.logger.Info("ws write error", zap.Error(err))
return return
} }
case <-ticker.C: case <-ticker.C:
@ -224,7 +224,7 @@ func (c *contextMap) Add(reqID string, cancel context.CancelFunc) error {
defer c.mu.Unlock() defer c.mu.Unlock()
if _, exist := c.m[reqID]; exist { if _, exist := c.m[reqID]; exist {
return fmt.Errorf("duplicated request id: %v", reqID) return fmt.Errorf("duplicated request id: %q", reqID)
} }
c.m[reqID] = cancel c.m[reqID] = cancel
return nil return nil

View File

@ -3,7 +3,7 @@ package macsandbox
import ( import (
"context" "context"
"os" "os"
"path" "path/filepath"
"syscall" "syscall"
"time" "time"
@ -137,15 +137,15 @@ func (e *environment) WorkDir() *os.File {
} }
func (e *environment) Open(p string, flags int, perm os.FileMode) (*os.File, error) { func (e *environment) Open(p string, flags int, perm os.FileMode) (*os.File, error) {
return os.OpenFile(path.Join(e.wdPath, p), flags, perm) return os.OpenFile(filepath.Join(e.wdPath, p), flags, perm)
} }
func (e *environment) MkdirAll(p string, perm os.FileMode) error { func (e *environment) MkdirAll(p string, perm os.FileMode) error {
return os.MkdirAll(path.Join(e.wdPath, p), perm) return os.MkdirAll(filepath.Join(e.wdPath, p), perm)
} }
func (e *environment) Symlink(oldName, newName string) error { func (e *environment) Symlink(oldName, newName string) error {
return os.Symlink(oldName, path.Join(e.wdPath, newName)) return os.Symlink(oldName, filepath.Join(e.wdPath, newName))
} }
func (e *environment) Destroy() error { func (e *environment) Destroy() error {
@ -171,7 +171,7 @@ func removeContents(dir string) error {
} }
for _, name := range names { for _, name := range names {
err = os.RemoveAll(path.Join(dir, name)) err = os.RemoveAll(filepath.Join(dir, name))
if err != nil { if err != nil {
return err return err
} }

10
env/mount_linux.go vendored
View File

@ -3,7 +3,7 @@ package env
import ( import (
"fmt" "fmt"
"os" "os"
"path" "path/filepath"
"github.com/criyle/go-sandbox/container" "github.com/criyle/go-sandbox/container"
"github.com/criyle/go-sandbox/pkg/mount" "github.com/criyle/go-sandbox/pkg/mount"
@ -61,12 +61,12 @@ func parseMountConfig(m *Mounts) (*mount.Builder, error) {
} }
for _, mt := range m.Mount { for _, mt := range m.Mount {
target := mt.Target target := mt.Target
if path.IsAbs(target) { if filepath.IsAbs(target) {
target = path.Clean(target[1:]) target = filepath.Clean(target[1:])
} }
source := mt.Source source := mt.Source
if !path.IsAbs(source) { if !filepath.IsAbs(source) {
source = path.Join(wd, source) source = filepath.Join(wd, source)
} }
switch mt.Type { switch mt.Type {
case "bind": case "bind":

View File

@ -7,7 +7,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path" "path/filepath"
"syscall" "syscall"
"time" "time"
"unicode/utf16" "unicode/utf16"
@ -286,15 +286,15 @@ func (e *Environment) WorkDir() *os.File {
// Open opens file related to root // Open opens file related to root
func (e *Environment) Open(p string, flags int, perm os.FileMode) (*os.File, error) { func (e *Environment) Open(p string, flags int, perm os.FileMode) (*os.File, error) {
return os.OpenFile(path.Join(e.root, p), flags, perm) return os.OpenFile(filepath.Join(e.root, p), flags, perm)
} }
func (e *Environment) MkdirAll(p string, perm os.FileMode) error { func (e *Environment) MkdirAll(p string, perm os.FileMode) error {
return os.MkdirAll(path.Join(e.root, p), perm) return os.MkdirAll(filepath.Join(e.root, p), perm)
} }
func (e *Environment) Symlink(oldName, newName string) error { func (e *Environment) Symlink(oldName, newName string) error {
return os.Symlink(oldName, path.Join(e.root, newName)) return os.Symlink(oldName, filepath.Join(e.root, newName))
} }
// Destroy destroys the environment // Destroy destroys the environment
@ -327,7 +327,7 @@ func removeContents(dir string) error {
} }
for _, name := range names { for _, name := range names {
err = os.RemoveAll(path.Join(dir, name)) err = os.RemoveAll(filepath.Join(dir, name))
if err != nil { if err != nil {
return err return err
} }

View File

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path" "path/filepath"
) )
func readerToFile(reader io.Reader) (*os.File, error) { func readerToFile(reader io.Reader) (*os.File, error) {
@ -49,13 +49,13 @@ func copyDir(src *os.File, dst string) error {
} }
func copyDirFile(src, dst, name string) error { func copyDirFile(src, dst, name string) error {
s, err := os.Open(path.Join(src, name)) s, err := os.Open(filepath.Join(src, name))
if err != nil { if err != nil {
return err return err
} }
defer s.Close() defer s.Close()
t, err := os.OpenFile(path.Join(dst, name), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) t, err := os.OpenFile(filepath.Join(dst, name), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil { if err != nil {
return err return err
} }

View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path"
"path/filepath" "path/filepath"
"sync" "sync"
@ -41,7 +40,7 @@ func (s *fileLocalStore) Get(id string) (string, envexec.File) {
s.mu.RLock() s.mu.RLock()
defer s.mu.RUnlock() defer s.mu.RUnlock()
p := path.Join(s.dir, id) p := filepath.Join(s.dir, id)
if _, err := os.Stat(p); os.IsNotExist(err) { if _, err := os.Stat(p); os.IsNotExist(err) {
return "", nil return "", nil
} }
@ -57,7 +56,7 @@ func (s *fileLocalStore) Remove(id string) bool {
defer s.mu.Unlock() defer s.mu.Unlock()
delete(s.name, id) delete(s.name, id)
p := path.Join(s.dir, id) p := filepath.Join(s.dir, id)
if _, err := os.Stat(p); os.IsNotExist(err) { if _, err := os.Stat(p); os.IsNotExist(err) {
return false return false
} }
@ -87,7 +86,7 @@ func (s *fileLocalStore) New() (*os.File, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
f, err := os.OpenFile(path.Join(s.dir, id), os.O_CREATE|os.O_RDWR|os.O_EXCL, 0644) f, err := os.OpenFile(filepath.Join(s.dir, id), os.O_CREATE|os.O_RDWR|os.O_EXCL, 0644)
if err == nil { if err == nil {
return f, nil return f, nil
} }

2
go.mod
View File

@ -6,7 +6,7 @@ require (
github.com/coreos/go-systemd/v22 v22.5.0 github.com/coreos/go-systemd/v22 v22.5.0
github.com/creack/pty v1.1.24 github.com/creack/pty v1.1.24
github.com/criyle/go-judge/pb v1.0.0 github.com/criyle/go-judge/pb v1.0.0
github.com/criyle/go-sandbox v0.11.4 github.com/criyle/go-sandbox v0.11.5
github.com/elastic/go-seccomp-bpf v1.5.0 github.com/elastic/go-seccomp-bpf v1.5.0
github.com/elastic/go-ucfg v0.8.8 github.com/elastic/go-ucfg v0.8.8
github.com/gin-contrib/zap v1.1.5 github.com/gin-contrib/zap v1.1.5

4
go.sum
View File

@ -20,8 +20,8 @@ github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/criyle/go-judge/pb v1.0.0 h1:8A4zHPPCGCDTuFY1GW5Hqpg+8ETIwzgXxiRpYKKb2zA= github.com/criyle/go-judge/pb v1.0.0 h1:8A4zHPPCGCDTuFY1GW5Hqpg+8ETIwzgXxiRpYKKb2zA=
github.com/criyle/go-judge/pb v1.0.0/go.mod h1:hjgixgK9NH9ktwc29xbXVdZDOlKfEkRkEbZ4W5bOMmw= github.com/criyle/go-judge/pb v1.0.0/go.mod h1:hjgixgK9NH9ktwc29xbXVdZDOlKfEkRkEbZ4W5bOMmw=
github.com/criyle/go-sandbox v0.11.4 h1:cbah7BvabMGHUDUOEe6iww7YA3dHYqGYumXYhO6bsAI= github.com/criyle/go-sandbox v0.11.5 h1:yT6nWRIPcCdRDXvFItaJEn2tR00DUrgXVIvKPM2cHog=
github.com/criyle/go-sandbox v0.11.4/go.mod h1:nfsXyZ2s0oQYV0je1fp5SJ7XrKTx5WQ4g5nl4SsFB/E= github.com/criyle/go-sandbox v0.11.5/go.mod h1:nfsXyZ2s0oQYV0je1fp5SJ7XrKTx5WQ4g5nl4SsFB/E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@ -60,7 +60,7 @@ type CachedFile struct {
func (f *CachedFile) EnvFile(fs filestore.FileStore) (envexec.File, error) { func (f *CachedFile) EnvFile(fs filestore.FileStore) (envexec.File, error) {
_, fd := fs.Get(f.FileID) _, fd := fs.Get(f.FileID)
if fd == nil { if fd == nil {
return nil, fmt.Errorf("file not exists with id %v", f.FileID) return nil, fmt.Errorf("file does not exists with id: %q", f.FileID)
} }
return fd, nil return fd, nil
} }

View File

@ -17,8 +17,10 @@ type waiter struct {
} }
func (w *waiter) Wait(ctx context.Context, u envexec.Process) bool { func (w *waiter) Wait(ctx context.Context, u envexec.Process) bool {
if w.clockTimeLimit < w.timeLimit { clockTimeLimit := w.clockTimeLimit
w.clockTimeLimit = w.timeLimit timeLimit := w.timeLimit
if clockTimeLimit < w.timeLimit {
clockTimeLimit = w.timeLimit
} }
start := time.Now() start := time.Now()
@ -40,11 +42,11 @@ func (w *waiter) Wait(ctx context.Context, u envexec.Process) bool {
return false return false
case <-ticker.C: case <-ticker.C:
if time.Since(start) > w.clockTimeLimit { if time.Since(start) > clockTimeLimit {
return true return true
} }
u := u.Usage() u := u.Usage()
if u.Time > w.timeLimit { if u.Time > timeLimit {
return true return true
} }
} }

View File

@ -4,7 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path" "path/filepath"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -347,10 +347,10 @@ func (w *worker) prepareCmd(rc Cmd, pipeFileName map[string]bool) (*envexec.Cmd,
var copyOutDir string var copyOutDir string
if rc.CopyOutDir != "" { if rc.CopyOutDir != "" {
if path.IsAbs(rc.CopyOutDir) { if filepath.IsAbs(rc.CopyOutDir) {
copyOutDir = rc.CopyOutDir copyOutDir = rc.CopyOutDir
} else { } else {
copyOutDir = path.Join(w.workDir, rc.CopyOutDir) copyOutDir = filepath.Join(w.workDir, rc.CopyOutDir)
} }
} }