forked from security/hakurei
This is way higher level than the container package and does not even work unless every path is mounted in the exact same location. This behaviour causes nothing but confusion and problems, Signed-off-by: Ophestra <cat@gensokyo.uk>
77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
package helper
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"slices"
|
|
"sync"
|
|
|
|
"hakurei.app/container"
|
|
"hakurei.app/helper/proc"
|
|
)
|
|
|
|
// New initialises a Helper instance with wt as the null-terminated argument writer.
|
|
func New(
|
|
ctx context.Context,
|
|
pathname *container.Absolute, name string,
|
|
wt io.WriterTo,
|
|
stat bool,
|
|
argF func(argsFd, statFd int) []string,
|
|
cmdF func(z *container.Container),
|
|
extraFiles []*os.File,
|
|
) Helper {
|
|
var args []string
|
|
h := new(helperContainer)
|
|
h.helperFiles, args = newHelperFiles(ctx, wt, stat, argF, extraFiles)
|
|
h.Container = container.NewCommand(ctx, pathname.String(), name, args...)
|
|
h.WaitDelay = WaitDelay
|
|
if cmdF != nil {
|
|
cmdF(h.Container)
|
|
}
|
|
return h
|
|
}
|
|
|
|
// helperContainer provides a [sandbox.Container] wrapper around helper ipc.
|
|
type helperContainer struct {
|
|
started bool
|
|
|
|
mu sync.Mutex
|
|
*helperFiles
|
|
*container.Container
|
|
}
|
|
|
|
func (h *helperContainer) Start() error {
|
|
h.mu.Lock()
|
|
defer h.mu.Unlock()
|
|
|
|
if h.started {
|
|
return errors.New("helper: already started")
|
|
}
|
|
h.started = true
|
|
|
|
h.Env = slices.Grow(h.Env, 2)
|
|
if h.useArgsFd {
|
|
h.Env = append(h.Env, HakureiHelper+"=1")
|
|
} else {
|
|
h.Env = append(h.Env, HakureiHelper+"=0")
|
|
}
|
|
if h.useStatFd {
|
|
h.Env = append(h.Env, HakureiStatus+"=1")
|
|
|
|
// stat is populated on fulfill
|
|
h.Cancel = func(*exec.Cmd) error { return h.stat.Close() }
|
|
} else {
|
|
h.Env = append(h.Env, HakureiStatus+"=0")
|
|
}
|
|
|
|
return proc.Fulfill(h.helperFiles.ctx, &h.ExtraFiles, func() error {
|
|
if err := h.Container.Start(); err != nil {
|
|
return err
|
|
}
|
|
return h.Container.Serve()
|
|
}, h.files, h.extraFiles)
|
|
}
|