forked from security/hakurei
There is no reason to give the home directory special treatment, as this behaviour can be quite confusing. The home directory also does not necessarily require its own mount point, it could be provided by a parent or simply be ephemeral. Signed-off-by: Ophestra <cat@gensokyo.uk>
109 lines
3.9 KiB
Go
109 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"hakurei.app/container"
|
|
"hakurei.app/container/seccomp"
|
|
"hakurei.app/hst"
|
|
"hakurei.app/internal"
|
|
)
|
|
|
|
func withNixDaemon(
|
|
ctx context.Context,
|
|
action string, command []string, net bool, updateConfig func(config *hst.Config) *hst.Config,
|
|
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func(),
|
|
) {
|
|
mustRunAppDropShell(ctx, updateConfig(&hst.Config{
|
|
ID: app.ID,
|
|
|
|
Path: pathShell,
|
|
Args: []string{bash, "-lc", "rm -f /nix/var/nix/daemon-socket/socket && " +
|
|
// start nix-daemon
|
|
"nix-daemon --store / & " +
|
|
// wait for socket to appear
|
|
"(while [ ! -S /nix/var/nix/daemon-socket/socket ]; do sleep 0.01; done) && " +
|
|
// create directory so nix stops complaining
|
|
"mkdir -p /nix/var/nix/profiles/per-user/root/channels && " +
|
|
strings.Join(command, " && ") +
|
|
// terminate nix-daemon
|
|
" && pkill nix-daemon",
|
|
},
|
|
|
|
Username: "hakurei",
|
|
Shell: pathShell,
|
|
Home: pathDataData.Append(app.ID),
|
|
ExtraPerms: []*hst.ExtraPermConfig{
|
|
{Path: dataHome, Execute: true},
|
|
{Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
|
|
},
|
|
|
|
Identity: app.Identity,
|
|
|
|
Container: &hst.ContainerConfig{
|
|
Hostname: formatHostname(app.Name) + "-" + action,
|
|
Userns: true, // nix sandbox requires userns
|
|
HostNet: net,
|
|
SeccompFlags: seccomp.AllowMultiarch,
|
|
Tty: dropShell,
|
|
Filesystem: []hst.FilesystemConfigJSON{
|
|
{FilesystemConfig: &hst.FSBind{Target: container.AbsFHSEtc, Source: pathSet.cacheDir.Append("etc"), Special: true}},
|
|
{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath, Target: pathNix, Write: true}},
|
|
{FilesystemConfig: &hst.FSLink{Target: pathCurrentSystem, Linkname: app.CurrentSystem.String()}},
|
|
{FilesystemConfig: &hst.FSLink{Target: pathBin, Linkname: pathSwBin.String()}},
|
|
{FilesystemConfig: &hst.FSLink{Target: container.AbsFHSUsrBin, Linkname: pathSwBin.String()}},
|
|
{FilesystemConfig: &hst.FSBind{Target: pathDataData.Append(app.ID), Source: pathSet.homeDir, Write: true, Ensure: true}},
|
|
},
|
|
},
|
|
}), dropShell, beforeFail)
|
|
}
|
|
|
|
func withCacheDir(
|
|
ctx context.Context,
|
|
action string, command []string, workDir *container.Absolute,
|
|
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func()) {
|
|
mustRunAppDropShell(ctx, &hst.Config{
|
|
ID: app.ID,
|
|
|
|
Path: pathShell,
|
|
Args: []string{bash, "-lc", strings.Join(command, " && ")},
|
|
|
|
Username: "nixos",
|
|
Shell: pathShell,
|
|
Home: pathDataData.Append(app.ID, "cache"),
|
|
ExtraPerms: []*hst.ExtraPermConfig{
|
|
{Path: dataHome, Execute: true},
|
|
{Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
|
|
{Path: workDir, Execute: true},
|
|
},
|
|
|
|
Identity: app.Identity,
|
|
|
|
Container: &hst.ContainerConfig{
|
|
Hostname: formatHostname(app.Name) + "-" + action,
|
|
SeccompFlags: seccomp.AllowMultiarch,
|
|
Tty: dropShell,
|
|
Filesystem: []hst.FilesystemConfigJSON{
|
|
{FilesystemConfig: &hst.FSBind{Target: container.AbsFHSEtc, Source: workDir.Append(container.FHSEtc), Special: true}},
|
|
{FilesystemConfig: &hst.FSBind{Source: workDir.Append("nix"), Target: pathNix}},
|
|
{FilesystemConfig: &hst.FSLink{Target: pathCurrentSystem, Linkname: app.CurrentSystem.String()}},
|
|
{FilesystemConfig: &hst.FSLink{Target: pathBin, Linkname: pathSwBin.String()}},
|
|
{FilesystemConfig: &hst.FSLink{Target: container.AbsFHSUsrBin, Linkname: pathSwBin.String()}},
|
|
{FilesystemConfig: &hst.FSBind{Source: workDir, Target: hst.AbsTmp.Append("bundle")}},
|
|
{FilesystemConfig: &hst.FSBind{Target: pathDataData.Append(app.ID, "cache"), Source: pathSet.cacheDir, Write: true, Ensure: true}},
|
|
},
|
|
},
|
|
}, dropShell, beforeFail)
|
|
}
|
|
|
|
func mustRunAppDropShell(ctx context.Context, config *hst.Config, dropShell bool, beforeFail func()) {
|
|
if dropShell {
|
|
config.Args = []string{bash, "-l"}
|
|
mustRunApp(ctx, config, beforeFail)
|
|
beforeFail()
|
|
internal.Exit(0)
|
|
}
|
|
mustRunApp(ctx, config, beforeFail)
|
|
}
|