diff options
| -rw-r--r-- | cmd/dist/main.go | 37 | ||||
| -rw-r--r-- | cmd/hakurei/command.go | 8 | ||||
| -rw-r--r-- | cmd/hakurei/command_test.go | 6 | ||||
| -rw-r--r-- | hst/container.go | 7 | ||||
| -rw-r--r-- | internal/outcome/outcome.go | 9 | ||||
| -rw-r--r-- | internal/outcome/shim.go | 7 | ||||
| -rw-r--r-- | internal/rosa/package/glib/loopvar-cast.patch | 13 | ||||
| -rw-r--r-- | internal/rosa/package/glib/package.az | 1 | ||||
| -rw-r--r-- | internal/rosa/package/python/package.az | 3 | ||||
| -rw-r--r-- | internal/wayland/security-context-v1-protocol.c | 2 | ||||
| -rw-r--r-- | internal/wayland/security-context-v1-protocol.h | 2 |
11 files changed, 86 insertions, 9 deletions
diff --git a/cmd/dist/main.go b/cmd/dist/main.go index 1034f282..40a0583c 100644 --- a/cmd/dist/main.go +++ b/cmd/dist/main.go @@ -4,6 +4,7 @@ package main import ( "archive/tar" + "bytes" "compress/gzip" "context" "crypto/sha512" @@ -57,6 +58,7 @@ func main() { verbose := os.Getenv("VERBOSE") != "" runTests := os.Getenv("HAKUREI_DIST_MAKE") == "" race := os.Getenv("HAKUREI_RACE") != "" + dynamic := os.Getenv("HAKUREI_DYNAMIC") != "" version = getenv("HAKUREI_VERSION", strings.TrimSpace(version)) prefix := getenv("PREFIX", "/usr/local") destdir := getenv("DESTDIR", "dist") @@ -69,6 +71,12 @@ func main() { version += "-race" } + if err := os.Setenv("CC", "clang"); err != nil { + log.Fatal(err) + } else if err = os.Setenv("CXX", "clang++"); err != nil { + log.Fatal(err) + } + if err := os.MkdirAll(destdir, 0755); err != nil { log.Fatal(err) } @@ -94,15 +102,36 @@ func main() { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() + const stubFlag = "-buildvcs=false" verboseFlag := "-v" if !verbose { - verboseFlag = "-buildvcs=false" + verboseFlag = stubFlag } raceFlag := "-race" if !race { - raceFlag = "-buildvcs=false" + raceFlag = stubFlag + } + + ldflagsStatic := " -extldflags=-static" + if dynamic { + cmd := exec.CommandContext(ctx, "llvm-config", "--host-target") + cmd.Stderr = os.Stderr + var p []byte + p, err = cmd.Output() + if err != nil { + log.Fatal(err) + } + p = bytes.TrimSpace(p) + _, abi, ok := strings.CutLast(string(p), "-") + if !ok { + log.Fatalf("invalid target %q", string(p)) + } + version += "-" + abi + + log.Println("WARNING: dynamic linking is not supported") + ldflagsStatic = "" } log.Printf("Building hakurei %s for %s/%s.", version, runtime.GOOS, runtime.GOARCH) @@ -112,7 +141,7 @@ func main() { "-trimpath", verboseFlag, raceFlag, "-o", s, "-ldflags=-s -w "+ - "-buildid= -linkmode external -extldflags=-static "+ + "-buildid= -linkmode external"+ldflagsStatic+" "+ "-X hakurei.app/internal/info.buildVersion="+version+" "+ "-X hakurei.app/internal/info.hakureiPath="+prefix+"/bin/hakurei "+ "-X hakurei.app/internal/info.hsuPath="+prefix+"/bin/hsu", @@ -136,7 +165,7 @@ func main() { log.Println("##### Testing Hakurei.") mustRun( ctx, nil, "go", "test", raceFlag, - "-ldflags=-buildid= -linkmode external -extldflags=-static", + "-ldflags=-buildid= -linkmode external"+ldflagsStatic, "./...", ) log.Println() diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go index 76004d4f..f14945ad 100644 --- a/cmd/hakurei/command.go +++ b/cmd/hakurei/command.go @@ -106,7 +106,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr flagSchedPolicy string flagSchedPriority int - flagPrivateRuntime, flagPrivateTmpdir bool + flagNoWait, flagPrivateRuntime, flagPrivateTmpdir bool flagWayland, flagX11, flagDBus, flagPipeWire, flagPulse bool ) @@ -194,6 +194,10 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr }, } + if flagNoWait { + config.Container.AdoptWaitDelay = -1 + } + if err := config.SchedPolicy.UnmarshalText( []byte(flagSchedPolicy), ); err != nil { @@ -315,6 +319,8 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr "Scheduling policy to set for the container"). Flag(&flagSchedPriority, "priority", command.IntFlag(0), "Scheduling priority to set for the container"). + Flag(&flagNoWait, "no-wait", command.BoolFlag(false), + "Do not wait for lingering processes to terminate"). Flag(&flagPrivateRuntime, "private-runtime", command.BoolFlag(false), "Do not share XDG_RUNTIME_DIR between containers under the same identity"). Flag(&flagPrivateTmpdir, "private-tmpdir", command.BoolFlag(false), diff --git a/cmd/hakurei/command_test.go b/cmd/hakurei/command_test.go index 059e18b1..49a1f9d4 100644 --- a/cmd/hakurei/command_test.go +++ b/cmd/hakurei/command_test.go @@ -39,8 +39,8 @@ commands: [--dbus-system <value>] [--mpris] [--dbus-log] [--id <value>] [-a <int>] [-g <value>] [-d <value>] [-u <value>] [--policy <value>] [--priority <int>] - [--private-runtime] [--private-tmpdir] [--wayland] [-X] - [--dbus] [--pipewire] [--pulse] <command> [<args>] + [--no-wait] [--private-runtime] [--private-tmpdir] + [--wayland] [-X] [--dbus] [--pipewire] [--pulse] <command> [<args>] flags: -X Enable direct connection to X11 @@ -62,6 +62,8 @@ flags: Reverse-DNS style Application identifier, leave empty to inherit instance identifier -mpris Allow owning MPRIS D-Bus path, has no effect if custom config is available + -no-wait + Do not wait for lingering processes to terminate -pipewire Enable connection to PipeWire via SecurityContext -policy string diff --git a/hst/container.go b/hst/container.go index 824b0982..c4cd2712 100644 --- a/hst/container.go +++ b/hst/container.go @@ -141,6 +141,13 @@ type ContainerConfig struct { // [WaitDelayDefault]. WaitDelay time.Duration `json:"wait_delay,omitempty"` + // Duration in nanoseconds to wait for lingering processes after the initial + // process terminates. + // + // Defaults to five seconds if zero or greater than five seconds. Values + // lesser than zero is equivalent to zero. + AdoptWaitDelay time.Duration `json:"adopt_wait_delay,omitempty"` + // Initial process environment variables. Env map[string]string `json:"env"` diff --git a/internal/outcome/outcome.go b/internal/outcome/outcome.go index 414b421f..19ca9c7b 100644 --- a/internal/outcome/outcome.go +++ b/internal/outcome/outcome.go @@ -6,6 +6,7 @@ import ( "errors" "maps" "strconv" + "time" "hakurei.app/check" "hakurei.app/container" @@ -125,6 +126,14 @@ func newOutcomeState(k syscallDispatcher, msg message.Msg, id *hst.ID, config *h s.Shim.WaitDelay = s.Container.WaitDelay } + if s.Container.AdoptWaitDelay > 5*time.Second { + s.Shim.AdoptWaitDelay = 5 * time.Second + } else if s.Container.AdoptWaitDelay < 0 { + s.Shim.AdoptWaitDelay = -1 + } else { + s.Shim.AdoptWaitDelay = s.Container.AdoptWaitDelay + } + if s.Container.Flags&hst.FMapRealUID != 0 { s.Mapuid, s.Mapgid = k.getuid(), k.getgid() } else { diff --git a/internal/outcome/shim.go b/internal/outcome/shim.go index 6e039b65..2e7b0910 100644 --- a/internal/outcome/shim.go +++ b/internal/outcome/shim.go @@ -72,6 +72,12 @@ type shimParams struct { // Limits are enforced on the priv side. WaitDelay time.Duration + // Duration to wait after the initial process terminates before all + // lingering processes are killed. + // + // Limits are enforced on the priv side. + AdoptWaitDelay time.Duration + // Verbosity pass through from [message.Msg]. Verbose bool @@ -286,6 +292,7 @@ func shimEntrypoint(k syscallDispatcher) { // bounds and default enforced in finalise.go z.WaitDelay = state.Shim.WaitDelay + z.AdoptWaitDelay = state.Shim.AdoptWaitDelay if stateParams.pipewirePulsePath != nil { zpw := container.NewCommand(ctx, msg, stateParams.pipewirePulsePath, pipewirePulseName) diff --git a/internal/rosa/package/glib/loopvar-cast.patch b/internal/rosa/package/glib/loopvar-cast.patch new file mode 100644 index 00000000..fd4f8c45 --- /dev/null +++ b/internal/rosa/package/glib/loopvar-cast.patch @@ -0,0 +1,13 @@ +diff --git a/glib/tests/string.c b/glib/tests/string.c +index 3d9229616..9553c9217 100644 +--- a/glib/tests/string.c ++++ b/glib/tests/string.c +@@ -348,7 +348,7 @@ test_string_prepend_c (void) + string = g_string_new ("hi pete!"); + + for (i = 0; i < 10000; i++) +- g_string_prepend_c (string, 'a'+(i%26)); ++ g_string_prepend_c (string, 'a'+(gchar)(i%26)); + + g_assert((strlen("hi pete!") + 10000) == string->len); + g_assert((strlen("hi pete!") + 10000) == strlen(string->str)); diff --git a/internal/rosa/package/glib/package.az b/internal/rosa/package/glib/package.az index 0fea441c..7f3040e0 100644 --- a/internal/rosa/package/glib/package.az +++ b/internal/rosa/package/glib/package.az @@ -9,6 +9,7 @@ package glib { tag = version; checksum = "h3Chw60ZesAtUzKQfHKsMvsfkEAK0HaTSV8ZANJK7vkTtb9f7D1P763_vROClV3Z"; }; + patches = [ "loopvar-cast.patch" ]; files = { "/etc/machine-id": "stub-machine-id-fhs"; diff --git a/internal/rosa/package/python/package.az b/internal/rosa/package/python/package.az index 35b36e5e..ca7d6c16 100644 --- a/internal/rosa/package/python/package.az +++ b/internal/rosa/package/python/package.az @@ -41,6 +41,9 @@ package python { // breaks on llvm "test_dbm_gnu", + + // broken on almost everything other than amd64 + "test_c_stack_unwind", ]; sep = " -x "; }, diff --git a/internal/wayland/security-context-v1-protocol.c b/internal/wayland/security-context-v1-protocol.c index 5b15b1b4..54cd69d2 100644 --- a/internal/wayland/security-context-v1-protocol.c +++ b/internal/wayland/security-context-v1-protocol.c @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.23.1 */ +/* Generated by wayland-scanner 1.26.0 */ /* * Copyright © 2021 Simon Ser diff --git a/internal/wayland/security-context-v1-protocol.h b/internal/wayland/security-context-v1-protocol.h index f973619e..0b5bc69e 100644 --- a/internal/wayland/security-context-v1-protocol.h +++ b/internal/wayland/security-context-v1-protocol.h @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.23.1 */ +/* Generated by wayland-scanner 1.26.0 */ #ifndef SECURITY_CONTEXT_V1_CLIENT_PROTOCOL_H #define SECURITY_CONTEXT_V1_CLIENT_PROTOCOL_H |
