aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/testsuite
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-10-17 21:29:27 +0900
committerOphestra <cat@gensokyo.uk>2026-10-17 21:29:27 +0900
commit4a75529f04d504e9072085fe77080fc66dfd2b2e (patch)
treeb2a3dd1132297d43b5d681ba06c3c612ba255463 /internal/testsuite
parenta7fe164e41705adf0e522c04c3edeb458a375aec (diff)
cmd/hakurei/testsuite: set credentials for store access
This avoids breaking ownership of lock files. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/testsuite')
-rw-r--r--internal/testsuite/testsuite.go96
1 files changed, 78 insertions, 18 deletions
diff --git a/internal/testsuite/testsuite.go b/internal/testsuite/testsuite.go
index c4ca23e9..367cb4c0 100644
--- a/internal/testsuite/testsuite.go
+++ b/internal/testsuite/testsuite.go
@@ -20,6 +20,7 @@ import (
"os/user"
"path/filepath"
"reflect"
+ "runtime"
"slices"
"strconv"
"strings"
@@ -603,6 +604,82 @@ func MustScanFor(f func(ps *StatScanner) bool) int {
return ps.Stat().PID
}
+// storeLookup describes a store lookup request.
+type storeLookup struct {
+ // Identifier to look up.
+ id hst.ID
+ // Address of value to write result to.
+ p *hst.State
+ // Error encountered while fulfilling the request.
+ done chan<- error
+}
+
+var (
+ // storeThreads holds channels for dispatching requests to goroutines
+ // locked to threads configured with specific credentials.
+ storeThreads = make(map[[2]uint32]chan<- storeLookup)
+ // storeThreadsMu synchronises access to storeThreads.
+ storeThreadsMu sync.Mutex
+)
+
+// LookupStore looks up the specified identifier from the hakurei state store
+// and stores its contents in the value pointed to by p.
+func LookupStore(cred *syscall.Credential, id hst.ID, p *hst.State) error {
+ var key [2]uint32
+ if cred != nil {
+ key[0], key[1] = cred.Uid, cred.Gid
+ }
+
+ storeThreadsMu.Lock()
+ c, ok := storeThreads[key]
+ if !ok {
+ s := store.New(check.MustAbs(HakureiPrefix + "state"))
+ r := make(chan storeLookup)
+ go func() {
+ if cred != nil {
+ runtime.LockOSThread()
+ if err := syscall.Setfsuid(int(cred.Uid)); err != nil {
+ log.Fatalf("setfsuid: %v", err)
+ } else if err = syscall.Setfsgid(int(cred.Gid)); err != nil {
+ log.Fatalf("setfsgid: %v", err)
+ }
+ }
+
+ req:
+ for req := range r {
+ ok = false
+ entries, copyError := s.All()
+ for entry := range entries {
+ if entry.ID == req.id {
+ ok = true
+ if _, err := entry.Load(req.p, nil); err != nil {
+ req.done <- err
+ continue req
+ }
+ break
+ }
+ }
+ if err := copyError(); err != nil {
+ req.done <- err
+ continue
+ }
+ if !ok {
+ req.done <- fmt.Errorf("instance %s is not present in store", id.String())
+ continue
+ }
+ req.done <- nil
+ }
+ }()
+ c = r
+ storeThreads[key] = c
+ }
+ storeThreadsMu.Unlock()
+
+ done := make(chan error, 1)
+ c <- storeLookup{id, p, done}
+ return <-done
+}
+
// StartHakurei starts a hakurei container configured by c.
func StartHakurei(
ctx context.Context,
@@ -614,8 +691,6 @@ func StartHakurei(
scan, wait, verbose, insecure bool,
c *hst.Config,
) (p hst.State, pid int, err error) {
- s := store.New(check.MustAbs("/tmp/hakurei.0/state"))
-
var hakureiFlags string
if verbose {
hakureiFlags += " -v"
@@ -732,22 +807,7 @@ func StartHakurei(
"hakurei", "--json", "show", id.String(),
)
- var ok bool
- entries, copyError := s.All()
- for entry := range entries {
- if entry.ID == id {
- ok = true
- if _, err = entry.Load(&p, nil); err != nil {
- return
- }
- break
- }
- }
- if err = copyError(); err != nil {
- log.Fatal(err)
- }
- if !ok {
- err = fmt.Errorf("instance %s is not present in store", id.String())
+ if err = LookupStore(cred, id, &p); err != nil {
return
}