container: remove custom cmd initialisation
All checks were successful
Test / Create distribution (push) Successful in 26s
Test / Hakurei (push) Successful in 45s
Test / Sandbox (push) Successful in 43s
Test / Hakurei (race detector) (push) Successful in 45s
Test / Sandbox (race detector) (push) Successful in 43s
Test / Planterette (push) Successful in 43s
Test / Flake checks (push) Successful in 1m27s

This part of the interface is very unintuitive and only used for testing, even in testing it is inelegant and can be done better.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-07-25 00:43:22 +09:00
parent 9d7a19d162
commit e71ae3b8c5
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
12 changed files with 57 additions and 135 deletions

View File

@ -35,9 +35,6 @@ type (
// with behaviour identical to its [exec.Cmd] counterpart.
ExtraFiles []*os.File
// Custom [exec.Cmd] initialisation function.
CommandContext func(ctx context.Context) (cmd *exec.Cmd)
// param encoder for shim and init
setup *gob.Encoder
// cancels cmd
@ -122,13 +119,8 @@ func (p *Container) Start() error {
p.SeccompPresets |= seccomp.PresetDenyTTY
}
if p.CommandContext != nil {
p.cmd = p.CommandContext(ctx)
} else {
p.cmd = exec.CommandContext(ctx, MustExecutable())
p.cmd.Args = []string{"init"}
}
p.cmd = exec.CommandContext(ctx, MustExecutable())
p.cmd.Args = []string{"init"}
p.cmd.Stdin, p.cmd.Stdout, p.cmd.Stderr = p.Stdin, p.Stdout, p.Stderr
p.cmd.WaitDelay = p.WaitDelay
if p.Cancel != nil {

View File

@ -6,7 +6,6 @@ import (
"encoding/gob"
"log"
"os"
"os/exec"
"strings"
"syscall"
"testing"
@ -26,6 +25,11 @@ const (
ignoreV = -1
)
func TestMain(m *testing.M) {
container.TryArgv0(hlog.Output{}, hlog.Prepare, internal.InstallOutput)
os.Exit(m.Run())
}
func TestContainer(t *testing.T) {
{
oldVerbose := hlog.Load()
@ -96,7 +100,6 @@ func TestContainer(t *testing.T) {
c.Uid = 1000
c.Gid = 100
c.Hostname = tc.host
c.CommandContext = commandContext
c.Stdout, c.Stderr = os.Stdout, os.Stderr
c.Ops = tc.ops
c.SeccompRules = tc.rules
@ -121,11 +124,7 @@ func TestContainer(t *testing.T) {
Place("/etc/hostname", []byte(c.Args[5]))
// in case test has cgo enabled
var libPaths []string
if entries, err := ldd.ExecFilter(ctx,
commandContext,
func(v []byte) []byte {
return bytes.SplitN(v, []byte("TestHelperInit\n"), 2)[1]
}, os.Args[0]); err != nil {
if entries, err := ldd.Exec(ctx, os.Args[0]); err != nil {
log.Fatalf("ldd: %v", err)
} else {
libPaths = ldd.Path(entries)
@ -197,14 +196,6 @@ func TestContainerString(t *testing.T) {
}
}
func TestHelperInit(t *testing.T) {
if len(os.Args) != 5 || os.Args[4] != "init" {
return
}
container.SetOutput(hlog.Output{})
container.Init(hlog.Prepare, internal.InstallOutput)
}
func TestHelperCheckContainer(t *testing.T) {
if len(os.Args) != 6 || os.Args[4] != "check" {
return
@ -274,8 +265,3 @@ func TestHelperCheckContainer(t *testing.T) {
}
})
}
func commandContext(ctx context.Context) *exec.Cmd {
return exec.CommandContext(ctx, os.Args[0], "-test.v",
"-test.run=TestHelperInit", "--", "init")
}

View File

@ -4,13 +4,10 @@ import (
"context"
"io"
"os"
"os/exec"
"testing"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal"
"hakurei.app/internal/hlog"
)
func TestContainer(t *testing.T) {
@ -36,20 +33,8 @@ func TestContainer(t *testing.T) {
testHelper(t, func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper {
return helper.New(ctx, os.Args[0], argsWt, stat, argF, func(z *container.Container) {
setOutput(&z.Stdout, &z.Stderr)
z.CommandContext = func(ctx context.Context) (cmd *exec.Cmd) {
return exec.CommandContext(ctx, os.Args[0], "-test.v",
"-test.run=TestHelperInit", "--", "init")
}
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev")
}, nil)
})
})
}
func TestHelperInit(t *testing.T) {
if len(os.Args) != 5 || os.Args[4] != "init" {
return
}
container.SetOutput(hlog.Output{})
container.Init(hlog.Prepare, func(bool) { internal.InstallOutput(false) })
}

View File

@ -38,7 +38,6 @@ func argF(argsFd, statFd int) []string {
func argFChecked(argsFd, statFd int) (args []string) {
args = make([]string, 0, 6)
args = append(args, "-test.run=TestHelperStub", "--")
if argsFd > -1 {
args = append(args, "--args", strconv.Itoa(argsFd))
}

View File

@ -25,7 +25,7 @@ func InternalHelperStub() {
sp = v
}
genericStub(flagRestoreFiles(3, ap, sp))
genericStub(flagRestoreFiles(1, ap, sp))
os.Exit(0)
}

View File

@ -1,9 +1,17 @@
package helper_test
import (
"os"
"testing"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal"
"hakurei.app/internal/hlog"
)
func TestHelperStub(t *testing.T) { helper.InternalHelperStub() }
func TestMain(m *testing.M) {
container.TryArgv0(hlog.Output{}, hlog.Prepare, internal.InstallOutput)
helper.InternalHelperStub()
os.Exit(m.Run())
}

View File

@ -5,7 +5,6 @@ import (
"context"
"io"
"os"
"os/exec"
"time"
"hakurei.app/container"
@ -19,16 +18,10 @@ var (
msgStaticGlibc = []byte("not a dynamic executable")
)
func Exec(ctx context.Context, p string) ([]*Entry, error) { return ExecFilter(ctx, nil, nil, p) }
func ExecFilter(ctx context.Context,
commandContext func(context.Context) *exec.Cmd,
f func([]byte) []byte,
p string) ([]*Entry, error) {
func Exec(ctx context.Context, p string) ([]*Entry, error) {
c, cancel := context.WithTimeout(ctx, lddTimeout)
defer cancel()
z := container.New(c, "ldd", p)
z.CommandContext = commandContext
z.Hostname = "hakurei-ldd"
z.SeccompFlags |= seccomp.AllowMultiarch
z.SeccompPresets |= seccomp.PresetStrict
@ -54,8 +47,5 @@ func ExecFilter(ctx context.Context,
}
v := stdout.Bytes()
if f != nil {
v = f(v)
}
return Parse(v)
}

View File

@ -1,22 +1,17 @@
package dbus_test
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"os/exec"
"strings"
"syscall"
"testing"
"time"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal"
"hakurei.app/internal/hlog"
"hakurei.app/system/dbus"
)
@ -64,20 +59,23 @@ func TestFinalise(t *testing.T) {
}
func TestProxyStartWaitCloseString(t *testing.T) {
oldWaitDelay := helper.WaitDelay
helper.WaitDelay = 16 * time.Second
t.Cleanup(func() { helper.WaitDelay = oldWaitDelay })
t.Run("sandbox", func(t *testing.T) {
proxyName := dbus.ProxyName
dbus.ProxyName = os.Args[0]
t.Cleanup(func() { dbus.ProxyName = proxyName })
testProxyFinaliseStartWaitCloseString(t, true)
})
t.Run("sandbox", func(t *testing.T) { testProxyFinaliseStartWaitCloseString(t, true) })
t.Run("direct", func(t *testing.T) { testProxyFinaliseStartWaitCloseString(t, false) })
}
func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) {
{
oldWaitDelay := helper.WaitDelay
helper.WaitDelay = 16 * time.Second
t.Cleanup(func() { helper.WaitDelay = oldWaitDelay })
}
{
proxyName := dbus.ProxyName
dbus.ProxyName = os.Args[0]
t.Cleanup(func() { dbus.ProxyName = proxyName })
}
var p *dbus.Proxy
t.Run("string for nil proxy", func(t *testing.T) {
@ -122,35 +120,12 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) {
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
defer cancel()
if !useSandbox {
p = dbus.NewDirect(ctx, final, nil)
} else {
p = dbus.New(ctx, final, nil)
}
p.CommandContext = func(ctx context.Context) (cmd *exec.Cmd) {
return exec.CommandContext(ctx, os.Args[0], "-test.v",
"-test.run=TestHelperInit", "--", "init")
}
p.CmdF = func(v any) {
if useSandbox {
z := v.(*container.Container)
if z.Args[0] != dbus.ProxyName {
panic(fmt.Sprintf("unexpected argv0 %q", os.Args[0]))
}
z.Args = append([]string{os.Args[0], "-test.run=TestHelperStub", "--"}, z.Args[1:]...)
} else {
cmd := v.(*exec.Cmd)
if cmd.Args[0] != dbus.ProxyName {
panic(fmt.Sprintf("unexpected argv0 %q", os.Args[0]))
}
cmd.Err = nil
cmd.Path = os.Args[0]
cmd.Args = append([]string{os.Args[0], "-test.run=TestHelperStub", "--"}, cmd.Args[1:]...)
}
}
p.FilterF = func(v []byte) []byte { return bytes.SplitN(v, []byte("TestHelperInit\n"), 2)[1] }
output := new(strings.Builder)
if !useSandbox {
p = dbus.NewDirect(ctx, final, output)
} else {
p = dbus.New(ctx, final, output)
}
t.Run("invalid wait", func(t *testing.T) {
wantErr := "dbus: not started"
@ -176,9 +151,9 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) {
}
t.Run("string", func(t *testing.T) {
wantSubstr := fmt.Sprintf("%s -test.run=TestHelperStub -- --args=3 --fd=4", os.Args[0])
wantSubstr := fmt.Sprintf("%s --args=3 --fd=4", os.Args[0])
if useSandbox {
wantSubstr = fmt.Sprintf(`argv: ["%s" "-test.run=TestHelperStub" "--" "--args=3" "--fd=4"], filter: true, rules: 0, flags: 0x1, presets: 0xf`, os.Args[0])
wantSubstr = fmt.Sprintf(`argv: ["%s" "--args=3" "--fd=4"], filter: true, rules: 0, flags: 0x1, presets: 0xf`, os.Args[0])
}
if got := p.String(); !strings.Contains(got, wantSubstr) {
t.Errorf("String: %q, want %q",
@ -203,11 +178,3 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) {
})
}
}
func TestHelperInit(t *testing.T) {
if len(os.Args) != 5 || os.Args[4] != "init" {
return
}
container.SetOutput(hlog.Output{})
container.Init(hlog.Prepare, internal.InstallOutput)
}

View File

@ -36,9 +36,6 @@ func (p *Proxy) Start() error {
if !p.useSandbox {
p.helper = helper.NewDirect(ctx, p.name, p.final, true, argF, func(cmd *exec.Cmd) {
if p.CmdF != nil {
p.CmdF(cmd)
}
if p.output != nil {
cmd.Stdout, cmd.Stderr = p.output, p.output
}
@ -56,7 +53,7 @@ func (p *Proxy) Start() error {
}
var libPaths []string
if entries, err := ldd.ExecFilter(ctx, p.CommandContext, p.FilterF, toolPath); err != nil {
if entries, err := ldd.Exec(ctx, toolPath); err != nil {
return err
} else {
libPaths = ldd.Path(entries)
@ -69,15 +66,10 @@ func (p *Proxy) Start() error {
z.SeccompFlags |= seccomp.AllowMultiarch
z.SeccompPresets |= seccomp.PresetStrict
z.Hostname = "hakurei-dbus"
z.CommandContext = p.CommandContext
if p.output != nil {
z.Stdout, z.Stderr = p.output, p.output
}
if p.CmdF != nil {
p.CmdF(z)
}
// these lib paths are unpredictable, so mount them first so they cannot cover anything
for _, name := range libPaths {
z.Bind(name, name, 0)

17
system/dbus/proc_test.go Normal file
View File

@ -0,0 +1,17 @@
package dbus_test
import (
"os"
"testing"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal"
"hakurei.app/internal/hlog"
)
func TestMain(m *testing.M) {
container.TryArgv0(hlog.Output{}, hlog.Prepare, internal.InstallOutput)
helper.InternalHelperStub()
os.Exit(m.Run())
}

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"io"
"os/exec"
"sync"
"syscall"
@ -37,10 +36,6 @@ type Proxy struct {
useSandbox bool
name string
CmdF func(any)
CommandContext func(ctx context.Context) (cmd *exec.Cmd)
FilterF func([]byte) []byte
mu, pmu sync.RWMutex
}

View File

@ -1,9 +0,0 @@
package dbus_test
import (
"testing"
"hakurei.app/helper"
)
func TestHelperStub(t *testing.T) { helper.InternalHelperStub() }