From 3938e8bce5948514f9a87cd5fe73a99142acc419 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Thu, 18 Jun 2026 03:51:49 +0900 Subject: [PATCH] cmd/app: multiple template uppers Having multiple environments is useful, and this was trivial to implement. Signed-off-by: Ophestra --- cmd/app/app.go | 17 +++++++++-------- cmd/app/app_test.go | 6 +++--- cmd/app/main.go | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/cmd/app/app.go b/cmd/app/app.go index b5e5ee92..7dd8b651 100644 --- a/cmd/app/app.go +++ b/cmd/app/app.go @@ -35,6 +35,10 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) { shell := fhs.AbsRoot.Append("bin", "zsh") home := hst.AbsPrivateTmp.Append("home") + root := hst.FSOverlay{ + Target: fhs.AbsRoot, + Lower: []*check.Absolute{base.Append("initial")}, + } c := hst.Config{ ID: id, Enablements: new(hst.Enablements), @@ -51,13 +55,7 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) { Container: &hst.ContainerConfig{ Env: make(map[string]string), Filesystem: []hst.FilesystemConfigJSON{ - {FilesystemConfig: &hst.FSOverlay{ - Target: fhs.AbsRoot, - Lower: []*check.Absolute{ - base.Append("template", "initial"), - }, - Upper: base.Append("template", "upper"), - }}, + {FilesystemConfig: &root}, {FilesystemConfig: &hst.FSBind{ Target: home, Source: base.Append("state", id), @@ -102,10 +100,13 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) { if err := scanOnce(); err != nil { return nil, err } - if v, err := strconv.Atoi(s.Text()); err != nil { + if template, identity, ok := strings.Cut(s.Text(), ":"); !ok { + return nil, io.ErrUnexpectedEOF + } else if v, err := strconv.Atoi(identity); err != nil { return nil, err } else { c.Identity = v + root.Upper = base.Append("template", template, "upper") } if err := scanOnce(); err != nil { diff --git a/cmd/app/app_test.go b/cmd/app/app_test.go index 7a83bcc8..10593607 100644 --- a/cmd/app/app_test.go +++ b/cmd/app/app_test.go @@ -20,7 +20,7 @@ func TestParse(t *testing.T) { want *hst.Config err error }{ - {"com.discordapp.Discord", `8 + {"com.discordapp.Discord", `nonfree:8 exec Discord --ozone-platform-hint=wayland gpu @@ -74,9 +74,9 @@ talk com.canonical.Unity {FilesystemConfig: &hst.FSOverlay{ Target: fhs.AbsRoot, Lower: []*check.Absolute{ - base.Append("template", "initial"), + base.Append("initial"), }, - Upper: base.Append("template", "upper"), + Upper: base.Append("template", "nonfree", "upper"), }}, {FilesystemConfig: &hst.FSBind{ Target: hst.AbsPrivateTmp.Append("home"), diff --git a/cmd/app/main.go b/cmd/app/main.go index 4cb711ba..86b964e3 100644 --- a/cmd/app/main.go +++ b/cmd/app/main.go @@ -7,6 +7,7 @@ package main import ( "context" "errors" + "fmt" "io" "log" "os" @@ -35,7 +36,7 @@ func main() { flagVerbose bool flagBase string - base, template, initial, upper, work *check.Absolute + base, template, initial *check.Absolute ) c := command.New(os.Stderr, log.Printf, "app", func([]string) (err error) { msg.SwapVerbose(flagVerbose) @@ -50,9 +51,7 @@ func main() { } template = base.Append("template") - initial = template.Append("initial") - upper = template.Append("upper") - work = template.Append("work") + initial = base.Append("initial") return }).Flag( &flagVerbose, @@ -71,7 +70,21 @@ func main() { ) c.NewCommand( "enter", "Enter mutable state template", - func([]string) error { + func(args []string) error { + if len(args) != 1 { + dents, err := os.ReadDir(template.String()) + if err != nil { + return err + } + for _, dent := range dents { + if !dent.IsDir() { + continue + } + fmt.Println(dent.Name()) + } + return nil + } + config := hst.Config{ ID: "app.hakurei.mutable", Container: &hst.ContainerConfig{ @@ -80,8 +93,8 @@ func main() { {FilesystemConfig: &hst.FSOverlay{ Target: fhs.AbsRoot, Lower: []*check.Absolute{initial}, - Upper: upper, - Work: work, + Upper: template.Append(args[0], "upper"), + Work: template.Append(args[0], "work"), }}, {FilesystemConfig: &hst.FSEphemeral{ Target: fhs.AbsTmp, @@ -131,7 +144,17 @@ func main() { "run", "Start the named application", func(args []string) error { if len(args) != 1 { - return errors.New("run requires 1 argument") + dents, err := os.ReadDir(base.Append("app").String()) + if err != nil { + return err + } + for _, dent := range dents { + if dent.IsDir() { + continue + } + fmt.Println(dent.Name()) + } + return nil } var config *hst.Config