Compare commits

..

7 Commits

Author SHA1 Message Date
be0e387ab0
internal/info: relocate from internal
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m27s
Test / Hakurei (push) Successful in 3m15s
Test / Hpkg (push) Successful in 4m11s
Test / Sandbox (race detector) (push) Successful in 4m18s
Test / Hakurei (race detector) (push) Successful in 5m2s
Test / Flake checks (push) Successful in 1m30s
This is cleaner and makes more sense. The longer LDFLAGS was never a valid concern since it is always inserted by a script.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-13 07:29:46 +09:00
abeb67964f
treewide: document linkname uses
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m17s
Test / Hakurei (push) Successful in 3m15s
Test / Hpkg (push) Successful in 4m6s
Test / Sandbox (race detector) (push) Successful in 4m12s
Test / Hakurei (race detector) (push) Successful in 5m2s
Test / Flake checks (push) Successful in 1m26s
These provide justification for each use of linkname. Poorly thought out uses of linkname are removed.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-13 07:14:16 +09:00
bf5d10743f
treewide: import internal/system
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m18s
Test / Hakurei (push) Successful in 3m15s
Test / Hpkg (push) Successful in 4m12s
Test / Sandbox (race detector) (push) Successful in 4m16s
Test / Hakurei (race detector) (push) Successful in 5m8s
Test / Flake checks (push) Successful in 1m31s
For #24.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-13 01:22:47 +09:00
4e7aab07d5
internal/system: relocate from system
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m18s
Test / Hakurei (push) Successful in 3m17s
Test / Sandbox (race detector) (push) Successful in 4m7s
Test / Hpkg (push) Successful in 4m13s
Test / Hakurei (race detector) (push) Successful in 5m3s
Test / Flake checks (push) Successful in 1m40s
These packages are highly specific to hakurei and are difficult to use safely from other pieces of code.

Their exported symbols are made available until v0.4.0 where they will be removed for #24.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-13 01:17:47 +09:00
15a66a2b31
treewide: import internal/helper
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m15s
Test / Hakurei (push) Successful in 3m15s
Test / Hpkg (push) Successful in 4m4s
Test / Sandbox (race detector) (push) Successful in 4m8s
Test / Hakurei (race detector) (push) Successful in 5m3s
Test / Flake checks (push) Successful in 1m27s
For #24.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-12 23:19:34 +09:00
f347d44c22
internal/helper: relocate from helper
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m26s
Test / Hakurei (push) Successful in 3m15s
Test / Hpkg (push) Successful in 4m8s
Test / Sandbox (race detector) (push) Successful in 4m16s
Test / Hakurei (race detector) (push) Successful in 5m5s
Test / Flake checks (push) Successful in 1m23s
This package is ugly and is pending removal only kept alive by xdg-dbus-proxy.

Its exported symbols are made available until v0.4.0 where it will be removed for #24.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-12 23:16:13 +09:00
b5630f6883
test: move package sandbox internal
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Hakurei (push) Successful in 43s
Test / Hpkg (push) Successful in 40s
Test / Hakurei (race detector) (push) Successful in 43s
Test / Sandbox (push) Successful in 1m56s
Test / Sandbox (race detector) (push) Successful in 2m39s
Test / Flake checks (push) Successful in 1m24s
This should never be used outside vm tests.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-12 23:03:22 +09:00
114 changed files with 511 additions and 150 deletions

View File

@ -11,21 +11,24 @@ import (
"strconv"
"sync"
"time"
_ "unsafe"
_ "unsafe" // for go:linkname
"hakurei.app/command"
"hakurei.app/container/check"
"hakurei.app/container/fhs"
"hakurei.app/hst"
"hakurei.app/internal"
"hakurei.app/internal/env"
"hakurei.app/internal/info"
"hakurei.app/internal/outcome"
"hakurei.app/internal/system/dbus"
"hakurei.app/message"
"hakurei.app/system/dbus"
)
// optionalErrorUnwrap calls [errors.Unwrap] and returns the resulting value
// if it is not nil, or the original value if it is.
//
//go:linkname optionalErrorUnwrap hakurei.app/container.optionalErrorUnwrap
func optionalErrorUnwrap(_ error) error
func optionalErrorUnwrap(err error) error
func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErrs, out io.Writer) command.Command {
var (
@ -350,7 +353,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
}).Flag(&flagShort, "short", command.BoolFlag(false), "Print instance id")
}
c.Command("version", "Display version information", func(args []string) error { fmt.Println(internal.Version()); return errSuccess })
c.Command("version", "Display version information", func(args []string) error { fmt.Println(info.Version()); return errSuccess })
c.Command("license", "Show full license text", func(args []string) error { fmt.Println(license); return errSuccess })
c.Command("template", "Produce a config template", func(args []string) error { encodeJSON(log.Fatal, os.Stdout, false, hst.Template()); return errSuccess })
c.Command("help", "Show this help message", func([]string) error { c.PrintHelp(); return errSuccess })

