refactor(envexec): normalize error messages
Some checks failed
Build / Goreleaser (push) Has been cancelled
Build / Upload artifacts-${{ matrix.os }}-${{ matrix.arch }} (amd64_v3, darwin) (push) Has been cancelled
Build / Upload artifacts-${{ matrix.os }}-${{ matrix.arch }} (amd64_v3, linux) (push) Has been cancelled
Build / Upload artifacts-${{ matrix.os }}-${{ matrix.arch }} (amd64_v3, windows) (push) Has been cancelled
Build / Upload artifacts-${{ matrix.os }}-${{ matrix.arch }} (arm64_v8.0, darwin) (push) Has been cancelled
Build / Upload artifacts-${{ matrix.os }}-${{ matrix.arch }} (arm64_v8.0, linux) (push) Has been cancelled
Build / Upload artifacts-${{ matrix.os }}-${{ matrix.arch }} (arm64_v8.0, windows) (push) Has been cancelled

This commit is contained in:
criyle 2025-05-25 22:44:50 -04:00
parent 86b85d8556
commit 7f663ba0fd
8 changed files with 53 additions and 55 deletions

View File

@ -53,7 +53,7 @@ func (c *environ) Execve(ctx context.Context, param envexec.ExecveParam) (envexe
if c.cgPool != nil {
cg, err = c.cgPool.Get()
if err != nil {
return nil, fmt.Errorf("execve: failed to get cgroup %v", err)
return nil, fmt.Errorf("execve: failed to get cgroup: %w", err)
}
if err := c.setCgroupLimit(cg, limit); err != nil {
return nil, err
@ -61,7 +61,7 @@ func (c *environ) Execve(ctx context.Context, param envexec.ExecveParam) (envexe
if c.cgFd {
f, err := cg.Open()
if err != nil {
return nil, fmt.Errorf("execve: failed to get cgroup fd %v", err)
return nil, fmt.Errorf("execve: failed to get cgroup fd: %w", err)
}
defer f.Close()
cgFd = f.Fd()
@ -130,7 +130,7 @@ func (c *environ) Open(path string, flags int, perm os.FileMode) (*os.File, erro
var err error
path, err = filepath.Rel(c.workDir, path)
if err != nil {
return nil, fmt.Errorf("openAtWorkDir: %v", err)
return nil, fmt.Errorf("openatworkdir: %w", err)
}
}
fd, err := syscall.Openat(int(c.wd.Fd()), path, flags|syscall.O_CLOEXEC, uint32(perm))
@ -139,7 +139,7 @@ func (c *environ) Open(path string, flags int, perm os.FileMode) (*os.File, erro
}
f := os.NewFile(uintptr(fd), path)
if f == nil {
return nil, fmt.Errorf("openAtWorkDir: failed to NewFile")
return nil, fmt.Errorf("openatworkdir: failed to create file")
}
return f, nil
}
@ -220,19 +220,19 @@ func (c *environ) setCgroupLimit(cg Cgroup, limit envexec.Limit) error {
}
if cpuSet != "" {
if err := cg.SetCpuset(cpuSet); isCgroupSetHasError(err) {
return fmt.Errorf("execve: cgroup failed to set cpu_set limit %v", err)
return fmt.Errorf("execve: cgroup: failed to set cpuset limit: %w", err)
}
}
if c.cpuRate && limit.Rate > 0 {
if err := cg.SetCPURate(limit.Rate); isCgroupSetHasError(err) {
return fmt.Errorf("execve: cgroup failed to set cpu_rate limit %v", err)
return fmt.Errorf("execve: cgroup: failed to set cpu rate limit: %w", err)
}
}
if err := cg.SetMemoryLimit(limit.Memory); isCgroupSetHasError(err) {
return fmt.Errorf("execve: cgroup failed to set memory limit %v", err)
return fmt.Errorf("execve: cgroup: failed to set memory limit: %w", err)
}
if err := cg.SetProcLimit(limit.Proc); isCgroupSetHasError(err) {
return fmt.Errorf("execve: cgroup failed to set process limit %v", err)
return fmt.Errorf("execve: cgroup: failed to set process limit: %w", err)
}
return nil
}

View File

@ -101,6 +101,6 @@ func FileToReader(f File) (io.ReadCloser, error) {
return file, nil
default:
return nil, fmt.Errorf("file cannot open as reader %v", f)
return nil, fmt.Errorf("file cannot open as reader: %T", f)
}
}

View File

@ -56,24 +56,24 @@ func copyOutAndCollect(m Environment, c *Cmd, ptc []pipeCollector, newStoreFile
stat, err := cf.Stat()
if err != nil {
return err
return fmt.Errorf("copyout: stat %q: %w", n.Name, err)
}
// check regular file
if stat.Mode()&os.ModeType != 0 {
t = ErrCopyOutNotRegularFile
return fmt.Errorf("%s: not a regular file: %v", n.Name, stat.Mode())
return fmt.Errorf("copyout: %q is not a regular file: %v", n.Name, stat.Mode())
}
// check size limit
s := stat.Size()
if c.CopyOutMax > 0 && s > int64(c.CopyOutMax) {
t = ErrCopyOutSizeExceeded
return fmt.Errorf("%s: size (%d) exceeded the limit (%d)", n.Name, s, c.CopyOutMax)
return fmt.Errorf("copyout: %q size (%d) exceeds limit (%d)", n.Name, s, c.CopyOutMax)
}
// create store file
buf, err := newStoreFile()
if err != nil {
t = ErrCopyOutCreateFile
return fmt.Errorf("%s: failed to create store file %v", n.Name, err)
return fmt.Errorf("copyout: failed to create store file for %q: %w", n.Name, err)
}
// Ensure not copy over file size
@ -81,7 +81,7 @@ func copyOutAndCollect(m Environment, c *Cmd, ptc []pipeCollector, newStoreFile
if err != nil {
t = ErrCopyOutCopyContent
buf.Close()
return err
return fmt.Errorf("copyout: failed to copy content for %q: %w", n.Name, err)
}
put(buf, n.Name)
return nil
@ -115,14 +115,14 @@ func copyOutAndCollect(m Environment, c *Cmd, ptc []pipeCollector, newStoreFile
buf, err := newStoreFile()
if err != nil {
errType = ErrCopyOutCreateFile
return fmt.Errorf("%s: failed to create store file %v", p.name, err)
return fmt.Errorf("collect: failed to create store file for %q: %w", p.name, err)
}
// Ensure not copy over file size
_, err = buf.ReadFrom(io.LimitReader(p.buffer, int64(p.limit)+1))
if err != nil {
errType = ErrCopyOutCopyContent
buf.Close()
return err
return fmt.Errorf("collect: failed to copy content for %q: %w", p.name, err)
}
put(buf, p.name)
if fi, err := p.buffer.Stat(); err == nil && fi.Size() > int64(p.limit) {

View File

@ -38,26 +38,26 @@ func copyIn(m Environment, copyIn map[string]File) ([]FileError, error) {
hf, err := FileToReader(f)
if err != nil {
return fmt.Errorf("failed to copyIn %v", err)
return fmt.Errorf("copyin: file to reader: %w", err)
}
defer hf.Close()
// ensure path exists
if err := m.MkdirAll(filepath.Dir(n), 0777); err != nil {
t = ErrCopyInCreateDir
return fmt.Errorf("failed to create dir %v", err)
return fmt.Errorf("copyin: create dir %q: %w", filepath.Dir(n), err)
}
cf, err := m.Open(n, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0777)
if err != nil {
t = ErrCopyInCreateFile
return err
return fmt.Errorf("copyin: open file %q: %w", n, err)
}
defer cf.Close()
_, err = io.Copy(cf, hf)
if err != nil {
t = ErrCopyInCopyContent
return err
return fmt.Errorf("copyin: copy content: %w", err)
}
return nil
})
@ -72,7 +72,7 @@ func symlink(m Environment, symlinks map[string]string) (*FileError, error) {
Name: k,
Type: ErrSymlink,
Message: err.Error(),
}, err
}, fmt.Errorf("symlink: %q -> %q: %w", k, v, err)
}
}
return nil, nil

View File

@ -46,7 +46,7 @@ func prepareCmdFdTTY(c *Cmd, count int, newStoreFile NewStoreFile) (f []*os.File
case *FileReader:
if hasInput {
return nil, nil, fmt.Errorf("cannot have multiple input when tty enabled")
return nil, nil, fmt.Errorf("tty: multiple input not allowed")
}
hasInput = true
@ -68,7 +68,7 @@ func prepareCmdFdTTY(c *Cmd, count int, newStoreFile NewStoreFile) (f []*os.File
var f *os.File
f, err = os.Open(t.Path)
if err != nil {
return nil, nil, fmt.Errorf("failed to open file: %v", t.Path)
return nil, nil, fmt.Errorf("tty: open file %v: %w", t.Path, err)
}
files[j] = f
@ -82,7 +82,7 @@ func prepareCmdFdTTY(c *Cmd, count int, newStoreFile NewStoreFile) (f []*os.File
done := make(chan struct{})
buf, err := newStoreFile()
if err != nil {
return nil, nil, fmt.Errorf("failed to create store file %v", err)
return nil, nil, fmt.Errorf("tty: create store file: %w", err)
}
pipeToCollect = append(pipeToCollect, pipeCollector{done, buf, t.Limit, t.Name, true})
@ -107,7 +107,7 @@ func prepareCmdFdTTY(c *Cmd, count int, newStoreFile NewStoreFile) (f []*os.File
}()
default:
return nil, nil, fmt.Errorf("unknown file type %v %t", t, t)
return nil, nil, fmt.Errorf("tty: unknown file type: %T", t)
}
}
@ -147,7 +147,7 @@ func prepareCmdFd(c *Cmd, count int, newFileStore NewStoreFile) (f []*os.File, p
if t.Stream {
r, w, err := os.Pipe()
if err != nil {
return nil, nil, fmt.Errorf("failed to create pipe %v", err)
return nil, nil, fmt.Errorf("pipe: create: %w", err)
}
go w.ReadFrom(t.Reader)
@ -155,7 +155,7 @@ func prepareCmdFd(c *Cmd, count int, newFileStore NewStoreFile) (f []*os.File, p
} else {
f, err := readerToFile(t.Reader)
if err != nil {
return nil, nil, fmt.Errorf("failed to open reader %v", err)
return nil, nil, fmt.Errorf("pipe: open reader: %w", err)
}
files[j] = f
}
@ -163,7 +163,7 @@ func prepareCmdFd(c *Cmd, count int, newFileStore NewStoreFile) (f []*os.File, p
case *FileInput:
f, err := os.Open(t.Path)
if err != nil {
return nil, nil, fmt.Errorf("failed to open file: %v", t.Path)
return nil, nil, fmt.Errorf("pipe: open file %v: %w", t.Path, err)
}
files[j] = f
@ -176,7 +176,7 @@ func prepareCmdFd(c *Cmd, count int, newFileStore NewStoreFile) (f []*os.File, p
if t.Pipe {
b, err := newPipeBuffer(t.Limit, newFileStore)
if err != nil {
return nil, nil, fmt.Errorf("failed to create pipe %v", err)
return nil, nil, fmt.Errorf("pipe: create: %w", err)
}
cf[t.Name] = b.W
@ -185,13 +185,13 @@ func prepareCmdFd(c *Cmd, count int, newFileStore NewStoreFile) (f []*os.File, p
} else {
f, err := c.Environment.Open(t.Name, os.O_CREATE|os.O_WRONLY, 0777)
if err != nil {
return nil, nil, fmt.Errorf("failed to create container file %v", err)
return nil, nil, fmt.Errorf("container: create file %v: %w", t.Name, err)
}
cf[t.Name] = f
buffer, err := c.Environment.Open(t.Name, os.O_RDWR, 0777)
if err != nil {
return nil, nil, fmt.Errorf("failed to open created container file %v", err)
return nil, nil, fmt.Errorf("container: open created file %v: %w", t.Name, err)
}
files[j] = f
@ -201,12 +201,12 @@ func prepareCmdFd(c *Cmd, count int, newFileStore NewStoreFile) (f []*os.File, p
case *FileWriter:
_, w, err := newPipe(t.Writer, t.Limit)
if err != nil {
return nil, nil, fmt.Errorf("failed to create pipe %v", err)
return nil, nil, fmt.Errorf("pipe: create: %w", err)
}
files[j] = w
default:
return nil, nil, fmt.Errorf("unknown file type %v %t", t, t)
return nil, nil, fmt.Errorf("unknown file type: %T", t)
}
}
return files, pipeToCollect, nil
@ -237,21 +237,21 @@ func prepareFds(r *Group, newStoreFile NewStoreFile) (f [][]*os.File, p [][]pipe
for i, c := range r.Cmd {
files[i], pipeToCollect[i], err = prepareCmdFd(c, fdCount[i], newStoreFile)
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("prepare fds: prepareCmdFd: %w", err)
}
}
// prepare pipes
for _, p := range r.Pipes {
if files[p.Out.Index][p.Out.Fd] != nil {
return nil, nil, fmt.Errorf("pipe mapping to existing file descriptor: out %d/%d", p.Out.Index, p.Out.Fd)
return nil, nil, fmt.Errorf("pipe: mapping to existing file descriptor: out %d/%d", p.Out.Index, p.Out.Fd)
}
if files[p.In.Index][p.In.Fd] != nil {
return nil, nil, fmt.Errorf("pipe mapping to existing file descriptor: in %d/%d", p.In.Index, p.In.Fd)
return nil, nil, fmt.Errorf("pipe: mapping to existing file descriptor: in %d/%d", p.In.Index, p.In.Fd)
}
out, in, pc, err := pipe(p, newStoreFile)
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("pipe: create: %w", err)
}
files[p.Out.Index][p.Out.Fd] = out
files[p.In.Index][p.In.Fd] = in
@ -265,7 +265,7 @@ func prepareFds(r *Group, newStoreFile NewStoreFile) (f [][]*os.File, p [][]pipe
for i, fds := range files {
for j, f := range fds {
if f == nil {
return nil, nil, fmt.Errorf("null passed to files for index/fd: %d/%d", i, j)
return nil, nil, fmt.Errorf("null file for index/fd: %d/%d", i, j)
}
}
}
@ -280,10 +280,10 @@ func countFd(r *Group) ([]int, error) {
for _, pi := range r.Pipes {
for _, p := range []PipeIndex{pi.In, pi.Out} {
if p.Index < 0 || p.Index >= len(r.Cmd) {
return nil, fmt.Errorf("pipe index out of range %v", p.Index)
return nil, fmt.Errorf("pipe: index out of range %v", p.Index)
}
if p.Fd < len(r.Cmd[p.Index].Files) && r.Cmd[p.Index].Files[p.Fd] != nil {
return nil, fmt.Errorf("pipe fd have been occupied %v %v", p.Index, p.Fd)
return nil, fmt.Errorf("pipe: fd already occupied %v %v", p.Index, p.Fd)
}
if p.Fd+1 > fdCount[p.Index] {
fdCount[p.Index] = p.Fd + 1
@ -297,12 +297,12 @@ func pipe(p Pipe, newStoreFile NewStoreFile) (out *os.File, in *os.File, pc *pip
if p.Proxy {
buffer, err := newStoreFile()
if err != nil {
return nil, nil, nil, err
return nil, nil, nil, fmt.Errorf("pipe: create store file: %w", err)
}
out1, in1, out2, in2, err := pipe2()
if err != nil {
buffer.Close()
return nil, nil, nil, err
return nil, nil, nil, fmt.Errorf("pipe: create: %w", err)
}
pc := pipeProxy(p, out1, in2, buffer)
@ -311,7 +311,7 @@ func pipe(p Pipe, newStoreFile NewStoreFile) (out *os.File, in *os.File, pc *pip
out, in, err = os.Pipe()
if err != nil {
return nil, nil, nil, err
return nil, nil, nil, fmt.Errorf("pipe: create: %w", err)
}
return out, in, nil, nil
}

View File

@ -61,28 +61,28 @@ func copyFileDir(srcDirFd, dstDirFd int, name string) error {
// open the source file
fd, err := syscall.Openat(srcDirFd, name, syscall.O_CLOEXEC|syscall.O_RDONLY, 0777)
if err != nil {
return err
return fmt.Errorf("copyfiledir: openat src %q: %w", name, err)
}
defer syscall.Close(fd)
var st syscall.Stat_t
if err := syscall.Fstat(fd, &st); err != nil {
return err
return fmt.Errorf("copyfiledir: fstat %q: %w", name, err)
}
if st.Mode&syscall.S_IFREG == 0 {
return fmt.Errorf("%s is not a regular file", name)
return fmt.Errorf("copyfiledir: %q is not a regular file", name)
}
// open the dst file
dstFd, err := syscall.Openat(dstDirFd, name, syscall.O_CLOEXEC|syscall.O_WRONLY|syscall.O_CREAT|syscall.O_TRUNC, 0777)
if err != nil {
return err
return fmt.Errorf("copyfiledir: openat dst %q: %w", name, err)
}
defer syscall.Close(dstFd)
// send file, ignore error for now if it is dir
if _, err := syscall.Sendfile(dstFd, fd, nil, int(st.Size)); err != nil && err != syscall.EINVAL {
return err
return fmt.Errorf("copyfiledir: sendfile %q: %w", name, err)
}
return nil
}

View File

@ -51,29 +51,29 @@ func copyDir(src *os.File, dst string) error {
func copyDirFile(src, dst, name string) error {
s, err := os.Open(filepath.Join(src, name))
if err != nil {
return err
return fmt.Errorf("copydir: open src %q: %w", filepath.Join(src, name), err)
}
defer s.Close()
t, err := os.OpenFile(filepath.Join(dst, name), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
if err != nil {
return err
return fmt.Errorf("copydir: open dst %q: %w", filepath.Join(dst, name), err)
}
defer t.Close()
stat, err := t.Stat()
if err != nil {
return err
return fmt.Errorf("copydir: stat dst %q: %w", filepath.Join(dst, name), err)
}
// check regular file
if stat.Mode()&os.ModeType != 0 {
return fmt.Errorf("File(%s) is not a regular file", name)
return fmt.Errorf("copydir: %q is not a regular file", name)
}
_, err = t.ReadFrom(s)
if err != nil {
return err
return fmt.Errorf("copydir: copy content for %q: %w", name, err)
}
return nil
}

View File

@ -51,8 +51,6 @@ var statusToString = []string{
"Judgement Failed",
"Invalid Interaction",
"Internal Error",
"CGroup Error",
"Container Error",
}
// stringToStatus map string to corresponding Status