container/path: fhs path constants
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m6s
Test / Hakurei (push) Successful in 3m6s
Test / Sandbox (race detector) (push) Successful in 4m14s
Test / Hpkg (push) Successful in 4m11s
Test / Hakurei (race detector) (push) Successful in 4m40s
Test / Flake checks (push) Successful in 1m18s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m6s
Test / Hakurei (push) Successful in 3m6s
Test / Sandbox (race detector) (push) Successful in 4m14s
Test / Hpkg (push) Successful in 4m11s
Test / Hakurei (race detector) (push) Successful in 4m40s
Test / Flake checks (push) Successful in 1m18s
This increases readability since this can help disambiguate absolute paths from similarly named path segments. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
38245559dc
commit
c6be82bcf9
@ -14,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/command"
|
"hakurei.app/command"
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal"
|
||||||
"hakurei.app/internal/app"
|
"hakurei.app/internal/app"
|
||||||
@ -94,7 +95,7 @@ func buildCommand(out io.Writer) command.Command {
|
|||||||
Gid: us,
|
Gid: us,
|
||||||
Username: "chronos",
|
Username: "chronos",
|
||||||
Name: "Hakurei Permissive Default",
|
Name: "Hakurei Permissive Default",
|
||||||
HomeDir: "/var/empty",
|
HomeDir: container.FHSVarEmpty,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
passwd = u
|
passwd = u
|
||||||
|
@ -43,12 +43,12 @@ func Test_printShowInstance(t *testing.T) {
|
|||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Flags: userns devel net device tty mapuid autoetc
|
Flags: userns devel net device tty mapuid autoetc
|
||||||
Root: /var/lib/hakurei/base/org.debian (2)
|
Root: /var/lib/hakurei/base/org.debian (2)
|
||||||
Etc: /etc
|
Etc: /etc/
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
||||||
|
|
||||||
Filesystem
|
Filesystem
|
||||||
w+tmpfs:/tmp
|
w+tmpfs:/tmp/
|
||||||
+/nix/store
|
+/nix/store
|
||||||
+/run/current-system
|
+/run/current-system
|
||||||
+/run/opengl-driver
|
+/run/opengl-driver
|
||||||
@ -123,12 +123,12 @@ App
|
|||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Flags: userns devel net device tty mapuid autoetc
|
Flags: userns devel net device tty mapuid autoetc
|
||||||
Root: /var/lib/hakurei/base/org.debian (2)
|
Root: /var/lib/hakurei/base/org.debian (2)
|
||||||
Etc: /etc
|
Etc: /etc/
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
Arguments: chromium --ignore-gpu-blocklist --disable-smooth-scrolling --enable-features=UseOzonePlatform --ozone-platform=wayland
|
||||||
|
|
||||||
Filesystem
|
Filesystem
|
||||||
w+tmpfs:/tmp
|
w+tmpfs:/tmp/
|
||||||
+/nix/store
|
+/nix/store
|
||||||
+/run/current-system
|
+/run/current-system
|
||||||
+/run/opengl-driver
|
+/run/opengl-driver
|
||||||
@ -276,7 +276,7 @@ App
|
|||||||
"device": true,
|
"device": true,
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"dst": "/tmp",
|
"dst": "/tmp/",
|
||||||
"src": "tmpfs",
|
"src": "tmpfs",
|
||||||
"write": true
|
"write": true
|
||||||
},
|
},
|
||||||
@ -311,7 +311,7 @@ App
|
|||||||
],
|
],
|
||||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
"root_flags": 2,
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc/",
|
||||||
"auto_etc": true
|
"auto_etc": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -408,7 +408,7 @@ App
|
|||||||
"device": true,
|
"device": true,
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"dst": "/tmp",
|
"dst": "/tmp/",
|
||||||
"src": "tmpfs",
|
"src": "tmpfs",
|
||||||
"write": true
|
"write": true
|
||||||
},
|
},
|
||||||
@ -443,7 +443,7 @@ App
|
|||||||
],
|
],
|
||||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
"root_flags": 2,
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc/",
|
||||||
"auto_etc": true
|
"auto_etc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,7 +594,7 @@ func Test_printPs(t *testing.T) {
|
|||||||
"device": true,
|
"device": true,
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"dst": "/tmp",
|
"dst": "/tmp/",
|
||||||
"src": "tmpfs",
|
"src": "tmpfs",
|
||||||
"write": true
|
"write": true
|
||||||
},
|
},
|
||||||
@ -629,7 +629,7 @@ func Test_printPs(t *testing.T) {
|
|||||||
],
|
],
|
||||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
"root_flags": 2,
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc/",
|
||||||
"auto_etc": true
|
"auto_etc": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system"
|
"hakurei.app/system"
|
||||||
@ -94,17 +95,17 @@ func (app *appInfo) toFst(pathSet *appPathSet, argv []string, flagDropShell bool
|
|||||||
Filesystem: []*hst.FilesystemConfig{
|
Filesystem: []*hst.FilesystemConfig{
|
||||||
{Src: path.Join(pathSet.nixPath, "store"), Dst: "/nix/store", Must: true},
|
{Src: path.Join(pathSet.nixPath, "store"), Dst: "/nix/store", Must: true},
|
||||||
{Src: pathSet.metaPath, Dst: path.Join(hst.Tmp, "app"), Must: true},
|
{Src: pathSet.metaPath, Dst: path.Join(hst.Tmp, "app"), Must: true},
|
||||||
{Src: "/etc/resolv.conf"},
|
{Src: container.FHSEtc + "resolv.conf"},
|
||||||
{Src: "/sys/block"},
|
{Src: container.FHSSys + "block"},
|
||||||
{Src: "/sys/bus"},
|
{Src: container.FHSSys + "bus"},
|
||||||
{Src: "/sys/class"},
|
{Src: container.FHSSys + "class"},
|
||||||
{Src: "/sys/dev"},
|
{Src: container.FHSSys + "dev"},
|
||||||
{Src: "/sys/devices"},
|
{Src: container.FHSSys + "devices"},
|
||||||
},
|
},
|
||||||
Link: [][2]string{
|
Link: [][2]string{
|
||||||
{app.CurrentSystem, "/run/current-system"},
|
{app.CurrentSystem, container.FHSRun + "current-system"},
|
||||||
{"/run/current-system/sw/bin", "/bin"},
|
{container.FHSRun + "current-system/sw/bin", "/bin"},
|
||||||
{"/run/current-system/sw/bin", "/usr/bin"},
|
{container.FHSRun + "current-system/sw/bin", container.FHSUsrBin},
|
||||||
},
|
},
|
||||||
Etc: path.Join(pathSet.cacheDir, "etc"),
|
Etc: path.Join(pathSet.cacheDir, "etc"),
|
||||||
AutoEtc: true,
|
AutoEtc: true,
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/command"
|
"hakurei.app/command"
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal"
|
||||||
"hakurei.app/internal/hlog"
|
"hakurei.app/internal/hlog"
|
||||||
@ -275,12 +276,12 @@ func main() {
|
|||||||
"path:" + a.NixGL + "#nixVulkanNvidia",
|
"path:" + a.NixGL + "#nixVulkanNvidia",
|
||||||
}, true, func(config *hst.Config) *hst.Config {
|
}, true, func(config *hst.Config) *hst.Config {
|
||||||
config.Container.Filesystem = append(config.Container.Filesystem, []*hst.FilesystemConfig{
|
config.Container.Filesystem = append(config.Container.Filesystem, []*hst.FilesystemConfig{
|
||||||
{Src: "/etc/resolv.conf"},
|
{Src: container.FHSEtc + "resolv.conf"},
|
||||||
{Src: "/sys/block"},
|
{Src: container.FHSSys + "block"},
|
||||||
{Src: "/sys/bus"},
|
{Src: container.FHSSys + "bus"},
|
||||||
{Src: "/sys/class"},
|
{Src: container.FHSSys + "class"},
|
||||||
{Src: "/sys/dev"},
|
{Src: container.FHSSys + "dev"},
|
||||||
{Src: "/sys/devices"},
|
{Src: container.FHSSys + "devices"},
|
||||||
}...)
|
}...)
|
||||||
appendGPUFilesystem(config)
|
appendGPUFilesystem(config)
|
||||||
return config
|
return config
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal/hlog"
|
"hakurei.app/internal/hlog"
|
||||||
)
|
)
|
||||||
@ -21,7 +22,7 @@ func init() {
|
|||||||
if p, ok := os.LookupEnv("HAKUREI_DATA_HOME"); ok {
|
if p, ok := os.LookupEnv("HAKUREI_DATA_HOME"); ok {
|
||||||
dataHome = p
|
dataHome = p
|
||||||
} else {
|
} else {
|
||||||
dataHome = "/var/lib/hakurei/" + strconv.Itoa(os.Getuid())
|
dataHome = container.FHSVarLib + "hakurei/" + strconv.Itoa(os.Getuid())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal"
|
"hakurei.app/internal"
|
||||||
@ -52,9 +53,9 @@ func withNixDaemon(
|
|||||||
{Src: pathSet.nixPath, Dst: "/nix", Write: true, Must: true},
|
{Src: pathSet.nixPath, Dst: "/nix", Write: true, Must: true},
|
||||||
},
|
},
|
||||||
Link: [][2]string{
|
Link: [][2]string{
|
||||||
{app.CurrentSystem, "/run/current-system"},
|
{app.CurrentSystem, container.FHSRun + "current-system"},
|
||||||
{"/run/current-system/sw/bin", "/bin"},
|
{container.FHSRun + "current-system/sw/bin", "/bin"},
|
||||||
{"/run/current-system/sw/bin", "/usr/bin"},
|
{container.FHSRun + "current-system/sw/bin", container.FHSUsrBin},
|
||||||
},
|
},
|
||||||
Etc: path.Join(pathSet.cacheDir, "etc"),
|
Etc: path.Join(pathSet.cacheDir, "etc"),
|
||||||
AutoEtc: true,
|
AutoEtc: true,
|
||||||
@ -93,11 +94,11 @@ func withCacheDir(
|
|||||||
{Src: workDir, Dst: path.Join(hst.Tmp, "bundle"), Must: true},
|
{Src: workDir, Dst: path.Join(hst.Tmp, "bundle"), Must: true},
|
||||||
},
|
},
|
||||||
Link: [][2]string{
|
Link: [][2]string{
|
||||||
{app.CurrentSystem, "/run/current-system"},
|
{app.CurrentSystem, container.FHSRun + "current-system"},
|
||||||
{"/run/current-system/sw/bin", "/bin"},
|
{container.FHSRun + "current-system/sw/bin", "/bin"},
|
||||||
{"/run/current-system/sw/bin", "/usr/bin"},
|
{container.FHSRun + "current-system/sw/bin", container.FHSUsrBin},
|
||||||
},
|
},
|
||||||
Etc: path.Join(workDir, "etc"),
|
Etc: path.Join(workDir, container.FHSEtc),
|
||||||
AutoEtc: true,
|
AutoEtc: true,
|
||||||
},
|
},
|
||||||
}, dropShell, beforeFail)
|
}, dropShell, beforeFail)
|
||||||
|
@ -12,7 +12,7 @@ func init() { gob.Register(new(AutoEtcOp)) }
|
|||||||
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
||||||
func (f *Ops) Etc(host, prefix string) *Ops {
|
func (f *Ops) Etc(host, prefix string) *Ops {
|
||||||
e := &AutoEtcOp{prefix}
|
e := &AutoEtcOp{prefix}
|
||||||
f.Mkdir("/etc", 0755)
|
f.Mkdir(FHSEtc, 0755)
|
||||||
f.Bind(host, e.hostPath(), 0)
|
f.Bind(host, e.hostPath(), 0)
|
||||||
*f = append(*f, e)
|
*f = append(*f, e)
|
||||||
return f
|
return f
|
||||||
@ -22,7 +22,7 @@ type AutoEtcOp struct{ Prefix string }
|
|||||||
|
|
||||||
func (e *AutoEtcOp) early(*Params) error { return nil }
|
func (e *AutoEtcOp) early(*Params) error { return nil }
|
||||||
func (e *AutoEtcOp) apply(*Params) error {
|
func (e *AutoEtcOp) apply(*Params) error {
|
||||||
const target = sysrootPath + "/etc/"
|
const target = sysrootPath + FHSEtc
|
||||||
rel := e.hostRel() + "/"
|
rel := e.hostRel() + "/"
|
||||||
|
|
||||||
if err := os.MkdirAll(target, 0755); err != nil {
|
if err := os.MkdirAll(target, 0755); err != nil {
|
||||||
@ -40,7 +40,7 @@ func (e *AutoEtcOp) apply(*Params) error {
|
|||||||
case "group":
|
case "group":
|
||||||
|
|
||||||
case "mtab":
|
case "mtab":
|
||||||
if err = os.Symlink("/proc/mounts", target+n); err != nil {
|
if err = os.Symlink(FHSProc+"mounts", target+n); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ func (e *AutoEtcOp) apply(*Params) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (e *AutoEtcOp) hostPath() string { return "/etc/" + e.hostRel() }
|
func (e *AutoEtcOp) hostPath() string { return FHSEtc + e.hostRel() }
|
||||||
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
||||||
|
|
||||||
func (e *AutoEtcOp) Is(op Op) bool {
|
func (e *AutoEtcOp) Is(op Op) bool {
|
||||||
|
@ -42,7 +42,7 @@ func (r *AutoRootOp) early(params *Params) error {
|
|||||||
if IsAutoRootBindable(name) {
|
if IsAutoRootBindable(name) {
|
||||||
op := &BindMountOp{
|
op := &BindMountOp{
|
||||||
Source: path.Join(r.Host, name),
|
Source: path.Join(r.Host, name),
|
||||||
Target: "/" + name,
|
Target: FHSRoot + name,
|
||||||
Flags: r.Flags,
|
Flags: r.Flags,
|
||||||
}
|
}
|
||||||
if err = op.early(params); err != nil {
|
if err = op.early(params); err != nil {
|
||||||
|
@ -18,10 +18,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Nonexistent is a path that cannot exist.
|
|
||||||
// /proc is chosen because a system with covered /proc is unsupported by this package.
|
|
||||||
Nonexistent = "/proc/nonexistent"
|
|
||||||
|
|
||||||
// CancelSignal is the signal expected by container init on context cancel.
|
// CancelSignal is the signal expected by container init on context cancel.
|
||||||
// A custom [Container.Cancel] function must eventually deliver this signal.
|
// A custom [Container.Cancel] function must eventually deliver this signal.
|
||||||
CancelSignal = SIGTERM
|
CancelSignal = SIGTERM
|
||||||
@ -142,7 +138,7 @@ func (p *Container) Start() error {
|
|||||||
} else {
|
} else {
|
||||||
p.cmd.Cancel = func() error { return p.cmd.Process.Signal(CancelSignal) }
|
p.cmd.Cancel = func() error { return p.cmd.Process.Signal(CancelSignal) }
|
||||||
}
|
}
|
||||||
p.cmd.Dir = "/"
|
p.cmd.Dir = FHSRoot
|
||||||
p.cmd.SysProcAttr = &SysProcAttr{
|
p.cmd.SysProcAttr = &SysProcAttr{
|
||||||
Setsid: !p.RetainSession,
|
Setsid: !p.RetainSession,
|
||||||
Pdeathsig: SIGKILL,
|
Pdeathsig: SIGKILL,
|
||||||
@ -251,6 +247,6 @@ func (p *Container) ProcessState() *os.ProcessState {
|
|||||||
|
|
||||||
func New(ctx context.Context, name string, args ...string) *Container {
|
func New(ctx context.Context, name string, args ...string) *Container {
|
||||||
return &Container{name: name, ctx: ctx,
|
return &Container{name: name, ctx: ctx,
|
||||||
Params: Params{Args: append([]string{name}, args...), Dir: "/", Ops: new(Ops)},
|
Params: Params{Args: append([]string{name}, args...), Dir: FHSRoot, Ops: new(Ops)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ const (
|
|||||||
|
|
||||||
it should be noted that none of this should become relevant at any point since the resulting
|
it should be noted that none of this should become relevant at any point since the resulting
|
||||||
intermediate root tmpfs should be effectively anonymous */
|
intermediate root tmpfs should be effectively anonymous */
|
||||||
intermediateHostPath = "/proc/self/fd"
|
intermediateHostPath = FHSProc + "self/fd"
|
||||||
|
|
||||||
// setup params file descriptor
|
// setup params file descriptor
|
||||||
setupEnv = "HAKUREI_SETUP"
|
setupEnv = "HAKUREI_SETUP"
|
||||||
@ -88,17 +88,17 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
if err := SetDumpable(SUID_DUMP_USER); err != nil {
|
if err := SetDumpable(SUID_DUMP_USER); err != nil {
|
||||||
log.Fatalf("cannot set SUID_DUMP_USER: %s", err)
|
log.Fatalf("cannot set SUID_DUMP_USER: %s", err)
|
||||||
}
|
}
|
||||||
if err := os.WriteFile("/proc/self/uid_map",
|
if err := os.WriteFile(FHSProc+"self/uid_map",
|
||||||
append([]byte{}, strconv.Itoa(params.Uid)+" "+strconv.Itoa(params.HostUid)+" 1\n"...),
|
append([]byte{}, strconv.Itoa(params.Uid)+" "+strconv.Itoa(params.HostUid)+" 1\n"...),
|
||||||
0); err != nil {
|
0); err != nil {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
if err := os.WriteFile("/proc/self/setgroups",
|
if err := os.WriteFile(FHSProc+"self/setgroups",
|
||||||
[]byte("deny\n"),
|
[]byte("deny\n"),
|
||||||
0); err != nil && !os.IsNotExist(err) {
|
0); err != nil && !os.IsNotExist(err) {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
if err := os.WriteFile("/proc/self/gid_map",
|
if err := os.WriteFile(FHSProc+"self/gid_map",
|
||||||
append([]byte{}, strconv.Itoa(params.Gid)+" "+strconv.Itoa(params.HostGid)+" 1\n"...),
|
append([]byte{}, strconv.Itoa(params.Gid)+" "+strconv.Itoa(params.HostGid)+" 1\n"...),
|
||||||
0); err != nil {
|
0); err != nil {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
@ -117,7 +117,7 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
// cache sysctl before pivot_root
|
// cache sysctl before pivot_root
|
||||||
LastCap()
|
LastCap()
|
||||||
|
|
||||||
if err := Mount("", "/", "", MS_SILENT|MS_SLAVE|MS_REC, ""); err != nil {
|
if err := Mount("", FHSRoot, "", MS_SILENT|MS_SLAVE|MS_REC, ""); err != nil {
|
||||||
log.Fatalf("cannot make / rslave: %v", err)
|
log.Fatalf("cannot make / rslave: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
if err := PivotRoot(intermediateHostPath, hostDir); err != nil {
|
if err := PivotRoot(intermediateHostPath, hostDir); err != nil {
|
||||||
log.Fatalf("cannot pivot into intermediate root: %v", err)
|
log.Fatalf("cannot pivot into intermediate root: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.Chdir("/"); err != nil {
|
if err := os.Chdir(FHSRoot); err != nil {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
{
|
{
|
||||||
var fd int
|
var fd int
|
||||||
if err := IgnoringEINTR(func() (err error) {
|
if err := IgnoringEINTR(func() (err error) {
|
||||||
fd, err = Open("/", O_DIRECTORY|O_RDONLY, 0)
|
fd, err = Open(FHSRoot, O_DIRECTORY|O_RDONLY, 0)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Fatalf("cannot open intermediate root: %v", err)
|
log.Fatalf("cannot open intermediate root: %v", err)
|
||||||
@ -207,7 +207,7 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
if err := Unmount(".", MNT_DETACH); err != nil {
|
if err := Unmount(".", MNT_DETACH); err != nil {
|
||||||
log.Fatalf("cannot unmount intemediate root: %v", err)
|
log.Fatalf("cannot unmount intemediate root: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.Chdir("/"); err != nil {
|
if err := os.Chdir(FHSRoot); err != nil {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ const (
|
|||||||
FstypeNULL = zeroString
|
FstypeNULL = zeroString
|
||||||
// FstypeProc represents the proc pseudo-filesystem.
|
// FstypeProc represents the proc pseudo-filesystem.
|
||||||
// A fully visible instance of proc must be available in the mount namespace for proc to be mounted.
|
// A fully visible instance of proc must be available in the mount namespace for proc to be mounted.
|
||||||
// This filesystem type is usually mounted on /proc.
|
// This filesystem type is usually mounted on [FHSProc].
|
||||||
FstypeProc = "proc"
|
FstypeProc = "proc"
|
||||||
// FstypeDevpts represents the devpts pseudo-filesystem.
|
// FstypeDevpts represents the devpts pseudo-filesystem.
|
||||||
// This type of filesystem is usually mounted on /dev/pts.
|
// This type of filesystem is usually mounted on /dev/pts.
|
||||||
|
@ -215,7 +215,7 @@ func (d *MountDevOp) apply(params *Params) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := hostProc.bindMount(
|
if err := hostProc.bindMount(
|
||||||
toHost("/dev/"+name),
|
toHost(FHSDev+name),
|
||||||
targetPath,
|
targetPath,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
@ -225,15 +225,15 @@ func (d *MountDevOp) apply(params *Params) error {
|
|||||||
}
|
}
|
||||||
for i, name := range []string{"stdin", "stdout", "stderr"} {
|
for i, name := range []string{"stdin", "stdout", "stderr"} {
|
||||||
if err := os.Symlink(
|
if err := os.Symlink(
|
||||||
"/proc/self/fd/"+string(rune(i+'0')),
|
FHSProc+"self/fd/"+string(rune(i+'0')),
|
||||||
path.Join(target, name),
|
path.Join(target, name),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, pair := range [][2]string{
|
for _, pair := range [][2]string{
|
||||||
{"/proc/self/fd", "fd"},
|
{FHSProc + "self/fd", "fd"},
|
||||||
{"/proc/kcore", "core"},
|
{FHSProc + "kcore", "core"},
|
||||||
{"pts/ptmx", "ptmx"},
|
{"pts/ptmx", "ptmx"},
|
||||||
} {
|
} {
|
||||||
if err := os.Symlink(pair[0], path.Join(target, pair[1])); err != nil {
|
if err := os.Symlink(pair[0], path.Join(target, pair[1])); err != nil {
|
||||||
@ -436,7 +436,7 @@ func (t *TmpfileOp) apply(params *Params) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tmpPath string
|
var tmpPath string
|
||||||
if f, err := os.CreateTemp("/", "tmp.*"); err != nil {
|
if f, err := os.CreateTemp(FHSRoot, "tmp.*"); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
} else if _, err = f.Write(t.Data); err != nil {
|
} else if _, err = f.Write(t.Data); err != nil {
|
||||||
return wrapErrSuffix(err,
|
return wrapErrSuffix(err,
|
||||||
|
@ -14,9 +14,49 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
hostPath = "/" + hostDir
|
// FHSRoot points to the file system root.
|
||||||
|
FHSRoot = "/"
|
||||||
|
// FHSEtc points to the directory for system-specific configuration.
|
||||||
|
FHSEtc = "/etc/"
|
||||||
|
// FHSTmp points to the place for small temporary files.
|
||||||
|
FHSTmp = "/tmp/"
|
||||||
|
|
||||||
|
// FHSRun points to a "tmpfs" file system for system packages to place runtime data, socket files, and similar.
|
||||||
|
FHSRun = "/run/"
|
||||||
|
// FHSRunUser points to a directory containing per-user runtime directories,
|
||||||
|
// each usually individually mounted "tmpfs" instances.
|
||||||
|
FHSRunUser = FHSRun + "user/"
|
||||||
|
|
||||||
|
// FHSUsr points to vendor-supplied operating system resources.
|
||||||
|
FHSUsr = "/usr/"
|
||||||
|
// FHSUsrBin points to binaries and executables for user commands that shall appear in the $PATH search path.
|
||||||
|
FHSUsrBin = FHSUsr + "bin/"
|
||||||
|
|
||||||
|
// FHSVar points to persistent, variable system data. Writable during normal system operation.
|
||||||
|
FHSVar = "/var/"
|
||||||
|
// FHSVarLib points to persistent system data.
|
||||||
|
FHSVarLib = FHSVar + "lib/"
|
||||||
|
// FHSVarEmpty points to a nonstandard directory that is usually empty.
|
||||||
|
FHSVarEmpty = FHSVar + "empty/"
|
||||||
|
|
||||||
|
// FHSDev points to the root directory for device nodes.
|
||||||
|
FHSDev = "/dev/"
|
||||||
|
// FHSProc points to a virtual kernel file system exposing the process list and other functionality.
|
||||||
|
FHSProc = "/proc/"
|
||||||
|
// FHSProcSys points to a hierarchy below /proc/ that exposes a number of kernel tunables.
|
||||||
|
FHSProcSys = FHSProc + "sys/"
|
||||||
|
// FHSSys points to a virtual kernel file system exposing discovered devices and other functionality.
|
||||||
|
FHSSys = "/sys/"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Nonexistent is a path that cannot exist.
|
||||||
|
// /proc is chosen because a system with covered /proc is unsupported by this package.
|
||||||
|
Nonexistent = FHSProc + "nonexistent"
|
||||||
|
|
||||||
|
hostPath = FHSRoot + hostDir
|
||||||
hostDir = "host"
|
hostDir = "host"
|
||||||
sysrootPath = "/" + sysrootDir
|
sysrootPath = FHSRoot + sysrootDir
|
||||||
sysrootDir = "sysroot"
|
sysrootDir = "sysroot"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
kernelOverflowuidPath = "/proc/sys/kernel/overflowuid"
|
kernelOverflowuidPath = FHSProcSys + "kernel/overflowuid"
|
||||||
kernelOverflowgidPath = "/proc/sys/kernel/overflowgid"
|
kernelOverflowgidPath = FHSProcSys + "kernel/overflowgid"
|
||||||
kernelCapLastCapPath = "/proc/sys/kernel/cap_last_cap"
|
kernelCapLastCapPath = FHSProcSys + "kernel/cap_last_cap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustReadSysctl() {
|
func mustReadSysctl() {
|
||||||
|
@ -12,7 +12,7 @@ func Template() *Config {
|
|||||||
return &Config{
|
return &Config{
|
||||||
ID: "org.chromium.Chromium",
|
ID: "org.chromium.Chromium",
|
||||||
|
|
||||||
Path: "/run/current-system/sw/bin/chromium",
|
Path: container.FHSRun + "current-system/sw/bin/chromium",
|
||||||
Args: []string{
|
Args: []string{
|
||||||
"chromium",
|
"chromium",
|
||||||
"--ignore-gpu-blocklist",
|
"--ignore-gpu-blocklist",
|
||||||
@ -46,12 +46,12 @@ func Template() *Config {
|
|||||||
DirectWayland: false,
|
DirectWayland: false,
|
||||||
|
|
||||||
Username: "chronos",
|
Username: "chronos",
|
||||||
Shell: "/run/current-system/sw/bin/zsh",
|
Shell: container.FHSRun + "current-system/sw/bin/zsh",
|
||||||
Data: "/var/lib/hakurei/u0/org.chromium.Chromium",
|
Data: container.FHSVarLib + "hakurei/u0/org.chromium.Chromium",
|
||||||
Dir: "/data/data/org.chromium.Chromium",
|
Dir: "/data/data/org.chromium.Chromium",
|
||||||
ExtraPerms: []*ExtraPermConfig{
|
ExtraPerms: []*ExtraPermConfig{
|
||||||
{Path: "/var/lib/hakurei/u0", Ensure: true, Execute: true},
|
{Path: container.FHSVarLib + "hakurei/u0", Ensure: true, Execute: true},
|
||||||
{Path: "/var/lib/hakurei/u0/org.chromium.Chromium", Read: true, Write: true, Execute: true},
|
{Path: container.FHSVarLib + "hakurei/u0/org.chromium.Chromium", Read: true, Write: true, Execute: true},
|
||||||
},
|
},
|
||||||
|
|
||||||
Identity: 9,
|
Identity: 9,
|
||||||
@ -78,19 +78,19 @@ func Template() *Config {
|
|||||||
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
|
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
|
||||||
},
|
},
|
||||||
Filesystem: []*FilesystemConfig{
|
Filesystem: []*FilesystemConfig{
|
||||||
{Dst: "/tmp", Src: SourceTmpfs, Write: true},
|
{Dst: container.FHSTmp, Src: SourceTmpfs, Write: true},
|
||||||
{Src: "/nix/store"},
|
{Src: "/nix/store"},
|
||||||
{Src: "/run/current-system"},
|
{Src: container.FHSRun + "current-system"},
|
||||||
{Src: "/run/opengl-driver"},
|
{Src: container.FHSRun + "opengl-driver"},
|
||||||
{Src: "/var/db/nix-channels"},
|
{Src: container.FHSVar + "db/nix-channels"},
|
||||||
{Src: "/var/lib/hakurei/u0/org.chromium.Chromium",
|
{Src: container.FHSVarLib + "hakurei/u0/org.chromium.Chromium",
|
||||||
Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
|
Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
|
||||||
{Src: "/dev/dri", Device: true},
|
{Src: container.FHSDev + "dri", Device: true},
|
||||||
},
|
},
|
||||||
Link: [][2]string{{"/run/user/65534", "/run/user/150"}},
|
Link: [][2]string{{container.FHSRunUser + "65534", container.FHSRunUser + "150"}},
|
||||||
AutoRoot: "/var/lib/hakurei/base/org.debian",
|
AutoRoot: container.FHSVarLib + "hakurei/base/org.debian",
|
||||||
RootFlags: container.BindWritable,
|
RootFlags: container.BindWritable,
|
||||||
Etc: "/etc",
|
Etc: container.FHSEtc,
|
||||||
AutoEtc: true,
|
AutoEtc: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ func TestTemplate(t *testing.T) {
|
|||||||
"device": true,
|
"device": true,
|
||||||
"filesystem": [
|
"filesystem": [
|
||||||
{
|
{
|
||||||
"dst": "/tmp",
|
"dst": "/tmp/",
|
||||||
"src": "tmpfs",
|
"src": "tmpfs",
|
||||||
"write": true
|
"write": true
|
||||||
},
|
},
|
||||||
@ -133,7 +133,7 @@ func TestTemplate(t *testing.T) {
|
|||||||
],
|
],
|
||||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
"root_flags": 2,
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc/",
|
||||||
"auto_etc": true
|
"auto_etc": true
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
@ -23,7 +23,7 @@ var testCasesNixos = []sealTestCase{
|
|||||||
Container: &hst.ContainerConfig{
|
Container: &hst.ContainerConfig{
|
||||||
Userns: true, Net: true, MapRealUID: true, Env: nil, AutoEtc: true,
|
Userns: true, Net: true, MapRealUID: true, Env: nil, AutoEtc: true,
|
||||||
Filesystem: []*hst.FilesystemConfig{
|
Filesystem: []*hst.FilesystemConfig{
|
||||||
{Src: "/bin", Must: true}, {Src: "/usr/bin", Must: true},
|
{Src: "/bin", Must: true}, {Src: "/usr/bin/", Must: true},
|
||||||
{Src: "/nix/store", Must: true}, {Src: "/run/current-system", Must: true},
|
{Src: "/nix/store", Must: true}, {Src: "/run/current-system", Must: true},
|
||||||
{Src: "/sys/block"}, {Src: "/sys/bus"}, {Src: "/sys/class"}, {Src: "/sys/dev"}, {Src: "/sys/devices"},
|
{Src: "/sys/block"}, {Src: "/sys/bus"}, {Src: "/sys/class"}, {Src: "/sys/dev"}, {Src: "/sys/devices"},
|
||||||
{Src: "/run/opengl-driver", Must: true}, {Src: "/dev/dri", Device: true},
|
{Src: "/run/opengl-driver", Must: true}, {Src: "/dev/dri", Device: true},
|
||||||
@ -116,11 +116,11 @@ var testCasesNixos = []sealTestCase{
|
|||||||
"XDG_SESSION_TYPE=tty",
|
"XDG_SESSION_TYPE=tty",
|
||||||
},
|
},
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Proc("/proc").
|
Proc("/proc/").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
DevWritable("/dev", true).
|
DevWritable("/dev/", true).
|
||||||
Bind("/bin", "/bin", 0).
|
Bind("/bin", "/bin", 0).
|
||||||
Bind("/usr/bin", "/usr/bin", 0).
|
Bind("/usr/bin/", "/usr/bin/", 0).
|
||||||
Bind("/nix/store", "/nix/store", 0).
|
Bind("/nix/store", "/nix/store", 0).
|
||||||
Bind("/run/current-system", "/run/current-system", 0).
|
Bind("/run/current-system", "/run/current-system", 0).
|
||||||
Bind("/sys/block", "/sys/block", container.BindOptional).
|
Bind("/sys/block", "/sys/block", container.BindOptional).
|
||||||
@ -130,11 +130,11 @@ var testCasesNixos = []sealTestCase{
|
|||||||
Bind("/sys/devices", "/sys/devices", container.BindOptional).
|
Bind("/sys/devices", "/sys/devices", container.BindOptional).
|
||||||
Bind("/run/opengl-driver", "/run/opengl-driver", 0).
|
Bind("/run/opengl-driver", "/run/opengl-driver", 0).
|
||||||
Bind("/dev/dri", "/dev/dri", container.BindDevice|container.BindWritable|container.BindOptional).
|
Bind("/dev/dri", "/dev/dri", container.BindDevice|container.BindWritable|container.BindOptional).
|
||||||
Etc("/etc", "8e2c76b066dabe574cf073bdb46eb5c1").
|
Etc("/etc/", "8e2c76b066dabe574cf073bdb46eb5c1").
|
||||||
Remount("/dev", syscall.MS_RDONLY).
|
Remount("/dev/", syscall.MS_RDONLY).
|
||||||
Tmpfs("/run/user", 4096, 0755).
|
Tmpfs("/run/user/", 4096, 0755).
|
||||||
Bind("/tmp/hakurei.1971/runtime/1", "/run/user/1971", container.BindWritable).
|
Bind("/tmp/hakurei.1971/runtime/1", "/run/user/1971", container.BindWritable).
|
||||||
Bind("/tmp/hakurei.1971/tmpdir/1", "/tmp", container.BindWritable).
|
Bind("/tmp/hakurei.1971/tmpdir/1", "/tmp/", container.BindWritable).
|
||||||
Bind("/var/lib/persist/module/hakurei/0/1", "/var/lib/persist/module/hakurei/0/1", container.BindWritable).
|
Bind("/var/lib/persist/module/hakurei/0/1", "/var/lib/persist/module/hakurei/0/1", container.BindWritable).
|
||||||
Place("/etc/passwd", []byte("u0_a1:x:1971:100:Hakurei:/var/lib/persist/module/hakurei/0/1:/run/current-system/sw/bin/zsh\n")).
|
Place("/etc/passwd", []byte("u0_a1:x:1971:100:Hakurei:/var/lib/persist/module/hakurei/0/1:/run/current-system/sw/bin/zsh\n")).
|
||||||
Place("/etc/group", []byte("hakurei:x:100:\n")).
|
Place("/etc/group", []byte("hakurei:x:100:\n")).
|
||||||
|
@ -44,18 +44,18 @@ var testCasesPd = []sealTestCase{
|
|||||||
},
|
},
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Root("/", "4a450b6596d7bc15bd01780eb9a607ac", container.BindWritable).
|
Root("/", "4a450b6596d7bc15bd01780eb9a607ac", container.BindWritable).
|
||||||
Proc("/proc").
|
Proc("/proc/").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
DevWritable("/dev", true).
|
DevWritable("/dev/", true).
|
||||||
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Readonly("/var/run/nscd", 0755).
|
Readonly("/var/run/nscd", 0755).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
Tmpfs("/run/dbus", 8192, 0755).
|
Tmpfs("/run/dbus", 8192, 0755).
|
||||||
Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac").
|
Etc("/etc/", "4a450b6596d7bc15bd01780eb9a607ac").
|
||||||
Remount("/dev", syscall.MS_RDONLY).
|
Remount("/dev/", syscall.MS_RDONLY).
|
||||||
Tmpfs("/run/user", 4096, 0755).
|
Tmpfs("/run/user/", 4096, 0755).
|
||||||
Bind("/tmp/hakurei.1971/runtime/0", "/run/user/65534", container.BindWritable).
|
Bind("/tmp/hakurei.1971/runtime/0", "/run/user/65534", container.BindWritable).
|
||||||
Bind("/tmp/hakurei.1971/tmpdir/0", "/tmp", container.BindWritable).
|
Bind("/tmp/hakurei.1971/tmpdir/0", "/tmp/", container.BindWritable).
|
||||||
Bind("/home/chronos", "/home/chronos", container.BindWritable).
|
Bind("/home/chronos", "/home/chronos", container.BindWritable).
|
||||||
Place("/etc/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
Place("/etc/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
||||||
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
||||||
@ -179,19 +179,19 @@ var testCasesPd = []sealTestCase{
|
|||||||
},
|
},
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Root("/", "ebf083d1b175911782d413369b64ce7c", container.BindWritable).
|
Root("/", "ebf083d1b175911782d413369b64ce7c", container.BindWritable).
|
||||||
Proc("/proc").
|
Proc("/proc/").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
DevWritable("/dev", true).
|
DevWritable("/dev/", true).
|
||||||
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Readonly("/var/run/nscd", 0755).
|
Readonly("/var/run/nscd", 0755).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
Tmpfs("/run/dbus", 8192, 0755).
|
Tmpfs("/run/dbus", 8192, 0755).
|
||||||
Etc("/etc", "ebf083d1b175911782d413369b64ce7c").
|
Etc("/etc/", "ebf083d1b175911782d413369b64ce7c").
|
||||||
Remount("/dev", syscall.MS_RDONLY).
|
Remount("/dev/", syscall.MS_RDONLY).
|
||||||
Tmpfs("/run/user", 4096, 0755).
|
Tmpfs("/run/user/", 4096, 0755).
|
||||||
Bind("/tmp/hakurei.1971/runtime/9", "/run/user/65534", container.BindWritable).
|
Bind("/tmp/hakurei.1971/runtime/9", "/run/user/65534", container.BindWritable).
|
||||||
Bind("/tmp/hakurei.1971/tmpdir/9", "/tmp", container.BindWritable).
|
Bind("/tmp/hakurei.1971/tmpdir/9", "/tmp/", container.BindWritable).
|
||||||
Bind("/home/chronos", "/home/chronos", container.BindWritable).
|
Bind("/home/chronos", "/home/chronos", container.BindWritable).
|
||||||
Place("/etc/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
Place("/etc/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
||||||
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
||||||
|
@ -81,13 +81,13 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
|
|||||||
}
|
}
|
||||||
|
|
||||||
params.
|
params.
|
||||||
Proc("/proc").
|
Proc(container.FHSProc).
|
||||||
Tmpfs(hst.Tmp, 1<<12, 0755)
|
Tmpfs(hst.Tmp, 1<<12, 0755)
|
||||||
|
|
||||||
if !s.Device {
|
if !s.Device {
|
||||||
params.DevWritable("/dev", true)
|
params.DevWritable(container.FHSDev, true)
|
||||||
} else {
|
} else {
|
||||||
params.Bind("/dev", "/dev", container.BindWritable|container.BindDevice)
|
params.Bind(container.FHSDev, container.FHSDev, container.BindWritable|container.BindDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retrieve paths and hide them if they're made available in the sandbox;
|
/* retrieve paths and hide them if they're made available in the sandbox;
|
||||||
@ -111,7 +111,7 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
|
|||||||
if path.IsAbs(pair[1]) {
|
if path.IsAbs(pair[1]) {
|
||||||
// get parent dir of socket
|
// get parent dir of socket
|
||||||
dir := path.Dir(pair[1])
|
dir := path.Dir(pair[1])
|
||||||
if dir == "." || dir == "/" {
|
if dir == "." || dir == container.FHSRoot {
|
||||||
os.Printf("dbus socket %q is in an unusual location", pair[1])
|
os.Printf("dbus socket %q is in an unusual location", pair[1])
|
||||||
}
|
}
|
||||||
hidePaths = append(hidePaths, dir)
|
hidePaths = append(hidePaths, dir)
|
||||||
@ -229,19 +229,19 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
|
|||||||
|
|
||||||
if !s.AutoEtc {
|
if !s.AutoEtc {
|
||||||
if s.Etc != "" {
|
if s.Etc != "" {
|
||||||
params.Bind(s.Etc, "/etc", 0)
|
params.Bind(s.Etc, container.FHSEtc, 0)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
etcPath := s.Etc
|
etcPath := s.Etc
|
||||||
if etcPath == "" {
|
if etcPath == "" {
|
||||||
etcPath = "/etc"
|
etcPath = container.FHSEtc
|
||||||
}
|
}
|
||||||
params.Etc(etcPath, prefix)
|
params.Etc(etcPath, prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// no more ContainerConfig paths beyond this point
|
// no more ContainerConfig paths beyond this point
|
||||||
if !s.Device {
|
if !s.Device {
|
||||||
params.Remount("/dev", syscall.MS_RDONLY)
|
params.Remount(container.FHSDev, syscall.MS_RDONLY)
|
||||||
}
|
}
|
||||||
|
|
||||||
return params, maps.Clone(s.Env), nil
|
return params, maps.Clone(s.Env), nil
|
||||||
|
@ -88,7 +88,7 @@ func (seal *outcome) Run(rs *RunState) error {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
cmd := exec.CommandContext(ctx, hsuPath)
|
cmd := exec.CommandContext(ctx, hsuPath)
|
||||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
cmd.Dir = "/" // container init enters final working directory
|
cmd.Dir = container.FHSRoot // container init enters final working directory
|
||||||
// shim runs in the same session as monitor; see shim.go for behaviour
|
// shim runs in the same session as monitor; see shim.go for behaviour
|
||||||
cmd.Cancel = func() error { return cmd.Process.Signal(syscall.SIGCONT) }
|
cmd.Cancel = func() error { return cmd.Process.Signal(syscall.SIGCONT) }
|
||||||
|
|
||||||
|
@ -242,19 +242,19 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
Tty: true,
|
Tty: true,
|
||||||
AutoEtc: true,
|
AutoEtc: true,
|
||||||
|
|
||||||
AutoRoot: "/",
|
AutoRoot: container.FHSRoot,
|
||||||
RootFlags: container.BindWritable,
|
RootFlags: container.BindWritable,
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind GPU stuff
|
// bind GPU stuff
|
||||||
if config.Enablements&(system.EX11|system.EWayland) != 0 {
|
if config.Enablements&(system.EX11|system.EWayland) != 0 {
|
||||||
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/dri", Device: true})
|
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: container.FHSDev + "dri", Device: true})
|
||||||
}
|
}
|
||||||
// opportunistically bind kvm
|
// opportunistically bind kvm
|
||||||
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/kvm", Device: true})
|
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: container.FHSDev + "kvm", Device: true})
|
||||||
|
|
||||||
// hide nscd from container if present
|
// hide nscd from container if present
|
||||||
const nscd = "/var/run/nscd"
|
const nscd = container.FHSVar + "run/nscd"
|
||||||
if _, err := sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) {
|
if _, err := sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) {
|
||||||
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Dst: nscd, Src: hst.SourceTmpfs})
|
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Dst: nscd, Src: hst.SourceTmpfs})
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// inner XDG_RUNTIME_DIR default formatting of `/run/user/%d` as mapped uid
|
// inner XDG_RUNTIME_DIR default formatting of `/run/user/%d` as mapped uid
|
||||||
innerRuntimeDir := path.Join("/run/user", mapuid.String())
|
innerRuntimeDir := path.Join(container.FHSRunUser, mapuid.String())
|
||||||
seal.env[xdgRuntimeDir] = innerRuntimeDir
|
seal.env[xdgRuntimeDir] = innerRuntimeDir
|
||||||
seal.env[xdgSessionClass] = "user"
|
seal.env[xdgSessionClass] = "user"
|
||||||
seal.env[xdgSessionType] = "tty"
|
seal.env[xdgSessionType] = "tty"
|
||||||
@ -307,7 +307,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
runtimeDirInst := path.Join(runtimeDir, seal.user.aid.String())
|
runtimeDirInst := path.Join(runtimeDir, seal.user.aid.String())
|
||||||
seal.sys.Ensure(runtimeDirInst, 0700)
|
seal.sys.Ensure(runtimeDirInst, 0700)
|
||||||
seal.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read, acl.Write, acl.Execute)
|
seal.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read, acl.Write, acl.Execute)
|
||||||
seal.container.Tmpfs("/run/user", 1<<12, 0755)
|
seal.container.Tmpfs(container.FHSRunUser, 1<<12, 0755)
|
||||||
seal.container.Bind(runtimeDirInst, innerRuntimeDir, container.BindWritable)
|
seal.container.Bind(runtimeDirInst, innerRuntimeDir, container.BindWritable)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,11 +319,11 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
seal.sys.Ensure(tmpdirInst, 01700)
|
seal.sys.Ensure(tmpdirInst, 01700)
|
||||||
seal.sys.UpdatePermType(system.User, tmpdirInst, acl.Read, acl.Write, acl.Execute)
|
seal.sys.UpdatePermType(system.User, tmpdirInst, acl.Read, acl.Write, acl.Execute)
|
||||||
// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp
|
// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp
|
||||||
seal.container.Bind(tmpdirInst, "/tmp", container.BindWritable)
|
seal.container.Bind(tmpdirInst, container.FHSTmp, container.BindWritable)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
homeDir := "/var/empty"
|
homeDir := container.FHSVarEmpty
|
||||||
if seal.user.home != "" {
|
if seal.user.home != "" {
|
||||||
homeDir = seal.user.home
|
homeDir = seal.user.home
|
||||||
}
|
}
|
||||||
@ -337,9 +337,9 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
seal.env["USER"] = username
|
seal.env["USER"] = username
|
||||||
seal.env[shell] = config.Shell
|
seal.env[shell] = config.Shell
|
||||||
|
|
||||||
seal.container.Place("/etc/passwd",
|
seal.container.Place(container.FHSEtc+"passwd",
|
||||||
[]byte(username+":x:"+mapuid.String()+":"+mapgid.String()+":Hakurei:"+homeDir+":"+config.Shell+"\n"))
|
[]byte(username+":x:"+mapuid.String()+":"+mapgid.String()+":Hakurei:"+homeDir+":"+config.Shell+"\n"))
|
||||||
seal.container.Place("/etc/group",
|
seal.container.Place(container.FHSEtc+"group",
|
||||||
[]byte("hakurei:x:"+mapgid.String()+":\n"))
|
[]byte("hakurei:x:"+mapgid.String()+":\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +388,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
} else {
|
} else {
|
||||||
seal.sys.ChangeHosts("#" + seal.user.uid.String())
|
seal.sys.ChangeHosts("#" + seal.user.uid.String())
|
||||||
seal.env[display] = d
|
seal.env[display] = d
|
||||||
seal.container.Bind("/tmp/.X11-unix", "/tmp/.X11-unix", 0)
|
seal.container.Bind(container.FHSTmp+".X11-unix", container.FHSTmp+".X11-unix", 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
seal.container.Bind(sessionPath, sessionInner, 0)
|
seal.container.Bind(sessionPath, sessionInner, 0)
|
||||||
seal.sys.UpdatePerm(sessionPath, acl.Read, acl.Write)
|
seal.sys.UpdatePerm(sessionPath, acl.Read, acl.Write)
|
||||||
if config.SystemBus != nil {
|
if config.SystemBus != nil {
|
||||||
systemInner := "/run/dbus/system_bus_socket"
|
systemInner := container.FHSRun + "dbus/system_bus_socket"
|
||||||
seal.env[dbusSystemBusAddress] = "unix:path=" + systemInner
|
seal.env[dbusSystemBusAddress] = "unix:path=" + systemInner
|
||||||
seal.container.Bind(systemPath, systemInner, 0)
|
seal.container.Bind(systemPath, systemInner, 0)
|
||||||
seal.sys.UpdatePerm(systemPath, acl.Read, acl.Write)
|
seal.sys.UpdatePerm(systemPath, acl.Read, acl.Write)
|
||||||
@ -475,7 +475,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mount root read-only as the final setup Op
|
// mount root read-only as the final setup Op
|
||||||
seal.container.Remount("/", syscall.MS_RDONLY)
|
seal.container.Remount(container.FHSRoot, syscall.MS_RDONLY)
|
||||||
|
|
||||||
// append ExtraPerms last
|
// append ExtraPerms last
|
||||||
for _, p := range config.ExtraPerms {
|
for _, p := range config.ExtraPerms {
|
||||||
|
@ -86,7 +86,7 @@ func (s *Std) Uid(aid int) (int, error) {
|
|||||||
cmd.Path = hsuPath
|
cmd.Path = hsuPath
|
||||||
cmd.Stderr = os.Stderr // pass through fatal messages
|
cmd.Stderr = os.Stderr // pass through fatal messages
|
||||||
cmd.Env = []string{"HAKUREI_APP_ID=" + strconv.Itoa(aid)}
|
cmd.Env = []string{"HAKUREI_APP_ID=" + strconv.Itoa(aid)}
|
||||||
cmd.Dir = "/"
|
cmd.Dir = container.FHSRoot
|
||||||
var (
|
var (
|
||||||
p []byte
|
p []byte
|
||||||
exitError *exec.ExitError
|
exitError *exec.ExitError
|
||||||
|
@ -28,7 +28,7 @@ func Exec(ctx context.Context, p string) ([]*Entry, error) {
|
|||||||
stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
|
stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
|
||||||
z.Stdout = stdout
|
z.Stdout = stdout
|
||||||
z.Stderr = stderr
|
z.Stderr = stderr
|
||||||
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev", false)
|
z.Bind(container.FHSRoot, container.FHSRoot, 0).Proc(container.FHSProc).Dev(container.FHSProc, false)
|
||||||
|
|
||||||
if err := z.Start(); err != nil {
|
if err := z.Start(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user