internal/app: relocate state initialisation
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m9s
Test / Hakurei (push) Successful in 3m4s
Test / Hpkg (push) Successful in 4m4s
Test / Sandbox (race detector) (push) Successful in 4m37s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Flake checks (push) Successful in 1m28s

This is useful for testing.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-10-10 20:12:05 +09:00
parent f6dd9dab6a
commit 24de7c50a0
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
5 changed files with 19 additions and 24 deletions

View File

@ -450,15 +450,7 @@ func TestApp(t *testing.T) {
var gotSys *system.I var gotSys *system.I
{ {
sPriv := outcomeState{ sPriv := newOutcomeState(tc.k, msg, &tc.id, tc.config, &Hsu{k: tc.k})
ID: &tc.id,
Identity: tc.config.Identity,
UserID: (&Hsu{k: tc.k}).MustIDMsg(msg),
EnvPaths: copyPaths(tc.k),
Container: tc.config.Container,
}
sPriv.populateEarly(tc.k, msg)
if err := sPriv.populateLocal(tc.k, msg); err != nil { if err := sPriv.populateLocal(tc.k, msg); err != nil {
t.Fatalf("populateLocal: error = %#v", err) t.Fatalf("populateLocal: error = %#v", err)
} }
@ -574,6 +566,7 @@ type stubNixOS struct {
func (k *stubNixOS) new(func(k syscallDispatcher)) { panic("not implemented") } func (k *stubNixOS) new(func(k syscallDispatcher)) { panic("not implemented") }
func (k *stubNixOS) getpid() int { return 0xdeadbeef }
func (k *stubNixOS) getuid() int { return 1971 } func (k *stubNixOS) getuid() int { return 1971 }
func (k *stubNixOS) getgid() int { return 100 } func (k *stubNixOS) getgid() int { return 100 }

View File

@ -29,6 +29,8 @@ type syscallDispatcher interface {
// just synchronising access is not enough, as this is for test instrumentation. // just synchronising access is not enough, as this is for test instrumentation.
new(f func(k syscallDispatcher)) new(f func(k syscallDispatcher))
// getpid provides [os.Getpid].
getpid() int
// getuid provides [os.Getuid]. // getuid provides [os.Getuid].
getuid() int getuid() int
// getgid provides [os.Getgid]. // getgid provides [os.Getgid].
@ -70,6 +72,7 @@ type direct struct{}
func (k direct) new(f func(k syscallDispatcher)) { go f(k) } func (k direct) new(f func(k syscallDispatcher)) { go f(k) }
func (direct) getpid() int { return os.Getpid() }
func (direct) getuid() int { return os.Getuid() } func (direct) getuid() int { return os.Getuid() }
func (direct) getgid() int { return os.Getgid() } func (direct) getgid() int { return os.Getgid() }
func (direct) lookupEnv(key string) (string, bool) { return os.LookupEnv(key) } func (direct) lookupEnv(key string) (string, bool) { return os.LookupEnv(key) }

View File

@ -11,6 +11,7 @@ import (
type panicDispatcher struct{} type panicDispatcher struct{}
func (panicDispatcher) new(func(k syscallDispatcher)) { panic("unreachable") } func (panicDispatcher) new(func(k syscallDispatcher)) { panic("unreachable") }
func (panicDispatcher) getpid() int { panic("unreachable") }
func (panicDispatcher) getuid() int { panic("unreachable") } func (panicDispatcher) getuid() int { panic("unreachable") }
func (panicDispatcher) getgid() int { panic("unreachable") } func (panicDispatcher) getgid() int { panic("unreachable") }
func (panicDispatcher) lookupEnv(string) (string, bool) { panic("unreachable") } func (panicDispatcher) lookupEnv(string) (string, bool) { panic("unreachable") }

View File

@ -68,14 +68,7 @@ func (k *outcome) finalise(ctx context.Context, msg message.Msg, id *state.ID, c
} }
// early validation complete at this point // early validation complete at this point
s := outcomeState{ s := newOutcomeState(k.syscallDispatcher, msg, id, config, &Hsu{k: k})
ID: id,
Identity: config.Identity,
UserID: (&Hsu{k: k}).MustIDMsg(msg),
EnvPaths: copyPaths(k.syscallDispatcher),
Container: config.Container,
}
s.populateEarly(k.syscallDispatcher, msg)
if err := s.populateLocal(k.syscallDispatcher, msg); err != nil { if err := s.populateLocal(k.syscallDispatcher, msg); err != nil {
return err return err
} }
@ -87,7 +80,7 @@ func (k *outcome) finalise(ctx context.Context, msg message.Msg, id *state.ID, c
k.sys = sys k.sys = sys
k.supp = supp k.supp = supp
k.state = &s k.state = s
k.config = config k.config = config
return nil return nil
} }

View File

@ -2,7 +2,6 @@ package app
import ( import (
"errors" "errors"
"os"
"strconv" "strconv"
"hakurei.app/container" "hakurei.app/container"
@ -72,10 +71,16 @@ func (s *outcomeState) valid() bool {
s.EnvPaths != nil s.EnvPaths != nil
} }
// populateEarly populates exported fields via syscallDispatcher. // newOutcomeState returns the address of a new outcomeState with its exported fields populated via syscallDispatcher.
// This must only be called from the priv side. func newOutcomeState(k syscallDispatcher, msg message.Msg, id *state.ID, config *hst.Config, hsu *Hsu) *outcomeState {
func (s *outcomeState) populateEarly(k syscallDispatcher, msg message.Msg) { s := outcomeState{
s.Shim = &shimParams{PrivPID: os.Getpid(), Verbose: msg.IsVerbose()} Shim: &shimParams{PrivPID: k.getpid(), Verbose: msg.IsVerbose()},
ID: id,
Identity: config.Identity,
UserID: hsu.MustIDMsg(msg),
EnvPaths: copyPaths(k),
Container: config.Container,
}
// enforce bounds and default early // enforce bounds and default early
if s.Container.WaitDelay < 0 { if s.Container.WaitDelay < 0 {
@ -94,7 +99,7 @@ func (s *outcomeState) populateEarly(k syscallDispatcher, msg message.Msg) {
s.Mapuid, s.Mapgid = k.overflowUid(msg), k.overflowGid(msg) s.Mapuid, s.Mapgid = k.overflowUid(msg), k.overflowGid(msg)
} }
return return &s
} }
// populateLocal populates unexported fields from transmitted exported fields. // populateLocal populates unexported fields from transmitted exported fields.