1
0
forked from rosa/hakurei

cmd/app: multiple template uppers

Having multiple environments is useful, and this was trivial to implement.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-06-18 03:51:49 +09:00
parent aee15b4f2a
commit 3938e8bce5
3 changed files with 43 additions and 19 deletions
+9 -8
View File
@@ -35,6 +35,10 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) {
shell := fhs.AbsRoot.Append("bin", "zsh") shell := fhs.AbsRoot.Append("bin", "zsh")
home := hst.AbsPrivateTmp.Append("home") home := hst.AbsPrivateTmp.Append("home")
root := hst.FSOverlay{
Target: fhs.AbsRoot,
Lower: []*check.Absolute{base.Append("initial")},
}
c := hst.Config{ c := hst.Config{
ID: id, ID: id,
Enablements: new(hst.Enablements), Enablements: new(hst.Enablements),
@@ -51,13 +55,7 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) {
Container: &hst.ContainerConfig{ Container: &hst.ContainerConfig{
Env: make(map[string]string), Env: make(map[string]string),
Filesystem: []hst.FilesystemConfigJSON{ Filesystem: []hst.FilesystemConfigJSON{
{FilesystemConfig: &hst.FSOverlay{ {FilesystemConfig: &root},
Target: fhs.AbsRoot,
Lower: []*check.Absolute{
base.Append("template", "initial"),
},
Upper: base.Append("template", "upper"),
}},
{FilesystemConfig: &hst.FSBind{ {FilesystemConfig: &hst.FSBind{
Target: home, Target: home,
Source: base.Append("state", id), 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 { if err := scanOnce(); err != nil {
return nil, err 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 return nil, err
} else { } else {
c.Identity = v c.Identity = v
root.Upper = base.Append("template", template, "upper")
} }
if err := scanOnce(); err != nil { if err := scanOnce(); err != nil {
+3 -3
View File
@@ -20,7 +20,7 @@ func TestParse(t *testing.T) {
want *hst.Config want *hst.Config
err error err error
}{ }{
{"com.discordapp.Discord", `8 {"com.discordapp.Discord", `nonfree:8
exec Discord --ozone-platform-hint=wayland exec Discord --ozone-platform-hint=wayland
gpu gpu
@@ -74,9 +74,9 @@ talk com.canonical.Unity
{FilesystemConfig: &hst.FSOverlay{ {FilesystemConfig: &hst.FSOverlay{
Target: fhs.AbsRoot, Target: fhs.AbsRoot,
Lower: []*check.Absolute{ Lower: []*check.Absolute{
base.Append("template", "initial"), base.Append("initial"),
}, },
Upper: base.Append("template", "upper"), Upper: base.Append("template", "nonfree", "upper"),
}}, }},
{FilesystemConfig: &hst.FSBind{ {FilesystemConfig: &hst.FSBind{
Target: hst.AbsPrivateTmp.Append("home"), Target: hst.AbsPrivateTmp.Append("home"),
+31 -8
View File
@@ -7,6 +7,7 @@ package main
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"io" "io"
"log" "log"
"os" "os"
@@ -35,7 +36,7 @@ func main() {
flagVerbose bool flagVerbose bool
flagBase string 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) { c := command.New(os.Stderr, log.Printf, "app", func([]string) (err error) {
msg.SwapVerbose(flagVerbose) msg.SwapVerbose(flagVerbose)
@@ -50,9 +51,7 @@ func main() {
} }
template = base.Append("template") template = base.Append("template")
initial = template.Append("initial") initial = base.Append("initial")
upper = template.Append("upper")
work = template.Append("work")
return return
}).Flag( }).Flag(
&flagVerbose, &flagVerbose,
@@ -71,7 +70,21 @@ func main() {
) )
c.NewCommand( c.NewCommand(
"enter", "Enter mutable state template", "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{ config := hst.Config{
ID: "app.hakurei.mutable", ID: "app.hakurei.mutable",
Container: &hst.ContainerConfig{ Container: &hst.ContainerConfig{
@@ -80,8 +93,8 @@ func main() {
{FilesystemConfig: &hst.FSOverlay{ {FilesystemConfig: &hst.FSOverlay{
Target: fhs.AbsRoot, Target: fhs.AbsRoot,
Lower: []*check.Absolute{initial}, Lower: []*check.Absolute{initial},
Upper: upper, Upper: template.Append(args[0], "upper"),
Work: work, Work: template.Append(args[0], "work"),
}}, }},
{FilesystemConfig: &hst.FSEphemeral{ {FilesystemConfig: &hst.FSEphemeral{
Target: fhs.AbsTmp, Target: fhs.AbsTmp,
@@ -131,7 +144,17 @@ func main() {
"run", "Start the named application", "run", "Start the named application",
func(args []string) error { func(args []string) error {
if len(args) != 1 { 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 var config *hst.Config