View File

@ -1,18 +1,13 @@
package main_test
package main
import (
"io"
"reflect"
"strings"
"testing"
_ "unsafe"
"hakurei.app/container/stub"
)
//go:linkname decodeJSON hakurei.app/cmd/hakurei.decodeJSON
func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any)
func TestDecodeJSON(t *testing.T) {
t.Parallel()
@ -62,9 +57,6 @@ func TestDecodeJSON(t *testing.T) {
}
}
//go:linkname encodeJSON hakurei.app/cmd/hakurei.encodeJSON
func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any)
func TestEncodeJSON(t *testing.T) {
t.Parallel()
@ -74,7 +66,7 @@ func TestEncodeJSON(t *testing.T) {
want string
}{
{"marshaler", errorJSONMarshaler{},
`cannot encode json for main_test.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
`cannot encode json for main.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
{"default", func() {},
`cannot write json: json: unsupported type: func()`},
}

View File

@ -12,8 +12,8 @@ import (
"time"
"hakurei.app/hst"
"hakurei.app/internal"
"hakurei.app/internal/env"
"hakurei.app/internal/info"
"hakurei.app/internal/outcome"
"hakurei.app/internal/store"
"hakurei.app/message"
@ -24,20 +24,20 @@ func printShowSystem(output io.Writer, short, flagJSON bool) {
t := newPrinter(output)
defer t.MustFlush()
info := &hst.Info{Version: internal.Version(), User: new(outcome.Hsu).MustID(nil)}
env.CopyPaths().Copy(&info.Paths, info.User)
hi := &hst.Info{Version: info.Version(), User: new(outcome.Hsu).MustID(nil)}
env.CopyPaths().Copy(&hi.Paths, hi.User)
if flagJSON {
encodeJSON(log.Fatal, output, short, info)
encodeJSON(log.Fatal, output, short, hi)
return
}
t.Printf("Version:\t%s\n", info.Version)
t.Printf("User:\t%d\n", info.User)
t.Printf("TempDir:\t%s\n", info.TempDir)
t.Printf("SharePath:\t%s\n", info.SharePath)
t.Printf("RuntimePath:\t%s\n", info.RuntimePath)
t.Printf("RunDirPath:\t%s\n", info.RunDirPath)
t.Printf("Version:\t%s\n", hi.Version)
t.Printf("User:\t%d\n", hi.User)
t.Printf("TempDir:\t%s\n", hi.TempDir)
t.Printf("SharePath:\t%s\n", hi.SharePath)
t.Printf("RuntimePath:\t%s\n", hi.RuntimePath)
t.Printf("RunDirPath:\t%s\n", hi.RunDirPath)
}
// printShowInstance writes a representation of [hst.State] or [hst.Config] to output.

View File

@ -10,11 +10,11 @@ import (
"os/exec"
"hakurei.app/hst"
"hakurei.app/internal"
"hakurei.app/internal/info"
"hakurei.app/message"
)
var hakureiPathVal = internal.MustHakureiPath().String()
var hakureiPathVal = info.MustHakureiPath().String()
func mustRunApp(ctx context.Context, msg message.Msg, config *hst.Config, beforeFail func()) {
var (

View File

@ -14,8 +14,10 @@ import (
. "hakurei.app/container/check"
)
// unsafeAbs returns check.Absolute on any string value.
//
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
func unsafeAbs(_ string) *Absolute
func unsafeAbs(pathname string) *Absolute
func TestAbsoluteError(t *testing.T) {
t.Parallel()

View File

@ -8,8 +8,10 @@ import (
/* constants in this file bypass abs check, be extremely careful when changing them! */
// unsafeAbs returns check.Absolute on any string value.
//
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
func unsafeAbs(_ string) *check.Absolute
func unsafeAbs(pathname string) *check.Absolute
var (
// AbsRoot is [Root] as [check.Absolute].

View File

@ -7,8 +7,10 @@ import (
"hakurei.app/container/stub"
)
// Made available here to check panic recovery behaviour.
//
//go:linkname handleExitNew hakurei.app/container/stub.handleExitNew
func handleExitNew(_ testing.TB)
func handleExitNew(t testing.TB)
// overrideTFailNow overrides the Fail and FailNow method.
type overrideTFailNow struct {

6
dist/release.sh vendored
View File

@ -10,9 +10,9 @@ cp -rv "dist/comp" "${out}"
go generate ./...
go build -trimpath -v -o "${out}/bin/" -ldflags "-s -w -buildid= -extldflags '-static'
-X hakurei.app/internal.buildVersion=${VERSION}
-X hakurei.app/internal.hakureiPath=/usr/bin/hakurei
-X hakurei.app/internal.hsuPath=/usr/bin/hsu
-X hakurei.app/internal/info.buildVersion=${VERSION}
-X hakurei.app/internal/info.hakureiPath=/usr/bin/hakurei
-X hakurei.app/internal/info.hsuPath=/usr/bin/hsu
-X main.hakureiPath=/usr/bin/hakurei" ./...
rm -f "./${out}.tar.gz" && tar -C dist -czf "${out}.tar.gz" "${pname}"

73
helper/deprecated.go Normal file
View File

@ -0,0 +1,73 @@
// Package helper exposes the internal/helper package.
//
// Deprecated: This package will be removed in 0.4.
package helper
import (
"context"
"io"
"os"
"os/exec"
"time"
_ "unsafe" // for go:linkname
"hakurei.app/container"
"hakurei.app/container/check"
"hakurei.app/internal/helper"
"hakurei.app/message"
)
//go:linkname WaitDelay hakurei.app/internal/helper.WaitDelay
var WaitDelay time.Duration
const (
// HakureiHelper is set to 1 when args fd is enabled and 0 otherwise.
HakureiHelper = helper.HakureiHelper
// HakureiStatus is set to 1 when stat fd is enabled and 0 otherwise.
HakureiStatus = helper.HakureiStatus
)
type Helper = helper.Helper
// NewCheckedArgs returns a checked null-terminated argument writer for a copy of args.
//
//go:linkname NewCheckedArgs hakurei.app/internal/helper.NewCheckedArgs
func NewCheckedArgs(args ...string) (wt io.WriterTo, err error)
// MustNewCheckedArgs returns a checked null-terminated argument writer for a copy of args.
// If s contains a NUL byte this function panics instead of returning an error.
//
//go:linkname MustNewCheckedArgs hakurei.app/internal/helper.MustNewCheckedArgs
func MustNewCheckedArgs(args ...string) io.WriterTo
// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.
// Function argF returns an array of arguments passed directly to the child process.
//
//go:linkname NewDirect hakurei.app/internal/helper.NewDirect
func NewDirect(
ctx context.Context,
name string,
wt io.WriterTo,
stat bool,
argF func(argsFd, statFd int) []string,
cmdF func(cmd *exec.Cmd),
extraFiles []*os.File,
) Helper
// New initialises a Helper instance with wt as the null-terminated argument writer.
//
//go:linkname New hakurei.app/internal/helper.New
func New(
ctx context.Context,
msg message.Msg,
pathname *check.Absolute, name string,
wt io.WriterTo,
stat bool,
argF func(argsFd, statFd int) []string,
cmdF func(z *container.Container),
extraFiles []*os.File,
) Helper
// InternalHelperStub is an internal function but exported because it is cross-package;
// it is part of the implementation of the helper stub.
func InternalHelperStub() { helper.InternalHelperStub() }

63
helper/proc/deprecated.go Normal file
View File

@ -0,0 +1,63 @@
// Deprecated: This package will be removed in 0.4.
package proc
import (
"context"
"io"
"os"
"os/exec"
"time"
_ "unsafe" // for go:linkname
"hakurei.app/internal/helper/proc"
)
//go:linkname FulfillmentTimeout hakurei.app/internal/helper/proc.FulfillmentTimeout
var FulfillmentTimeout time.Duration
// A File is an extra file with deferred initialisation.
type File = proc.File
// ExtraFilesPre is a linked list storing addresses of [os.File].
type ExtraFilesPre = proc.ExtraFilesPre
// Fulfill calls the [File.Fulfill] method on all files, starts cmd and blocks until all fulfillment completes.
//
//go:linkname Fulfill hakurei.app/internal/helper/proc.Fulfill
func Fulfill(ctx context.Context,
v *[]*os.File, start func() error,
files []File, extraFiles *ExtraFilesPre,
) (err error)
// InitFile initialises f as part of the slice extraFiles points to,
// and returns its final fd value.
//
//go:linkname InitFile hakurei.app/internal/helper/proc.InitFile
func InitFile(f File, extraFiles *ExtraFilesPre) (fd uintptr)
// BaseFile implements the Init method of the File interface and provides indirect access to extra file state.
type BaseFile = proc.BaseFile
//go:linkname ExtraFile hakurei.app/internal/helper/proc.ExtraFile
func ExtraFile(cmd *exec.Cmd, f *os.File) (fd uintptr)
//go:linkname ExtraFileSlice hakurei.app/internal/helper/proc.ExtraFileSlice
func ExtraFileSlice(extraFiles *[]*os.File, f *os.File) (fd uintptr)
// NewWriterTo returns a [File] that receives content from wt on fulfillment.
//
//go:linkname NewWriterTo hakurei.app/internal/helper/proc.NewWriterTo
func NewWriterTo(wt io.WriterTo) File
// NewStat returns a [File] implementing the behaviour
// of the receiving end of xdg-dbus-proxy stat fd.
//
//go:linkname NewStat hakurei.app/internal/helper/proc.NewStat
func NewStat(s *io.Closer) File
var (
//go:linkname ErrStatFault hakurei.app/internal/helper/proc.ErrStatFault
ErrStatFault error
//go:linkname ErrStatRead hakurei.app/internal/helper/proc.ErrStatRead
ErrStatRead error
)

View File

@ -6,11 +6,13 @@ import (
"reflect"
"testing"
"time"
_ "unsafe"
_ "unsafe" // for go:linkname
"hakurei.app/hst"
)
// Made available here to check time encoding behaviour of [hst.ID].
//
//go:linkname newInstanceID hakurei.app/hst.newInstanceID
func newInstanceID(id *hst.ID, p uint64) error

View File

@ -7,7 +7,7 @@ import (
"syscall"
"testing"
"hakurei.app/helper"
"hakurei.app/internal/helper"
)
func TestArgsString(t *testing.T) {

View File

@ -10,7 +10,7 @@ import (
"sync"
"syscall"
"hakurei.app/helper/proc"
"hakurei.app/internal/helper/proc"
)
// NewDirect initialises a new direct Helper instance with wt as the null-terminated argument writer.

View File

@ -9,7 +9,7 @@ import (
"testing"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal/helper"
)
func TestCmd(t *testing.T) {

View File

@ -11,7 +11,7 @@ import (
"hakurei.app/container"
"hakurei.app/container/check"
"hakurei.app/helper/proc"
"hakurei.app/internal/helper/proc"
"hakurei.app/message"
)

View File

@ -9,7 +9,7 @@ import (
"hakurei.app/container"
"hakurei.app/container/check"
"hakurei.app/container/fhs"
"hakurei.app/helper"
"hakurei.app/internal/helper"
)
func TestContainer(t *testing.T) {

View File

@ -8,7 +8,7 @@ import (
"os"
"time"
"hakurei.app/helper/proc"
"hakurei.app/internal/helper/proc"
)
var WaitDelay = 2 * time.Second

View File

@ -13,7 +13,7 @@ import (
"testing"
"time"
"hakurei.app/helper"
"hakurei.app/internal/helper"
)
var (

View File

@ -5,7 +5,7 @@ import (
"testing"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal/helper"
)
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }

View File

@ -1,4 +1,4 @@
package internal
package info
import (
"log"

View File

@ -1,4 +1,4 @@
package internal
package info
import (
"reflect"

View File

@ -1,4 +1,4 @@
package internal
package info
// FallbackVersion is returned when a version string was not set by the linker.
const FallbackVersion = "dirty"

View File

@ -14,9 +14,9 @@ import (
"hakurei.app/container/check"
"hakurei.app/container/seccomp"
"hakurei.app/container/std"
"hakurei.app/internal"
"hakurei.app/internal/info"
"hakurei.app/internal/system/dbus"
"hakurei.app/message"
"hakurei.app/system/dbus"
)
// osFile represents [os.File].
@ -156,7 +156,7 @@ func (direct) seccompLoad(rules []std.NativeRule, flags seccomp.ExportFlag) erro
return seccomp.Load(rules, flags)
}
func (direct) mustHsuPath() *check.Absolute { return internal.MustHsuPath() }
func (direct) mustHsuPath() *check.Absolute { return info.MustHsuPath() }
func (direct) dbusAddress() (session, system string) { return dbus.Address() }

View File

@ -24,8 +24,8 @@ import (
"hakurei.app/container/std"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/internal/system"
"hakurei.app/message"
"hakurei.app/system"
)
// call initialises a [stub.Call].

View File

@ -8,8 +8,8 @@ import (
"os/user"
"hakurei.app/hst"
"hakurei.app/internal/system"
"hakurei.app/message"
"hakurei.app/system"
)
func newWithMessage(msg string) error { return newWithMessageError(msg, os.ErrInvalid) }

View File

@ -12,6 +12,8 @@ import (
// IsPollDescriptor reports whether fd is the descriptor being used by the poller.
//
// Made available here to determine and reject impossible fd.
//
//go:linkname IsPollDescriptor internal/poll.IsPollDescriptor
func IsPollDescriptor(fd uintptr) bool

View File

@ -21,10 +21,10 @@ import (
"hakurei.app/container/seccomp"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
"hakurei.app/message"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
)
func TestOutcomeMain(t *testing.T) {

View File

@ -10,9 +10,9 @@ import (
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/internal/env"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
"hakurei.app/message"
"hakurei.app/system"
"hakurei.app/system/acl"
)
// envAllocSize is the initial size of the env map pre-allocated when the configured env map is nil.

View File

@ -16,10 +16,10 @@ import (
"hakurei.app/container/check"
"hakurei.app/container/fhs"
"hakurei.app/hst"
"hakurei.app/internal"
"hakurei.app/internal/info"
"hakurei.app/internal/store"
"hakurei.app/internal/system"
"hakurei.app/message"
"hakurei.app/system"
)
const (
@ -39,7 +39,7 @@ func (k *outcome) main(msg message.Msg, identifierFd int) {
}
// read comp value early for early failure
hsuPath := internal.MustHsuPath()
hsuPath := info.MustHsuPath()
const (
// transitions to processCommit, or processFinal on failure

View File

@ -16,11 +16,11 @@ import (
"hakurei.app/container/seccomp"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
"hakurei.app/internal/validate"
"hakurei.app/message"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
)
const varRunNscd = fhs.Var + "run/nscd"

View File

@ -14,9 +14,9 @@ import (
"hakurei.app/container/std"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
)
func TestSpParamsOp(t *testing.T) {

View File

@ -5,8 +5,8 @@ import (
"hakurei.app/container/fhs"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
)
func init() { gob.Register(new(spDBusOp)) }

View File

@ -6,12 +6,12 @@ import (
"hakurei.app/container"
"hakurei.app/container/stub"
"hakurei.app/helper"
"hakurei.app/hst"
"hakurei.app/internal/helper"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
"hakurei.app/message"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
)
func TestSpDBusOp(t *testing.T) {

View File

@ -11,8 +11,8 @@ import (
"hakurei.app/container/check"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
)
func TestSpPulseOp(t *testing.T) {

View File

@ -7,8 +7,8 @@ import (
"hakurei.app/container/fhs"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
)
const (

View File

@ -8,8 +8,8 @@ import (
"hakurei.app/container/std"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
)
func TestSpRuntimeOp(t *testing.T) {

View File

@ -7,8 +7,8 @@ import (
"hakurei.app/container/fhs"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
)
func init() { gob.Register(spTmpdirOp{}) }

View File

@ -8,8 +8,8 @@ import (
"hakurei.app/container/std"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
)
func TestSpTmpdirOp(t *testing.T) {

View File

@ -5,8 +5,8 @@ import (
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/system/wayland"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/wayland"
)
func init() { gob.Register(new(spWaylandOp)) }
@ -25,8 +25,8 @@ func (s *spWaylandOp) toSystem(state *outcomeStateSys) error {
// outer wayland socket (usually `/run/user/%d/wayland-%d`)
var socketPath *check.Absolute
if name, ok := state.k.lookupEnv(wayland.WaylandDisplay); !ok {
state.msg.Verbose(wayland.WaylandDisplay + " is not set, assuming " + wayland.FallbackName)
if name, ok := state.k.lookupEnv(wayland.Display); !ok {
state.msg.Verbose(wayland.Display + " is not set, assuming " + wayland.FallbackName)
socketPath = state.sc.RuntimePath.Append(wayland.FallbackName)
} else if a, err := check.NewAbs(name); err != nil {
socketPath = state.sc.RuntimePath.Append(name)
@ -53,7 +53,7 @@ func (s *spWaylandOp) toSystem(state *outcomeStateSys) error {
func (s *spWaylandOp) toContainer(state *outcomeStateParams) error {
innerPath := state.runtimeDir.Append(wayland.FallbackName)
state.env[wayland.WaylandDisplay] = wayland.FallbackName
state.env[wayland.Display] = wayland.FallbackName
if s.SocketPath == nil {
state.params.Bind(state.instancePath().Append("wayland"), innerPath, 0)
} else {

View File

@ -6,9 +6,9 @@ import (
"hakurei.app/container"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system"
"hakurei.app/system/acl"
"hakurei.app/system/wayland"
"hakurei.app/internal/system"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/wayland"
)
func TestSpWaylandOp(t *testing.T) {
@ -47,7 +47,7 @@ func TestSpWaylandOp(t *testing.T) {
Ops: new(container.Ops).
Bind(m(wantInstancePrefix+"/wayland"), m("/run/user/1000/wayland-0"), 0),
}, paramsWantEnv(config, map[string]string{
wayland.WaylandDisplay: wayland.FallbackName,
wayland.Display: wayland.FallbackName,
}, nil), nil},
{"success direct", func(isShim, _ bool) outcomeOp {
@ -75,7 +75,7 @@ func TestSpWaylandOp(t *testing.T) {
Ops: new(container.Ops).
Bind(m("/proc/nonexistent/wayland"), m("/run/user/1000/wayland-0"), 0),
}, paramsWantEnv(config, map[string]string{
wayland.WaylandDisplay: wayland.FallbackName,
wayland.Display: wayland.FallbackName,
}, nil), nil},
{"success", func(bool, bool) outcomeOp {
@ -98,7 +98,7 @@ func TestSpWaylandOp(t *testing.T) {
Ops: new(container.Ops).
Bind(m(wantInstancePrefix+"/wayland"), m("/run/user/1000/wayland-0"), 0),
}, paramsWantEnv(config, map[string]string{
wayland.WaylandDisplay: wayland.FallbackName,
wayland.Display: wayland.FallbackName,
}, nil), nil},
})
}

View File

@ -11,7 +11,7 @@ import (
"hakurei.app/container/check"
"hakurei.app/container/fhs"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/internal/system/acl"
)
var absX11SocketDir = fhs.AbsTmp.Append(".X11-unix")

View File

@ -7,7 +7,7 @@ import (
"hakurei.app/container"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/internal/system/acl"
)
func TestSpX11Op(t *testing.T) {

View File

@ -27,7 +27,7 @@ func TestEntryData(t *testing.T) {
return buf.String()
}
}
templateStateGob := mustEncodeGob(newTemplateState())
templateStateGob := mustEncodeGob(NewTemplateState())
testCases := []struct {
name string
@ -45,11 +45,11 @@ func TestEntryData(t *testing.T) {
Step: "validate configuration", Err: hst.ErrConfigNull,
Msg: "invalid configuration"}},
{"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, newTemplateState(), &hst.AppError{
{"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, NewTemplateState(), &hst.AppError{
Step: "validate state enablement", Err: os.ErrInvalid,
Msg: "state entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa has unexpected enablement byte 0xd, 0xff"}},
{"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, newTemplateState(), nil},
{"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, NewTemplateState(), nil},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@ -105,7 +105,7 @@ func TestEntryData(t *testing.T) {
t.Run("encode fault", func(t *testing.T) {
t.Parallel()
s := newTemplateState()
s := NewTemplateState()
t.Run("gob", func(t *testing.T) {
var want = &hst.AppError{Step: "encode state body", Err: stub.UniqueError(0xcafe)}
@ -123,8 +123,8 @@ func TestEntryData(t *testing.T) {
})
}
// newTemplateState returns the address of a new template [hst.State] struct.
func newTemplateState() *hst.State {
// NewTemplateState returns the address of a new template [hst.State] struct.
func NewTemplateState() *hst.State {
return &hst.State{
ID: hst.ID(bytes.Repeat([]byte{0xaa}, len(hst.ID{}))),
PID: 0xcafe,

View File

@ -10,7 +10,7 @@ import (
"strings"
"syscall"
"testing"
_ "unsafe"
_ "unsafe" // for go:linkname
"hakurei.app/container/check"
"hakurei.app/container/stub"
@ -18,18 +18,23 @@ import (
"hakurei.app/internal/store"
)
//go:linkname newTemplateState hakurei.app/internal/store.newTemplateState
func newTemplateState() *hst.State
// Made available here for direct validation of state entry files.
//
//go:linkname entryDecode hakurei.app/internal/store.entryDecode
func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error)
// Made available here for direct access to known segment handles.
//
//go:linkname newHandle hakurei.app/internal/store.newHandle
func newHandle(base *check.Absolute, identity int) *store.Handle
// Made available here to check open error handling behaviour.
//
//go:linkname open hakurei.app/internal/store.(*EntryHandle).open
func open(eh *store.EntryHandle, flag int, perm os.FileMode) (*os.File, error)
// Made available here to check the saveload cycle.
//
//go:linkname save hakurei.app/internal/store.(*EntryHandle).save
func save(eh *store.EntryHandle, state *hst.State) error
@ -91,9 +96,9 @@ func TestStateEntryHandle(t *testing.T) {
t.Run("saveload", func(t *testing.T) {
t.Parallel()
eh := store.EntryHandle{Pathname: check.MustAbs(t.TempDir()).Append("entry"),
ID: newTemplateState().ID}
ID: store.NewTemplateState().ID}
if err := save(&eh, newTemplateState()); err != nil {
if err := save(&eh, store.NewTemplateState()); err != nil {
t.Fatalf("save: error = %v", err)
}
@ -112,7 +117,7 @@ func TestStateEntryHandle(t *testing.T) {
t.Fatal(f.Close())
}
if want := newTemplateState(); !reflect.DeepEqual(&got, want) {
if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
t.Errorf("entryDecode: %#v, want %#v", &got, want)
}
})
@ -122,7 +127,7 @@ func TestStateEntryHandle(t *testing.T) {
if et, err := eh.Load(nil); err != nil {
t.Fatalf("load: error = %v", err)
} else if want := newTemplateState().Enablements.Unwrap(); et != want {
} else if want := store.NewTemplateState().Enablements.Unwrap(); et != want {
t.Errorf("load: et = %x, want %x", et, want)
}
})
@ -133,7 +138,7 @@ func TestStateEntryHandle(t *testing.T) {
var got hst.State
if _, err := eh.Load(&got); err != nil {
t.Fatalf("load: error = %v", err)
} else if want := newTemplateState(); !reflect.DeepEqual(&got, want) {
} else if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
t.Errorf("load: %#v, want %#v", &got, want)
}
})

View File

@ -12,13 +12,15 @@ import (
"syscall"
"testing"
"time"
_ "unsafe"
_ "unsafe" // for go:linkname
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/internal/store"
)
// Made available here to check bigLock error handling behaviour.
//
//go:linkname bigLock hakurei.app/internal/store.(*Store).bigLock
func bigLock(s *store.Store) (unlock func(), err error)

View File

@ -8,7 +8,7 @@ import (
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/internal/system/acl"
)
// UpdatePerm calls UpdatePermType with the [Process] criteria.

View File

@ -13,7 +13,7 @@ import (
"strconv"
"testing"
"hakurei.app/system/acl"
"hakurei.app/internal/system/acl"
)
const testFileName = "acl.test"

View File

@ -3,7 +3,7 @@ package acl_test
import (
"testing"
"hakurei.app/system/acl"
"hakurei.app/internal/system/acl"
)
func TestPerms(t *testing.T) {

View File

@ -7,7 +7,7 @@ import (
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/internal/system/acl"
)
func TestACLUpdateOp(t *testing.T) {

View File

@ -13,7 +13,7 @@ import (
"hakurei.app/container"
"hakurei.app/hst"
"hakurei.app/system/dbus"
"hakurei.app/internal/system/dbus"
)
// ErrDBusConfig is returned when a required [hst.BusConfig] argument is nil.

View File

@ -5,7 +5,7 @@ import (
"reflect"
"testing"
"hakurei.app/system/dbus"
"hakurei.app/internal/system/dbus"
)
func TestParse(t *testing.T) {

View File

@ -7,7 +7,7 @@ import (
"testing"
"hakurei.app/hst"
"hakurei.app/system/dbus"
"hakurei.app/internal/system/dbus"
)
func TestConfigArgs(t *testing.T) {

View File

@ -11,9 +11,9 @@ import (
"testing"
"time"
"hakurei.app/helper"
"hakurei.app/internal/helper"
"hakurei.app/internal/system/dbus"
"hakurei.app/message"
"hakurei.app/system/dbus"
)
func TestFinalise(t *testing.T) {

View File

@ -12,7 +12,7 @@ import (
"hakurei.app/container/check"
"hakurei.app/container/seccomp"
"hakurei.app/container/std"
"hakurei.app/helper"
"hakurei.app/internal/helper"
"hakurei.app/ldd"
)

View File

@ -5,7 +5,7 @@ import (
"testing"
"hakurei.app/container"
"hakurei.app/helper"
"hakurei.app/internal/helper"
)
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }

View File

@ -6,8 +6,8 @@ import (
"sync"
"syscall"
"hakurei.app/helper"
"hakurei.app/hst"
"hakurei.app/internal/helper"
"hakurei.app/message"
)

View File

@ -10,9 +10,9 @@ import (
"testing"
"hakurei.app/container/stub"
"hakurei.app/helper"
"hakurei.app/hst"
"hakurei.app/system/dbus"
"hakurei.app/internal/helper"
"hakurei.app/internal/system/dbus"
)
func TestDBusProxyOp(t *testing.T) {

View File

@ -7,9 +7,9 @@ import (
"os"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
"hakurei.app/system/internal/xcb"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
"hakurei.app/internal/system/xcb"
)
type osFile interface {

View File

@ -10,9 +10,9 @@ import (
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/system/dbus"
"hakurei.app/system/internal/xcb"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/dbus"
"hakurei.app/internal/system/xcb"
)
// call initialises a [stub.Call].

View File

@ -44,7 +44,7 @@ type Op interface {
String() string
}
// TypeString extends [Enablement.String] to support [User] and [Process].
// TypeString extends [hst.Enablement.String] to support [User] and [Process].
func TypeString(e hst.Enablement) string {
switch e {
case User:

View File

@ -11,8 +11,8 @@ import (
"hakurei.app/container/check"
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/internal/system/xcb"
"hakurei.app/message"
"hakurei.app/system/internal/xcb"
)
func TestCriteria(t *testing.T) {

View File

@ -7,8 +7,8 @@ import (
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/system/acl"
"hakurei.app/system/wayland"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/wayland"
)
type waylandConn interface {

View File

@ -1,4 +1,3 @@
// Package wayland implements Wayland security_context_v1 protocol.
package wayland
import (

View File

@ -1,3 +1,4 @@
// Package wayland implements Wayland security_context_v1 protocol.
package wayland
//go:generate sh -c "wayland-scanner client-header `pkg-config --variable=datarootdir wayland-protocols`/wayland-protocols/staging/security-context/security-context-v1.xml security-context-v1-protocol.h"
@ -13,10 +14,21 @@ import "C"
import (
"errors"
"strings"
"syscall"
)
var (
ErrContainsNull = errors.New("string contains null character")
const (
// Display contains the name of the server socket
// (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1147)
// which is concatenated with XDG_RUNTIME_DIR
// (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1171)
// or used as-is if absolute
// (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1176).
Display = "WAYLAND_DISPLAY"
// FallbackName is used as the wayland socket name if WAYLAND_DISPLAY is unset
// (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1149).
FallbackName = "wayland-0"
)
var resErr = [...]error{
@ -27,10 +39,10 @@ var resErr = [...]error{
func bindWaylandFd(socketPath string, fd uintptr, appID, instanceID string, syncFd uintptr) error {
if hasNull(appID) || hasNull(instanceID) {
return ErrContainsNull
return syscall.EINVAL
}
res := C.hakurei_bind_wayland_fd(C.CString(socketPath), C.int(fd), C.CString(appID), C.CString(instanceID), C.int(syncFd))
return resErr[int32(res)]
}
func hasNull(s string) bool { return strings.IndexByte(s, '\x00') > -1 }
func hasNull(s string) bool { return strings.IndexByte(s, 0) > -1 }

View File

@ -6,8 +6,8 @@ import (
"testing"
"hakurei.app/container/stub"
"hakurei.app/system/acl"
"hakurei.app/system/wayland"
"hakurei.app/internal/system/acl"
"hakurei.app/internal/system/wayland"
)
type stubWaylandConn struct {

View File

@ -2,7 +2,7 @@ package system
import (
"hakurei.app/hst"
"hakurei.app/system/internal/xcb"
"hakurei.app/internal/system/xcb"
)
// ChangeHosts inserts the target user into X11 hosts and deletes it once its [Enablement] is no longer satisfied.

View File

@ -5,7 +5,7 @@ import (
"hakurei.app/container/stub"
"hakurei.app/hst"
"hakurei.app/system/internal/xcb"
"hakurei.app/internal/system/xcb"
)
func TestXHostOp(t *testing.T) {

View File

@ -65,7 +65,7 @@ buildGoModule rec {
lib.attrsets.foldlAttrs
(
ldflags: name: value:
ldflags ++ [ "-X hakurei.app/internal.${name}=${value}" ]
ldflags ++ [ "-X hakurei.app/internal/info.${name}=${value}" ]
)
(
[ "-s -w" ]

Some files were not shown because too many files have changed in this diff Show More