forked from rosa/hakurei
container: enter init path early
There is generally no use case where any setup is required before init, and requiring the explicit function call is error-prone and unnecessary. It also causes trouble with packages using a similar trick. This change moves argv0 check early and makes it an import side effect. The stub will be removed in v0.5. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -46,7 +46,6 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/ext"
|
"hakurei.app/ext"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
@@ -59,9 +58,6 @@ var license string
|
|||||||
type earlyHardeningErrs struct{ yamaLSM, dumpable error }
|
type earlyHardeningErrs struct{ yamaLSM, dumpable error }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// early init path, skips root check and duplicate PR_SET_DUMPABLE
|
|
||||||
container.TryArgv0(nil)
|
|
||||||
|
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
log.SetPrefix("hakurei: ")
|
log.SetPrefix("hakurei: ")
|
||||||
msg := message.New(log.Default())
|
msg := message.New(log.Default())
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/command"
|
"hakurei.app/command"
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/ext"
|
"hakurei.app/ext"
|
||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
@@ -67,8 +66,6 @@ func writeFileExcl(name string, data []byte, perm os.FileMode) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
container.TryArgv0(nil)
|
|
||||||
|
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
log.SetPrefix("mbf: ")
|
log.SetPrefix("mbf: ")
|
||||||
msg := message.New(log.Default())
|
msg := message.New(log.Default())
|
||||||
|
|||||||
@@ -287,7 +287,6 @@ func unsafeAddArgument(args *fuseArgs, arg string) {
|
|||||||
|
|
||||||
func _main(s ...string) (exitCode int) {
|
func _main(s ...string) (exitCode int) {
|
||||||
msg := message.New(log.Default())
|
msg := message.New(log.Default())
|
||||||
container.TryArgv0(msg)
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
// don't mask creation mode, kernel already did that
|
// don't mask creation mode, kernel already did that
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(AutoEtcOp)) }
|
|
||||||
|
|
||||||
// Etc is a helper for appending [AutoEtcOp] to [Ops].
|
// Etc is a helper for appending [AutoEtcOp] to [Ops].
|
||||||
func (f *Ops) Etc(host *check.Absolute, prefix string) *Ops {
|
func (f *Ops) Etc(host *check.Absolute, prefix string) *Ops {
|
||||||
e := &AutoEtcOp{prefix}
|
e := &AutoEtcOp{prefix}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
@@ -9,8 +8,6 @@ import (
|
|||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(AutoRootOp)) }
|
|
||||||
|
|
||||||
// Root is a helper for appending [AutoRootOp] to [Ops].
|
// Root is a helper for appending [AutoRootOp] to [Ops].
|
||||||
func (f *Ops) Root(host *check.Absolute, flags int) *Ops {
|
func (f *Ops) Root(host *check.Absolute, flags int) *Ops {
|
||||||
*f = append(*f, &AutoRootOp{host, flags, nil})
|
*f = append(*f, &AutoRootOp{host, flags, nil})
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ import (
|
|||||||
|
|
||||||
// Note: this package requires cgo, which is unavailable in the Go playground.
|
// Note: this package requires cgo, which is unavailable in the Go playground.
|
||||||
func Example() {
|
func Example() {
|
||||||
// Must be called early if the current process starts containers.
|
|
||||||
container.TryArgv0(nil)
|
|
||||||
|
|
||||||
// Configure the container.
|
// Configure the container.
|
||||||
z := container.New(context.Background(), nil)
|
z := container.New(context.Background(), nil)
|
||||||
z.Hostname = "hakurei-example"
|
z.Hostname = "hakurei-example"
|
||||||
@@ -876,8 +873,6 @@ var (
|
|||||||
var helperCommands []func(c command.Command)
|
var helperCommands []func(c command.Command)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
container.TryArgv0(nil)
|
|
||||||
|
|
||||||
if os.Getenv(envDoCheck) == "1" {
|
if os.Getenv(envDoCheck) == "1" {
|
||||||
c := command.New(os.Stderr, log.Printf, "helper", func(args []string) error {
|
c := command.New(os.Stderr, log.Printf, "helper", func(args []string) error {
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
|
|||||||
+30
-10
@@ -2,6 +2,7 @@ package container
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/gob"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -130,7 +131,7 @@ type initParams struct {
|
|||||||
Verbose bool
|
Verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init is called by [TryArgv0] if the current process is the container init.
|
// Init is called if the current process is the container init.
|
||||||
func Init(msg message.Msg) { initEntrypoint(direct{}, msg) }
|
func Init(msg message.Msg) { initEntrypoint(direct{}, msg) }
|
||||||
|
|
||||||
func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
||||||
@@ -642,18 +643,37 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
// initName is the prefix used by log.std in the init process.
|
// initName is the prefix used by log.std in the init process.
|
||||||
const initName = "init"
|
const initName = "init"
|
||||||
|
|
||||||
// TryArgv0 calls [Init] if the last element of argv0 is "init".
|
var _ = func() struct{} {
|
||||||
// If a nil msg is passed, the system logger is used instead.
|
for _, v := range []any{
|
||||||
func TryArgv0(msg message.Msg) {
|
(*AutoEtcOp)(nil),
|
||||||
if msg == nil {
|
(*AutoRootOp)(nil),
|
||||||
log.SetPrefix(initName + ": ")
|
(*BindMountOp)(nil),
|
||||||
log.SetFlags(0)
|
(*DaemonOp)(nil),
|
||||||
msg = message.New(log.Default())
|
(*MkdirOp)(nil),
|
||||||
|
(*MountDevOp)(nil),
|
||||||
|
(*MountOverlayOp)(nil),
|
||||||
|
(*MountProcOp)(nil),
|
||||||
|
(*MountTmpfsOp)(nil),
|
||||||
|
(*RemountOp)(nil),
|
||||||
|
(*SymlinkOp)(nil),
|
||||||
|
(*TmpfileOp)(nil),
|
||||||
|
} {
|
||||||
|
gob.Register(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(os.Args) > 0 && filepath.Base(os.Args[0]) == initName {
|
if len(os.Args) == 1 && filepath.Base(os.Args[0]) == initName {
|
||||||
|
log.SetPrefix(initName + ": ")
|
||||||
|
log.SetFlags(0)
|
||||||
|
msg := message.New(log.Default())
|
||||||
|
|
||||||
Init(msg)
|
Init(msg)
|
||||||
msg.BeforeExit()
|
msg.BeforeExit()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
}
|
return struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// TryArgv0 is a noop.
|
||||||
|
//
|
||||||
|
// Deprecated: init is now implemented as an import side effect.
|
||||||
|
func TryArgv0(_ message.Msg) {}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
@@ -10,8 +9,6 @@ import (
|
|||||||
"hakurei.app/container/std"
|
"hakurei.app/container/std"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(BindMountOp)) }
|
|
||||||
|
|
||||||
// Bind is a helper for appending [BindMountOp] to [Ops].
|
// Bind is a helper for appending [BindMountOp] to [Ops].
|
||||||
func (f *Ops) Bind(source, target *check.Absolute, flags int) *Ops {
|
func (f *Ops) Bind(source, target *check.Absolute, flags int) *Ops {
|
||||||
*f = append(*f, &BindMountOp{nil, source, target, flags})
|
*f = append(*f, &BindMountOp{nil, source, target, flags})
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package container
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/gob"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -16,8 +15,6 @@ import (
|
|||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(DaemonOp)) }
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// daemonTimeout is the duration a [DaemonOp] is allowed to block before the
|
// daemonTimeout is the duration a [DaemonOp] is allowed to block before the
|
||||||
// [DaemonOp.Target] marker becomes available.
|
// [DaemonOp.Target] marker becomes available.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
. "syscall"
|
. "syscall"
|
||||||
@@ -10,8 +9,6 @@ import (
|
|||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(MountDevOp)) }
|
|
||||||
|
|
||||||
// Dev appends an [Op] that mounts a subset of host /dev.
|
// Dev appends an [Op] that mounts a subset of host /dev.
|
||||||
func (f *Ops) Dev(target *check.Absolute, mqueue bool) *Ops {
|
func (f *Ops) Dev(target *check.Absolute, mqueue bool) *Ops {
|
||||||
*f = append(*f, &MountDevOp{target, mqueue, false})
|
*f = append(*f, &MountDevOp{target, mqueue, false})
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(MkdirOp)) }
|
|
||||||
|
|
||||||
// Mkdir is a helper for appending [MkdirOp] to [Ops].
|
// Mkdir is a helper for appending [MkdirOp] to [Ops].
|
||||||
func (f *Ops) Mkdir(name *check.Absolute, perm os.FileMode) *Ops {
|
func (f *Ops) Mkdir(name *check.Absolute, perm os.FileMode) *Ops {
|
||||||
*f = append(*f, &MkdirOp{name, perm})
|
*f = append(*f, &MkdirOp{name, perm})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
@@ -19,8 +18,6 @@ const (
|
|||||||
intermediatePatternOverlayWork = "overlay.work.*"
|
intermediatePatternOverlayWork = "overlay.work.*"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(MountOverlayOp)) }
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// OverlayEphemeralUnexpectedUpper is set when [MountOverlayOp.Work] is nil
|
// OverlayEphemeralUnexpectedUpper is set when [MountOverlayOp.Work] is nil
|
||||||
// and [MountOverlayOp.Upper] holds an unexpected value.
|
// and [MountOverlayOp.Upper] holds an unexpected value.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
@@ -14,8 +13,6 @@ const (
|
|||||||
intermediatePatternTmpfile = "tmp.*"
|
intermediatePatternTmpfile = "tmp.*"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(TmpfileOp)) }
|
|
||||||
|
|
||||||
// Place is a helper for appending [TmpfileOp] to [Ops].
|
// Place is a helper for appending [TmpfileOp] to [Ops].
|
||||||
func (f *Ops) Place(name *check.Absolute, data []byte) *Ops {
|
func (f *Ops) Place(name *check.Absolute, data []byte) *Ops {
|
||||||
*f = append(*f, &TmpfileOp{name, data})
|
*f = append(*f, &TmpfileOp{name, data})
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
. "syscall"
|
. "syscall"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(MountProcOp)) }
|
|
||||||
|
|
||||||
// Proc is a helper for appending [MountProcOp] to [Ops].
|
// Proc is a helper for appending [MountProcOp] to [Ops].
|
||||||
func (f *Ops) Proc(target *check.Absolute) *Ops {
|
func (f *Ops) Proc(target *check.Absolute) *Ops {
|
||||||
*f = append(*f, &MountProcOp{target})
|
*f = append(*f, &MountProcOp{target})
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(RemountOp)) }
|
|
||||||
|
|
||||||
// Remount is a helper for appending [RemountOp] to [Ops].
|
// Remount is a helper for appending [RemountOp] to [Ops].
|
||||||
func (f *Ops) Remount(target *check.Absolute, flags uintptr) *Ops {
|
func (f *Ops) Remount(target *check.Absolute, flags uintptr) *Ops {
|
||||||
*f = append(*f, &RemountOp{target, flags})
|
*f = append(*f, &RemountOp{target, flags})
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(SymlinkOp)) }
|
|
||||||
|
|
||||||
// Link appends an [Op] that creates a symlink in the container filesystem.
|
// Link appends an [Op] that creates a symlink in the container filesystem.
|
||||||
func (f *Ops) Link(target *check.Absolute, linkName string, dereference bool) *Ops {
|
func (f *Ops) Link(target *check.Absolute, linkName string, dereference bool) *Ops {
|
||||||
*f = append(*f, &SymlinkOp{target, linkName, dereference})
|
*f = append(*f, &SymlinkOp{target, linkName, dereference})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
@@ -11,8 +10,6 @@ import (
|
|||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { gob.Register(new(MountTmpfsOp)) }
|
|
||||||
|
|
||||||
type TmpfsSizeError int
|
type TmpfsSizeError int
|
||||||
|
|
||||||
func (e TmpfsSizeError) Error() string {
|
func (e TmpfsSizeError) Error() string {
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/internal/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }
|
func TestMain(m *testing.M) { helper.InternalHelperStub(); os.Exit(m.Run()) }
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/internal/helper"
|
"hakurei.app/internal/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) { container.TryArgv0(nil); helper.InternalHelperStub(); os.Exit(m.Run()) }
|
func TestMain(m *testing.M) { helper.InternalHelperStub(); os.Exit(m.Run()) }
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ func newRContext(tb testing.TB, c *pkg.Cache) *pkg.RContext {
|
|||||||
return &r
|
return &r
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) { container.TryArgv0(nil); os.Exit(m.Run()) }
|
|
||||||
|
|
||||||
// overrideIdent overrides the ID method of [Artifact].
|
// overrideIdent overrides the ID method of [Artifact].
|
||||||
type overrideIdent struct {
|
type overrideIdent struct {
|
||||||
id pkg.ID
|
id pkg.ID
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
"hakurei.app/internal/rosa"
|
"hakurei.app/internal/rosa"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
@@ -28,8 +27,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
container.TryArgv0(nil)
|
|
||||||
|
|
||||||
code := m.Run()
|
code := m.Run()
|
||||||
if buildTestCache != nil {
|
if buildTestCache != nil {
|
||||||
buildTestCacheCancel()
|
buildTestCacheCancel()
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package ldd_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/ldd"
|
"hakurei.app/ldd"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
@@ -42,5 +40,3 @@ func TestExec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) { container.TryArgv0(nil); os.Exit(m.Run()) }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user