19 Commits

Author SHA1 Message Date
cat 33b855123e internal/rosa/package/spirv: spirv-headers 1.4.350.0 to 1.4.350.1
Test / Create distribution (push) Successful in 51s
Test / Sandbox (push) Successful in 2m43s
Test / ShareFS (push) Successful in 3m43s
Test / Sandbox (race detector) (push) Successful in 5m46s
Test / Hakurei (race detector) (push) Successful in 7m0s
Test / Hakurei (push) Successful in 2m35s
Test / Flake checks (push) Successful in 1m38s
This unfortunately does not unblock SPIRV-LLVM-Translator.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 04:43:04 +09:00
cat 58ce134718 internal/outcome: attempt nscd path-hiding if present
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m46s
Test / ShareFS (push) Successful in 3m56s
Test / Hakurei (push) Successful in 4m9s
Test / Sandbox (race detector) (push) Successful in 5m42s
Test / Hakurei (race detector) (push) Successful in 6m50s
Test / Flake checks (push) Successful in 1m9s
This avoids creating the mount point on musl setups which accomplishes nothing and can run into permission problems.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 02:42:35 +09:00
cat 2066093343 cmd/app: remove sysfs bind mounts
Test / Create distribution (push) Successful in 51s
Test / Sandbox (push) Successful in 2m57s
Test / ShareFS (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 5m26s
Test / Hakurei (race detector) (push) Successful in 6m39s
Test / Hakurei (push) Successful in 2m46s
Test / Flake checks (push) Successful in 1m9s
This should be in common instead.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 01:57:55 +09:00
cat 07509b3ba2 cmd/app: additional bind types
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m58s
Test / ShareFS (push) Successful in 3m54s
Test / Hakurei (push) Successful in 4m7s
Test / Sandbox (race detector) (push) Successful in 5m27s
Test / Hakurei (race detector) (push) Successful in 6m43s
Test / Flake checks (push) Successful in 1m25s
This adds optional and device mount points.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 01:51:57 +09:00
cat a7485d587a cmd/app: pass user-specified arguments
Test / Create distribution (push) Successful in 50s
Test / Sandbox (push) Successful in 2m52s
Test / ShareFS (push) Successful in 3m48s
Test / Sandbox (race detector) (push) Successful in 5m20s
Test / Hakurei (race detector) (push) Successful in 6m37s
Test / Hakurei (push) Successful in 2m40s
Test / Flake checks (push) Successful in 1m26s
An extra argument is added to pad out argv0.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 01:44:47 +09:00
cat 4892beefc1 cmd/app: optionally override configured command
Test / Create distribution (push) Successful in 50s
Test / Sandbox (push) Successful in 2m45s
Test / ShareFS (push) Successful in 3m50s
Test / Hakurei (push) Successful in 4m1s
Test / Sandbox (race detector) (push) Successful in 5m33s
Test / Hakurei (race detector) (push) Successful in 6m35s
Test / Flake checks (push) Successful in 1m9s
Useful for multiple applications sharing state.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 01:31:07 +09:00
cat 7ab54b8c94 internal/rosa: read overridden version string from source
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 3m2s
Test / ShareFS (push) Successful in 4m2s
Test / Hakurei (push) Successful in 4m10s
Test / Sandbox (race detector) (push) Successful in 5m31s
Test / Hakurei (race detector) (push) Successful in 6m42s
Test / Flake checks (push) Successful in 1m7s
This is more correct than the hardcoded string and is generally more robust against relative paths.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 01:18:12 +09:00
cat a4fab67811 internal/pkg: optionally exempt implementations from cures counter
Test / Create distribution (push) Successful in 51s
Test / Sandbox (push) Successful in 2m49s
Test / ShareFS (push) Successful in 3m48s
Test / Hakurei (push) Successful in 3m59s
Test / Sandbox (race detector) (push) Successful in 5m23s
Test / Hakurei (race detector) (push) Successful in 6m39s
Test / Flake checks (push) Successful in 1m26s
This avoids holding up many slots with a long pipeline.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 01:03:28 +09:00
cat ed5cdd38a4 cmd/dist: build hsu separately
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m41s
Test / ShareFS (push) Successful in 3m47s
Test / Hakurei (push) Successful in 4m0s
Test / Sandbox (race detector) (push) Successful in 5m25s
Test / Hakurei (race detector) (push) Successful in 6m36s
Test / Flake checks (push) Successful in 1m8s
This program must be built with cgo disabled, and was missed when migrating build script.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 00:59:47 +09:00
cat f6318304ee hst: fix ephemeral overlay order
Test / Create distribution (push) Successful in 1m0s
Test / Sandbox (push) Successful in 2m55s
Test / ShareFS (push) Successful in 4m13s
Test / Hakurei (push) Successful in 4m19s
Test / Sandbox (race detector) (push) Successful in 5m58s
Test / Hakurei (race detector) (push) Successful in 6m53s
Test / Flake checks (push) Successful in 1m11s
This is quite counterintuitive otherwise.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 00:20:31 +09:00
cat cb618093d5 hst: optionally disable file placement
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m39s
Test / ShareFS (push) Successful in 3m46s
Test / Sandbox (race detector) (push) Successful in 5m28s
Test / Hakurei (race detector) (push) Successful in 6m37s
Test / Hakurei (push) Successful in 2m46s
Test / Flake checks (push) Successful in 1m17s
This works around stubborn package managers.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-20 00:16:35 +09:00
cat b0b2471c0c cmd/app: include template name in container metadata
Test / Create distribution (push) Successful in 55s
Test / Sandbox (push) Successful in 3m3s
Test / ShareFS (push) Successful in 3m46s
Test / Hakurei (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 5m27s
Test / Hakurei (race detector) (push) Successful in 6m38s
Test / Flake checks (push) Successful in 1m10s
This helps disambiguate active mutable containers.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-19 23:36:31 +09:00
cat 344d2b8207 cmd/app: use ROSA_ prefix
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 2m52s
Test / ShareFS (push) Successful in 3m51s
Test / Hakurei (push) Successful in 3m59s
Test / Sandbox (race detector) (push) Successful in 5m29s
Test / Hakurei (race detector) (push) Successful in 6m38s
Test / Flake checks (push) Successful in 1m24s
This avoids awkward case-insensitive zsh completion.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-19 23:29:51 +09:00
cat 3938e8bce5 cmd/app: multiple template uppers
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m44s
Test / ShareFS (push) Successful in 3m53s
Test / Hakurei (push) Successful in 4m6s
Test / Sandbox (race detector) (push) Successful in 5m27s
Test / Hakurei (race detector) (push) Successful in 6m40s
Test / Flake checks (push) Successful in 1m12s
Having multiple environments is useful, and this was trivial to implement.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-18 03:51:49 +09:00
cat aee15b4f2a cmd/app: common configuration file
Test / Create distribution (push) Successful in 1m36s
Test / Sandbox (push) Successful in 3m28s
Test / ShareFS (push) Successful in 4m33s
Test / Hakurei (push) Successful in 4m41s
Test / Sandbox (race detector) (push) Successful in 6m45s
Test / Hakurei (race detector) (push) Successful in 7m46s
Test / Flake checks (push) Successful in 1m33s
Generally useful for shared storage and environment.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-18 02:35:56 +09:00
cat 18b1103fdc internal/rosa/llvm: 22.1.7 to 22.1.8
Test / Create distribution (push) Successful in 1m13s
Test / Sandbox (push) Successful in 3m20s
Test / ShareFS (push) Successful in 8m47s
Test / Hakurei (push) Successful in 8m51s
Test / Sandbox (race detector) (push) Successful in 2m54s
Test / Hakurei (race detector) (push) Successful in 4m22s
Test / Flake checks (push) Successful in 1m18s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-17 21:49:38 +09:00
cat c5a02da0f0 internal/rosa/package/python: 3.14.5 to 3.14.6
Test / Create distribution (push) Successful in 1m8s
Test / Sandbox (push) Successful in 3m14s
Test / ShareFS (push) Successful in 6m39s
Test / Hakurei (push) Successful in 7m35s
Test / Sandbox (race detector) (push) Successful in 2m53s
Test / Hakurei (race detector) (push) Successful in 4m27s
Test / Flake checks (push) Successful in 1m19s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-17 21:49:07 +09:00
cat c0c2f3233a internal/rosa/package/util-linux: 2.42.1 to 2.42.2
Test / Create distribution (push) Successful in 55s
Test / Sandbox (push) Successful in 2m58s
Test / ShareFS (push) Successful in 3m57s
Test / Hakurei (push) Successful in 4m7s
Test / Sandbox (race detector) (push) Successful in 5m47s
Test / Hakurei (race detector) (push) Successful in 7m4s
Test / Flake checks (push) Successful in 1m34s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-17 21:44:47 +09:00
cat bda00ac90e internal/rosa/package/hakurei: 0.4.3 to 0.4.4
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m41s
Test / ShareFS (push) Successful in 3m48s
Test / Hakurei (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 5m33s
Test / Hakurei (race detector) (push) Successful in 6m42s
Test / Flake checks (push) Successful in 1m23s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-06-17 21:40:04 +09:00
32 changed files with 318 additions and 135 deletions
+39 -16
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")
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),
@@ -70,19 +68,13 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) {
Write: true,
Perm: 01777,
}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("block")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("bus")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("class")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("dev")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("devices")}},
},
Username: "chronos",
Shell: shell,
Home: home,
Path: shell,
Args: []string{"zsh", "-c"},
Args: []string{"zsh", "-ic"},
Flags: hst.FCoverRun,
},
@@ -102,16 +94,19 @@ 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 {
return nil, err
}
c.Container.Args = append(c.Container.Args, s.Text())
c.Container.Args = append(c.Container.Args, s.Text(), "")
var flagGPU, flagSystemBus bool
flags := map[string]*bool{
@@ -200,6 +195,20 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) {
)
continue
case "ro+":
source, target, err := parsePair(value)
if err != nil {
return nil, err
}
c.Container.Filesystem = append(c.Container.Filesystem,
hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{
Target: target,
Source: source,
Optional: true,
}},
)
continue
case "rw":
source, target, err := parsePair(value)
if err != nil {
@@ -214,6 +223,20 @@ func parse(id string, base *check.Absolute, r io.Reader) (*hst.Config, error) {
)
continue
case "dev":
source, target, err := parsePair(value)
if err != nil {
return nil, err
}
c.Container.Filesystem = append(c.Container.Filesystem,
hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{
Target: target,
Source: source,
Device: true,
}},
)
continue
case "own":
c.SessionBus.Own = append(c.SessionBus.Own, value)
continue
+5 -10
View File
@@ -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"),
@@ -91,12 +91,6 @@ talk com.canonical.Unity
Perm: 01777,
}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("block")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("bus")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("class")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("dev")}},
{FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("devices")}},
{FilesystemConfig: &hst.FSBind{
Source: check.MustAbs("/sdcard"),
Write: true,
@@ -118,8 +112,9 @@ talk com.canonical.Unity
Home: hst.AbsPrivateTmp.Append("home"),
Path: fhs.AbsRoot.Append("bin", "zsh"),
Args: []string{
"zsh", "-c",
"zsh", "-ic",
"exec Discord --ozone-platform-hint=wayland",
"",
},
Flags: hst.FCoverRun | hst.FUserns | hst.FHostNet | hst.FMapRealUID |
+89 -32
View File
@@ -7,6 +7,8 @@ package main
import (
"context"
"errors"
"fmt"
"io"
"log"
"os"
"os/exec"
@@ -34,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)
@@ -49,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,
@@ -59,7 +59,7 @@ func main() {
"Increase log verbosity",
).Flag(
&flagBase,
"d", command.StringFlag("$HAKUREI_APP_PATH"),
"d", command.StringFlag("$ROSA_APP_PATH"),
"Configuration and state directory",
)
@@ -70,17 +70,31 @@ 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",
ID: "app.hakurei.mutable." + args[0],
Container: &hst.ContainerConfig{
Hostname: "mutable",
Hostname: args[0] + "-mutable",
Filesystem: []hst.FilesystemConfigJSON{
{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,
@@ -89,7 +103,8 @@ func main() {
}},
},
Username: "chronos",
Flags: hst.FMultiarch |
Flags: hst.FNoPlace |
hst.FMultiarch |
hst.FDevel |
hst.FUserns |
hst.FHostNet |
@@ -126,29 +141,71 @@ func main() {
)
}
c.NewCommand(
"run", "Start the named application",
func(args []string) error {
if len(args) != 1 {
return errors.New("run requires 1 argument")
}
{
var (
flagCommand string
)
c.NewCommand(
"run", "Start the named application",
func(args []string) error {
if len(args) < 1 {
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
f, err := os.Open(base.Append("app", args[0]).String())
if err != nil {
return err
}
config, err = parse(args[0], base, f)
if closeErr := f.Close(); err == nil {
err = closeErr
}
if err != nil {
return err
}
var config *hst.Config
var r io.Reader
f, err := os.Open(base.Append("app", args[0]).String())
if err != nil {
return err
}
r = f
return run(ctx, msg, config)
},
)
var common *os.File
if common, err = os.Open(base.Append("common").String()); err != nil {
if !errors.Is(err, os.ErrNotExist) {
_ = f.Close()
return err
}
} else {
r = io.MultiReader(f, common)
}
config, err = parse(args[0], base, r)
if closeErr := f.Close(); err == nil {
err = closeErr
}
if common != nil {
if closeErr := common.Close(); err == nil {
err = closeErr
}
}
if err != nil {
return err
}
if flagCommand != "" {
config.Container.Args[2] = flagCommand
}
return run(ctx, msg, config, args[1:]...)
},
).
Flag(
&flagCommand,
"command", command.StringFlag(""),
"Override configured command",
)
}
c.MustParse(os.Args[1:], func(err error) {
if e, ok := errors.AsType[*exec.ExitError](err); ok && e != nil {
+7 -1
View File
@@ -12,7 +12,12 @@ import (
)
// run starts a container via cmd/hakurei and returns after it terminates.
func run(ctx context.Context, msg message.Msg, config *hst.Config) error {
func run(
ctx context.Context,
msg message.Msg,
config *hst.Config,
args ...string,
) error {
c, cancel := context.WithCancel(ctx)
defer cancel()
@@ -25,6 +30,7 @@ func run(ctx context.Context, msg message.Msg, config *hst.Config) error {
cmd.Args = append(cmd.Args, "-v")
}
cmd.Args = append(cmd.Args, "run", "3")
cmd.Args = append(cmd.Args, args...)
r, w, err := os.Pipe()
if err != nil {
+24 -9
View File
@@ -35,8 +35,11 @@ func getenv(key, fallback string) string {
// mustRun runs a command with the current process's environment and panics
// on error or non-zero exit code.
func mustRun(ctx context.Context, name string, arg ...string) {
func mustRun(ctx context.Context, env []string, name string, arg ...string) {
cmd := exec.CommandContext(ctx, name, arg...)
if env != nil {
cmd.Env = append(cmd.Environ(), env...)
}
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
panic(err)
@@ -49,6 +52,7 @@ var comp []byte
func main() {
log.SetFlags(0)
log.SetPrefix("")
log.SetOutput(os.Stdout)
verbose := os.Getenv("VERBOSE") != ""
runTests := os.Getenv("HAKUREI_DIST_MAKE") == ""
@@ -91,26 +95,37 @@ func main() {
verboseFlag = "-buildvcs=false"
}
log.Printf("Building hakurei for %s/%s.", runtime.GOOS, runtime.GOARCH)
mustRun(ctx, "go", "generate", "./...")
log.Printf("Building hakurei %s for %s/%s.", version, runtime.GOOS, runtime.GOARCH)
mustRun(ctx, nil, "go", "generate", "./...")
mustRun(
ctx, "go", "build",
ctx, nil, "go", "build",
"-trimpath",
verboseFlag, "-o", s,
"-ldflags=-s -w "+
"-buildid= -linkmode external -extldflags=-static "+
"-X hakurei.app/internal/info.buildVersion="+version+" "+
"-X hakurei.app/internal/info.hakureiPath="+prefix+"/bin/hakurei "+
"-X hakurei.app/internal/info.hsuPath="+prefix+"/bin/hsu "+
"-X main.hakureiPath="+prefix+"/bin/hakurei",
"./...",
"-X hakurei.app/internal/info.hsuPath="+prefix+"/bin/hsu",
"./cmd/hakurei",
"./cmd/sharefs",
)
log.Println()
log.Printf("Building cmd/hsu for %s/%s.", runtime.GOOS, runtime.GOARCH)
mustRun(
ctx, []string{"CGO_ENABLED=0"}, "go", "build",
"-trimpath",
verboseFlag, "-o", s,
"-ldflags=-s -w "+
"-buildid= "+
"-X main.hakureiPath="+prefix+"/bin/hakurei",
"./cmd/hsu",
)
log.Println()
if runTests {
log.Println("##### Testing Hakurei.")
mustRun(
ctx, "go", "test",
ctx, nil, "go", "test",
"-ldflags=-buildid= -linkmode external -extldflags=-static",
"./...",
)
+5 -2
View File
@@ -64,7 +64,7 @@ func TestPrintShowInstance(t *testing.T) {
Identity: 9 (org.chromium.Chromium)
Enablements: wayland, dbus, pipewire
Groups: video, dialout, plugdev
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, noplace, device, cover_run, runtime, tmpdir
Home: /data/data/org.chromium.Chromium
Hostname: localhost
Path: /run/current-system/sw/bin/chromium
@@ -161,7 +161,7 @@ App
Identity: 9 (org.chromium.Chromium)
Enablements: wayland, dbus, pipewire
Groups: video, dialout, plugdev
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, noplace, device, cover_run, runtime, tmpdir
Home: /data/data/org.chromium.Chromium
Hostname: localhost
Path: /run/current-system/sw/bin/chromium
@@ -354,6 +354,7 @@ App
"tty": true,
"multiarch": true,
"map_real_uid": true,
"noplace": true,
"device": true,
"cover_run": true,
"share_runtime": true,
@@ -506,6 +507,7 @@ App
"tty": true,
"multiarch": true,
"map_real_uid": true,
"noplace": true,
"device": true,
"cover_run": true,
"share_runtime": true,
@@ -705,6 +707,7 @@ func TestPrintPs(t *testing.T) {
"tty": true,
"multiarch": true,
"map_real_uid": true,
"noplace": true,
"device": true,
"cover_run": true,
"share_runtime": true,
+10
View File
@@ -65,6 +65,8 @@ const (
// Some programs fail to connect to dbus session running as a different uid,
// this option works around it by mapping priv-side caller uid in container.
FMapRealUID
// FNoPlace disables placement of /etc/passwd and /etc/group.
FNoPlace
// FDevice mount /dev/ from the init mount namespace as is in the container
// mount namespace.
@@ -101,6 +103,8 @@ func (flags Flags) String() string {
return "tty"
case FMapRealUID:
return "mapuid"
case FNoPlace:
return "noplace"
case FDevice:
return "device"
case FCoverRun:
@@ -197,6 +201,8 @@ type containerConfigJSON = struct {
// Corresponds to [FMapRealUID].
MapRealUID bool `json:"map_real_uid"`
// Corresponds to [FNoPlace].
NoPlace bool `json:"noplace,omitempty"`
// Corresponds to [FDevice].
Device bool `json:"device,omitempty"`
@@ -224,6 +230,7 @@ func (c *ContainerConfig) MarshalJSON() ([]byte, error) {
Tty: c.Flags&FTty != 0,
Multiarch: c.Flags&FMultiarch != 0,
MapRealUID: c.Flags&FMapRealUID != 0,
NoPlace: c.Flags&FNoPlace != 0,
Device: c.Flags&FDevice != 0,
CoverRun: c.Flags&FCoverRun != 0,
ShareRuntime: c.Flags&FShareRuntime != 0,
@@ -266,6 +273,9 @@ func (c *ContainerConfig) UnmarshalJSON(data []byte) error {
if v.MapRealUID {
c.Flags |= FMapRealUID
}
if v.NoPlace {
c.Flags |= FNoPlace
}
if v.Device {
c.Flags |= FDevice
}
+3 -3
View File
@@ -21,8 +21,8 @@ func TestFlagsString(t *testing.T) {
}{
{"none", 0, "none"},
{"none high", hst.FAll + 1, "none"},
{"all", hst.FAll, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir"},
{"all high", math.MaxUint, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, cover_run, runtime, tmpdir"},
{"all", hst.FAll, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, noplace, device, cover_run, runtime, tmpdir"},
{"all high", math.MaxUint, "multiarch, compat, devel, userns, net, abstract, tty, mapuid, noplace, device, cover_run, runtime, tmpdir"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@@ -53,7 +53,7 @@ func TestContainerConfig(t *testing.T) {
{"hostnet hostabstract mapuid", &hst.ContainerConfig{Flags: hst.FHostNet | hst.FHostAbstract | hst.FMapRealUID},
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"host_net":true,"host_abstract":true,"map_real_uid":true}`},
{"all", &hst.ContainerConfig{Flags: hst.FAll},
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"seccomp_compat":true,"devel":true,"userns":true,"host_net":true,"host_abstract":true,"tty":true,"multiarch":true,"map_real_uid":true,"device":true,"cover_run":true,"share_runtime":true,"share_tmpdir":true}`},
`{"env":null,"filesystem":null,"shell":null,"home":null,"args":null,"seccomp_compat":true,"devel":true,"userns":true,"host_net":true,"host_abstract":true,"tty":true,"multiarch":true,"map_real_uid":true,"noplace":true,"device":true,"cover_run":true,"share_runtime":true,"share_tmpdir":true}`},
}
for _, tc := range testCases {
+2 -2
View File
@@ -82,9 +82,9 @@ func (o *FSOverlay) Apply(z *ApplyState) {
z.Overlay(o.Target, o.Upper, o.Work, o.Lower...)
} else {
z.OverlayEphemeral(o.Target, slices.Concat(
[]*check.Absolute{o.Upper},
o.Lower,
[]*check.Absolute{o.Upper})...,
)
)...)
}
} else {
z.OverlayReadonly(o.Target, o.Lower...)
+1 -1
View File
@@ -70,7 +70,7 @@ func TestFSOverlay(t *testing.T) {
Upper: m("/tmp/upper"),
}, true, container.Ops{&container.MountOverlayOp{
Target: m("/"),
Lower: ms("/tmp/.src0", "/tmp/.src1", "/tmp/upper"),
Lower: ms("/tmp/upper", "/tmp/.src0", "/tmp/.src1"),
Upper: fhs.AbsRoot,
}}, m("/"), ms("/tmp/upper", "/tmp/.src0", "/tmp/.src1"),
"e*/:/tmp/upper:/tmp/.src0:/tmp/.src1"},
+1
View File
@@ -244,6 +244,7 @@ func TestTemplate(t *testing.T) {
"tty": true,
"multiarch": true,
"map_real_uid": true,
"noplace": true,
"device": true,
"cover_run": true,
"share_runtime": true,
+24 -4
View File
@@ -1,21 +1,29 @@
// Package env provides the [Paths] struct for efficiently building paths from the environment.
// Package env provides the [Paths] struct for efficiently building paths from
// the environment.
package env
import (
"errors"
"io/fs"
"log"
"os"
"strconv"
"hakurei.app/check"
"hakurei.app/fhs"
"hakurei.app/hst"
)
const VarRunNscd = fhs.Var + "run/nscd"
// Paths holds paths copied from the environment and is used to create [hst.Paths].
type Paths struct {
// TempDir is returned by [os.TempDir].
TempDir *check.Absolute
// RuntimePath is copied from $XDG_RUNTIME_DIR.
RuntimePath *check.Absolute
// Whether [VarRunNscd] is a directory.
HasNscd bool
}
// Copy expands [Paths] into [hst.Paths].
@@ -37,14 +45,17 @@ func (env *Paths) Copy(v *hst.Paths, userid int) {
}
// CopyPaths returns a populated [Paths].
func CopyPaths() *Paths { return CopyPathsFunc(log.Fatalf, os.TempDir, os.Getenv) }
func CopyPaths() *Paths {
return CopyPathsFunc(log.Fatalf, os.TempDir, os.Getenv, os.Stat)
}
// CopyPathsFunc returns a populated [Paths],
// using the provided [log.Fatalf], [os.TempDir], [os.Getenv] functions.
// CopyPathsFunc returns a populated [Paths], using the provided [log.Fatalf],
// [os.TempDir], [os.Getenv] functions.
func CopyPathsFunc(
fatalf func(format string, v ...any),
tempdir func() string,
getenv func(key string) string,
stat func(name string) (fs.FileInfo, error),
) *Paths {
const xdgRuntimeDir = "XDG_RUNTIME_DIR"
@@ -61,5 +72,14 @@ func CopyPathsFunc(
env.RuntimePath = a
}
if fi, err := stat(VarRunNscd); err != nil {
if !errors.Is(err, fs.ErrNotExist) {
fatalf("%v", err)
panic("unreachable")
}
} else {
env.HasNscd = fi.IsDir()
}
return &env
}
+4 -1
View File
@@ -2,6 +2,7 @@ package env_test
import (
"fmt"
"io/fs"
"reflect"
"testing"
@@ -104,7 +105,9 @@ func TestCopyPaths(t *testing.T) {
t.Fatalf("fatalf: %q, want %q", got, tc.fatal)
}
panic(stub.PanicExit)
}, func() string { return tc.tmp }, func(key string) string { return tc.env[key] })
}, func() string { return tc.tmp }, func(key string) string { return tc.env[key] }, func(name string) (fs.FileInfo, error) {
return nil, fs.ErrNotExist
})
if tc.fatal != "" {
t.Fatalf("copyPaths: expected fatal %q", tc.fatal)
+2
View File
@@ -23,6 +23,7 @@ import (
"hakurei.app/container/seccomp"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/internal/env"
"hakurei.app/internal/stub"
"hakurei.app/internal/system"
"hakurei.app/message"
@@ -174,6 +175,7 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) {
call("cmdOutput", stub.ExpectArgs{container.Nonexistent, os.Stderr, []string{}, "/"}, []byte("0"), nil),
call("tempdir", stub.ExpectArgs{}, container.Nonexistent+"/tmp", nil),
call("lookupEnv", stub.ExpectArgs{"XDG_RUNTIME_DIR"}, wantRuntimePath, nil),
call("stat", stub.ExpectArgs{env.VarRunNscd}, stubFileInfoIsDir(true), nil),
call("getuid", stub.ExpectArgs{}, 1000, nil),
call("getgid", stub.ExpectArgs{}, 100, nil),
+1 -1
View File
@@ -110,7 +110,7 @@ func newOutcomeState(k syscallDispatcher, msg message.Msg, id *hst.ID, config *h
Paths: env.CopyPathsFunc(k.fatalf, k.tempdir, func(key string) string {
v, _ := k.lookupEnv(key)
return v
}),
}, k.stat),
Container: config.Container,
}
+2 -8
View File
@@ -143,10 +143,6 @@ func TestOutcomeRun(t *testing.T) {
// spTmpdirOp
Bind(m("/tmp/hakurei.0/tmpdir/9"), fhs.AbsTmp, std.BindWritable).
// spAccountOp
Place(m("/etc/passwd"), []byte("chronos:x:1971:100:Hakurei:/data/data/org.chromium.Chromium:/run/current-system/sw/bin/zsh\n")).
Place(m("/etc/group"), []byte("hakurei:x:100:\n")).
// spWaylandOp
Bind(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/wayland"), m("/run/user/1971/wayland-0"), 0).
@@ -453,7 +449,7 @@ func TestOutcomeRun(t *testing.T) {
Path: m("/nix/store/yqivzpzzn7z5x0lq9hmbzygh45d8rhqd-chromium-start"),
Flags: hst.FUserns | hst.FHostNet | hst.FMapRealUID | hst.FShareRuntime | hst.FShareTmpdir,
Flags: hst.FUserns | hst.FHostNet | hst.FMapRealUID | hst.FNoPlace | hst.FShareRuntime | hst.FShareTmpdir,
},
SystemBus: &hst.BusConfig{
Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
@@ -548,8 +544,6 @@ func TestOutcomeRun(t *testing.T) {
Tmpfs(m("/run/user/"), xdgRuntimeDirSize, 0755).
Bind(m("/tmp/hakurei.0/runtime/1"), m("/run/user/1971"), std.BindWritable).
Bind(m("/tmp/hakurei.0/tmpdir/1"), m("/tmp/"), std.BindWritable).
Place(m("/etc/passwd"), []byte("u0_a1:x:1971:100:Hakurei:/var/lib/persist/module/hakurei/0/1:/run/current-system/sw/bin/zsh\n")).
Place(m("/etc/group"), []byte("hakurei:x:100:\n")).
Bind(m("/run/user/1971/wayland-0"), m("/run/user/1971/wayland-0"), 0).
Bind(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/pipewire"), m("/run/user/1971/pipewire-0"), 0).
Bind(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus"), m("/run/user/1971/bus"), 0).
@@ -716,7 +710,7 @@ func (k *stubNixOS) lookupEnv(key string) (string, bool) {
func (k *stubNixOS) stat(name string) (fs.FileInfo, error) {
switch name {
case "/var/run/nscd":
return nil, nil
return stubFileInfoIsDir(true), nil
case "/run/user/1971/pulse":
return nil, nil
case "/run/user/1971/pulse/native":
-4
View File
@@ -78,10 +78,6 @@ func TestShimEntrypoint(t *testing.T) {
// spTmpdirOp
Bind(m("/tmp/hakurei.10/tmpdir/9999"), fhs.AbsTmp, std.BindWritable).
// spAccountOp
Place(m("/etc/passwd"), []byte("chronos:x:1000:100:Hakurei:/data/data/org.chromium.Chromium:/run/current-system/sw/bin/zsh\n")).
Place(m("/etc/group"), []byte("hakurei:x:100:\n")).
// spWaylandOp
Bind(m("/tmp/hakurei.10/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/wayland"), m("/run/user/1000/wayland-0"), 0).
+13 -10
View File
@@ -6,6 +6,7 @@ import (
"syscall"
"hakurei.app/fhs"
"hakurei.app/hst"
"hakurei.app/internal/validate"
)
@@ -41,16 +42,18 @@ func (s spAccountOp) toContainer(state *outcomeStateParams) error {
state.env["USER"] = username
state.env["SHELL"] = state.Container.Shell.String()
state.params.
Place(fhs.AbsEtc.Append("passwd"),
[]byte(username+":x:"+
state.mapuid.String()+":"+
state.mapgid.String()+
":Hakurei:"+
state.Container.Home.String()+":"+
state.Container.Shell.String()+"\n")).
Place(fhs.AbsEtc.Append("group"),
[]byte("hakurei:x:"+state.mapgid.String()+":\n"))
if state.Container.Flags&hst.FNoPlace == 0 {
state.params.
Place(fhs.AbsEtc.Append("passwd"),
[]byte(username+":x:"+
state.mapuid.String()+":"+
state.mapgid.String()+
":Hakurei:"+
state.Container.Home.String()+":"+
state.Container.Shell.String()+"\n")).
Place(fhs.AbsEtc.Append("group"),
[]byte("hakurei:x:"+state.mapgid.String()+":\n"))
}
return nil
}
+2 -3
View File
@@ -38,6 +38,7 @@ func TestSpAccountOp(t *testing.T) {
{"success fallback username", func(bool, bool) outcomeOp { return spAccountOp{} }, func() *hst.Config {
c := hst.Template()
c.Container.Username = ""
c.Container.Flags = hst.FMapRealUID
return c
}, nil, []stub.Call{
// this op performs basic validation and does not make calls during toSystem
@@ -60,9 +61,7 @@ func TestSpAccountOp(t *testing.T) {
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
Dir: config.Container.Home,
Ops: new(container.Ops).
Place(m("/etc/passwd"), []byte("chronos:x:1000:100:Hakurei:/data/data/org.chromium.Chromium:/run/current-system/sw/bin/zsh\n")).
Place(m("/etc/group"), []byte("hakurei:x:100:\n")),
Ops: new(container.Ops),
}, paramsWantEnv(config, map[string]string{
"HOME": config.Container.Home.String(),
"USER": config.Container.Username,
+14 -9
View File
@@ -18,13 +18,12 @@ import (
"hakurei.app/hst"
"hakurei.app/internal/acl"
"hakurei.app/internal/dbus"
"hakurei.app/internal/env"
"hakurei.app/internal/system"
"hakurei.app/internal/validate"
"hakurei.app/message"
)
const varRunNscd = fhs.Var + "run/nscd"
func init() { gob.Register(new(spParamsOp)) }
// spParamsOp initialises unordered fields of [container.Params] and the
@@ -136,17 +135,23 @@ type spFilesystemOp struct {
}
func (s *spFilesystemOp) toSystem(state *outcomeStateSys) error {
/* retrieve paths and hide them if they're made available in the sandbox;
this feature tries to improve user experience of permissive defaults, and
to warn about issues in custom configuration; it is NOT a security feature
and should not be treated as such, ALWAYS be careful with what you bind */
// retrieve paths and hide them if they're made available in the sandbox
//
// this feature tries to improve user experience of permissive defaults, and
// to warn about issues in custom configuration; it is NOT a security feature
// and should not be treated as such, ALWAYS be careful with what you bind
hidePaths := []string{
state.sc.RuntimePath.String(),
state.sc.SharePath.String(),
}
// this causes emulated passwd database to be bypassed on some /etc/ setups
varRunNscd,
if state.Paths == nil || state.HasNscd {
hidePaths = append(hidePaths,
// this causes emulated passwd database to be bypassed on some /etc/
// setups, made optional to avoid needlessly creating it on
// non-glibc systems when invoking permissive defaults
env.VarRunNscd,
)
}
// dbus.Address does not go through syscallDispatcher
+6
View File
@@ -278,6 +278,8 @@ type archiveArtifact struct {
f Artifact
}
var _ CuresExempt = archiveArtifact{}
// NewArchive returns a new [Artifact] backed by the supplied [Artifact]. The
// source [Artifact] must be a [FileArtifact] and produce a stream compatible
// with [Reader].
@@ -403,3 +405,7 @@ func (a archiveArtifact) Cure(t *TContext) (err error) {
}
return
}
// CuresExempt exempts the cheap [KindArchive] implementation often found at
// the end of a [FileArtifact] pipeline.
func (archiveArtifact) CuresExempt() {}
+5
View File
@@ -25,6 +25,7 @@ type decompressArtifact struct {
}
var _ FileArtifact = new(decompressArtifact)
var _ CuresExempt = new(decompressArtifact)
// decompressArtifactNamed embeds decompressArtifact for a [fmt.Stringer] stream.
type decompressArtifactNamed struct {
@@ -117,3 +118,7 @@ func (a *decompressArtifact) Cure(r *RContext) (io.ReadCloser, error) {
return nil, os.ErrInvalid
}
}
// CuresExempt exempts the cheap [KindDecompress] implementation often part of
// a [FileArtifact] pipeline.
func (*decompressArtifact) CuresExempt() {}
+4
View File
@@ -11,6 +11,7 @@ import (
type fileArtifact []byte
var _ KnownChecksum = new(fileArtifact)
var _ CuresExempt = new(fileArtifact)
// fileArtifactNamed embeds fileArtifact alongside a caller-supplied name.
type fileArtifactNamed struct {
@@ -79,3 +80,6 @@ func (a *fileArtifact) Checksum() Checksum {
func (a *fileArtifact) Cure(*RContext) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(*a)), nil
}
// CuresExempt exempts the cheap [KindFile] implementation.
func (*fileArtifact) CuresExempt() {}
+14
View File
@@ -485,6 +485,16 @@ type KnownChecksum interface {
Checksum() Checksum
}
// CuresExempt is optionally implemented for an artifact exempt to the
// cache-wide cures counter and limit.
type CuresExempt interface {
Artifact
// CuresExempt is a no-op function but serves to distinguish implementations
// that are cures-exempt.
CuresExempt()
}
// FileArtifact refers to an [Artifact] backed by a single file.
//
// FileArtifact does not support fine-grained cancellation. Its context is
@@ -1892,6 +1902,10 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
}
}()
if _, ok := a.(CuresExempt); ok {
curesExempt = true
}
var (
ctx context.Context
done chan<- struct{}
+6
View File
@@ -16,6 +16,8 @@ type tarArtifact struct {
f Artifact
}
var _ CuresExempt = new(tarArtifact)
// tarArtifactNamed embeds tarArtifact for a [fmt.Stringer] tarball.
type tarArtifactNamed struct {
tarArtifact
@@ -211,3 +213,7 @@ func (a *tarArtifact) Cure(t *TContext) (err error) {
}
return
}
// CuresExempt exempts the cheap [KindTar] implementation often at the end of a
// [FileArtifact] pipeline.
func (*tarArtifact) CuresExempt() {}
+2 -2
View File
@@ -190,8 +190,8 @@ ln -s \
})
const (
version = "22.1.7"
checksum = "GFjsoTzJ72YWQuAaNmlO67IIkoZ8Z12u3n0dOEMSpltmyXUJp8e3cccWDrscXILZ"
version = "22.1.8"
checksum = "_QzoDE0W6cv0vfIWeLPDvqG_vKhz6IGWl1nqUUvhlKWiRzf5dMGqeC3tyS2XgI6j"
)
native.MustRegister("llvm-project", func(t Toolchain) (*Metadata, pkg.Artifact) {
+8 -3
View File
@@ -2,11 +2,11 @@ package hakurei-source {
description = "hakurei source tree";
exclude = true;
version# = "0.4.3";
version# = "0.4.4";
output = remoteTar {
url = "https://git.gensokyo.uk/rosa/hakurei/archive/"+
"v"+version+".tar.gz";
checksum = "1LqBJIcYcAFTVfydCahOm4hjjKhY953X9ars0eQj32hnpNncWFefuT6OJpZzIlZv";
checksum = "BCIKpRiVv2tDg8lyX1bG_VgTBBMFCByv726x6DfJ0LiRg5ma4T5fcxYUaQl8JMVB";
compress = gzip;
};
}
@@ -48,8 +48,13 @@ go build -trimpath -tags=rosa -o /work/system/libexec/hakurei -ldflags="-s -w
-X hakurei.app/internal/info.buildVersion=$(cat cmd/dist/VERSION)
-X hakurei.app/internal/info.hakureiPath=/system/bin/hakurei
-X hakurei.app/internal/info.hsuPath=/system/bin/hsu
" ./cmd/hakurei ./cmd/sharefs
echo "Building hsu for $(go env GOOS)/$(go env GOARCH)."
CGO_ENABLED=0 go build -trimpath -tags=rosa -o /work/system/libexec/hakurei -ldflags="-s -w
-buildid=
-X main.hakureiPath=/system/bin/hakurei
" ./...
" ./cmd/hsu
echo`;
check = `
echo '##### Testing hakurei.'
+2 -2
View File
@@ -3,11 +3,11 @@ package python {
website = "https://www.python.org";
anitya = 13254;
version# = "3.14.5";
version# = "3.14.6";
source = remoteTar {
url = "https://www.python.org/ftp/python/"+version+
"/Python-"+version+".tgz";
checksum = "zYIpDlk2ftZ-UVGCQS1rthle2OHoyXV653ztWiopKV1NhmIJf1K2hHbkwM4DozQ9";
checksum = "yynwXnElUvlAweA_RkBKQY35P59Gu5YU6ickJs6Z-blIoHgw5KgKXROY1gq2w0ez";
compress = gzip;
};
patches = [ "zipfile-no-default-strict_timestamps.patch" ];
@@ -1,8 +1,8 @@
diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
index 19aea290b58..51603ba9510 100644
index 2b6e6163b96..180b1bdb42a 100644
--- a/Lib/zipfile/__init__.py
+++ b/Lib/zipfile/__init__.py
@@ -617,7 +617,7 @@ def _decodeExtra(self, filename_crc):
@@ -621,7 +621,7 @@ def _decodeExtra(self, filename_crc):
extra = extra[ln+4:]
@classmethod
@@ -10,13 +10,13 @@ index 19aea290b58..51603ba9510 100644
+ def from_file(cls, filename, arcname=None, *, strict_timestamps=False):
"""Construct an appropriate ZipInfo for a file on the filesystem.
filename should be the path to a file or directory on the filesystem.
@@ -1412,7 +1412,7 @@ class ZipFile:
_windows_illegal_name_trans_table = None
filename should be the path to a file or directory on the
@@ -1421,7 +1421,7 @@ class ZipFile:
_ignore_invalid_names = False
def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True,
- compresslevel=None, *, strict_timestamps=True, metadata_encoding=None):
+ compresslevel=None, *, strict_timestamps=False, metadata_encoding=None):
"""Open the ZIP file with mode read 'r', write 'w', exclusive create 'x',
or append 'a'."""
"""Open the ZIP file with mode read 'r', write 'w', exclusive create
'x', or append 'a'."""
if mode not in ('r', 'w', 'x', 'a'):
+2 -2
View File
@@ -5,11 +5,11 @@ package spirv-headers {
// upstream changed version scheme, anitya incapable of filtering them
latest = anityaFilterSPIRV;
version# = "1.4.350.0";
version# = "1.4.350.1";
source = remoteGitHub {
suffix = "KhronosGroup/SPIRV-Headers";
tag = "vulkan-sdk-"+version;
checksum = "wFCZquDVL4HoE-kWbS_BHHb_d71EYR2A2kVp08oDutektpnQzhDP89wo821GgcpG";
checksum = "6cmvMCH5aiHykXcozckfMOVA0nm0am4Xr2g9swBB9FtOV1vYBHgats5aRv4uQ9Kq";
};
exec = cmake {
+2 -2
View File
@@ -5,7 +5,7 @@ package util-linux {
// release candidates confuse Anitya
latest = anityaFallback;
version# = "2.42.1";
version# = "2.42.2";
source = remoteTar {
url = "https://www.kernel.org/pub/linux/utils/util-linux/"+
"v"+join {
@@ -19,7 +19,7 @@ package util-linux {
};
sep = ".";
}+"/util-linux-"+version+".tar.gz";
checksum = "f1c006mnFL9jTEsqnJn08hHqwcL8TpjCJNIToZNuGEPsLmEdNL87r8RzBT-nl9QB";
checksum = "Z4IZapPCKQP37aeWMDhxcvuOCy-IR_aHZvfUEMZ0T7trwC1znZACKH_3ddqXwBCg";
compress = gzip;
};
+12 -1
View File
@@ -7,6 +7,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"iter"
@@ -1255,6 +1256,16 @@ func (s *S) RegisterFS(fsys fs.FS) error {
// The resulting IR is curable on the daemon. Must not be used concurrently with
// any other method.
func (s *S) SetSource(fsys fs.FS) error {
var version string
if p, err := fs.ReadFile(fsys, "cmd/dist/VERSION"); err != nil {
return err
} else if len(p) < 2 {
return fmt.Errorf("invalid version string %q", string(p))
} else {
version = unsafe.String(unsafe.SliceData(p), len(p))
}
version = version[1:len(version)-1] + "-CURRENT"
var buf bytes.Buffer
w, err := gzip.NewWriterLevel(&buf, gzip.BestSpeed)
if err != nil {
@@ -1326,7 +1337,7 @@ func (s *S) SetSource(fsys fs.FS) error {
return &Metadata{
Name: name,
Description: "hakurei source tree (current)",
Version: "1.0.0-CURRENT",
Version: version,
Exclude: true,
}, pkg.NewTar(pkg.NewDecompress(a, pkg.Gzip))
}),