container: use absolute for pathname
All checks were successful
Test / Flake checks (push) Successful in 1m26s
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 1m59s
Test / Hakurei (push) Successful in 2m58s
Test / Hpkg (push) Successful in 3m45s
Test / Sandbox (race detector) (push) Successful in 4m11s
Test / Hakurei (race detector) (push) Successful in 4m47s
All checks were successful
Test / Flake checks (push) Successful in 1m26s
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 1m59s
Test / Hakurei (push) Successful in 2m58s
Test / Hpkg (push) Successful in 3m45s
Test / Sandbox (race detector) (push) Successful in 4m11s
Test / Hakurei (race detector) (push) Successful in 4m47s
This is simultaneously more efficient and less error-prone. This change caused minor API changes in multiple other packages. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -115,9 +115,15 @@ func buildCommand(out io.Writer) command.Command {
|
||||
|
||||
config.Identity = aid
|
||||
config.Groups = groups
|
||||
config.Data = homeDir
|
||||
config.Username = userName
|
||||
|
||||
if a, err := container.NewAbs(homeDir); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return err
|
||||
} else {
|
||||
config.Data = a
|
||||
}
|
||||
|
||||
if wayland {
|
||||
config.Enablements |= system.EWayland
|
||||
}
|
||||
@@ -213,7 +219,7 @@ func buildCommand(out io.Writer) command.Command {
|
||||
|
||||
var psFlagShort bool
|
||||
c.NewCommand("ps", "List active instances", func(args []string) error {
|
||||
printPs(os.Stdout, time.Now().UTC(), state.NewMulti(std.Paths().RunDirPath), psFlagShort, flagJSON)
|
||||
printPs(os.Stdout, time.Now().UTC(), state.NewMulti(std.Paths().RunDirPath.String()), psFlagShort, flagJSON)
|
||||
return errSuccess
|
||||
}).Flag(&psFlagShort, "short", command.BoolFlag(false), "Print instance id")
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ func tryShort(name string) (config *hst.Config, entry *state.State) {
|
||||
if likePrefix && len(name) >= 8 {
|
||||
hlog.Verbose("argument looks like prefix")
|
||||
|
||||
s := state.NewMulti(std.Paths().RunDirPath)
|
||||
s := state.NewMulti(std.Paths().RunDirPath.String())
|
||||
if entries, err := state.Join(s); err != nil {
|
||||
log.Printf("cannot join store: %v", err)
|
||||
// drop to fetch from file
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/internal/hlog"
|
||||
@@ -77,13 +78,13 @@ func printShowInstance(
|
||||
if len(config.Groups) > 0 {
|
||||
t.Printf(" Groups:\t%s\n", strings.Join(config.Groups, ", "))
|
||||
}
|
||||
if config.Data != "" {
|
||||
if config.Data != nil {
|
||||
t.Printf(" Data:\t%s\n", config.Data)
|
||||
}
|
||||
if config.Container != nil {
|
||||
container := config.Container
|
||||
if container.Hostname != "" {
|
||||
t.Printf(" Hostname:\t%s\n", container.Hostname)
|
||||
params := config.Container
|
||||
if params.Hostname != "" {
|
||||
t.Printf(" Hostname:\t%s\n", params.Hostname)
|
||||
}
|
||||
flags := make([]string, 0, 7)
|
||||
writeFlag := func(name string, value bool) {
|
||||
@@ -91,30 +92,32 @@ func printShowInstance(
|
||||
flags = append(flags, name)
|
||||
}
|
||||
}
|
||||
writeFlag("userns", container.Userns)
|
||||
writeFlag("devel", container.Devel)
|
||||
writeFlag("net", container.Net)
|
||||
writeFlag("device", container.Device)
|
||||
writeFlag("tty", container.Tty)
|
||||
writeFlag("mapuid", container.MapRealUID)
|
||||
writeFlag("userns", params.Userns)
|
||||
writeFlag("devel", params.Devel)
|
||||
writeFlag("net", params.Net)
|
||||
writeFlag("device", params.Device)
|
||||
writeFlag("tty", params.Tty)
|
||||
writeFlag("mapuid", params.MapRealUID)
|
||||
writeFlag("directwl", config.DirectWayland)
|
||||
writeFlag("autoetc", container.AutoEtc)
|
||||
writeFlag("autoetc", params.AutoEtc)
|
||||
if len(flags) == 0 {
|
||||
flags = append(flags, "none")
|
||||
}
|
||||
t.Printf(" Flags:\t%s\n", strings.Join(flags, " "))
|
||||
|
||||
if container.AutoRoot != "" {
|
||||
t.Printf(" Root:\t%s (%d)\n", container.AutoRoot, container.RootFlags)
|
||||
if params.AutoRoot != nil {
|
||||
t.Printf(" Root:\t%s (%d)\n", params.AutoRoot, params.RootFlags)
|
||||
}
|
||||
|
||||
etc := container.Etc
|
||||
if etc == "" {
|
||||
etc = "/etc"
|
||||
etc := params.Etc
|
||||
if etc == nil {
|
||||
etc = container.AbsFHSEtc
|
||||
}
|
||||
t.Printf(" Etc:\t%s\n", etc)
|
||||
|
||||
t.Printf(" Path:\t%s\n", config.Path)
|
||||
if config.Path != nil {
|
||||
t.Printf(" Path:\t%s\n", config.Path)
|
||||
}
|
||||
}
|
||||
if len(config.Args) > 0 {
|
||||
t.Printf(" Arguments:\t%s\n", strings.Join(config.Args, " "))
|
||||
@@ -125,12 +128,19 @@ func printShowInstance(
|
||||
if config.Container != nil && len(config.Container.Filesystem) > 0 {
|
||||
t.Printf("Filesystem\n")
|
||||
for _, f := range config.Container.Filesystem {
|
||||
if f == nil {
|
||||
g := 4
|
||||
if f.Src == nil {
|
||||
t.Println(" <invalid>")
|
||||
continue
|
||||
} else {
|
||||
g += len(f.Src.String())
|
||||
}
|
||||
if f.Dst != nil {
|
||||
g += len(f.Dst.String())
|
||||
}
|
||||
|
||||
expr := new(strings.Builder)
|
||||
expr.Grow(3 + len(f.Src) + 1 + len(f.Dst))
|
||||
expr.Grow(g)
|
||||
|
||||
if f.Device {
|
||||
expr.WriteString(" d")
|
||||
@@ -144,9 +154,14 @@ func printShowInstance(
|
||||
} else {
|
||||
expr.WriteString("+")
|
||||
}
|
||||
expr.WriteString(f.Src)
|
||||
if f.Dst != "" {
|
||||
expr.WriteString(":" + f.Dst)
|
||||
src := f.Src.String()
|
||||
if src != container.Nonexistent {
|
||||
expr.WriteString(src)
|
||||
} else {
|
||||
expr.WriteString("tmpfs")
|
||||
}
|
||||
if f.Dst != nil {
|
||||
expr.WriteString(":" + f.Dst.String())
|
||||
}
|
||||
t.Printf("%s\n", expr.String())
|
||||
}
|
||||
|
||||
@@ -83,18 +83,17 @@ App
|
||||
Identity: 0
|
||||
Enablements: (no enablements)
|
||||
Flags: none
|
||||
Etc: /etc
|
||||
Path:
|
||||
Etc: /etc/
|
||||
|
||||
`},
|
||||
{"config nil entries", nil, &hst.Config{Container: &hst.ContainerConfig{Filesystem: make([]*hst.FilesystemConfig, 1)}, ExtraPerms: make([]*hst.ExtraPermConfig, 1)}, false, false, `App
|
||||
{"config nil entries", nil, &hst.Config{Container: &hst.ContainerConfig{Filesystem: make([]hst.FilesystemConfig, 1)}, ExtraPerms: make([]*hst.ExtraPermConfig, 1)}, false, false, `App
|
||||
Identity: 0
|
||||
Enablements: (no enablements)
|
||||
Flags: none
|
||||
Etc: /etc
|
||||
Path:
|
||||
Etc: /etc/
|
||||
|
||||
Filesystem
|
||||
<invalid>
|
||||
|
||||
Extra ACL
|
||||
|
||||
@@ -277,7 +276,7 @@ App
|
||||
"filesystem": [
|
||||
{
|
||||
"dst": "/tmp/",
|
||||
"src": "tmpfs",
|
||||
"src": "/proc/nonexistent",
|
||||
"write": true
|
||||
},
|
||||
{
|
||||
@@ -304,10 +303,10 @@ App
|
||||
}
|
||||
],
|
||||
"symlink": [
|
||||
[
|
||||
"/run/user/65534",
|
||||
"/run/user/150"
|
||||
]
|
||||
{
|
||||
"target": "/run/user/65534",
|
||||
"linkname": "/run/user/150"
|
||||
}
|
||||
],
|
||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||
"root_flags": 2,
|
||||
@@ -409,7 +408,7 @@ App
|
||||
"filesystem": [
|
||||
{
|
||||
"dst": "/tmp/",
|
||||
"src": "tmpfs",
|
||||
"src": "/proc/nonexistent",
|
||||
"write": true
|
||||
},
|
||||
{
|
||||
@@ -436,10 +435,10 @@ App
|
||||
}
|
||||
],
|
||||
"symlink": [
|
||||
[
|
||||
"/run/user/65534",
|
||||
"/run/user/150"
|
||||
]
|
||||
{
|
||||
"target": "/run/user/65534",
|
||||
"linkname": "/run/user/150"
|
||||
}
|
||||
],
|
||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||
"root_flags": 2,
|
||||
@@ -595,7 +594,7 @@ func Test_printPs(t *testing.T) {
|
||||
"filesystem": [
|
||||
{
|
||||
"dst": "/tmp/",
|
||||
"src": "tmpfs",
|
||||
"src": "/proc/nonexistent",
|
||||
"write": true
|
||||
},
|
||||
{
|
||||
@@ -622,10 +621,10 @@ func Test_printPs(t *testing.T) {
|
||||
}
|
||||
],
|
||||
"symlink": [
|
||||
[
|
||||
"/run/user/65534",
|
||||
"/run/user/150"
|
||||
]
|
||||
{
|
||||
"target": "/run/user/65534",
|
||||
"linkname": "/run/user/150"
|
||||
}
|
||||
],
|
||||
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||
"root_flags": 2,
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/seccomp"
|
||||
@@ -56,18 +55,18 @@ type appInfo struct {
|
||||
// store path to nixGL source
|
||||
NixGL string `json:"nix_gl,omitempty"`
|
||||
// store path to activate-and-exec script
|
||||
Launcher string `json:"launcher"`
|
||||
Launcher *container.Absolute `json:"launcher"`
|
||||
// store path to /run/current-system
|
||||
CurrentSystem string `json:"current_system"`
|
||||
CurrentSystem *container.Absolute `json:"current_system"`
|
||||
// store path to home-manager activation package
|
||||
ActivationPackage string `json:"activation_package"`
|
||||
}
|
||||
|
||||
func (app *appInfo) toFst(pathSet *appPathSet, argv []string, flagDropShell bool) *hst.Config {
|
||||
func (app *appInfo) toHst(pathSet *appPathSet, pathname *container.Absolute, argv []string, flagDropShell bool) *hst.Config {
|
||||
config := &hst.Config{
|
||||
ID: app.ID,
|
||||
|
||||
Path: argv[0],
|
||||
Path: pathname,
|
||||
Args: argv,
|
||||
|
||||
Enablements: app.Enablements,
|
||||
@@ -77,9 +76,9 @@ func (app *appInfo) toFst(pathSet *appPathSet, argv []string, flagDropShell bool
|
||||
DirectWayland: app.DirectWayland,
|
||||
|
||||
Username: "hakurei",
|
||||
Shell: shellPath,
|
||||
Shell: pathShell,
|
||||
Data: pathSet.homeDir,
|
||||
Dir: path.Join("/data/data", app.ID),
|
||||
Dir: pathDataData.Append(app.ID),
|
||||
|
||||
Identity: app.Identity,
|
||||
Groups: app.Groups,
|
||||
@@ -92,22 +91,22 @@ func (app *appInfo) toFst(pathSet *appPathSet, argv []string, flagDropShell bool
|
||||
Device: app.Device,
|
||||
Tty: app.Tty || flagDropShell,
|
||||
MapRealUID: app.MapRealUID,
|
||||
Filesystem: []*hst.FilesystemConfig{
|
||||
{Src: path.Join(pathSet.nixPath, "store"), Dst: "/nix/store", Must: true},
|
||||
{Src: pathSet.metaPath, Dst: path.Join(hst.Tmp, "app"), Must: true},
|
||||
{Src: container.FHSEtc + "resolv.conf"},
|
||||
{Src: container.FHSSys + "block"},
|
||||
{Src: container.FHSSys + "bus"},
|
||||
{Src: container.FHSSys + "class"},
|
||||
{Src: container.FHSSys + "dev"},
|
||||
{Src: container.FHSSys + "devices"},
|
||||
Filesystem: []hst.FilesystemConfig{
|
||||
{Src: pathSet.nixPath.Append("store"), Dst: pathNixStore, Must: true},
|
||||
{Src: pathSet.metaPath, Dst: hst.AbsTmp.Append("app"), Must: true},
|
||||
{Src: container.AbsFHSEtc.Append("resolv.conf")},
|
||||
{Src: container.AbsFHSSys.Append("block")},
|
||||
{Src: container.AbsFHSSys.Append("bus")},
|
||||
{Src: container.AbsFHSSys.Append("class")},
|
||||
{Src: container.AbsFHSSys.Append("dev")},
|
||||
{Src: container.AbsFHSSys.Append("devices")},
|
||||
},
|
||||
Link: [][2]string{
|
||||
{app.CurrentSystem, container.FHSRun + "current-system"},
|
||||
{container.FHSRun + "current-system/sw/bin", "/bin"},
|
||||
{container.FHSRun + "current-system/sw/bin", container.FHSUsrBin},
|
||||
Link: []hst.LinkConfig{
|
||||
{pathCurrentSystem, app.CurrentSystem.String()},
|
||||
{pathBin, pathSwBin.String()},
|
||||
{container.AbsFHSUsrBin, pathSwBin.String()},
|
||||
},
|
||||
Etc: path.Join(pathSet.cacheDir, "etc"),
|
||||
Etc: pathSet.cacheDir.Append("etc"),
|
||||
AutoEtc: true,
|
||||
},
|
||||
ExtraPerms: []*hst.ExtraPermConfig{
|
||||
@@ -141,6 +140,14 @@ func loadAppInfo(name string, beforeFail func()) *appInfo {
|
||||
beforeFail()
|
||||
log.Fatal("application identifier must not be empty")
|
||||
}
|
||||
if bundle.Launcher == nil {
|
||||
beforeFail()
|
||||
log.Fatal("launcher must not be empty")
|
||||
}
|
||||
if bundle.CurrentSystem == nil {
|
||||
beforeFail()
|
||||
log.Fatal("current-system must not be empty")
|
||||
}
|
||||
|
||||
return bundle
|
||||
}
|
||||
|
||||
@@ -17,15 +17,13 @@ import (
|
||||
"hakurei.app/internal/hlog"
|
||||
)
|
||||
|
||||
const shellPath = "/run/current-system/sw/bin/bash"
|
||||
|
||||
var (
|
||||
errSuccess = errors.New("success")
|
||||
)
|
||||
|
||||
func init() {
|
||||
hlog.Prepare("hpkg")
|
||||
if err := os.Setenv("SHELL", shellPath); err != nil {
|
||||
if err := os.Setenv("SHELL", pathShell.String()); err != nil {
|
||||
log.Fatalf("cannot set $SHELL: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -82,31 +80,32 @@ func main() {
|
||||
Extract package and set up for cleanup.
|
||||
*/
|
||||
|
||||
var workDir string
|
||||
var workDir *container.Absolute
|
||||
if p, err := os.MkdirTemp("", "hpkg.*"); err != nil {
|
||||
log.Printf("cannot create temporary directory: %v", err)
|
||||
return err
|
||||
} else {
|
||||
workDir = p
|
||||
} else if workDir, err = container.NewAbs(p); err != nil {
|
||||
log.Printf("invalid temporary directory: %v", err)
|
||||
return err
|
||||
}
|
||||
cleanup := func() {
|
||||
// should be faster than a native implementation
|
||||
mustRun(chmod, "-R", "+w", workDir)
|
||||
mustRun(rm, "-rf", workDir)
|
||||
mustRun(chmod, "-R", "+w", workDir.String())
|
||||
mustRun(rm, "-rf", workDir.String())
|
||||
}
|
||||
beforeRunFail.Store(&cleanup)
|
||||
|
||||
mustRun(tar, "-C", workDir, "-xf", pkgPath)
|
||||
mustRun(tar, "-C", workDir.String(), "-xf", pkgPath)
|
||||
|
||||
/*
|
||||
Parse bundle and app metadata, do pre-install checks.
|
||||
*/
|
||||
|
||||
bundle := loadAppInfo(path.Join(workDir, "bundle.json"), cleanup)
|
||||
bundle := loadAppInfo(path.Join(workDir.String(), "bundle.json"), cleanup)
|
||||
pathSet := pathSetByApp(bundle.ID)
|
||||
|
||||
a := bundle
|
||||
if s, err := os.Stat(pathSet.metaPath); err != nil {
|
||||
if s, err := os.Stat(pathSet.metaPath.String()); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
cleanup()
|
||||
log.Printf("cannot access %q: %v", pathSet.metaPath, err)
|
||||
@@ -118,7 +117,7 @@ func main() {
|
||||
log.Printf("metadata path %q is not a file", pathSet.metaPath)
|
||||
return syscall.EBADMSG
|
||||
} else {
|
||||
a = loadAppInfo(pathSet.metaPath, cleanup)
|
||||
a = loadAppInfo(pathSet.metaPath.String(), cleanup)
|
||||
if a.ID != bundle.ID {
|
||||
cleanup()
|
||||
log.Printf("app %q claims to have identifier %q",
|
||||
@@ -209,7 +208,7 @@ func main() {
|
||||
*/
|
||||
|
||||
// serialise metadata to ensure consistency
|
||||
if f, err := os.OpenFile(pathSet.metaPath+"~", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644); err != nil {
|
||||
if f, err := os.OpenFile(pathSet.metaPath.String()+"~", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644); err != nil {
|
||||
cleanup()
|
||||
log.Printf("cannot create metadata file: %v", err)
|
||||
return err
|
||||
@@ -222,7 +221,7 @@ func main() {
|
||||
// not fatal
|
||||
}
|
||||
|
||||
if err := os.Rename(pathSet.metaPath+"~", pathSet.metaPath); err != nil {
|
||||
if err := os.Rename(pathSet.metaPath.String()+"~", pathSet.metaPath.String()); err != nil {
|
||||
cleanup()
|
||||
log.Printf("cannot rename metadata file: %v", err)
|
||||
return err
|
||||
@@ -251,7 +250,7 @@ func main() {
|
||||
|
||||
id := args[0]
|
||||
pathSet := pathSetByApp(id)
|
||||
a := loadAppInfo(pathSet.metaPath, func() {})
|
||||
a := loadAppInfo(pathSet.metaPath.String(), func() {})
|
||||
if a.ID != id {
|
||||
log.Printf("app %q claims to have identifier %q", id, a.ID)
|
||||
return syscall.EBADE
|
||||
@@ -275,13 +274,13 @@ func main() {
|
||||
"--override-input nixpkgs path:/etc/nixpkgs " +
|
||||
"path:" + a.NixGL + "#nixVulkanNvidia",
|
||||
}, true, func(config *hst.Config) *hst.Config {
|
||||
config.Container.Filesystem = append(config.Container.Filesystem, []*hst.FilesystemConfig{
|
||||
{Src: container.FHSEtc + "resolv.conf"},
|
||||
{Src: container.FHSSys + "block"},
|
||||
{Src: container.FHSSys + "bus"},
|
||||
{Src: container.FHSSys + "class"},
|
||||
{Src: container.FHSSys + "dev"},
|
||||
{Src: container.FHSSys + "devices"},
|
||||
config.Container.Filesystem = append(config.Container.Filesystem, []hst.FilesystemConfig{
|
||||
{Src: container.AbsFHSEtc.Append("resolv.conf")},
|
||||
{Src: container.AbsFHSSys.Append("block")},
|
||||
{Src: container.AbsFHSSys.Append("bus")},
|
||||
{Src: container.AbsFHSSys.Append("class")},
|
||||
{Src: container.AbsFHSSys.Append("dev")},
|
||||
{Src: container.AbsFHSSys.Append("devices")},
|
||||
}...)
|
||||
appendGPUFilesystem(config)
|
||||
return config
|
||||
@@ -292,15 +291,16 @@ func main() {
|
||||
Create app configuration.
|
||||
*/
|
||||
|
||||
pathname := a.Launcher
|
||||
argv := make([]string, 1, len(args))
|
||||
if !flagDropShell {
|
||||
argv[0] = a.Launcher
|
||||
if flagDropShell {
|
||||
pathname = pathShell
|
||||
argv[0] = bash
|
||||
} else {
|
||||
argv[0] = shellPath
|
||||
argv[0] = a.Launcher.String()
|
||||
}
|
||||
argv = append(argv, args[1:]...)
|
||||
|
||||
config := a.toFst(pathSet, argv, flagDropShell)
|
||||
config := a.toHst(pathSet, pathname, argv, flagDropShell)
|
||||
|
||||
/*
|
||||
Expose GPU devices.
|
||||
@@ -308,7 +308,7 @@ func main() {
|
||||
|
||||
if a.GPU {
|
||||
config.Container.Filesystem = append(config.Container.Filesystem,
|
||||
&hst.FilesystemConfig{Src: path.Join(pathSet.nixPath, ".nixGL"), Dst: path.Join(hst.Tmp, "nixGL")})
|
||||
hst.FilesystemConfig{Src: pathSet.nixPath.Append(".nixGL"), Dst: hst.AbsTmp.Append("nixGL")})
|
||||
appendGPUFilesystem(config)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
|
||||
@@ -13,19 +12,34 @@ import (
|
||||
"hakurei.app/internal/hlog"
|
||||
)
|
||||
|
||||
const bash = "bash"
|
||||
|
||||
var (
|
||||
dataHome string
|
||||
dataHome *container.Absolute
|
||||
)
|
||||
|
||||
func init() {
|
||||
// dataHome
|
||||
if p, ok := os.LookupEnv("HAKUREI_DATA_HOME"); ok {
|
||||
dataHome = p
|
||||
if a, err := container.NewAbs(os.Getenv("HAKUREI_DATA_HOME")); err == nil {
|
||||
dataHome = a
|
||||
} else {
|
||||
dataHome = container.FHSVarLib + "hakurei/" + strconv.Itoa(os.Getuid())
|
||||
dataHome = container.AbsFHSVarLib.Append("hakurei/" + strconv.Itoa(os.Getuid()))
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
pathBin = container.AbsFHSRoot.Append("bin")
|
||||
|
||||
pathNix = container.MustAbs("/nix/")
|
||||
pathNixStore = pathNix.Append("store/")
|
||||
pathCurrentSystem = container.AbsFHSRun.Append("current-system")
|
||||
pathSwBin = pathCurrentSystem.Append("sw/bin/")
|
||||
pathShell = pathSwBin.Append(bash)
|
||||
|
||||
pathData = container.MustAbs("/data")
|
||||
pathDataData = pathData.Append("data")
|
||||
)
|
||||
|
||||
func lookPath(file string) string {
|
||||
if p, err := exec.LookPath(file); err != nil {
|
||||
log.Fatalf("%s: command not found", file)
|
||||
@@ -51,52 +65,52 @@ func mustRun(name string, arg ...string) {
|
||||
|
||||
type appPathSet struct {
|
||||
// ${dataHome}/${id}
|
||||
baseDir string
|
||||
baseDir *container.Absolute
|
||||
// ${baseDir}/app
|
||||
metaPath string
|
||||
metaPath *container.Absolute
|
||||
// ${baseDir}/files
|
||||
homeDir string
|
||||
homeDir *container.Absolute
|
||||
// ${baseDir}/cache
|
||||
cacheDir string
|
||||
cacheDir *container.Absolute
|
||||
// ${baseDir}/cache/nix
|
||||
nixPath string
|
||||
nixPath *container.Absolute
|
||||
}
|
||||
|
||||
func pathSetByApp(id string) *appPathSet {
|
||||
pathSet := new(appPathSet)
|
||||
pathSet.baseDir = path.Join(dataHome, id)
|
||||
pathSet.metaPath = path.Join(pathSet.baseDir, "app")
|
||||
pathSet.homeDir = path.Join(pathSet.baseDir, "files")
|
||||
pathSet.cacheDir = path.Join(pathSet.baseDir, "cache")
|
||||
pathSet.nixPath = path.Join(pathSet.cacheDir, "nix")
|
||||
pathSet.baseDir = dataHome.Append(id)
|
||||
pathSet.metaPath = pathSet.baseDir.Append("app")
|
||||
pathSet.homeDir = pathSet.baseDir.Append("files")
|
||||
pathSet.cacheDir = pathSet.baseDir.Append("cache")
|
||||
pathSet.nixPath = pathSet.cacheDir.Append("nix")
|
||||
return pathSet
|
||||
}
|
||||
|
||||
func appendGPUFilesystem(config *hst.Config) {
|
||||
config.Container.Filesystem = append(config.Container.Filesystem, []*hst.FilesystemConfig{
|
||||
config.Container.Filesystem = append(config.Container.Filesystem, []hst.FilesystemConfig{
|
||||
// flatpak commit 763a686d874dd668f0236f911de00b80766ffe79
|
||||
{Src: "/dev/dri", Device: true},
|
||||
{Src: container.AbsFHSDev.Append("dri"), Device: true},
|
||||
// mali
|
||||
{Src: "/dev/mali", Device: true},
|
||||
{Src: "/dev/mali0", Device: true},
|
||||
{Src: "/dev/umplock", Device: true},
|
||||
{Src: container.AbsFHSDev.Append("mali"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("mali0"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("umplock"), Device: true},
|
||||
// nvidia
|
||||
{Src: "/dev/nvidiactl", Device: true},
|
||||
{Src: "/dev/nvidia-modeset", Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidiactl"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia-modeset"), Device: true},
|
||||
// nvidia OpenCL/CUDA
|
||||
{Src: "/dev/nvidia-uvm", Device: true},
|
||||
{Src: "/dev/nvidia-uvm-tools", Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia-uvm"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia-uvm-tools"), Device: true},
|
||||
|
||||
// flatpak commit d2dff2875bb3b7e2cd92d8204088d743fd07f3ff
|
||||
{Src: "/dev/nvidia0", Device: true}, {Src: "/dev/nvidia1", Device: true},
|
||||
{Src: "/dev/nvidia2", Device: true}, {Src: "/dev/nvidia3", Device: true},
|
||||
{Src: "/dev/nvidia4", Device: true}, {Src: "/dev/nvidia5", Device: true},
|
||||
{Src: "/dev/nvidia6", Device: true}, {Src: "/dev/nvidia7", Device: true},
|
||||
{Src: "/dev/nvidia8", Device: true}, {Src: "/dev/nvidia9", Device: true},
|
||||
{Src: "/dev/nvidia10", Device: true}, {Src: "/dev/nvidia11", Device: true},
|
||||
{Src: "/dev/nvidia12", Device: true}, {Src: "/dev/nvidia13", Device: true},
|
||||
{Src: "/dev/nvidia14", Device: true}, {Src: "/dev/nvidia15", Device: true},
|
||||
{Src: "/dev/nvidia16", Device: true}, {Src: "/dev/nvidia17", Device: true},
|
||||
{Src: "/dev/nvidia18", Device: true}, {Src: "/dev/nvidia19", Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia0"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia1"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia2"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia3"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia4"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia5"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia6"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia7"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia8"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia9"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia10"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia11"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia12"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia13"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia14"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia15"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia16"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia17"), Device: true},
|
||||
{Src: container.AbsFHSDev.Append("nvidia18"), Device: true}, {Src: container.AbsFHSDev.Append("nvidia19"), Device: true},
|
||||
}...)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
@@ -19,8 +18,8 @@ func withNixDaemon(
|
||||
mustRunAppDropShell(ctx, updateConfig(&hst.Config{
|
||||
ID: app.ID,
|
||||
|
||||
Path: shellPath,
|
||||
Args: []string{shellPath, "-lc", "rm -f /nix/var/nix/daemon-socket/socket && " +
|
||||
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
|
||||
@@ -33,9 +32,9 @@ func withNixDaemon(
|
||||
},
|
||||
|
||||
Username: "hakurei",
|
||||
Shell: shellPath,
|
||||
Shell: pathShell,
|
||||
Data: pathSet.homeDir,
|
||||
Dir: path.Join("/data/data", app.ID),
|
||||
Dir: pathDataData.Append(app.ID),
|
||||
ExtraPerms: []*hst.ExtraPermConfig{
|
||||
{Path: dataHome, Execute: true},
|
||||
{Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
|
||||
@@ -49,15 +48,15 @@ func withNixDaemon(
|
||||
Net: net,
|
||||
SeccompFlags: seccomp.AllowMultiarch,
|
||||
Tty: dropShell,
|
||||
Filesystem: []*hst.FilesystemConfig{
|
||||
{Src: pathSet.nixPath, Dst: "/nix", Write: true, Must: true},
|
||||
Filesystem: []hst.FilesystemConfig{
|
||||
{Src: pathSet.nixPath, Dst: pathNix, Write: true, Must: true},
|
||||
},
|
||||
Link: [][2]string{
|
||||
{app.CurrentSystem, container.FHSRun + "current-system"},
|
||||
{container.FHSRun + "current-system/sw/bin", "/bin"},
|
||||
{container.FHSRun + "current-system/sw/bin", container.FHSUsrBin},
|
||||
Link: []hst.LinkConfig{
|
||||
{pathCurrentSystem, app.CurrentSystem.String()},
|
||||
{pathBin, pathSwBin.String()},
|
||||
{container.AbsFHSUsrBin, pathSwBin.String()},
|
||||
},
|
||||
Etc: path.Join(pathSet.cacheDir, "etc"),
|
||||
Etc: pathSet.cacheDir.Append("etc"),
|
||||
AutoEtc: true,
|
||||
},
|
||||
}), dropShell, beforeFail)
|
||||
@@ -65,18 +64,18 @@ func withNixDaemon(
|
||||
|
||||
func withCacheDir(
|
||||
ctx context.Context,
|
||||
action string, command []string, workDir string,
|
||||
action string, command []string, workDir *container.Absolute,
|
||||
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func()) {
|
||||
mustRunAppDropShell(ctx, &hst.Config{
|
||||
ID: app.ID,
|
||||
|
||||
Path: shellPath,
|
||||
Args: []string{shellPath, "-lc", strings.Join(command, " && ")},
|
||||
Path: pathShell,
|
||||
Args: []string{bash, "-lc", strings.Join(command, " && ")},
|
||||
|
||||
Username: "nixos",
|
||||
Shell: shellPath,
|
||||
Shell: pathShell,
|
||||
Data: pathSet.cacheDir, // this also ensures cacheDir via shim
|
||||
Dir: path.Join("/data/data", app.ID, "cache"),
|
||||
Dir: pathDataData.Append(app.ID, "cache"),
|
||||
ExtraPerms: []*hst.ExtraPermConfig{
|
||||
{Path: dataHome, Execute: true},
|
||||
{Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
|
||||
@@ -89,16 +88,16 @@ func withCacheDir(
|
||||
Hostname: formatHostname(app.Name) + "-" + action,
|
||||
SeccompFlags: seccomp.AllowMultiarch,
|
||||
Tty: dropShell,
|
||||
Filesystem: []*hst.FilesystemConfig{
|
||||
{Src: path.Join(workDir, "nix"), Dst: "/nix", Must: true},
|
||||
{Src: workDir, Dst: path.Join(hst.Tmp, "bundle"), Must: true},
|
||||
Filesystem: []hst.FilesystemConfig{
|
||||
{Src: workDir.Append("nix"), Dst: pathNix, Must: true},
|
||||
{Src: workDir, Dst: hst.AbsTmp.Append("bundle"), Must: true},
|
||||
},
|
||||
Link: [][2]string{
|
||||
{app.CurrentSystem, container.FHSRun + "current-system"},
|
||||
{container.FHSRun + "current-system/sw/bin", "/bin"},
|
||||
{container.FHSRun + "current-system/sw/bin", container.FHSUsrBin},
|
||||
Link: []hst.LinkConfig{
|
||||
{pathCurrentSystem, app.CurrentSystem.String()},
|
||||
{pathBin, pathSwBin.String()},
|
||||
{container.AbsFHSUsrBin, pathSwBin.String()},
|
||||
},
|
||||
Etc: path.Join(workDir, container.FHSEtc),
|
||||
Etc: workDir.Append(container.FHSEtc),
|
||||
AutoEtc: true,
|
||||
},
|
||||
}, dropShell, beforeFail)
|
||||
@@ -106,7 +105,7 @@ func withCacheDir(
|
||||
|
||||
func mustRunAppDropShell(ctx context.Context, config *hst.Config, dropShell bool, beforeFail func()) {
|
||||
if dropShell {
|
||||
config.Args = []string{shellPath, "-l"}
|
||||
config.Args = []string{bash, "-l"}
|
||||
mustRunApp(ctx, config, beforeFail)
|
||||
beforeFail()
|
||||
internal.Exit(0)
|
||||
|
||||
Reference in New Issue
Block a user