diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-10-17 21:29:27 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-10-17 21:29:27 +0900 |
| commit | 4a75529f04d504e9072085fe77080fc66dfd2b2e (patch) | |
| tree | b2a3dd1132297d43b5d681ba06c3c612ba255463 /internal | |
| parent | a7fe164e41705adf0e522c04c3edeb458a375aec (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')
| -rw-r--r-- | internal/testsuite/testsuite.go | 96 |
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 } |
