internal/app: relocate late sys/params outcome
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m10s
Test / Hakurei (push) Successful in 3m11s
Test / Hpkg (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 4m30s
Test / Hakurei (race detector) (push) Successful in 5m22s
Test / Flake checks (push) Successful in 1m29s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m10s
Test / Hakurei (push) Successful in 3m11s
Test / Hpkg (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 4m30s
Test / Hakurei (race detector) (push) Successful in 5m22s
Test / Flake checks (push) Successful in 1m29s
This will end up merged with another op after reordering. For now relocate it into its dedicated op for test instrumentation. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
5bf28901a4
commit
034c59a26a
@ -10,17 +10,12 @@ import (
|
|||||||
"maps"
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/fhs"
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal/app/state"
|
"hakurei.app/internal/app/state"
|
||||||
"hakurei.app/system"
|
"hakurei.app/system"
|
||||||
"hakurei.app/system/acl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newWithMessage(msg string) error { return newWithMessageError(msg, os.ErrInvalid) }
|
func newWithMessage(msg string) error { return newWithMessageError(msg, os.ErrInvalid) }
|
||||||
@ -49,10 +44,8 @@ type outcome struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID, config *hst.Config) error {
|
func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID, config *hst.Config) error {
|
||||||
const (
|
// only used for a nil configured env map
|
||||||
// only used for a nil configured env map
|
const envAllocSize = 1 << 6
|
||||||
envAllocSize = 1 << 6
|
|
||||||
)
|
|
||||||
|
|
||||||
var kp finaliseProcess
|
var kp finaliseProcess
|
||||||
|
|
||||||
@ -60,7 +53,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
|
|||||||
// unreachable
|
// unreachable
|
||||||
panic("invalid call to finalise")
|
panic("invalid call to finalise")
|
||||||
}
|
}
|
||||||
if k.ctx != nil || k.proc != nil {
|
if k.ctx != nil || k.sys != nil || k.proc != nil {
|
||||||
// unreachable
|
// unreachable
|
||||||
panic("attempting to finalise twice")
|
panic("attempting to finalise twice")
|
||||||
}
|
}
|
||||||
@ -80,6 +73,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
|
|||||||
k.ct = ct
|
k.ct = ct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hsu expects numerical group ids
|
||||||
kp.supp = make([]string, len(config.Groups))
|
kp.supp = make([]string, len(config.Groups))
|
||||||
for i, name := range config.Groups {
|
for i, name := range config.Groups {
|
||||||
if gid, err := k.lookupGroupId(name); err != nil {
|
if gid, err := k.lookupGroupId(name); err != nil {
|
||||||
@ -123,7 +117,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
kp.runDirPath, kp.identity, kp.id = s.sc.RunDirPath, s.identity, s.id
|
kp.runDirPath, kp.identity, kp.id = s.sc.RunDirPath, s.identity, s.id
|
||||||
k.sys = system.New(k.ctx, msg, s.uid.unwrap())
|
sys := system.New(k.ctx, msg, s.uid.unwrap())
|
||||||
|
|
||||||
{
|
{
|
||||||
ops := []outcomeOp{
|
ops := []outcomeOp{
|
||||||
@ -151,8 +145,9 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
|
|||||||
if et&hst.EDBus != 0 {
|
if et&hst.EDBus != 0 {
|
||||||
ops = append(ops, &spDBusOp{})
|
ops = append(ops, &spDBusOp{})
|
||||||
}
|
}
|
||||||
|
ops = append(ops, spFinal{})
|
||||||
|
|
||||||
stateSys := outcomeStateSys{sys: k.sys, outcomeState: &s}
|
stateSys := outcomeStateSys{sys: sys, outcomeState: &s}
|
||||||
for _, op := range ops {
|
for _, op := range ops {
|
||||||
if err := op.toSystem(&stateSys, config); err != nil {
|
if err := op.toSystem(&stateSys, config); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -171,45 +166,9 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// flatten and sort env for deterministic behaviour
|
|
||||||
k.container.Env = make([]string, 0, len(stateParams.env))
|
|
||||||
for key, value := range stateParams.env {
|
|
||||||
if strings.IndexByte(key, '=') != -1 {
|
|
||||||
return &hst.AppError{Step: "flatten environment", Err: syscall.EINVAL,
|
|
||||||
Msg: fmt.Sprintf("invalid environment variable %s", key)}
|
|
||||||
}
|
|
||||||
k.container.Env = append(k.container.Env, key+"="+value)
|
|
||||||
}
|
|
||||||
slices.Sort(k.container.Env)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mount root read-only as the final setup Op
|
|
||||||
// TODO(ophestra): move this to spFilesystemOp after #8 and #9
|
|
||||||
k.container.Remount(fhs.AbsRoot, syscall.MS_RDONLY)
|
|
||||||
|
|
||||||
// append ExtraPerms last
|
|
||||||
for _, p := range config.ExtraPerms {
|
|
||||||
if p == nil || p.Path == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Ensure {
|
|
||||||
k.sys.Ensure(p.Path, 0700)
|
|
||||||
}
|
|
||||||
|
|
||||||
perms := make(acl.Perms, 0, 3)
|
|
||||||
if p.Read {
|
|
||||||
perms = append(perms, acl.Read)
|
|
||||||
}
|
|
||||||
if p.Write {
|
|
||||||
perms = append(perms, acl.Write)
|
|
||||||
}
|
|
||||||
if p.Execute {
|
|
||||||
perms = append(perms, acl.Execute)
|
|
||||||
}
|
|
||||||
k.sys.UpdatePermType(system.User, p.Path, perms...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k.sys = sys
|
||||||
k.proc = &kp
|
k.proc = &kp
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
63
internal/app/spfinal.go
Normal file
63
internal/app/spfinal.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"hakurei.app/container/fhs"
|
||||||
|
"hakurei.app/hst"
|
||||||
|
"hakurei.app/system"
|
||||||
|
"hakurei.app/system/acl"
|
||||||
|
)
|
||||||
|
|
||||||
|
// spFinal is a transitional op destined for removal after #3, #8, #9 has been resolved.
|
||||||
|
// It exists to avoid reordering the expected entries in test cases.
|
||||||
|
type spFinal struct{}
|
||||||
|
|
||||||
|
func (s spFinal) toSystem(state *outcomeStateSys, config *hst.Config) error {
|
||||||
|
// append ExtraPerms last
|
||||||
|
for _, p := range config.ExtraPerms {
|
||||||
|
if p == nil || p.Path == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Ensure {
|
||||||
|
state.sys.Ensure(p.Path, 0700)
|
||||||
|
}
|
||||||
|
|
||||||
|
perms := make(acl.Perms, 0, 3)
|
||||||
|
if p.Read {
|
||||||
|
perms = append(perms, acl.Read)
|
||||||
|
}
|
||||||
|
if p.Write {
|
||||||
|
perms = append(perms, acl.Write)
|
||||||
|
}
|
||||||
|
if p.Execute {
|
||||||
|
perms = append(perms, acl.Execute)
|
||||||
|
}
|
||||||
|
state.sys.UpdatePermType(system.User, p.Path, perms...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s spFinal) toContainer(state *outcomeStateParams) error {
|
||||||
|
// TODO(ophestra): move this to spFilesystemOp after #8 and #9
|
||||||
|
|
||||||
|
// mount root read-only as the final setup Op
|
||||||
|
state.params.Remount(fhs.AbsRoot, syscall.MS_RDONLY)
|
||||||
|
|
||||||
|
state.params.Env = make([]string, 0, len(state.env))
|
||||||
|
for key, value := range state.env {
|
||||||
|
if strings.IndexByte(key, '=') != -1 {
|
||||||
|
return &hst.AppError{Step: "flatten environment", Err: syscall.EINVAL,
|
||||||
|
Msg: fmt.Sprintf("invalid environment variable %s", key)}
|
||||||
|
}
|
||||||
|
state.params.Env = append(state.params.Env, key+"="+value)
|
||||||
|
}
|
||||||
|
// range over map has randomised order
|
||||||
|
slices.Sort(state.params.Env)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user