internal/outcome: optional shim private dir
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m20s
Test / Hakurei (push) Successful in 3m24s
Test / Hpkg (push) Successful in 4m1s
Test / Sandbox (race detector) (push) Successful in 4m32s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Flake checks (push) Successful in 1m40s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m20s
Test / Hakurei (push) Successful in 3m24s
Test / Hpkg (push) Successful in 4m1s
Test / Sandbox (race detector) (push) Successful in 4m32s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Flake checks (push) Successful in 1m40s
This is a private work directory owned by the specific shim. Useful for sockets owned by this instance of the shim and requires no direct assistance from the priv-side process. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -53,6 +53,10 @@ type syscallDispatcher interface {
|
|||||||
readdir(name string) ([]os.DirEntry, error)
|
readdir(name string) ([]os.DirEntry, error)
|
||||||
// tempdir provides [os.TempDir].
|
// tempdir provides [os.TempDir].
|
||||||
tempdir() string
|
tempdir() string
|
||||||
|
// mkdir provides [os.Mkdir].
|
||||||
|
mkdir(name string, perm os.FileMode) error
|
||||||
|
// removeAll provides [os.RemoveAll].
|
||||||
|
removeAll(path string) error
|
||||||
// exit provides [os.Exit].
|
// exit provides [os.Exit].
|
||||||
exit(code int)
|
exit(code int)
|
||||||
|
|
||||||
@@ -121,6 +125,8 @@ func (direct) stat(name string) (os.FileInfo, error) { return os.Stat(name)
|
|||||||
func (direct) open(name string) (osFile, error) { return os.Open(name) }
|
func (direct) open(name string) (osFile, error) { return os.Open(name) }
|
||||||
func (direct) readdir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
|
func (direct) readdir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
|
||||||
func (direct) tempdir() string { return os.TempDir() }
|
func (direct) tempdir() string { return os.TempDir() }
|
||||||
|
func (direct) mkdir(name string, perm os.FileMode) error { return os.Mkdir(name, perm) }
|
||||||
|
func (direct) removeAll(path string) error { return os.RemoveAll(path) }
|
||||||
func (direct) exit(code int) { os.Exit(code) }
|
func (direct) exit(code int) { os.Exit(code) }
|
||||||
|
|
||||||
func (direct) evalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) }
|
func (direct) evalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) }
|
||||||
|
|||||||
@@ -701,6 +701,8 @@ func (panicDispatcher) stat(string) (os.FileInfo, error) { pa
|
|||||||
func (panicDispatcher) open(string) (osFile, error) { panic("unreachable") }
|
func (panicDispatcher) open(string) (osFile, error) { panic("unreachable") }
|
||||||
func (panicDispatcher) readdir(string) ([]os.DirEntry, error) { panic("unreachable") }
|
func (panicDispatcher) readdir(string) ([]os.DirEntry, error) { panic("unreachable") }
|
||||||
func (panicDispatcher) tempdir() string { panic("unreachable") }
|
func (panicDispatcher) tempdir() string { panic("unreachable") }
|
||||||
|
func (panicDispatcher) mkdir(string, os.FileMode) error { panic("unreachable") }
|
||||||
|
func (panicDispatcher) removeAll(string) error { panic("unreachable") }
|
||||||
func (panicDispatcher) exit(int) { panic("unreachable") }
|
func (panicDispatcher) exit(int) { panic("unreachable") }
|
||||||
func (panicDispatcher) evalSymlinks(string) (string, error) { panic("unreachable") }
|
func (panicDispatcher) evalSymlinks(string) (string, error) { panic("unreachable") }
|
||||||
func (panicDispatcher) prctl(uintptr, uintptr, uintptr) error { panic("unreachable") }
|
func (panicDispatcher) prctl(uintptr, uintptr, uintptr) error { panic("unreachable") }
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
|
"hakurei.app/container/check"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
@@ -83,6 +84,55 @@ func Shim(msg message.Msg) {
|
|||||||
shimEntrypoint(direct{msg})
|
shimEntrypoint(direct{msg})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A shimPrivate holds state of the private work directory owned by shim.
|
||||||
|
type shimPrivate struct {
|
||||||
|
// Path to directory if created.
|
||||||
|
pathname *check.Absolute
|
||||||
|
|
||||||
|
k syscallDispatcher
|
||||||
|
id *stringPair[hst.ID]
|
||||||
|
}
|
||||||
|
|
||||||
|
// unwrap returns the underlying pathname.
|
||||||
|
func (sp *shimPrivate) unwrap() *check.Absolute {
|
||||||
|
if sp.pathname == nil {
|
||||||
|
if a, err := check.NewAbs(sp.k.tempdir()); err != nil {
|
||||||
|
sp.k.fatal(err)
|
||||||
|
panic("unreachable")
|
||||||
|
} else {
|
||||||
|
pathname := a.Append(".hakurei-shim-" + sp.id.String())
|
||||||
|
sp.k.getMsg().Verbosef("creating private work directory %q", pathname)
|
||||||
|
if err = sp.k.mkdir(pathname.String(), 0700); err != nil {
|
||||||
|
sp.k.fatal(err)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
sp.pathname = pathname
|
||||||
|
return sp.unwrap()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return sp.pathname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the absolute pathname to the directory held by shimPrivate.
|
||||||
|
func (sp *shimPrivate) String() string { return sp.unwrap().String() }
|
||||||
|
|
||||||
|
// destroy removes the directory held by shimPrivate.
|
||||||
|
func (sp *shimPrivate) destroy() {
|
||||||
|
defer func() { sp.pathname = nil }()
|
||||||
|
if sp.pathname != nil {
|
||||||
|
sp.k.getMsg().Verbosef("destroying private work directory %q", sp.pathname)
|
||||||
|
if err := sp.k.removeAll(sp.pathname.String()); err != nil {
|
||||||
|
sp.k.getMsg().GetLogger().Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// shimPipeWireTimeout is the duration pipewire-pulse is allowed to run before its socket becomes available.
|
||||||
|
shimPipeWireTimeout = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
func shimEntrypoint(k syscallDispatcher) {
|
func shimEntrypoint(k syscallDispatcher) {
|
||||||
msg := k.getMsg()
|
msg := k.getMsg()
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
@@ -208,6 +258,7 @@ func shimEntrypoint(k syscallDispatcher) {
|
|||||||
|
|
||||||
ctx, stop := k.notifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
ctx, stop := k.notifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
cancelContainer.Store(&stop)
|
cancelContainer.Store(&stop)
|
||||||
|
sp := shimPrivate{k: k, id: state.id}
|
||||||
z := container.New(ctx, msg)
|
z := container.New(ctx, msg)
|
||||||
z.Params = *stateParams.params
|
z.Params = *stateParams.params
|
||||||
z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr
|
z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
@@ -225,9 +276,11 @@ func shimEntrypoint(k syscallDispatcher) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printMessageError(f, "cannot start container:", err)
|
printMessageError(f, "cannot start container:", err)
|
||||||
|
sp.destroy()
|
||||||
k.exit(hst.ExitFailure)
|
k.exit(hst.ExitFailure)
|
||||||
}
|
}
|
||||||
if err := k.containerServe(z); err != nil {
|
if err := k.containerServe(z); err != nil {
|
||||||
|
sp.destroy()
|
||||||
printMessageError(func(v ...any) { k.fatal(fmt.Sprintln(v...)) },
|
printMessageError(func(v ...any) { k.fatal(fmt.Sprintln(v...)) },
|
||||||
"cannot configure container:", err)
|
"cannot configure container:", err)
|
||||||
}
|
}
|
||||||
@@ -236,10 +289,13 @@ func shimEntrypoint(k syscallDispatcher) {
|
|||||||
seccomp.Preset(std.PresetStrict, seccomp.AllowMultiarch),
|
seccomp.Preset(std.PresetStrict, seccomp.AllowMultiarch),
|
||||||
seccomp.AllowMultiarch,
|
seccomp.AllowMultiarch,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
sp.destroy()
|
||||||
k.fatalf("cannot load syscall filter: %v", err)
|
k.fatalf("cannot load syscall filter: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := k.containerWait(z); err != nil {
|
if err := k.containerWait(z); err != nil {
|
||||||
|
sp.destroy()
|
||||||
|
|
||||||
var exitError *exec.ExitError
|
var exitError *exec.ExitError
|
||||||
if !errors.As(err, &exitError) {
|
if !errors.As(err, &exitError) {
|
||||||
if errors.Is(err, context.Canceled) {
|
if errors.Is(err, context.Canceled) {
|
||||||
@@ -250,4 +306,5 @@ func shimEntrypoint(k syscallDispatcher) {
|
|||||||
}
|
}
|
||||||
k.exit(exitError.ExitCode())
|
k.exit(exitError.ExitCode())
|
||||||
}
|
}
|
||||||
|
sp.destroy()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user