From 087959e81bcd52104676ccacedd605e6491b4376 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Thu, 3 Jul 2025 04:11:38 +0900 Subject: [PATCH] app: remove split implementation It is completely nonsensical and highly error-prone to have multiple implementations of this in the same build. This should be switched at compile time instead therefore the split packages are pointless. Signed-off-by: Ophestra --- cmd/hakurei/command.go | 11 +++---- cmd/hakurei/internal/app/instance/errors.go | 17 ---------- cmd/hakurei/internal/app/instance/new.go | 33 ------------------- cmd/hakurei/internal/app/instance/shim.go | 6 ---- cmd/hakurei/parse.go | 2 +- cmd/hakurei/print.go | 2 +- cmd/hakurei/print_test.go | 7 ++-- {cmd/hakurei/internal => internal}/app/app.go | 14 +++++++- .../app.go => internal/app/app_linux.go | 12 +++---- .../app/app_linux_test.go | 12 +++---- .../app/app_nixos_linux_test.go | 6 ++-- .../app/app_pd_linux_test.go | 8 ++--- .../app/app_stub_linux_test.go | 2 +- .../app/container_linux.go | 6 ++-- .../errors.go => internal/app/errors_linux.go | 3 +- .../app/export_linux_test.go | 6 ++-- .../instance/common => internal/app}/path.go | 2 +- .../common => internal/app}/path_test.go | 2 +- .../app/process_linux.go | 5 ++- .../seal.go => internal/app/seal_linux.go | 9 +++-- .../shim.go => internal/app/shim_linux.go | 2 +- .../internal/app => internal/app/state}/id.go | 2 +- .../app => internal/app/state}/id_test.go | 26 +++++++-------- .../internal => internal/app}/state/join.go | 0 .../internal => internal/app}/state/multi.go | 9 +++-- .../app}/state/multi_test.go | 2 +- .../internal => internal/app}/state/state.go | 8 ++--- .../app}/state/state_test.go | 5 ++- .../app/strings_linux.go | 8 ++--- 29 files changed, 88 insertions(+), 139 deletions(-) delete mode 100644 cmd/hakurei/internal/app/instance/errors.go delete mode 100644 cmd/hakurei/internal/app/instance/new.go delete mode 100644 cmd/hakurei/internal/app/instance/shim.go rename {cmd/hakurei/internal => internal}/app/app.go (81%) rename cmd/hakurei/internal/app/internal/setuid/app.go => internal/app/app_linux.go (83%) rename cmd/hakurei/internal/app/internal/setuid/app_test.go => internal/app/app_linux_test.go (92%) rename cmd/hakurei/internal/app/internal/setuid/app_nixos_test.go => internal/app/app_nixos_linux_test.go (98%) rename cmd/hakurei/internal/app/internal/setuid/app_pd_test.go => internal/app/app_pd_linux_test.go (99%) rename cmd/hakurei/internal/app/internal/setuid/app_stub_test.go => internal/app/app_stub_linux_test.go (99%) rename cmd/hakurei/internal/app/instance/common/container.go => internal/app/container_linux.go (96%) rename cmd/hakurei/internal/app/internal/setuid/errors.go => internal/app/errors_linux.go (98%) rename cmd/hakurei/internal/app/internal/setuid/export_test.go => internal/app/export_linux_test.go (78%) rename {cmd/hakurei/internal/app/instance/common => internal/app}/path.go (94%) rename {cmd/hakurei/internal/app/instance/common => internal/app}/path_test.go (99%) rename cmd/hakurei/internal/app/internal/setuid/process.go => internal/app/process_linux.go (98%) rename cmd/hakurei/internal/app/internal/setuid/seal.go => internal/app/seal_linux.go (98%) rename cmd/hakurei/internal/app/internal/setuid/shim.go => internal/app/shim_linux.go (99%) rename {cmd/hakurei/internal/app => internal/app/state}/id.go (97%) rename {cmd/hakurei/internal/app => internal/app/state}/id_test.go (58%) rename {cmd/hakurei/internal => internal/app}/state/join.go (100%) rename {cmd/hakurei/internal => internal/app}/state/multi.go (97%) rename {cmd/hakurei/internal => internal/app}/state/multi_test.go (73%) rename {cmd/hakurei/internal => internal/app}/state/state.go (86%) rename {cmd/hakurei/internal => internal/app}/state/state_test.go (96%) rename cmd/hakurei/internal/app/internal/setuid/strings.go => internal/app/strings_linux.go (51%) diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go index 130329e..bbe679f 100644 --- a/cmd/hakurei/command.go +++ b/cmd/hakurei/command.go @@ -13,12 +13,11 @@ import ( "syscall" "time" - "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/app/instance" - "hakurei.app/cmd/hakurei/internal/state" "hakurei.app/command" "hakurei.app/hst" "hakurei.app/internal" + "hakurei.app/internal/app" + "hakurei.app/internal/app/state" "hakurei.app/internal/hlog" "hakurei.app/system" "hakurei.app/system/dbus" @@ -33,7 +32,7 @@ func buildCommand(out io.Writer) command.Command { Flag(&flagVerbose, "v", command.BoolFlag(false), "Increase log verbosity"). Flag(&flagJSON, "json", command.BoolFlag(false), "Serialise output in JSON when applicable") - c.Command("shim", command.UsageInternal, func([]string) error { instance.ShimMain(); return errSuccess }) + c.Command("shim", command.UsageInternal, func([]string) error { app.ShimMain(); return errSuccess }) c.Command("app", "Load app from configuration file", func(args []string) error { if len(args) < 1 { @@ -244,14 +243,14 @@ func runApp(config *hst.Config) { ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() // unreachable - a := instance.MustNew(instance.ISetuid, ctx, std) + a := app.MustNew(ctx, std) rs := new(app.RunState) if sa, err := a.Seal(config); err != nil { hlog.PrintBaseError(err, "cannot seal app:") internal.Exit(1) } else { - internal.Exit(instance.PrintRunStateErr(instance.ISetuid, rs, sa.Run(rs))) + internal.Exit(app.PrintRunStateErr(rs, sa.Run(rs))) } *(*int)(nil) = 0 // not reached diff --git a/cmd/hakurei/internal/app/instance/errors.go b/cmd/hakurei/internal/app/instance/errors.go deleted file mode 100644 index a5a8113..0000000 --- a/cmd/hakurei/internal/app/instance/errors.go +++ /dev/null @@ -1,17 +0,0 @@ -package instance - -import ( - "syscall" - - "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/app/internal/setuid" -) - -func PrintRunStateErr(whence int, rs *app.RunState, runErr error) (code int) { - switch whence { - case ISetuid: - return setuid.PrintRunStateErr(rs, runErr) - default: - panic(syscall.EINVAL) - } -} diff --git a/cmd/hakurei/internal/app/instance/new.go b/cmd/hakurei/internal/app/instance/new.go deleted file mode 100644 index 7e22f9e..0000000 --- a/cmd/hakurei/internal/app/instance/new.go +++ /dev/null @@ -1,33 +0,0 @@ -// Package instance exposes cross-package implementation details and provides constructors for builtin implementations. -package instance - -import ( - "context" - "log" - "syscall" - - "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/app/internal/setuid" - "hakurei.app/internal/sys" -) - -const ( - ISetuid = iota -) - -func New(whence int, ctx context.Context, os sys.State) (app.App, error) { - switch whence { - case ISetuid: - return setuid.New(ctx, os) - default: - return nil, syscall.EINVAL - } -} - -func MustNew(whence int, ctx context.Context, os sys.State) app.App { - a, err := New(whence, ctx, os) - if err != nil { - log.Fatalf("cannot create app: %v", err) - } - return a -} diff --git a/cmd/hakurei/internal/app/instance/shim.go b/cmd/hakurei/internal/app/instance/shim.go deleted file mode 100644 index f10b282..0000000 --- a/cmd/hakurei/internal/app/instance/shim.go +++ /dev/null @@ -1,6 +0,0 @@ -package instance - -import "hakurei.app/cmd/hakurei/internal/app/internal/setuid" - -// ShimMain is the main function of the shim process and runs as the unconstrained target user. -func ShimMain() { setuid.ShimMain() } diff --git a/cmd/hakurei/parse.go b/cmd/hakurei/parse.go index 16ece2f..bfbe144 100644 --- a/cmd/hakurei/parse.go +++ b/cmd/hakurei/parse.go @@ -10,8 +10,8 @@ import ( "strings" "syscall" - "hakurei.app/cmd/hakurei/internal/state" "hakurei.app/hst" + "hakurei.app/internal/app/state" "hakurei.app/internal/hlog" ) diff --git a/cmd/hakurei/print.go b/cmd/hakurei/print.go index 477ae3e..4f4e403 100644 --- a/cmd/hakurei/print.go +++ b/cmd/hakurei/print.go @@ -12,8 +12,8 @@ import ( "text/tabwriter" "time" - "hakurei.app/cmd/hakurei/internal/state" "hakurei.app/hst" + "hakurei.app/internal/app/state" "hakurei.app/internal/hlog" "hakurei.app/system/dbus" ) diff --git a/cmd/hakurei/print_test.go b/cmd/hakurei/print_test.go index 4e047bb..98486e0 100644 --- a/cmd/hakurei/print_test.go +++ b/cmd/hakurei/print_test.go @@ -5,14 +5,13 @@ import ( "testing" "time" - "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/state" "hakurei.app/hst" + "hakurei.app/internal/app/state" "hakurei.app/system/dbus" ) var ( - testID = app.ID{ + testID = state.ID{ 0x8e, 0x2c, 0x76, 0xb0, 0x66, 0xda, 0xbe, 0x57, 0x4c, 0xf0, 0x73, 0xbd, @@ -460,7 +459,7 @@ func Test_printPs(t *testing.T) { {"no entries", make(state.Entries), false, false, " Instance PID Application Uptime\n"}, {"no entries short", make(state.Entries), true, false, ""}, {"nil instance", state.Entries{testID: nil}, false, false, " Instance PID Application Uptime\n"}, - {"state corruption", state.Entries{app.ID{}: testState}, false, false, " Instance PID Application Uptime\n"}, + {"state corruption", state.Entries{state.ID{}: testState}, false, false, " Instance PID Application Uptime\n"}, {"valid pd", state.Entries{testID: &state.State{ID: testID, PID: 1 << 8, Config: new(hst.Config), Time: testAppTime}}, false, false, ` Instance PID Application Uptime 8e2c76b0 256 0 (app.hakurei.8e2c76b0) 1h2m32s diff --git a/cmd/hakurei/internal/app/app.go b/internal/app/app.go similarity index 81% rename from cmd/hakurei/internal/app/app.go rename to internal/app/app.go index b76773b..359a0ce 100644 --- a/cmd/hakurei/internal/app/app.go +++ b/internal/app/app.go @@ -2,15 +2,19 @@ package app import ( + "context" + "log" "syscall" "time" "hakurei.app/hst" + "hakurei.app/internal/app/state" + "hakurei.app/internal/sys" ) type App interface { // ID returns a copy of [ID] held by App. - ID() ID + ID() state.ID // Seal determines the outcome of config as a [SealedApp]. // The value of config might be overwritten and must not be used again. @@ -47,3 +51,11 @@ func (rs *RunState) SetStart() { now := time.Now().UTC() rs.Time = &now } + +func MustNew(ctx context.Context, os sys.State) App { + a, err := New(ctx, os) + if err != nil { + log.Fatalf("cannot create app: %v", err) + } + return a +} diff --git a/cmd/hakurei/internal/app/internal/setuid/app.go b/internal/app/app_linux.go similarity index 83% rename from cmd/hakurei/internal/app/internal/setuid/app.go rename to internal/app/app_linux.go index a8e350f..89ff6ed 100644 --- a/cmd/hakurei/internal/app/internal/setuid/app.go +++ b/internal/app/app_linux.go @@ -1,12 +1,12 @@ -package setuid +package app import ( "context" "fmt" "sync" - . "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/hst" + "hakurei.app/internal/app/state" "hakurei.app/internal/hlog" "hakurei.app/internal/sys" ) @@ -16,15 +16,15 @@ func New(ctx context.Context, os sys.State) (App, error) { a.sys = os a.ctx = ctx - id := new(ID) - err := NewAppID(id) + id := new(state.ID) + err := state.NewAppID(id) a.id = newID(id) return a, err } type app struct { - id *stringPair[ID] + id *stringPair[state.ID] sys sys.State ctx context.Context @@ -32,7 +32,7 @@ type app struct { mu sync.RWMutex } -func (a *app) ID() ID { a.mu.RLock(); defer a.mu.RUnlock(); return a.id.unwrap() } +func (a *app) ID() state.ID { a.mu.RLock(); defer a.mu.RUnlock(); return a.id.unwrap() } func (a *app) String() string { if a == nil { diff --git a/cmd/hakurei/internal/app/internal/setuid/app_test.go b/internal/app/app_linux_test.go similarity index 92% rename from cmd/hakurei/internal/app/internal/setuid/app_test.go rename to internal/app/app_linux_test.go index a07f6ac..7d572b5 100644 --- a/cmd/hakurei/internal/app/internal/setuid/app_test.go +++ b/internal/app/app_linux_test.go @@ -1,4 +1,4 @@ -package setuid_test +package app_test import ( "encoding/json" @@ -7,10 +7,10 @@ import ( "testing" "time" - "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/app/internal/setuid" "hakurei.app/container" "hakurei.app/hst" + "hakurei.app/internal/app" + "hakurei.app/internal/app/state" "hakurei.app/internal/sys" "hakurei.app/system" ) @@ -19,7 +19,7 @@ type sealTestCase struct { name string os sys.State config *hst.Config - id app.ID + id state.ID wantSys *system.I wantContainer *container.Params } @@ -29,7 +29,7 @@ func TestApp(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - a := setuid.NewWithID(tc.id, tc.os) + a := app.NewWithID(tc.id, tc.os) var ( gotSys *system.I gotContainer *container.Params @@ -39,7 +39,7 @@ func TestApp(t *testing.T) { t.Errorf("Seal: error = %v", err) return } else { - gotSys, gotContainer = setuid.AppIParams(a, sa) + gotSys, gotContainer = app.AppIParams(a, sa) } }) { return diff --git a/cmd/hakurei/internal/app/internal/setuid/app_nixos_test.go b/internal/app/app_nixos_linux_test.go similarity index 98% rename from cmd/hakurei/internal/app/internal/setuid/app_nixos_test.go rename to internal/app/app_nixos_linux_test.go index c4bcaf8..ba56bfa 100644 --- a/cmd/hakurei/internal/app/internal/setuid/app_nixos_test.go +++ b/internal/app/app_nixos_linux_test.go @@ -1,10 +1,10 @@ -package setuid_test +package app_test import ( - "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/container" "hakurei.app/container/seccomp" "hakurei.app/hst" + "hakurei.app/internal/app/state" "hakurei.app/system" "hakurei.app/system/acl" "hakurei.app/system/dbus" @@ -52,7 +52,7 @@ var testCasesNixos = []sealTestCase{ Data: "/var/lib/persist/module/hakurei/0/1", Identity: 1, Groups: []string{}, }, - app.ID{ + state.ID{ 0x8e, 0x2c, 0x76, 0xb0, 0x66, 0xda, 0xbe, 0x57, 0x4c, 0xf0, 0x73, 0xbd, diff --git a/cmd/hakurei/internal/app/internal/setuid/app_pd_test.go b/internal/app/app_pd_linux_test.go similarity index 99% rename from cmd/hakurei/internal/app/internal/setuid/app_pd_test.go rename to internal/app/app_pd_linux_test.go index 8985465..a2f9f24 100644 --- a/cmd/hakurei/internal/app/internal/setuid/app_pd_test.go +++ b/internal/app/app_pd_linux_test.go @@ -1,12 +1,12 @@ -package setuid_test +package app_test import ( "os" - "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/container" "hakurei.app/container/seccomp" "hakurei.app/hst" + "hakurei.app/internal/app/state" "hakurei.app/system" "hakurei.app/system/acl" "hakurei.app/system/dbus" @@ -16,7 +16,7 @@ var testCasesPd = []sealTestCase{ { "nixos permissive defaults no enablements", new(stubNixOS), &hst.Config{Username: "chronos", Data: "/home/chronos"}, - app.ID{ + state.ID{ 0x4a, 0x45, 0x0b, 0x65, 0x96, 0xd7, 0xbc, 0x15, 0xbd, 0x01, 0x78, 0x0e, @@ -115,7 +115,7 @@ var testCasesPd = []sealTestCase{ }, Enablements: system.EWayland | system.EDBus | system.EPulse, }, - app.ID{ + state.ID{ 0xeb, 0xf0, 0x83, 0xd1, 0xb1, 0x75, 0x91, 0x17, 0x82, 0xd4, 0x13, 0x36, diff --git a/cmd/hakurei/internal/app/internal/setuid/app_stub_test.go b/internal/app/app_stub_linux_test.go similarity index 99% rename from cmd/hakurei/internal/app/internal/setuid/app_stub_test.go rename to internal/app/app_stub_linux_test.go index 93a8c3f..0efc585 100644 --- a/cmd/hakurei/internal/app/internal/setuid/app_stub_test.go +++ b/internal/app/app_stub_linux_test.go @@ -1,4 +1,4 @@ -package setuid_test +package app_test import ( "fmt" diff --git a/cmd/hakurei/internal/app/instance/common/container.go b/internal/app/container_linux.go similarity index 96% rename from cmd/hakurei/internal/app/instance/common/container.go rename to internal/app/container_linux.go index 5ef9012..98cddc7 100644 --- a/cmd/hakurei/internal/app/instance/common/container.go +++ b/internal/app/container_linux.go @@ -1,4 +1,4 @@ -package common +package app import ( "errors" @@ -19,9 +19,9 @@ import ( // allocating slightly more as a margin for future expansion const preallocateOpsCount = 1 << 5 -// NewContainer initialises [sandbox.Params] via [hst.ContainerConfig]. +// newContainer initialises [container.Params] via [hst.ContainerConfig]. // Note that remaining container setup must be queued by the caller. -func NewContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*container.Params, map[string]string, error) { +func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*container.Params, map[string]string, error) { if s == nil { return nil, nil, syscall.EBADE } diff --git a/cmd/hakurei/internal/app/internal/setuid/errors.go b/internal/app/errors_linux.go similarity index 98% rename from cmd/hakurei/internal/app/internal/setuid/errors.go rename to internal/app/errors_linux.go index 58f88a2..b9bd6f5 100644 --- a/cmd/hakurei/internal/app/internal/setuid/errors.go +++ b/internal/app/errors_linux.go @@ -1,10 +1,9 @@ -package setuid +package app import ( "errors" "log" - . "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/internal/hlog" ) diff --git a/cmd/hakurei/internal/app/internal/setuid/export_test.go b/internal/app/export_linux_test.go similarity index 78% rename from cmd/hakurei/internal/app/internal/setuid/export_test.go rename to internal/app/export_linux_test.go index 5c7dd06..73c9df9 100644 --- a/cmd/hakurei/internal/app/internal/setuid/export_test.go +++ b/internal/app/export_linux_test.go @@ -1,13 +1,13 @@ -package setuid +package app import ( - . "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/container" + "hakurei.app/internal/app/state" "hakurei.app/internal/sys" "hakurei.app/system" ) -func NewWithID(id ID, os sys.State) App { +func NewWithID(id state.ID, os sys.State) App { a := new(app) a.id = newID(&id) a.sys = os diff --git a/cmd/hakurei/internal/app/instance/common/path.go b/internal/app/path.go similarity index 94% rename from cmd/hakurei/internal/app/instance/common/path.go rename to internal/app/path.go index ce40f4f..56e373d 100644 --- a/cmd/hakurei/internal/app/instance/common/path.go +++ b/internal/app/path.go @@ -1,4 +1,4 @@ -package common +package app import ( "path/filepath" diff --git a/cmd/hakurei/internal/app/instance/common/path_test.go b/internal/app/path_test.go similarity index 99% rename from cmd/hakurei/internal/app/instance/common/path_test.go rename to internal/app/path_test.go index b14f24d..b01d73c 100644 --- a/cmd/hakurei/internal/app/instance/common/path_test.go +++ b/internal/app/path_test.go @@ -1,4 +1,4 @@ -package common +package app import ( "testing" diff --git a/cmd/hakurei/internal/app/internal/setuid/process.go b/internal/app/process_linux.go similarity index 98% rename from cmd/hakurei/internal/app/internal/setuid/process.go rename to internal/app/process_linux.go index 8bc36e2..818c7d7 100644 --- a/cmd/hakurei/internal/app/internal/setuid/process.go +++ b/internal/app/process_linux.go @@ -1,4 +1,4 @@ -package setuid +package app import ( "context" @@ -12,10 +12,9 @@ import ( "syscall" "time" - . "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/state" "hakurei.app/container" "hakurei.app/internal" + "hakurei.app/internal/app/state" "hakurei.app/internal/hlog" "hakurei.app/system" ) diff --git a/cmd/hakurei/internal/app/internal/setuid/seal.go b/internal/app/seal_linux.go similarity index 98% rename from cmd/hakurei/internal/app/internal/setuid/seal.go rename to internal/app/seal_linux.go index 8e39deb..40c68c1 100644 --- a/cmd/hakurei/internal/app/internal/setuid/seal.go +++ b/internal/app/seal_linux.go @@ -1,4 +1,4 @@ -package setuid +package app import ( "bytes" @@ -16,11 +16,10 @@ import ( "sync/atomic" "syscall" - . "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/app/instance/common" "hakurei.app/container" "hakurei.app/hst" "hakurei.app/internal" + "hakurei.app/internal/app/state" "hakurei.app/internal/hlog" "hakurei.app/internal/sys" "hakurei.app/system" @@ -66,7 +65,7 @@ var posixUsername = regexp.MustCompilePOSIX("^[a-z_]([A-Za-z0-9_-]{0,31}|[A-Za-z // outcome stores copies of various parts of [hst.Config] type outcome struct { // copied from initialising [app] - id *stringPair[ID] + id *stringPair[state.ID] // copied from [sys.State] response runDirPath string @@ -281,7 +280,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co { var uid, gid int var err error - seal.container, seal.env, err = common.NewContainer(config.Container, sys, &uid, &gid) + seal.container, seal.env, err = newContainer(config.Container, sys, &uid, &gid) if err != nil { return hlog.WrapErrSuffix(err, "cannot initialise container configuration:") diff --git a/cmd/hakurei/internal/app/internal/setuid/shim.go b/internal/app/shim_linux.go similarity index 99% rename from cmd/hakurei/internal/app/internal/setuid/shim.go rename to internal/app/shim_linux.go index 3751e87..876c3e8 100644 --- a/cmd/hakurei/internal/app/internal/setuid/shim.go +++ b/internal/app/shim_linux.go @@ -1,4 +1,4 @@ -package setuid +package app import ( "context" diff --git a/cmd/hakurei/internal/app/id.go b/internal/app/state/id.go similarity index 97% rename from cmd/hakurei/internal/app/id.go rename to internal/app/state/id.go index e674c7d..11bbc3f 100644 --- a/cmd/hakurei/internal/app/id.go +++ b/internal/app/state/id.go @@ -1,4 +1,4 @@ -package app +package state import ( "crypto/rand" diff --git a/cmd/hakurei/internal/app/id_test.go b/internal/app/state/id_test.go similarity index 58% rename from cmd/hakurei/internal/app/id_test.go rename to internal/app/state/id_test.go index 1fe18fd..abf2c19 100644 --- a/cmd/hakurei/internal/app/id_test.go +++ b/internal/app/state/id_test.go @@ -1,22 +1,22 @@ -package app_test +package state_test import ( "errors" "testing" - . "hakurei.app/cmd/hakurei/internal/app" + "hakurei.app/internal/app/state" ) func TestParseAppID(t *testing.T) { t.Run("bad length", func(t *testing.T) { - if err := ParseAppID(new(ID), "meow"); !errors.Is(err, ErrInvalidLength) { - t.Errorf("ParseAppID: error = %v, wantErr = %v", err, ErrInvalidLength) + if err := state.ParseAppID(new(state.ID), "meow"); !errors.Is(err, state.ErrInvalidLength) { + t.Errorf("ParseAppID: error = %v, wantErr = %v", err, state.ErrInvalidLength) } }) t.Run("bad byte", func(t *testing.T) { wantErr := "invalid char '\\n' at byte 15" - if err := ParseAppID(new(ID), "02bc7f8936b2af6\n\ne2535cd71ef0bb7"); err == nil || err.Error() != wantErr { + if err := state.ParseAppID(new(state.ID), "02bc7f8936b2af6\n\ne2535cd71ef0bb7"); err == nil || err.Error() != wantErr { t.Errorf("ParseAppID: error = %v, wantErr = %v", err, wantErr) } }) @@ -30,30 +30,30 @@ func TestParseAppID(t *testing.T) { func FuzzParseAppID(f *testing.F) { for i := 0; i < 16; i++ { - id := new(ID) - if err := NewAppID(id); err != nil { + id := new(state.ID) + if err := state.NewAppID(id); err != nil { panic(err.Error()) } f.Add(id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]) } f.Fuzz(func(t *testing.T, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 byte) { - testParseAppID(t, &ID{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}) + testParseAppID(t, &state.ID{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}) }) } func testParseAppIDWithRandom(t *testing.T) { - id := new(ID) - if err := NewAppID(id); err != nil { + id := new(state.ID) + if err := state.NewAppID(id); err != nil { t.Fatalf("cannot generate app ID: %v", err) } testParseAppID(t, id) } -func testParseAppID(t *testing.T, id *ID) { +func testParseAppID(t *testing.T, id *state.ID) { s := id.String() - got := new(ID) - if err := ParseAppID(got, s); err != nil { + got := new(state.ID) + if err := state.ParseAppID(got, s); err != nil { t.Fatalf("cannot parse app ID: %v", err) } diff --git a/cmd/hakurei/internal/state/join.go b/internal/app/state/join.go similarity index 100% rename from cmd/hakurei/internal/state/join.go rename to internal/app/state/join.go diff --git a/cmd/hakurei/internal/state/multi.go b/internal/app/state/multi.go similarity index 97% rename from cmd/hakurei/internal/state/multi.go rename to internal/app/state/multi.go index 1b26c88..80a3abf 100644 --- a/cmd/hakurei/internal/state/multi.go +++ b/internal/app/state/multi.go @@ -13,7 +13,6 @@ import ( "sync" "syscall" - "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/hst" "hakurei.app/internal/hlog" ) @@ -130,7 +129,7 @@ type multiBackend struct { lock sync.RWMutex } -func (b *multiBackend) filename(id *app.ID) string { +func (b *multiBackend) filename(id *ID) string { return path.Join(b.path, id.String()) } @@ -190,8 +189,8 @@ func (b *multiBackend) load(decode bool) (Entries, error) { return nil, fmt.Errorf("unexpected directory %q in store", e.Name()) } - id := new(app.ID) - if err := app.ParseAppID(id, e.Name()); err != nil { + id := new(ID) + if err := ParseAppID(id, e.Name()); err != nil { return nil, err } @@ -336,7 +335,7 @@ func (b *multiBackend) encodeState(w io.WriteSeeker, state *State, configWriter return err } -func (b *multiBackend) Destroy(id app.ID) error { +func (b *multiBackend) Destroy(id ID) error { b.lock.Lock() defer b.lock.Unlock() diff --git a/cmd/hakurei/internal/state/multi_test.go b/internal/app/state/multi_test.go similarity index 73% rename from cmd/hakurei/internal/state/multi_test.go rename to internal/app/state/multi_test.go index 396c660..d493a38 100644 --- a/cmd/hakurei/internal/state/multi_test.go +++ b/internal/app/state/multi_test.go @@ -3,7 +3,7 @@ package state_test import ( "testing" - "hakurei.app/cmd/hakurei/internal/state" + "hakurei.app/internal/app/state" ) func TestMulti(t *testing.T) { testStore(t, state.NewMulti(t.TempDir())) } diff --git a/cmd/hakurei/internal/state/state.go b/internal/app/state/state.go similarity index 86% rename from cmd/hakurei/internal/state/state.go rename to internal/app/state/state.go index 787396a..42750ec 100644 --- a/cmd/hakurei/internal/state/state.go +++ b/internal/app/state/state.go @@ -1,3 +1,4 @@ +// Package state provides cross-process state tracking for hakurei container instances. package state import ( @@ -5,13 +6,12 @@ import ( "io" "time" - "hakurei.app/cmd/hakurei/internal/app" "hakurei.app/hst" ) var ErrNoConfig = errors.New("state does not contain config") -type Entries map[app.ID]*State +type Entries map[ID]*State type Store interface { // Do calls f exactly once and ensures store exclusivity until f returns. @@ -30,7 +30,7 @@ type Store interface { // Cursor provides access to the store type Cursor interface { Save(state *State, configWriter io.WriterTo) error - Destroy(id app.ID) error + Destroy(id ID) error Load() (Entries, error) Len() (int, error) } @@ -38,7 +38,7 @@ type Cursor interface { // State is an instance state type State struct { // hakurei instance id - ID app.ID `json:"instance"` + ID ID `json:"instance"` // child process PID value PID int `json:"pid"` // sealed app configuration diff --git a/cmd/hakurei/internal/state/state_test.go b/internal/app/state/state_test.go similarity index 96% rename from cmd/hakurei/internal/state/state_test.go rename to internal/app/state/state_test.go index dce7e44..0025918 100644 --- a/cmd/hakurei/internal/state/state_test.go +++ b/internal/app/state/state_test.go @@ -10,9 +10,8 @@ import ( "testing" "time" - "hakurei.app/cmd/hakurei/internal/app" - "hakurei.app/cmd/hakurei/internal/state" "hakurei.app/hst" + "hakurei.app/internal/app/state" ) func testStore(t *testing.T, s state.Store) { @@ -134,7 +133,7 @@ func testStore(t *testing.T, s state.Store) { } func makeState(t *testing.T, s *state.State, ct io.Writer) { - if err := app.NewAppID(&s.ID); err != nil { + if err := state.NewAppID(&s.ID); err != nil { t.Fatalf("cannot create dummy state: %v", err) } if err := gob.NewEncoder(ct).Encode(hst.Template()); err != nil { diff --git a/cmd/hakurei/internal/app/internal/setuid/strings.go b/internal/app/strings_linux.go similarity index 51% rename from cmd/hakurei/internal/app/internal/setuid/strings.go rename to internal/app/strings_linux.go index 274dcc4..e4465ce 100644 --- a/cmd/hakurei/internal/app/internal/setuid/strings.go +++ b/internal/app/strings_linux.go @@ -1,13 +1,13 @@ -package setuid +package app import ( "strconv" - . "hakurei.app/cmd/hakurei/internal/app" + "hakurei.app/internal/app/state" ) -func newInt(v int) *stringPair[int] { return &stringPair[int]{v, strconv.Itoa(v)} } -func newID(id *ID) *stringPair[ID] { return &stringPair[ID]{*id, id.String()} } +func newInt(v int) *stringPair[int] { return &stringPair[int]{v, strconv.Itoa(v)} } +func newID(id *state.ID) *stringPair[state.ID] { return &stringPair[state.ID]{*id, id.String()} } // stringPair stores a value and its string representation. type stringPair[T comparable] struct {