Compare commits
41 Commits
master
...
94a3ea9e5c
| Author | SHA1 | Date | |
|---|---|---|---|
| 94a3ea9e5c | |||
| 3a52d45378 | |||
| b1e381fcff | |||
| 9fad74b374 | |||
| 05cdf1135d | |||
| 217e83276f | |||
| fbf1dd4c6c | |||
| 5a552993e5 | |||
| 63b1f3fc4b | |||
| 42bed68072 | |||
| 0066556d19 | |||
| fa6e0f1ea0 | |||
| bdbdced477 | |||
| 8a80f6dbab | |||
| f5fdfcb271 | |||
| 87a19d7ec1 | |||
| f81527eb07 | |||
| 0e20a7d86e | |||
| d881c059b1 | |||
| c17b6ee190 | |||
| 65a0cf068d | |||
| 964e47fcec | |||
| 78bfc3acec | |||
| de580952af | |||
| dbb07b0631 | |||
| ed4692659e | |||
| f19b86fe94 | |||
| bc069cc83d | |||
| def2b8fab7 | |||
| 23c957b22c | |||
| dc13407386 | |||
| 42a2918644 | |||
| d8e720bcc9 | |||
| 459acd7dce | |||
| e7c64bcd41 | |||
| eee4e3be5e | |||
| 01ed763993 | |||
| 3930b2bf7f | |||
| 5158ecffd1 | |||
| d41dd227dd | |||
| 0d7be9c287 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
# go generate
|
# go generate
|
||||||
/cmd/hakurei/LICENSE
|
/cmd/hakurei/LICENSE
|
||||||
/cmd/mbf/internal/pkgserver/ui/static
|
/cmd/pkgserver/ui/static/*.js
|
||||||
/internal/pkg/internal/testtool/testtool
|
/internal/pkg/testdata/testtool
|
||||||
/internal/rosa/hakurei_current.tar.gz
|
/internal/rosa/hakurei_current.tar.gz
|
||||||
|
|
||||||
# cmd/dist default destination
|
# cmd/dist default destination
|
||||||
|
|||||||
5
all.sh
5
all.sh
@@ -1,3 +1,6 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
HAKUREI_DIST_MAKE='' exec "$(dirname -- "$0")/cmd/dist/dist.sh"
|
TOOLCHAIN_VERSION="$(go version)"
|
||||||
|
cd "$(dirname -- "$0")/"
|
||||||
|
echo "# Building cmd/dist using ${TOOLCHAIN_VERSION}."
|
||||||
|
go run -v --tags=dist ./cmd/dist
|
||||||
|
|||||||
@@ -4,23 +4,15 @@ import "strings"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// SpecialOverlayEscape is the escape string for overlay mount options.
|
// SpecialOverlayEscape is the escape string for overlay mount options.
|
||||||
//
|
|
||||||
// Deprecated: This is no longer used and will be removed in 0.5.
|
|
||||||
SpecialOverlayEscape = `\`
|
SpecialOverlayEscape = `\`
|
||||||
// SpecialOverlayOption is the separator string between overlay mount options.
|
// SpecialOverlayOption is the separator string between overlay mount options.
|
||||||
//
|
|
||||||
// Deprecated: This is no longer used and will be removed in 0.5.
|
|
||||||
SpecialOverlayOption = ","
|
SpecialOverlayOption = ","
|
||||||
// SpecialOverlayPath is the separator string between overlay paths.
|
// SpecialOverlayPath is the separator string between overlay paths.
|
||||||
//
|
|
||||||
// Deprecated: This is no longer used and will be removed in 0.5.
|
|
||||||
SpecialOverlayPath = ":"
|
SpecialOverlayPath = ":"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EscapeOverlayDataSegment escapes a string for formatting into the data
|
// EscapeOverlayDataSegment escapes a string for formatting into the data
|
||||||
// argument of an overlay mount system call.
|
// argument of an overlay mount system call.
|
||||||
//
|
|
||||||
// Deprecated: This is no longer used and will be removed in 0.5.
|
|
||||||
func EscapeOverlayDataSegment(s string) string {
|
func EscapeOverlayDataSegment(s string) string {
|
||||||
if s == "" {
|
if s == "" {
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
10
cmd/dist/dist.sh
vendored
10
cmd/dist/dist.sh
vendored
@@ -1,10 +0,0 @@
|
|||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
TOOLCHAIN_VERSION="$(go version)"
|
|
||||||
cd "$(dirname -- "$0")/../.."
|
|
||||||
echo "Building cmd/dist using ${TOOLCHAIN_VERSION}."
|
|
||||||
FLAGS=''
|
|
||||||
if test -n "$VERBOSE"; then
|
|
||||||
FLAGS="$FLAGS -v"
|
|
||||||
fi
|
|
||||||
go run $FLAGS --tags=dist ./cmd/dist
|
|
||||||
30
cmd/dist/main.go
vendored
30
cmd/dist/main.go
vendored
@@ -42,19 +42,14 @@ func mustRun(ctx context.Context, name string, arg ...string) {
|
|||||||
var comp []byte
|
var comp []byte
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
fmt.Println()
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
log.SetPrefix("")
|
log.SetPrefix("# ")
|
||||||
|
|
||||||
verbose := os.Getenv("VERBOSE") != ""
|
|
||||||
runTests := os.Getenv("HAKUREI_DIST_MAKE") == ""
|
|
||||||
version := getenv("HAKUREI_VERSION", "untagged")
|
version := getenv("HAKUREI_VERSION", "untagged")
|
||||||
prefix := getenv("PREFIX", "/usr")
|
prefix := getenv("PREFIX", "/usr")
|
||||||
destdir := getenv("DESTDIR", "dist")
|
destdir := getenv("DESTDIR", "dist")
|
||||||
|
|
||||||
if verbose {
|
|
||||||
log.Println()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(destdir, 0755); err != nil {
|
if err := os.MkdirAll(destdir, 0755); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -81,17 +76,12 @@ func main() {
|
|||||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
verboseFlag := "-v"
|
log.Println("Building hakurei.")
|
||||||
if !verbose {
|
|
||||||
verboseFlag = "-buildvcs=false"
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Building hakurei for %s/%s.", runtime.GOOS, runtime.GOARCH)
|
|
||||||
mustRun(ctx, "go", "generate", "./...")
|
mustRun(ctx, "go", "generate", "./...")
|
||||||
mustRun(
|
mustRun(
|
||||||
ctx, "go", "build",
|
ctx, "go", "build",
|
||||||
"-trimpath",
|
"-trimpath",
|
||||||
verboseFlag, "-o", s,
|
"-v", "-o", s,
|
||||||
"-ldflags=-s -w "+
|
"-ldflags=-s -w "+
|
||||||
"-buildid= -linkmode external -extldflags=-static "+
|
"-buildid= -linkmode external -extldflags=-static "+
|
||||||
"-X hakurei.app/internal/info.buildVersion="+version+" "+
|
"-X hakurei.app/internal/info.buildVersion="+version+" "+
|
||||||
@@ -100,19 +90,17 @@ func main() {
|
|||||||
"-X main.hakureiPath="+prefix+"/bin/hakurei",
|
"-X main.hakureiPath="+prefix+"/bin/hakurei",
|
||||||
"./...",
|
"./...",
|
||||||
)
|
)
|
||||||
log.Println()
|
fmt.Println()
|
||||||
|
|
||||||
if runTests {
|
log.Println("Testing Hakurei.")
|
||||||
log.Println("##### Testing Hakurei.")
|
|
||||||
mustRun(
|
mustRun(
|
||||||
ctx, "go", "test",
|
ctx, "go", "test",
|
||||||
"-ldflags=-buildid= -linkmode external -extldflags=-static",
|
"-ldflags=-buildid= -linkmode external -extldflags=-static",
|
||||||
"./...",
|
"./...",
|
||||||
)
|
)
|
||||||
log.Println()
|
fmt.Println()
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("##### Creating distribution.")
|
log.Println("Creating distribution.")
|
||||||
const suffix = ".tar.gz"
|
const suffix = ".tar.gz"
|
||||||
distName := "hakurei-" + version + "-" + runtime.GOARCH
|
distName := "hakurei-" + version + "-" + runtime.GOARCH
|
||||||
var f *os.File
|
var f *os.File
|
||||||
@@ -133,7 +121,7 @@ func main() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
h := sha512.New()
|
h := sha512.New()
|
||||||
gw, _ := gzip.NewWriterLevel(io.MultiWriter(f, h), gzip.BestCompression)
|
gw := gzip.NewWriter(io.MultiWriter(f, h))
|
||||||
tw := tar.NewWriter(gw)
|
tw := tar.NewWriter(gw)
|
||||||
|
|
||||||
mustWriteHeader := func(name string, size int64, mode os.FileMode) {
|
mustWriteHeader := func(name string, size int64, mode os.FileMode) {
|
||||||
|
|||||||
76
cmd/irdump/main.go
Normal file
76
cmd/irdump/main.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"hakurei.app/command"
|
||||||
|
"hakurei.app/internal/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.SetFlags(0)
|
||||||
|
log.SetPrefix("irdump: ")
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagOutput string
|
||||||
|
flagReal bool
|
||||||
|
flagHeader bool
|
||||||
|
flagForce bool
|
||||||
|
flagRaw bool
|
||||||
|
)
|
||||||
|
c := command.New(os.Stderr, log.Printf, "irdump", func(args []string) (err error) {
|
||||||
|
var input *os.File
|
||||||
|
if len(args) != 1 {
|
||||||
|
return errors.New("irdump requires 1 argument")
|
||||||
|
}
|
||||||
|
if input, err = os.Open(args[0]); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer input.Close()
|
||||||
|
|
||||||
|
var output *os.File
|
||||||
|
if flagOutput == "" {
|
||||||
|
output = os.Stdout
|
||||||
|
} else {
|
||||||
|
defer output.Close()
|
||||||
|
if output, err = os.Create(flagOutput); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var out string
|
||||||
|
if out, err = pkg.Disassemble(input, flagReal, flagHeader, flagForce, flagRaw); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err = output.WriteString(out); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}).Flag(
|
||||||
|
&flagOutput,
|
||||||
|
"o", command.StringFlag(""),
|
||||||
|
"Output file for asm (leave empty for stdout)",
|
||||||
|
).Flag(
|
||||||
|
&flagReal,
|
||||||
|
"r", command.BoolFlag(false),
|
||||||
|
"skip label generation; idents print real value",
|
||||||
|
).Flag(
|
||||||
|
&flagHeader,
|
||||||
|
"H", command.BoolFlag(false),
|
||||||
|
"display artifact headers",
|
||||||
|
).Flag(
|
||||||
|
&flagForce,
|
||||||
|
"f", command.BoolFlag(false),
|
||||||
|
"force display (skip validations)",
|
||||||
|
).Flag(
|
||||||
|
&flagRaw,
|
||||||
|
"R", command.BoolFlag(false),
|
||||||
|
"don't format output",
|
||||||
|
)
|
||||||
|
|
||||||
|
c.MustParse(os.Args[1:], func(err error) {
|
||||||
|
log.Fatal(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
)
|
)
|
||||||
@@ -21,14 +20,7 @@ type cache struct {
|
|||||||
c *pkg.Cache
|
c *pkg.Cache
|
||||||
|
|
||||||
cures, jobs int
|
cures, jobs int
|
||||||
// Primarily to work around missing landlock LSM.
|
hostAbstract, idle bool
|
||||||
hostAbstract bool
|
|
||||||
// Set SCHED_IDLE.
|
|
||||||
idle bool
|
|
||||||
// Unset [pkg.CSuppressInit].
|
|
||||||
verboseInit bool
|
|
||||||
// Loaded artifact of [rosa.QEMU].
|
|
||||||
qemu pkg.Artifact
|
|
||||||
|
|
||||||
base string
|
base string
|
||||||
}
|
}
|
||||||
@@ -39,6 +31,9 @@ func (cache *cache) open() (err error) {
|
|||||||
return os.ErrInvalid
|
return os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cache.base == "" {
|
||||||
|
cache.base = "cache"
|
||||||
|
}
|
||||||
var base *check.Absolute
|
var base *check.Absolute
|
||||||
if cache.base, err = filepath.Abs(cache.base); err != nil {
|
if cache.base, err = filepath.Abs(cache.base); err != nil {
|
||||||
return
|
return
|
||||||
@@ -53,9 +48,6 @@ func (cache *cache) open() (err error) {
|
|||||||
if cache.hostAbstract {
|
if cache.hostAbstract {
|
||||||
flags |= pkg.CHostAbstract
|
flags |= pkg.CHostAbstract
|
||||||
}
|
}
|
||||||
if !cache.verboseInit {
|
|
||||||
flags |= pkg.CSuppressInit
|
|
||||||
}
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
defer close(done)
|
defer close(done)
|
||||||
@@ -81,39 +73,6 @@ func (cache *cache) open() (err error) {
|
|||||||
cache.jobs,
|
cache.jobs,
|
||||||
base,
|
base,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
done <- struct{}{}
|
|
||||||
|
|
||||||
if cache.qemu != nil {
|
|
||||||
var pathname *check.Absolute
|
|
||||||
pathname, _, err = cache.c.Cure(cache.qemu)
|
|
||||||
if err != nil {
|
|
||||||
cache.c.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pkg.RegisterArch("riscv64", container.BinfmtEntry{
|
|
||||||
Offset: 0,
|
|
||||||
Magic: "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00",
|
|
||||||
Mask: "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff",
|
|
||||||
Interpreter: pathname.Append(
|
|
||||||
"system/bin",
|
|
||||||
"qemu-riscv64",
|
|
||||||
),
|
|
||||||
})
|
|
||||||
pkg.RegisterArch("arm64", container.BinfmtEntry{
|
|
||||||
Offset: 0,
|
|
||||||
Magic: "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00",
|
|
||||||
Mask: "\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff",
|
|
||||||
Interpreter: pathname.Append(
|
|
||||||
"system/bin",
|
|
||||||
"qemu-aarch64",
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,9 +99,10 @@ func cancelIdent(
|
|||||||
var ident pkg.ID
|
var ident pkg.ID
|
||||||
if _, err := io.ReadFull(conn, ident[:]); err != nil {
|
if _, err := io.ReadFull(conn, ident[:]); err != nil {
|
||||||
return nil, false, errors.Join(err, conn.Close())
|
return nil, false, errors.Join(err, conn.Close())
|
||||||
|
} else if err = conn.Close(); err != nil {
|
||||||
|
return nil, false, err
|
||||||
}
|
}
|
||||||
ok := cache.Cancel(unique.Make(ident))
|
return &ident, cache.Cancel(unique.Make(ident)), nil
|
||||||
return &ident, ok, conn.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve services connections from a [net.UnixListener].
|
// serve services connections from a [net.UnixListener].
|
||||||
@@ -193,11 +194,11 @@ func serve(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case specialAbort:
|
case specialAbort:
|
||||||
log.Println("aborting all pending cures")
|
|
||||||
cm.c.Abort()
|
|
||||||
if _err := conn.Close(); _err != nil {
|
if _err := conn.Close(); _err != nil {
|
||||||
log.Println(_err)
|
log.Println(_err)
|
||||||
}
|
}
|
||||||
|
log.Println("aborting all pending cures")
|
||||||
|
cm.c.Abort()
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -305,7 +306,6 @@ func cancelRemote(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
addr *net.UnixAddr,
|
addr *net.UnixAddr,
|
||||||
a pkg.Artifact,
|
a pkg.Artifact,
|
||||||
wait bool,
|
|
||||||
) error {
|
) error {
|
||||||
done, conn, err := dial(ctx, addr)
|
done, conn, err := dial(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -324,19 +324,13 @@ func cancelRemote(
|
|||||||
} else if n != len(id) {
|
} else if n != len(id) {
|
||||||
return errors.Join(io.ErrShortWrite, conn.Close())
|
return errors.Join(io.ErrShortWrite, conn.Close())
|
||||||
}
|
}
|
||||||
if wait {
|
return conn.Close()
|
||||||
if _, err = conn.Read(make([]byte, 1)); err == io.EOF {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors.Join(err, conn.Close())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// abortRemote aborts all [pkg.Artifact] curing on a daemon.
|
// abortRemote aborts all [pkg.Artifact] curing on a daemon.
|
||||||
func abortRemote(
|
func abortRemote(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
addr *net.UnixAddr,
|
addr *net.UnixAddr,
|
||||||
wait bool,
|
|
||||||
) error {
|
) error {
|
||||||
done, conn, err := dial(ctx, addr)
|
done, conn, err := dial(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -345,10 +339,5 @@ func abortRemote(
|
|||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
err = writeSpecialHeader(conn, specialAbort)
|
err = writeSpecialHeader(conn, specialAbort)
|
||||||
if wait && err == nil {
|
|
||||||
if _, err = conn.Read(make([]byte, 1)); err == io.EOF {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors.Join(err, conn.Close())
|
return errors.Join(err, conn.Close())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,11 +106,11 @@ func TestDaemon(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err = cancelRemote(ctx, &addr, pkg.NewFile("nonexistent", nil), true); err != nil {
|
if err = cancelRemote(ctx, &addr, pkg.NewFile("nonexistent", nil)); err != nil {
|
||||||
t.Fatalf("cancelRemote: error = %v", err)
|
t.Fatalf("cancelRemote: error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = abortRemote(ctx, &addr, true); err != nil {
|
if err = abortRemote(ctx, &addr); err != nil {
|
||||||
t.Fatalf("abortRemote: error = %v", err)
|
t.Fatalf("abortRemote: error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,25 @@ func commandInfo(
|
|||||||
args []string,
|
args []string,
|
||||||
w io.Writer,
|
w io.Writer,
|
||||||
writeStatus bool,
|
writeStatus bool,
|
||||||
r *rosa.Report,
|
reportPath string,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return errors.New("info requires at least 1 argument")
|
return errors.New("info requires at least 1 argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var r *rosa.Report
|
||||||
|
if reportPath != "" {
|
||||||
|
if r, err = rosa.OpenReport(reportPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if closeErr := r.Close(); err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
defer r.HandleAccess(&err)()
|
||||||
|
}
|
||||||
|
|
||||||
// recovered by HandleAccess
|
// recovered by HandleAccess
|
||||||
mustPrintln := func(a ...any) {
|
mustPrintln := func(a ...any) {
|
||||||
if _, _err := fmt.Fprintln(w, a...); _err != nil {
|
if _, _err := fmt.Fprintln(w, a...); _err != nil {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ status : not in report
|
|||||||
var (
|
var (
|
||||||
cm *cache
|
cm *cache
|
||||||
buf strings.Builder
|
buf strings.Builder
|
||||||
r *rosa.Report
|
rp string
|
||||||
)
|
)
|
||||||
|
|
||||||
if tc.status != nil || tc.report != "" {
|
if tc.status != nil || tc.report != "" {
|
||||||
@@ -108,25 +108,14 @@ status : not in report
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tc.report != "" {
|
if tc.report != "" {
|
||||||
pathname := filepath.Join(t.TempDir(), "report")
|
rp = filepath.Join(t.TempDir(), "report")
|
||||||
err := os.WriteFile(
|
if err := os.WriteFile(
|
||||||
pathname,
|
rp,
|
||||||
unsafe.Slice(unsafe.StringData(tc.report), len(tc.report)),
|
unsafe.Slice(unsafe.StringData(tc.report), len(tc.report)),
|
||||||
0400,
|
0400,
|
||||||
)
|
); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err = rosa.OpenReport(pathname)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err = r.Close(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if tc.status != nil {
|
if tc.status != nil {
|
||||||
@@ -168,7 +157,7 @@ status : not in report
|
|||||||
tc.args,
|
tc.args,
|
||||||
&buf,
|
&buf,
|
||||||
cm != nil,
|
cm != nil,
|
||||||
r,
|
rp,
|
||||||
); !reflect.DeepEqual(err, wantErr) {
|
); !reflect.DeepEqual(err, wantErr) {
|
||||||
t.Fatalf("commandInfo: error = %v, want %v", err, wantErr)
|
t.Fatalf("commandInfo: error = %v, want %v", err, wantErr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
// Package ui holds the static web UI.
|
|
||||||
package ui
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
// Register arranges for mux to serve the embedded frontend.
|
|
||||||
func Register(mux *http.ServeMux) {
|
|
||||||
mux.Handle("GET /", http.FileServer(http.FS(static)))
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
//go:build frontend
|
|
||||||
|
|
||||||
package ui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"io/fs"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:generate tsc
|
|
||||||
//go:generate cp index.html style.css static
|
|
||||||
//go:embed static
|
|
||||||
var _static embed.FS
|
|
||||||
|
|
||||||
var static = func() fs.FS {
|
|
||||||
if f, err := fs.Sub(_static, "static"); err != nil {
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
168
cmd/mbf/main.go
168
cmd/mbf/main.go
@@ -20,7 +20,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -42,9 +41,6 @@ import (
|
|||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
"hakurei.app/internal/rosa"
|
"hakurei.app/internal/rosa"
|
||||||
"hakurei.app/message"
|
"hakurei.app/message"
|
||||||
|
|
||||||
"hakurei.app/cmd/mbf/internal/pkgserver"
|
|
||||||
"hakurei.app/cmd/mbf/internal/pkgserver/ui"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -63,16 +59,17 @@ func main() {
|
|||||||
defer stop()
|
defer stop()
|
||||||
|
|
||||||
var cm cache
|
var cm cache
|
||||||
defer func() { cm.Close() }()
|
defer func() {
|
||||||
|
cm.Close()
|
||||||
|
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
fmt.Println(r)
|
||||||
|
log.Fatal("consider scrubbing the on-disk cache")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flagQuiet bool
|
flagQuiet bool
|
||||||
flagQEMU bool
|
|
||||||
flagArch string
|
|
||||||
flagCheck bool
|
|
||||||
flagLTO bool
|
|
||||||
|
|
||||||
flagCrossOverride int
|
|
||||||
|
|
||||||
addr net.UnixAddr
|
addr net.UnixAddr
|
||||||
)
|
)
|
||||||
@@ -80,38 +77,11 @@ func main() {
|
|||||||
msg.SwapVerbose(!flagQuiet)
|
msg.SwapVerbose(!flagQuiet)
|
||||||
cm.ctx, cm.msg = ctx, msg
|
cm.ctx, cm.msg = ctx, msg
|
||||||
cm.base = os.ExpandEnv(cm.base)
|
cm.base = os.ExpandEnv(cm.base)
|
||||||
if cm.base == "" {
|
|
||||||
cm.base = "cache"
|
|
||||||
}
|
|
||||||
|
|
||||||
addr.Net = "unix"
|
addr.Net = "unix"
|
||||||
addr.Name = os.ExpandEnv(addr.Name)
|
addr.Name = os.ExpandEnv(addr.Name)
|
||||||
if addr.Name == "" {
|
if addr.Name == "" {
|
||||||
addr.Name = filepath.Join(cm.base, "daemon")
|
addr.Name = "daemon"
|
||||||
}
|
|
||||||
|
|
||||||
var flags int
|
|
||||||
if !flagCheck {
|
|
||||||
flags |= rosa.OptSkipCheck
|
|
||||||
}
|
|
||||||
if !flagLTO {
|
|
||||||
flags |= rosa.OptLLVMNoLTO
|
|
||||||
}
|
|
||||||
rosa.DropCaches("", flags)
|
|
||||||
cross := flagArch != "" && flagArch != runtime.GOARCH
|
|
||||||
if flagQEMU || cross {
|
|
||||||
cm.qemu = rosa.Std.Load(rosa.QEMU)
|
|
||||||
}
|
|
||||||
|
|
||||||
if cross {
|
|
||||||
if flagCrossOverride != -1 {
|
|
||||||
flags = flagCrossOverride
|
|
||||||
}
|
|
||||||
|
|
||||||
rosa.DropCaches(flagArch, flags)
|
|
||||||
if !rosa.HasStage0() {
|
|
||||||
return pkg.UnsupportedArchError(flagArch)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -119,30 +89,6 @@ func main() {
|
|||||||
&flagQuiet,
|
&flagQuiet,
|
||||||
"q", command.BoolFlag(false),
|
"q", command.BoolFlag(false),
|
||||||
"Do not print cure messages",
|
"Do not print cure messages",
|
||||||
).Flag(
|
|
||||||
&flagQEMU,
|
|
||||||
"register", command.BoolFlag(false),
|
|
||||||
"Enable additional target architectures",
|
|
||||||
).Flag(
|
|
||||||
&flagArch,
|
|
||||||
"arch", command.StringFlag(runtime.GOARCH),
|
|
||||||
"Target architecture",
|
|
||||||
).Flag(
|
|
||||||
&flagLTO,
|
|
||||||
"lto", command.BoolFlag(false),
|
|
||||||
"Enable LTO in stage2 and stage3 LLVM toolchains",
|
|
||||||
).Flag(
|
|
||||||
&flagCheck,
|
|
||||||
"check", command.BoolFlag(true),
|
|
||||||
"Run test suites",
|
|
||||||
).Flag(
|
|
||||||
&flagCrossOverride,
|
|
||||||
"cross-flags", command.IntFlag(-1),
|
|
||||||
"Override non-native target preset flags",
|
|
||||||
).Flag(
|
|
||||||
&cm.verboseInit,
|
|
||||||
"v", command.BoolFlag(false),
|
|
||||||
"Do not suppress verbose output from init",
|
|
||||||
).Flag(
|
).Flag(
|
||||||
&cm.cures,
|
&cm.cures,
|
||||||
"cures", command.IntFlag(0),
|
"cures", command.IntFlag(0),
|
||||||
@@ -175,17 +121,7 @@ func main() {
|
|||||||
c.NewCommand(
|
c.NewCommand(
|
||||||
"checksum", "Compute checksum of data read from standard input",
|
"checksum", "Compute checksum of data read from standard input",
|
||||||
func([]string) error {
|
func([]string) error {
|
||||||
done := make(chan struct{})
|
go func() { <-ctx.Done(); os.Exit(1) }()
|
||||||
defer close(done)
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
os.Exit(1)
|
|
||||||
case <-done:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
h := sha512.New384()
|
h := sha512.New384()
|
||||||
if _, err := io.Copy(h, os.Stdin); err != nil {
|
if _, err := io.Copy(h, os.Stdin); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -219,7 +155,6 @@ func main() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
var (
|
var (
|
||||||
flagBind string
|
|
||||||
flagStatus bool
|
flagStatus bool
|
||||||
flagReport string
|
flagReport string
|
||||||
)
|
)
|
||||||
@@ -227,52 +162,8 @@ func main() {
|
|||||||
"info",
|
"info",
|
||||||
"Display out-of-band metadata of an artifact",
|
"Display out-of-band metadata of an artifact",
|
||||||
func(args []string) (err error) {
|
func(args []string) (err error) {
|
||||||
const shutdownTimeout = 15 * time.Second
|
return commandInfo(&cm, args, os.Stdout, flagStatus, flagReport)
|
||||||
|
|
||||||
var r *rosa.Report
|
|
||||||
if flagReport != "" {
|
|
||||||
if r, err = rosa.OpenReport(flagReport); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if closeErr := r.Close(); err == nil {
|
|
||||||
err = closeErr
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
defer r.HandleAccess(&err)()
|
|
||||||
}
|
|
||||||
|
|
||||||
if flagBind == "" {
|
|
||||||
return commandInfo(&cm, args, os.Stdout, flagStatus, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
var mux http.ServeMux
|
|
||||||
ui.Register(&mux)
|
|
||||||
if err = pkgserver.Register(ctx, &mux, r); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
server := http.Server{Addr: flagBind, Handler: &mux}
|
|
||||||
go func() {
|
|
||||||
<-ctx.Done()
|
|
||||||
cc, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
|
||||||
defer cancel()
|
|
||||||
if _err := server.Shutdown(cc); _err != nil {
|
|
||||||
log.Fatal(_err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
msg.Verbosef("listening on %q", flagBind)
|
|
||||||
err = server.ListenAndServe()
|
|
||||||
if errors.Is(err, http.ErrServerClosed) {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return
|
|
||||||
},
|
},
|
||||||
).Flag(
|
|
||||||
&flagBind,
|
|
||||||
"bind", command.StringFlag(""),
|
|
||||||
"TCP address for the server to listen on",
|
|
||||||
).Flag(
|
).Flag(
|
||||||
&flagStatus,
|
&flagStatus,
|
||||||
"status", command.BoolFlag(false),
|
"status", command.BoolFlag(false),
|
||||||
@@ -431,7 +322,7 @@ func main() {
|
|||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
pathname, _, err = cache.Cure(
|
pathname, _, err = cache.Cure(
|
||||||
(t - 2).Load(rosa.LLVM),
|
(t - 2).Load(rosa.Clang),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -441,7 +332,7 @@ func main() {
|
|||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
pathname, checksum[0], err = cache.Cure(
|
pathname, checksum[0], err = cache.Cure(
|
||||||
(t - 1).Load(rosa.LLVM),
|
(t - 1).Load(rosa.Clang),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -450,7 +341,7 @@ func main() {
|
|||||||
log.Println("stage2:", pathname)
|
log.Println("stage2:", pathname)
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
pathname, checksum[1], err = cache.Cure(
|
pathname, checksum[1], err = cache.Cure(
|
||||||
t.Load(rosa.LLVM),
|
t.Load(rosa.Clang),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -506,9 +397,6 @@ func main() {
|
|||||||
flagExport string
|
flagExport string
|
||||||
flagRemote bool
|
flagRemote bool
|
||||||
flagNoReply bool
|
flagNoReply bool
|
||||||
|
|
||||||
flagBoot bool
|
|
||||||
flagStd bool
|
|
||||||
)
|
)
|
||||||
c.NewCommand(
|
c.NewCommand(
|
||||||
"cure",
|
"cure",
|
||||||
@@ -522,18 +410,11 @@ func main() {
|
|||||||
return fmt.Errorf("unknown artifact %q", args[0])
|
return fmt.Errorf("unknown artifact %q", args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
t := rosa.Std
|
|
||||||
if flagBoot {
|
|
||||||
t -= 2
|
|
||||||
} else if flagStd {
|
|
||||||
t -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
var pathname *check.Absolute
|
var pathname *check.Absolute
|
||||||
err := cm.Do(func(cache *pkg.Cache) (err error) {
|
err := cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
pathname, _, err = cache.Cure(t.Load(p))
|
pathname, _, err = cache.Cure(rosa.Std.Load(p))
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -586,7 +467,7 @@ func main() {
|
|||||||
return cm.Do(func(cache *pkg.Cache) error {
|
return cm.Do(func(cache *pkg.Cache) error {
|
||||||
return cache.EnterExec(
|
return cache.EnterExec(
|
||||||
ctx,
|
ctx,
|
||||||
t.Load(p),
|
rosa.Std.Load(p),
|
||||||
true, os.Stdin, os.Stdout, os.Stderr,
|
true, os.Stdin, os.Stdout, os.Stderr,
|
||||||
rosa.AbsSystem.Append("bin", "mksh"),
|
rosa.AbsSystem.Append("bin", "mksh"),
|
||||||
"sh",
|
"sh",
|
||||||
@@ -598,7 +479,7 @@ func main() {
|
|||||||
if flagNoReply {
|
if flagNoReply {
|
||||||
flags |= remoteNoReply
|
flags |= remoteNoReply
|
||||||
}
|
}
|
||||||
a := t.Load(p)
|
a := rosa.Std.Load(p)
|
||||||
pathname, err := cureRemote(ctx, &addr, a, flags)
|
pathname, err := cureRemote(ctx, &addr, a, flags)
|
||||||
if !flagNoReply && err == nil {
|
if !flagNoReply && err == nil {
|
||||||
log.Println(pathname)
|
log.Println(pathname)
|
||||||
@@ -608,7 +489,7 @@ func main() {
|
|||||||
cc, cancel := context.WithDeadline(context.Background(), daemonDeadline())
|
cc, cancel := context.WithDeadline(context.Background(), daemonDeadline())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if _err := cancelRemote(cc, &addr, a, false); _err != nil {
|
if _err := cancelRemote(cc, &addr, a); _err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,21 +517,13 @@ func main() {
|
|||||||
&flagNoReply,
|
&flagNoReply,
|
||||||
"no-reply", command.BoolFlag(false),
|
"no-reply", command.BoolFlag(false),
|
||||||
"Do not receive a reply from the daemon",
|
"Do not receive a reply from the daemon",
|
||||||
).Flag(
|
|
||||||
&flagBoot,
|
|
||||||
"boot", command.BoolFlag(false),
|
|
||||||
"Build on the stage0 toolchain",
|
|
||||||
).Flag(
|
|
||||||
&flagStd,
|
|
||||||
"std", command.BoolFlag(false),
|
|
||||||
"Build on the intermediate toolchain",
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.NewCommand(
|
c.NewCommand(
|
||||||
"abort",
|
"abort",
|
||||||
"Abort all pending cures on the daemon",
|
"Abort all pending cures on the daemon",
|
||||||
func([]string) error { return abortRemote(ctx, &addr, false) },
|
func([]string) error { return abortRemote(ctx, &addr) },
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -673,7 +546,7 @@ func main() {
|
|||||||
presets[i] = p
|
presets[i] = p
|
||||||
}
|
}
|
||||||
|
|
||||||
base := rosa.LLVM
|
base := rosa.Clang
|
||||||
if !flagWithToolchain {
|
if !flagWithToolchain {
|
||||||
base = rosa.Musl
|
base = rosa.Musl
|
||||||
}
|
}
|
||||||
@@ -745,7 +618,6 @@ func main() {
|
|||||||
z.Hostname = "localhost"
|
z.Hostname = "localhost"
|
||||||
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
|
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
|
||||||
z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr
|
z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
z.Quiet = !cm.verboseInit
|
|
||||||
if s, ok := os.LookupEnv("TERM"); ok {
|
if s, ok := os.LookupEnv("TERM"); ok {
|
||||||
z.Env = append(z.Env, "TERM="+s)
|
z.Env = append(z.Env, "TERM="+s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"hakurei.app/internal/rosa"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
rosa.DropCaches("", rosa.OptLLVMNoLTO)
|
|
||||||
os.Exit(m.Run())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCureAll(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
const env = "ROSA_TEST_DAEMON"
|
|
||||||
|
|
||||||
if !testing.Verbose() {
|
|
||||||
t.Skip("verbose flag not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
pathname, ok := os.LookupEnv(env)
|
|
||||||
if !ok {
|
|
||||||
t.Skip(env + " not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
addr := net.UnixAddr{Net: "unix", Name: pathname}
|
|
||||||
t.Cleanup(func() {
|
|
||||||
if t.Failed() {
|
|
||||||
if err := abortRemote(t.Context(), &addr, false); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
for i := range rosa.PresetEnd {
|
|
||||||
p := rosa.PArtifact(i)
|
|
||||||
t.Run(rosa.GetMetadata(p).Name, func(t *testing.T) {
|
|
||||||
_, err := cureRemote(t.Context(), &addr, rosa.Std.Load(p), 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
// Package pkgserver implements the package metadata service backend.
|
package main
|
||||||
package pkgserver
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -10,7 +8,6 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"hakurei.app/internal/info"
|
"hakurei.app/internal/info"
|
||||||
"hakurei.app/internal/rosa"
|
"hakurei.app/internal/rosa"
|
||||||
@@ -161,29 +158,6 @@ func (index *packageIndex) registerAPI(mux *http.ServeMux) {
|
|||||||
mux.HandleFunc("GET /status/", index.newStatusHandler(true))
|
mux.HandleFunc("GET /status/", index.newStatusHandler(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register arranges for mux to service API requests.
|
|
||||||
func Register(ctx context.Context, mux *http.ServeMux, report *rosa.Report) error {
|
|
||||||
var index packageIndex
|
|
||||||
index.search = make(searchCache)
|
|
||||||
if err := index.populate(report); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ticker := time.NewTicker(1 * time.Minute)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
ticker.Stop()
|
|
||||||
return
|
|
||||||
case <-ticker.C:
|
|
||||||
index.search.clean()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
index.registerAPI(mux)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeAPIPayload sets headers common to API responses and encodes payload as
|
// writeAPIPayload sets headers common to API responses and encodes payload as
|
||||||
// JSON for the response body.
|
// JSON for the response body.
|
||||||
func writeAPIPayload(w http.ResponseWriter, payload any) {
|
func writeAPIPayload(w http.ResponseWriter, payload any) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pkgserver
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -118,9 +118,11 @@ func TestAPIGet(t *testing.T) {
|
|||||||
checkStatus(t, resp, http.StatusOK)
|
checkStatus(t, resp, http.StatusOK)
|
||||||
checkAPIHeader(t, w.Header())
|
checkAPIHeader(t, w.Header())
|
||||||
checkPayloadFunc(t, resp, func(got *struct {
|
checkPayloadFunc(t, resp, func(got *struct {
|
||||||
|
Count int `json:"count"`
|
||||||
Values []*metadata `json:"values"`
|
Values []*metadata `json:"values"`
|
||||||
}) bool {
|
}) bool {
|
||||||
return slices.EqualFunc(got.Values, want, func(a, b *metadata) bool {
|
return got.Count == len(want) &&
|
||||||
|
slices.EqualFunc(got.Values, want, func(a, b *metadata) bool {
|
||||||
return (a.Version == b.Version ||
|
return (a.Version == b.Version ||
|
||||||
a.Version == rosa.Unversioned ||
|
a.Version == rosa.Unversioned ||
|
||||||
b.Version == rosa.Unversioned) &&
|
b.Version == rosa.Unversioned) &&
|
||||||
@@ -134,15 +136,15 @@ func TestAPIGet(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkWithSuffix("declarationAscending", "?limit=2&index=1&sort=0", []*metadata{
|
checkWithSuffix("declarationAscending", "?limit=2&index=0&sort=0", []*metadata{
|
||||||
|
{
|
||||||
|
Metadata: rosa.GetMetadata(0),
|
||||||
|
Version: rosa.Std.Version(0),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Metadata: rosa.GetMetadata(1),
|
Metadata: rosa.GetMetadata(1),
|
||||||
Version: rosa.Std.Version(1),
|
Version: rosa.Std.Version(1),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Metadata: rosa.GetMetadata(2),
|
|
||||||
Version: rosa.Std.Version(2),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
checkWithSuffix("declarationAscending offset", "?limit=3&index=5&sort=0", []*metadata{
|
checkWithSuffix("declarationAscending offset", "?limit=3&index=5&sort=0", []*metadata{
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pkgserver
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmp"
|
"cmp"
|
||||||
@@ -50,7 +50,7 @@ type metadata struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// populate deterministically populates packageIndex, optionally with a report.
|
// populate deterministically populates packageIndex, optionally with a report.
|
||||||
func (index *packageIndex) populate(report *rosa.Report) (err error) {
|
func (index *packageIndex) populate(cache *pkg.Cache, report *rosa.Report) (err error) {
|
||||||
if report != nil {
|
if report != nil {
|
||||||
defer report.HandleAccess(&err)()
|
defer report.HandleAccess(&err)()
|
||||||
index.handleAccess = report.HandleAccess
|
index.handleAccess = report.HandleAccess
|
||||||
@@ -58,7 +58,6 @@ func (index *packageIndex) populate(report *rosa.Report) (err error) {
|
|||||||
|
|
||||||
var work [rosa.PresetUnexportedStart]*metadata
|
var work [rosa.PresetUnexportedStart]*metadata
|
||||||
index.names = make(map[string]*metadata)
|
index.names = make(map[string]*metadata)
|
||||||
ir := pkg.NewIR()
|
|
||||||
for p := range rosa.PresetUnexportedStart {
|
for p := range rosa.PresetUnexportedStart {
|
||||||
m := metadata{
|
m := metadata{
|
||||||
p: p,
|
p: p,
|
||||||
@@ -73,8 +72,8 @@ func (index *packageIndex) populate(report *rosa.Report) (err error) {
|
|||||||
m.Version = ""
|
m.Version = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if report != nil {
|
if cache != nil && report != nil {
|
||||||
id := ir.Ident(rosa.Std.Load(p))
|
id := cache.Ident(rosa.Std.Load(p))
|
||||||
m.ids = pkg.Encode(id.Value())
|
m.ids = pkg.Encode(id.Value())
|
||||||
m.status, m.Size = report.ArtifactOf(id)
|
m.status, m.Size = report.ArtifactOf(id)
|
||||||
m.HasReport = m.Size >= 0
|
m.HasReport = m.Size >= 0
|
||||||
114
cmd/pkgserver/main.go
Normal file
114
cmd/pkgserver/main.go
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"hakurei.app/check"
|
||||||
|
"hakurei.app/command"
|
||||||
|
"hakurei.app/internal/pkg"
|
||||||
|
"hakurei.app/internal/rosa"
|
||||||
|
"hakurei.app/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
const shutdownTimeout = 15 * time.Second
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.SetFlags(0)
|
||||||
|
log.SetPrefix("pkgserver: ")
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagBaseDir string
|
||||||
|
flagAddr string
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||||
|
defer stop()
|
||||||
|
msg := message.New(log.Default())
|
||||||
|
|
||||||
|
c := command.New(os.Stderr, log.Printf, "pkgserver", func(args []string) error {
|
||||||
|
var (
|
||||||
|
cache *pkg.Cache
|
||||||
|
report *rosa.Report
|
||||||
|
)
|
||||||
|
switch len(args) {
|
||||||
|
case 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
baseDir, err := check.NewAbs(flagBaseDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cache, err = pkg.Open(ctx, msg, 0, 0, baseDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cache.Close()
|
||||||
|
|
||||||
|
report, err = rosa.OpenReport(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return errors.New("pkgserver requires 1 argument")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var index packageIndex
|
||||||
|
index.search = make(searchCache)
|
||||||
|
if err := index.populate(cache, report); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ticker := time.NewTicker(1 * time.Minute)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
ticker.Stop()
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
index.search.clean()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
var mux http.ServeMux
|
||||||
|
uiRoutes(&mux)
|
||||||
|
index.registerAPI(&mux)
|
||||||
|
server := http.Server{
|
||||||
|
Addr: flagAddr,
|
||||||
|
Handler: &mux,
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
<-ctx.Done()
|
||||||
|
c, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||||
|
defer cancel()
|
||||||
|
if err := server.Shutdown(c); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return server.ListenAndServe()
|
||||||
|
}).Flag(
|
||||||
|
&flagBaseDir,
|
||||||
|
"b", command.StringFlag(""),
|
||||||
|
"base directory for cache",
|
||||||
|
).Flag(
|
||||||
|
&flagAddr,
|
||||||
|
"addr", command.StringFlag(":8067"),
|
||||||
|
"TCP network address to listen on",
|
||||||
|
)
|
||||||
|
c.MustParse(os.Args[1:], func(err error) {
|
||||||
|
if errors.Is(err, http.ErrServerClosed) {
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
log.Fatal(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pkgserver
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -15,7 +15,7 @@ func newIndex(t *testing.T) *packageIndex {
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
var index packageIndex
|
var index packageIndex
|
||||||
if err := index.populate(nil); err != nil {
|
if err := index.populate(nil, nil); err != nil {
|
||||||
t.Fatalf("populate: error = %v", err)
|
t.Fatalf("populate: error = %v", err)
|
||||||
}
|
}
|
||||||
return &index
|
return &index
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pkgserver
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmp"
|
"cmp"
|
||||||
33
cmd/pkgserver/ui.go
Normal file
33
cmd/pkgserver/ui.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
func serveWebUI(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
|
w.Header().Set("Pragma", "no-cache")
|
||||||
|
w.Header().Set("Expires", "0")
|
||||||
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
w.Header().Set("X-XSS-Protection", "1")
|
||||||
|
w.Header().Set("X-Frame-Options", "DENY")
|
||||||
|
|
||||||
|
http.ServeFileFS(w, r, content, "ui/index.html")
|
||||||
|
}
|
||||||
|
func serveStaticContent(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/static/style.css":
|
||||||
|
http.ServeFileFS(w, r, content, "ui/static/style.css")
|
||||||
|
case "/favicon.ico":
|
||||||
|
http.ServeFileFS(w, r, content, "ui/static/favicon.ico")
|
||||||
|
case "/static/index.js":
|
||||||
|
http.ServeFileFS(w, r, content, "ui/static/index.js")
|
||||||
|
default:
|
||||||
|
http.NotFound(w, r)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func uiRoutes(mux *http.ServeMux) {
|
||||||
|
mux.HandleFunc("GET /{$}", serveWebUI)
|
||||||
|
mux.HandleFunc("GET /favicon.ico", serveStaticContent)
|
||||||
|
mux.HandleFunc("GET /static/", serveStaticContent)
|
||||||
|
}
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="static/style.css">
|
||||||
<title>Hakurei PkgServer</title>
|
<title>Hakurei PkgServer</title>
|
||||||
<script src="index.js"></script>
|
<script src="static/index.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Hakurei PkgServer</h1>
|
<h1>Hakurei PkgServer</h1>
|
||||||
BIN
cmd/pkgserver/ui/static/favicon.ico
Normal file
BIN
cmd/pkgserver/ui/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
9
cmd/pkgserver/ui_full.go
Normal file
9
cmd/pkgserver/ui_full.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build frontend
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:generate tsc -p ui
|
||||||
|
//go:embed ui/*
|
||||||
|
var content embed.FS
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build !frontend
|
//go:build !frontend
|
||||||
|
|
||||||
package ui
|
package main
|
||||||
|
|
||||||
import "testing/fstest"
|
import "testing/fstest"
|
||||||
|
|
||||||
var static fstest.MapFS
|
var content fstest.MapFS
|
||||||
@@ -20,14 +20,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
# Hopefully reduces spurious test failures:
|
|
||||||
memorySize = if pkgs.stdenv.hostPlatform.is32bit then 2046 else 8192;
|
|
||||||
|
|
||||||
diskSize = 6 * 1024;
|
diskSize = 6 * 1024;
|
||||||
|
|
||||||
qemu.options = [
|
qemu.options = [
|
||||||
# Increase test performance:
|
# Increase test performance:
|
||||||
"-smp 16"
|
"-smp 8"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ testers.nixosTest {
|
|||||||
# For go tests:
|
# For go tests:
|
||||||
(pkgs.writeShellScriptBin "sharefs-workload-hakurei-tests" ''
|
(pkgs.writeShellScriptBin "sharefs-workload-hakurei-tests" ''
|
||||||
cp -r "${self.packages.${system}.hakurei.src}" "/sdcard/hakurei" && cd "/sdcard/hakurei"
|
cp -r "${self.packages.${system}.hakurei.src}" "/sdcard/hakurei" && cd "/sdcard/hakurei"
|
||||||
${fhs}/bin/hakurei-fhs -c 'ROSA_SKIP_BINFMT=1 CC="clang -O3 -Werror" go test ./...'
|
${fhs}/bin/hakurei-fhs -c 'CC="clang -O3 -Werror" go test ./...'
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
package container
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"hakurei.app/check"
|
|
||||||
)
|
|
||||||
|
|
||||||
// escapeBinfmt escapes magic/mask sequences in a [BinfmtEntry].
|
|
||||||
func escapeBinfmt(buf *strings.Builder, s string) string {
|
|
||||||
const lowerhex = "0123456789abcdef"
|
|
||||||
|
|
||||||
buf.Reset()
|
|
||||||
for _, c := range unsafe.Slice(unsafe.StringData(s), len(s)) {
|
|
||||||
switch c {
|
|
||||||
case 0, '\\', ':':
|
|
||||||
buf.WriteString(`\x`)
|
|
||||||
buf.WriteByte(lowerhex[c>>4])
|
|
||||||
buf.WriteByte(lowerhex[c&0xf])
|
|
||||||
|
|
||||||
default:
|
|
||||||
buf.WriteByte(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// BinfmtEntry is an entry to be registered by the init process.
|
|
||||||
type BinfmtEntry struct {
|
|
||||||
// The offset of the magic/mask in the file, counted in bytes.
|
|
||||||
Offset byte
|
|
||||||
// The byte sequence binfmt_misc is matching for.
|
|
||||||
Magic string
|
|
||||||
// An (optional, defaults to all 0xff) mask.
|
|
||||||
Mask string
|
|
||||||
// The program that should be invoked with the binary as first argument.
|
|
||||||
Interpreter *check.Absolute
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid returns whether e can be registered into the kernel.
|
|
||||||
func (e *BinfmtEntry) Valid() bool {
|
|
||||||
return e != nil &&
|
|
||||||
int(e.Offset)+max(len(e.Magic), len(e.Mask)) < 128 &&
|
|
||||||
e.Interpreter != nil && len(e.Interpreter.String()) < 128
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package container
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"hakurei.app/fhs"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEscapeBinfmt(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
name string
|
|
||||||
magic string
|
|
||||||
want string
|
|
||||||
}{
|
|
||||||
{"packed DOS applications", "\x0eDEX", "\x0eDEX"},
|
|
||||||
|
|
||||||
{"riscv64 magic",
|
|
||||||
"\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00",
|
|
||||||
"\x7fELF\x02\x01\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\x02\\x00\xf3\\x00"},
|
|
||||||
{"riscv64 mask",
|
|
||||||
"\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff",
|
|
||||||
"\xff\xff\xff\xff\xff\xff\xff\\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
got := escapeBinfmt(new(strings.Builder), tc.magic)
|
|
||||||
if got != tc.want {
|
|
||||||
t.Errorf("escapeBinfmt: %q, want %q", got, tc.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBinfmtEntry(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
name string
|
|
||||||
e BinfmtEntry
|
|
||||||
valid bool
|
|
||||||
}{
|
|
||||||
{"zero", BinfmtEntry{}, false},
|
|
||||||
{"large offset", BinfmtEntry{Offset: 128}, false},
|
|
||||||
{"long magic", BinfmtEntry{Magic: strings.Repeat("\x00", 128)}, false},
|
|
||||||
{"long mask", BinfmtEntry{Mask: strings.Repeat("\x00", 128)}, false},
|
|
||||||
{"valid", BinfmtEntry{Interpreter: fhs.AbsRoot}, true},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
if tc.e.Valid() != tc.valid {
|
|
||||||
t.Errorf("Valid: %v", !tc.valid)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ const (
|
|||||||
CAP_SETPCAP = 0x8
|
CAP_SETPCAP = 0x8
|
||||||
CAP_NET_ADMIN = 0xc
|
CAP_NET_ADMIN = 0xc
|
||||||
CAP_DAC_OVERRIDE = 0x1
|
CAP_DAC_OVERRIDE = 0x1
|
||||||
CAP_SETFCAP = 0x1f
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
|||||||
@@ -67,9 +67,6 @@ type (
|
|||||||
// Copied to the underlying [exec.Cmd].
|
// Copied to the underlying [exec.Cmd].
|
||||||
WaitDelay time.Duration
|
WaitDelay time.Duration
|
||||||
|
|
||||||
// Suppress verbose output of init.
|
|
||||||
Quiet bool
|
|
||||||
|
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
msg message.Msg
|
msg message.Msg
|
||||||
@@ -91,20 +88,12 @@ type (
|
|||||||
// Time to wait for processes lingering after the initial process terminates.
|
// Time to wait for processes lingering after the initial process terminates.
|
||||||
AdoptWaitDelay time.Duration
|
AdoptWaitDelay time.Duration
|
||||||
|
|
||||||
// Map uid/gid 0 in the init process. Requires [FstypeProc] attached to
|
|
||||||
// [fhs.Proc] in the container filesystem.
|
|
||||||
InitAsRoot bool
|
|
||||||
// Mapped Uid in user namespace.
|
// Mapped Uid in user namespace.
|
||||||
Uid int
|
Uid int
|
||||||
// Mapped Gid in user namespace.
|
// Mapped Gid in user namespace.
|
||||||
Gid int
|
Gid int
|
||||||
// Hostname value in UTS namespace.
|
// Hostname value in UTS namespace.
|
||||||
Hostname string
|
Hostname string
|
||||||
// Register binfmt_misc entries.
|
|
||||||
Binfmt []BinfmtEntry
|
|
||||||
// Alternative pathname to attach binfmt_misc filesystem. The zero value
|
|
||||||
// requires [FstypeProc] to be made available at [fhs.Proc].
|
|
||||||
BinfmtPath *check.Absolute
|
|
||||||
// Sequential container setup ops.
|
// Sequential container setup ops.
|
||||||
*Ops
|
*Ops
|
||||||
|
|
||||||
@@ -224,9 +213,6 @@ func (p *Container) Start() error {
|
|||||||
if p.cmd.Process != nil {
|
if p.cmd.Process != nil {
|
||||||
return errors.New("container: already started")
|
return errors.New("container: already started")
|
||||||
}
|
}
|
||||||
if !p.InitAsRoot && len(p.Binfmt) > 0 {
|
|
||||||
return errors.New("container: init as root required, but not enabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ensureCloseOnExec(); err != nil {
|
if err := ensureCloseOnExec(); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -297,18 +283,6 @@ func (p *Container) Start() error {
|
|||||||
if !p.HostNet {
|
if !p.HostNet {
|
||||||
p.cmd.SysProcAttr.Cloneflags |= CLONE_NEWNET
|
p.cmd.SysProcAttr.Cloneflags |= CLONE_NEWNET
|
||||||
}
|
}
|
||||||
if p.InitAsRoot {
|
|
||||||
p.cmd.SysProcAttr.AmbientCaps = append(p.cmd.SysProcAttr.AmbientCaps,
|
|
||||||
// mappings during init as root
|
|
||||||
CAP_SETFCAP,
|
|
||||||
)
|
|
||||||
|
|
||||||
if !p.SeccompDisable &&
|
|
||||||
len(p.SeccompRules) == 0 &&
|
|
||||||
p.SeccompPresets&std.PresetDenyNS != 0 {
|
|
||||||
return errors.New("container: as root requires late namespace creation")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// place setup pipe before user supplied extra files, this is later restored by init
|
// place setup pipe before user supplied extra files, this is later restored by init
|
||||||
if r, w, err := os.Pipe(); err != nil {
|
if r, w, err := os.Pipe(); err != nil {
|
||||||
@@ -368,6 +342,8 @@ func (p *Container) Start() error {
|
|||||||
Err: ENOSYS,
|
Err: ENOSYS,
|
||||||
Origin: true,
|
Origin: true,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
p.msg.Verbosef("landlock abi version %d", abi)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rulesetFd, err := rulesetAttr.Create(0); err != nil {
|
if rulesetFd, err := rulesetAttr.Create(0); err != nil {
|
||||||
@@ -377,6 +353,7 @@ func (p *Container) Start() error {
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
p.msg.Verbosef("enforcing landlock ruleset %s", rulesetAttr)
|
||||||
if err = landlock.RestrictSelf(rulesetFd, 0); err != nil {
|
if err = landlock.RestrictSelf(rulesetFd, 0); err != nil {
|
||||||
_ = Close(rulesetFd)
|
_ = Close(rulesetFd)
|
||||||
return &StartError{
|
return &StartError{
|
||||||
@@ -433,6 +410,7 @@ func (p *Container) Start() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.msg.Verbose("starting container init")
|
||||||
if err := p.cmd.Start(); err != nil {
|
if err := p.cmd.Start(); err != nil {
|
||||||
return &StartError{
|
return &StartError{
|
||||||
Step: "start container init",
|
Step: "start container init",
|
||||||
@@ -503,6 +481,7 @@ func (p *Container) Serve() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case <-done:
|
case <-done:
|
||||||
|
p.msg.Verbose("setup payload took", time.Since(t))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}(p.setup[1])
|
}(p.setup[1])
|
||||||
@@ -512,7 +491,7 @@ func (p *Container) Serve() (err error) {
|
|||||||
Getuid(),
|
Getuid(),
|
||||||
Getgid(),
|
Getgid(),
|
||||||
len(p.ExtraFiles),
|
len(p.ExtraFiles),
|
||||||
p.msg.IsVerbose() && !p.Quiet,
|
p.msg.IsVerbose(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/command"
|
"hakurei.app/command"
|
||||||
@@ -235,9 +233,6 @@ func earlyMnt(mnt ...*vfs.MountInfoEntry) func(*testing.T, context.Context) []*v
|
|||||||
return func(*testing.T, context.Context) []*vfs.MountInfoEntry { return mnt }
|
return func(*testing.T, context.Context) []*vfs.MountInfoEntry { return mnt }
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname toHost hakurei.app/container.toHost
|
|
||||||
func toHost(name string) string
|
|
||||||
|
|
||||||
var containerTestCases = []struct {
|
var containerTestCases = []struct {
|
||||||
name string
|
name string
|
||||||
filter bool
|
filter bool
|
||||||
@@ -337,15 +332,13 @@ var containerTestCases = []struct {
|
|||||||
func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry {
|
func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry {
|
||||||
return []*vfs.MountInfoEntry{
|
return []*vfs.MountInfoEntry{
|
||||||
ent("/", hst.PrivateTmp, "rw", "overlay", "overlay",
|
ent("/", hst.PrivateTmp, "rw", "overlay", "overlay",
|
||||||
"rw"+
|
"rw,lowerdir="+
|
||||||
",lowerdir+="+
|
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+
|
||||||
toHost(ctx.Value(testVal("lower0")).(*check.Absolute).String())+
|
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
||||||
",lowerdir+="+
|
|
||||||
toHost(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
|
||||||
",upperdir="+
|
",upperdir="+
|
||||||
toHost(ctx.Value(testVal("upper")).(*check.Absolute).String())+
|
container.InternalToHostOvlEscape(ctx.Value(testVal("upper")).(*check.Absolute).String())+
|
||||||
",workdir="+
|
",workdir="+
|
||||||
toHost(ctx.Value(testVal("work")).(*check.Absolute).String())+
|
container.InternalToHostOvlEscape(ctx.Value(testVal("work")).(*check.Absolute).String())+
|
||||||
",redirect_dir=nofollow,uuid=on,userxattr"),
|
",redirect_dir=nofollow,uuid=on,userxattr"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -395,11 +388,9 @@ var containerTestCases = []struct {
|
|||||||
func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry {
|
func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry {
|
||||||
return []*vfs.MountInfoEntry{
|
return []*vfs.MountInfoEntry{
|
||||||
ent("/", hst.PrivateTmp, "rw", "overlay", "overlay",
|
ent("/", hst.PrivateTmp, "rw", "overlay", "overlay",
|
||||||
"ro"+
|
"ro,lowerdir="+
|
||||||
",lowerdir+="+
|
container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+
|
||||||
toHost(ctx.Value(testVal("lower0")).(*check.Absolute).String())+
|
container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
||||||
",lowerdir+="+
|
|
||||||
toHost(ctx.Value(testVal("lower1")).(*check.Absolute).String())+
|
|
||||||
",redirect_dir=nofollow,userxattr"),
|
",redirect_dir=nofollow,userxattr"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -409,11 +400,39 @@ var containerTestCases = []struct {
|
|||||||
func TestContainer(t *testing.T) {
|
func TestContainer(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var suffix string
|
t.Run("cancel", testContainerCancel(nil, func(t *testing.T, c *container.Container) {
|
||||||
runTests:
|
wantErr := context.Canceled
|
||||||
|
wantExitCode := 0
|
||||||
|
if err := c.Wait(); !reflect.DeepEqual(err, wantErr) {
|
||||||
|
if m, ok := container.InternalMessageFromError(err); ok {
|
||||||
|
t.Error(m)
|
||||||
|
}
|
||||||
|
t.Errorf("Wait: error = %#v, want %#v", err, wantErr)
|
||||||
|
}
|
||||||
|
if ps := c.ProcessState(); ps == nil {
|
||||||
|
t.Errorf("ProcessState unexpectedly returned nil")
|
||||||
|
} else if code := ps.ExitCode(); code != wantExitCode {
|
||||||
|
t.Errorf("ExitCode: %d, want %d", code, wantExitCode)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
t.Run("forward", testContainerCancel(func(c *container.Container) {
|
||||||
|
c.ForwardCancel = true
|
||||||
|
}, func(t *testing.T, c *container.Container) {
|
||||||
|
var exitError *exec.ExitError
|
||||||
|
if err := c.Wait(); !errors.As(err, &exitError) {
|
||||||
|
if m, ok := container.InternalMessageFromError(err); ok {
|
||||||
|
t.Error(m)
|
||||||
|
}
|
||||||
|
t.Errorf("Wait: error = %v", err)
|
||||||
|
}
|
||||||
|
if code := exitError.ExitCode(); code != blockExitCodeInterrupt {
|
||||||
|
t.Errorf("ExitCode: %d, want %d", code, blockExitCodeInterrupt)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
for i, tc := range containerTestCases {
|
for i, tc := range containerTestCases {
|
||||||
_suffix := suffix
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Run(tc.name+_suffix, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
wantOps, wantOpsCtx := tc.ops(t)
|
wantOps, wantOpsCtx := tc.ops(t)
|
||||||
@@ -437,8 +456,6 @@ runTests:
|
|||||||
c.SeccompDisable = !tc.filter
|
c.SeccompDisable = !tc.filter
|
||||||
c.RetainSession = tc.session
|
c.RetainSession = tc.session
|
||||||
c.HostNet = tc.net
|
c.HostNet = tc.net
|
||||||
c.InitAsRoot = _suffix != ""
|
|
||||||
c.Env = append(c.Env, "HAKUREI_TEST_SUFFIX="+_suffix)
|
|
||||||
if info.CanDegrade {
|
if info.CanDegrade {
|
||||||
if _, err := landlock.GetABI(); err != nil {
|
if _, err := landlock.GetABI(); err != nil {
|
||||||
if !errors.Is(err, syscall.ENOSYS) {
|
if !errors.Is(err, syscall.ENOSYS) {
|
||||||
@@ -448,9 +465,6 @@ runTests:
|
|||||||
t.Log("Landlock LSM is unavailable, enabling HostAbstract")
|
t.Log("Landlock LSM is unavailable, enabling HostAbstract")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c.InitAsRoot {
|
|
||||||
c.SeccompPresets &= ^std.PresetDenyNS
|
|
||||||
}
|
|
||||||
|
|
||||||
c.
|
c.
|
||||||
Readonly(check.MustAbs(pathReadonly), 0755).
|
Readonly(check.MustAbs(pathReadonly), 0755).
|
||||||
@@ -519,11 +533,6 @@ runTests:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if suffix == "" {
|
|
||||||
suffix = " as root"
|
|
||||||
goto runTests
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ent(root, target, vfsOptstr, fsType, source, fsOptstr string) *vfs.MountInfoEntry {
|
func ent(root, target, vfsOptstr, fsType, source, fsOptstr string) *vfs.MountInfoEntry {
|
||||||
@@ -546,10 +555,11 @@ func hostnameFromTestCase(name string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testContainerCancel(
|
func testContainerCancel(
|
||||||
t *testing.T,
|
|
||||||
containerExtra func(c *container.Container),
|
containerExtra func(c *container.Container),
|
||||||
waitCheck func(ps *os.ProcessState, waitErr error),
|
waitCheck func(t *testing.T, c *container.Container),
|
||||||
) {
|
) func(t *testing.T) {
|
||||||
|
return func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
ctx, cancel := context.WithCancel(t.Context())
|
ctx, cancel := context.WithCancel(t.Context())
|
||||||
|
|
||||||
c := helperNewContainer(ctx, "block")
|
c := helperNewContainer(ctx, "block")
|
||||||
@@ -559,36 +569,25 @@ func testContainerCancel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ready := make(chan struct{})
|
ready := make(chan struct{})
|
||||||
var waitErr error
|
if r, w, err := os.Pipe(); err != nil {
|
||||||
r, w, err := os.Pipe()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("cannot pipe: %v", err)
|
t.Fatalf("cannot pipe: %v", err)
|
||||||
}
|
} else {
|
||||||
|
|
||||||
c.ExtraFiles = append(c.ExtraFiles, w)
|
c.ExtraFiles = append(c.ExtraFiles, w)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ready)
|
defer close(ready)
|
||||||
if _, _err := r.Read(make([]byte, 1)); _err != nil {
|
if _, err = r.Read(make([]byte, 1)); err != nil {
|
||||||
panic(_err)
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if err = c.Start(); err != nil {
|
if err := c.Start(); err != nil {
|
||||||
if m, ok := container.InternalMessageFromError(err); ok {
|
if m, ok := container.InternalMessageFromError(err); ok {
|
||||||
t.Fatal(m)
|
t.Fatal(m)
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("cannot start container: %v", err)
|
t.Fatalf("cannot start container: %v", err)
|
||||||
}
|
}
|
||||||
}
|
} else if err = c.Serve(); err != nil {
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
waitErr = c.Wait()
|
|
||||||
_ = r.SetReadDeadline(time.Now())
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err = c.Serve(); err != nil {
|
|
||||||
if m, ok := container.InternalMessageFromError(err); ok {
|
if m, ok := container.InternalMessageFromError(err); ok {
|
||||||
t.Error(m)
|
t.Error(m)
|
||||||
} else {
|
} else {
|
||||||
@@ -597,67 +596,8 @@ func testContainerCancel(
|
|||||||
}
|
}
|
||||||
<-ready
|
<-ready
|
||||||
cancel()
|
cancel()
|
||||||
<-done
|
waitCheck(t, c)
|
||||||
waitCheck(c.ProcessState(), waitErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForward(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
f := func(ps *os.ProcessState, waitErr error) {
|
|
||||||
var exitError *exec.ExitError
|
|
||||||
if !errors.As(waitErr, &exitError) {
|
|
||||||
if m, ok := container.InternalMessageFromError(waitErr); ok {
|
|
||||||
t.Error(m)
|
|
||||||
}
|
}
|
||||||
t.Errorf("Wait: error = %v", waitErr)
|
|
||||||
}
|
|
||||||
if code := exitError.ExitCode(); code != blockExitCodeInterrupt {
|
|
||||||
t.Errorf("ExitCode: %d, want %d", code, blockExitCodeInterrupt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Run("direct", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
testContainerCancel(t, func(c *container.Container) {
|
|
||||||
c.ForwardCancel = true
|
|
||||||
}, f)
|
|
||||||
})
|
|
||||||
t.Run("as root", func(t *testing.T) {
|
|
||||||
testContainerCancel(t, func(c *container.Container) {
|
|
||||||
c.ForwardCancel = true
|
|
||||||
c.InitAsRoot = true
|
|
||||||
c.Proc(fhs.AbsProc)
|
|
||||||
}, f)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCancel(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
f := func(ps *os.ProcessState, waitErr error) {
|
|
||||||
wantErr := context.Canceled
|
|
||||||
if !reflect.DeepEqual(waitErr, wantErr) {
|
|
||||||
if m, ok := container.InternalMessageFromError(waitErr); ok {
|
|
||||||
t.Error(m)
|
|
||||||
}
|
|
||||||
t.Errorf("Wait: error = %#v, want %#v", waitErr, wantErr)
|
|
||||||
}
|
|
||||||
if ps == nil {
|
|
||||||
t.Errorf("ProcessState unexpectedly returned nil")
|
|
||||||
} else if code := ps.ExitCode(); code != 0 {
|
|
||||||
t.Errorf("ExitCode: %d, want %d", code, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Run("direct", func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
testContainerCancel(t, nil, f)
|
|
||||||
})
|
|
||||||
t.Run("as root", func(t *testing.T) {
|
|
||||||
testContainerCancel(t, func(c *container.Container) {
|
|
||||||
c.InitAsRoot = true
|
|
||||||
c.Proc(fhs.AbsProc)
|
|
||||||
}, f)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContainerString(t *testing.T) {
|
func TestContainerString(t *testing.T) {
|
||||||
@@ -693,8 +633,6 @@ func init() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
c.Command("container", command.UsageInternal, func(args []string) error {
|
c.Command("container", command.UsageInternal, func(args []string) error {
|
||||||
asRoot := os.Getenv("HAKUREI_TEST_SUFFIX") == " as root"
|
|
||||||
|
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return syscall.EINVAL
|
return syscall.EINVAL
|
||||||
}
|
}
|
||||||
@@ -712,66 +650,6 @@ func init() {
|
|||||||
return fmt.Errorf("gid: %d, want %d", gid, tc.gid)
|
return fmt.Errorf("gid: %d, want %d", gid, tc.gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// no attack surface increase during as root due to no_new_privs
|
|
||||||
var wantBounding uintptr = 1
|
|
||||||
asRootNot := " not"
|
|
||||||
if !asRoot {
|
|
||||||
wantBounding = 0
|
|
||||||
asRootNot = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
PR_CAP_AMBIENT = 0x2f
|
|
||||||
PR_CAP_AMBIENT_IS_SET = 0x1
|
|
||||||
)
|
|
||||||
for i := range container.LastCap(nil) + 1 {
|
|
||||||
r, _, errno := syscall.Syscall(
|
|
||||||
syscall.SYS_PRCTL,
|
|
||||||
PR_CAP_AMBIENT,
|
|
||||||
PR_CAP_AMBIENT_IS_SET,
|
|
||||||
i,
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
return os.NewSyscallError("prctl", errno)
|
|
||||||
}
|
|
||||||
if r != 0 {
|
|
||||||
return fmt.Errorf("capability %d in ambient set", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, _, errno = syscall.Syscall(
|
|
||||||
syscall.SYS_PRCTL,
|
|
||||||
syscall.PR_CAPBSET_READ,
|
|
||||||
i,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
return os.NewSyscallError("prctl", errno)
|
|
||||||
}
|
|
||||||
if r != wantBounding {
|
|
||||||
return fmt.Errorf("capability %d%s in bounding set", i, asRootNot)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _LINUX_CAPABILITY_VERSION_3 = 0x20080522
|
|
||||||
var capData struct {
|
|
||||||
effective uint32
|
|
||||||
permitted uint32
|
|
||||||
inheritable uint32
|
|
||||||
}
|
|
||||||
if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&struct {
|
|
||||||
version uint32
|
|
||||||
pid int32
|
|
||||||
}{_LINUX_CAPABILITY_VERSION_3, 0})), uintptr(unsafe.Pointer(&capData)), 0); errno != 0 {
|
|
||||||
return os.NewSyscallError("capget", errno)
|
|
||||||
}
|
|
||||||
|
|
||||||
if max(capData.effective, capData.permitted, capData.inheritable) != 0 {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"effective = %d, permitted = %d, inheritable = %d",
|
|
||||||
capData.effective, capData.permitted, capData.inheritable,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
wantHost := hostnameFromTestCase(tc.name)
|
wantHost := hostnameFromTestCase(tc.name)
|
||||||
if host, err := os.Hostname(); err != nil {
|
if host, err := os.Hostname(); err != nil {
|
||||||
return fmt.Errorf("cannot get hostname: %v", err)
|
return fmt.Errorf("cannot get hostname: %v", err)
|
||||||
@@ -889,7 +767,7 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
c.MustParse(os.Args[1:], func(err error) {
|
c.MustParse(os.Args[1:], func(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ type syscallDispatcher interface {
|
|||||||
remount(msg message.Msg, target string, flags uintptr) error
|
remount(msg message.Msg, target string, flags uintptr) error
|
||||||
// mountTmpfs provides mountTmpfs.
|
// mountTmpfs provides mountTmpfs.
|
||||||
mountTmpfs(fsname, target string, flags uintptr, size int, perm os.FileMode) error
|
mountTmpfs(fsname, target string, flags uintptr, size int, perm os.FileMode) error
|
||||||
// mountOverlay provides mountOverlay.
|
|
||||||
mountOverlay(target string, options [][2]string) error
|
|
||||||
// ensureFile provides ensureFile.
|
// ensureFile provides ensureFile.
|
||||||
ensureFile(name string, perm, pperm os.FileMode) error
|
ensureFile(name string, perm, pperm os.FileMode) error
|
||||||
// mustLoopback provides mustLoopback.
|
// mustLoopback provides mustLoopback.
|
||||||
@@ -171,9 +169,6 @@ func (direct) remount(msg message.Msg, target string, flags uintptr) error {
|
|||||||
func (k direct) mountTmpfs(fsname, target string, flags uintptr, size int, perm os.FileMode) error {
|
func (k direct) mountTmpfs(fsname, target string, flags uintptr, size int, perm os.FileMode) error {
|
||||||
return mountTmpfs(k, fsname, target, flags, size, perm)
|
return mountTmpfs(k, fsname, target, flags, size, perm)
|
||||||
}
|
}
|
||||||
func (k direct) mountOverlay(target string, options [][2]string) error {
|
|
||||||
return mountOverlay(target, options)
|
|
||||||
}
|
|
||||||
func (direct) ensureFile(name string, perm, pperm os.FileMode) error {
|
func (direct) ensureFile(name string, perm, pperm os.FileMode) error {
|
||||||
return ensureFile(name, perm, pperm)
|
return ensureFile(name, perm, pperm)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -468,14 +468,6 @@ func (k *kstub) mountTmpfs(fsname, target string, flags uintptr, size int, perm
|
|||||||
stub.CheckArg(k.Stub, "perm", perm, 4))
|
stub.CheckArg(k.Stub, "perm", perm, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *kstub) mountOverlay(target string, options [][2]string) error {
|
|
||||||
k.Helper()
|
|
||||||
return k.Expects("mountOverlay").Error(
|
|
||||||
stub.CheckArg(k.Stub, "target", target, 0),
|
|
||||||
stub.CheckArgReflect(k.Stub, "options", options, 1),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *kstub) ensureFile(name string, perm, pperm os.FileMode) error {
|
func (k *kstub) ensureFile(name string, perm, pperm os.FileMode) error {
|
||||||
k.Helper()
|
k.Helper()
|
||||||
return k.Expects("ensureFile").Error(
|
return k.Expects("ensureFile").Error(
|
||||||
|
|||||||
@@ -118,10 +118,6 @@ func errnoFallback(op, path string, err error) (syscall.Errno, *os.PathError) {
|
|||||||
|
|
||||||
// mount wraps syscall.Mount for error handling.
|
// mount wraps syscall.Mount for error handling.
|
||||||
func mount(source, target, fstype string, flags uintptr, data string) error {
|
func mount(source, target, fstype string, flags uintptr, data string) error {
|
||||||
if max(len(source), len(target), len(data))+1 > os.Getpagesize() {
|
|
||||||
return &MountError{source, target, fstype, flags, data, syscall.ENOMEM}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := syscall.Mount(source, target, fstype, flags, data)
|
err := syscall.Mount(source, target, fstype, flags, data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -11,13 +11,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
. "syscall"
|
. "syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/check"
|
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/ext"
|
"hakurei.app/ext"
|
||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
@@ -184,33 +182,23 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, gid := param.Uid, param.Gid
|
|
||||||
if param.InitAsRoot {
|
|
||||||
uid, gid = 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// write uid/gid map here so parent does not need to set dumpable
|
// write uid/gid map here so parent does not need to set dumpable
|
||||||
if err := k.setDumpable(ext.SUID_DUMP_USER); err != nil {
|
if err := k.setDumpable(ext.SUID_DUMP_USER); err != nil {
|
||||||
k.fatalf(msg, "cannot set SUID_DUMP_USER: %v", err)
|
k.fatalf(msg, "cannot set SUID_DUMP_USER: %v", err)
|
||||||
}
|
}
|
||||||
if err := k.writeFile(
|
if err := k.writeFile(fhs.Proc+"self/uid_map",
|
||||||
fhs.Proc+"self/uid_map",
|
append([]byte{}, strconv.Itoa(param.Uid)+" "+strconv.Itoa(param.HostUid)+" 1\n"...),
|
||||||
[]byte(strconv.Itoa(uid)+" "+strconv.Itoa(param.HostUid)+" 1\n"),
|
0); err != nil {
|
||||||
0,
|
|
||||||
); err != nil {
|
|
||||||
k.fatalf(msg, "%v", err)
|
k.fatalf(msg, "%v", err)
|
||||||
}
|
}
|
||||||
if err := k.writeFile(
|
if err := k.writeFile(fhs.Proc+"self/setgroups",
|
||||||
fhs.Proc+"self/setgroups",
|
|
||||||
[]byte("deny\n"),
|
[]byte("deny\n"),
|
||||||
0,
|
0); err != nil && !os.IsNotExist(err) {
|
||||||
); err != nil && !os.IsNotExist(err) {
|
|
||||||
k.fatalf(msg, "%v", err)
|
k.fatalf(msg, "%v", err)
|
||||||
}
|
}
|
||||||
if err := k.writeFile(fhs.Proc+"self/gid_map",
|
if err := k.writeFile(fhs.Proc+"self/gid_map",
|
||||||
[]byte(strconv.Itoa(gid)+" "+strconv.Itoa(param.HostGid)+" 1\n"),
|
append([]byte{}, strconv.Itoa(param.Gid)+" "+strconv.Itoa(param.HostGid)+" 1\n"...),
|
||||||
0,
|
0); err != nil {
|
||||||
); err != nil {
|
|
||||||
k.fatalf(msg, "%v", err)
|
k.fatalf(msg, "%v", err)
|
||||||
}
|
}
|
||||||
if err := k.setDumpable(ext.SUID_DUMP_DISABLE); err != nil {
|
if err := k.setDumpable(ext.SUID_DUMP_DISABLE); err != nil {
|
||||||
@@ -235,23 +223,6 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
state := &setupState{process: make(map[int]WaitStatus), Params: ¶m.Params, Msg: msg, Context: ctx}
|
state := &setupState{process: make(map[int]WaitStatus), Params: ¶m.Params, Msg: msg, Context: ctx}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if err := k.mount(SourceTmpfsRootfs, intermediateHostPath, FstypeTmpfs, MS_NODEV|MS_NOSUID, zeroString); err != nil {
|
|
||||||
k.fatalf(msg, "cannot mount intermediate root: %v", optionalErrorUnwrap(err))
|
|
||||||
}
|
|
||||||
if err := k.chdir(intermediateHostPath); err != nil {
|
|
||||||
k.fatalf(msg, "cannot enter intermediate host path: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(param.Binfmt) > 0 {
|
|
||||||
for i, e := range param.Binfmt {
|
|
||||||
if pathname, err := k.evalSymlinks(e.Interpreter.String()); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
} else if param.Binfmt[i].Interpreter, err = check.NewAbs(pathname); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* early is called right before pivot_root into intermediate root;
|
/* early is called right before pivot_root into intermediate root;
|
||||||
this step is mostly for gathering information that would otherwise be
|
this step is mostly for gathering information that would otherwise be
|
||||||
difficult to obtain via library functions after pivot_root, and
|
difficult to obtain via library functions after pivot_root, and
|
||||||
@@ -271,6 +242,13 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := k.mount(SourceTmpfsRootfs, intermediateHostPath, FstypeTmpfs, MS_NODEV|MS_NOSUID, zeroString); err != nil {
|
||||||
|
k.fatalf(msg, "cannot mount intermediate root: %v", optionalErrorUnwrap(err))
|
||||||
|
}
|
||||||
|
if err := k.chdir(intermediateHostPath); err != nil {
|
||||||
|
k.fatalf(msg, "cannot enter intermediate host path: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := k.mkdir(sysrootDir, 0755); err != nil {
|
if err := k.mkdir(sysrootDir, 0755); err != nil {
|
||||||
k.fatalf(msg, "%v", err)
|
k.fatalf(msg, "%v", err)
|
||||||
}
|
}
|
||||||
@@ -307,48 +285,6 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(param.Binfmt) > 0 {
|
|
||||||
const interpreter = "/interpreter"
|
|
||||||
|
|
||||||
if param.BinfmtPath == nil {
|
|
||||||
param.BinfmtPath = fhs.AbsProcSys.Append("fs/binfmt_misc")
|
|
||||||
}
|
|
||||||
binfmt := sysrootPath + param.BinfmtPath.String()
|
|
||||||
if err := k.mkdirAll(binfmt, 0); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
}
|
|
||||||
if err := k.mount(
|
|
||||||
SourceBinfmtMisc,
|
|
||||||
binfmt,
|
|
||||||
FstypeBinfmtMisc,
|
|
||||||
MS_NOSUID|MS_NOEXEC|MS_NODEV,
|
|
||||||
zeroString,
|
|
||||||
); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf strings.Builder
|
|
||||||
buf.Grow(1920)
|
|
||||||
|
|
||||||
register := binfmt + "/register"
|
|
||||||
for i, e := range param.Binfmt {
|
|
||||||
if err := k.symlink(hostPath+e.Interpreter.String(), interpreter); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
} else if err = k.writeFile(register, []byte(":"+
|
|
||||||
strconv.Itoa(i)+":"+
|
|
||||||
"M:"+
|
|
||||||
strconv.Itoa(int(e.Offset))+":"+
|
|
||||||
escapeBinfmt(&buf, e.Magic)+":"+
|
|
||||||
escapeBinfmt(&buf, e.Mask)+":"+
|
|
||||||
interpreter+":"+
|
|
||||||
"F"), 0); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
} else if err = k.remove(interpreter); err != nil {
|
|
||||||
k.fatal(msg, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup requiring host root complete at this point
|
// setup requiring host root complete at this point
|
||||||
if err := k.mount(hostDir, hostDir, zeroString, MS_SILENT|MS_REC|MS_PRIVATE, zeroString); err != nil {
|
if err := k.mount(hostDir, hostDir, zeroString, MS_SILENT|MS_REC|MS_PRIVATE, zeroString); err != nil {
|
||||||
k.fatalf(msg, "cannot make host root rprivate: %v", optionalErrorUnwrap(err))
|
k.fatalf(msg, "cannot make host root rprivate: %v", optionalErrorUnwrap(err))
|
||||||
@@ -387,19 +323,11 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var keepCaps []uintptr
|
|
||||||
if param.Privileged {
|
|
||||||
keepCaps = append(keepCaps, CAP_SYS_ADMIN, CAP_SETPCAP)
|
|
||||||
}
|
|
||||||
if param.InitAsRoot {
|
|
||||||
keepCaps = append(keepCaps, CAP_SETFCAP)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := k.capAmbientClearAll(); err != nil {
|
if err := k.capAmbientClearAll(); err != nil {
|
||||||
k.fatalf(msg, "cannot clear the ambient capability set: %v", err)
|
k.fatalf(msg, "cannot clear the ambient capability set: %v", err)
|
||||||
}
|
}
|
||||||
for i := range lastcap + 1 {
|
for i := uintptr(0); i <= lastcap; i++ {
|
||||||
if slices.Contains(keepCaps, i) {
|
if param.Privileged && i == CAP_SYS_ADMIN {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := k.capBoundingSetDrop(i); err != nil {
|
if err := k.capBoundingSetDrop(i); err != nil {
|
||||||
@@ -408,23 +336,20 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var keep [2]uint32
|
var keep [2]uint32
|
||||||
for _, c := range keepCaps {
|
if param.Privileged {
|
||||||
keep[capToIndex(c)] |= capToMask(c)
|
keep[capToIndex(CAP_SYS_ADMIN)] |= capToMask(CAP_SYS_ADMIN)
|
||||||
}
|
|
||||||
|
|
||||||
|
if err := k.capAmbientRaise(CAP_SYS_ADMIN); err != nil {
|
||||||
|
k.fatalf(msg, "cannot raise CAP_SYS_ADMIN: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := k.capset(
|
if err := k.capset(
|
||||||
&capHeader{_LINUX_CAPABILITY_VERSION_3, 0},
|
&capHeader{_LINUX_CAPABILITY_VERSION_3, 0},
|
||||||
&[2]capData{{keep[0], keep[0], keep[0]}, {keep[1], keep[1], keep[1]}},
|
&[2]capData{{0, keep[0], keep[0]}, {0, keep[1], keep[1]}},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
k.fatalf(msg, "cannot capset: %v", err)
|
k.fatalf(msg, "cannot capset: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range keepCaps {
|
|
||||||
if err := k.capAmbientRaise(c); err != nil {
|
|
||||||
k.fatalf(msg, "cannot raise %#x: %v", c, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !param.SeccompDisable {
|
if !param.SeccompDisable {
|
||||||
rules := param.SeccompRules
|
rules := param.SeccompRules
|
||||||
if len(rules) == 0 { // non-empty rules slice always overrides presets
|
if len(rules) == 0 { // non-empty rules slice always overrides presets
|
||||||
@@ -549,14 +474,6 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
|
|||||||
cmd.ExtraFiles = extraFiles
|
cmd.ExtraFiles = extraFiles
|
||||||
cmd.Dir = param.Dir.String()
|
cmd.Dir = param.Dir.String()
|
||||||
|
|
||||||
if param.InitAsRoot {
|
|
||||||
cmd.SysProcAttr = &SysProcAttr{
|
|
||||||
Cloneflags: CLONE_NEWUSER,
|
|
||||||
UidMappings: []SysProcIDMap{{ContainerID: param.Uid, HostID: 0, Size: 1}},
|
|
||||||
GidMappings: []SysProcIDMap{{ContainerID: param.Gid, HostID: 0, Size: 1}},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.Verbosef("starting initial process %s", param.Path)
|
msg.Verbosef("starting initial process %s", param.Path)
|
||||||
if err := k.start(cmd); err != nil {
|
if err := k.start(cmd); err != nil {
|
||||||
k.fatalf(msg, "%v", err)
|
k.fatalf(msg, "%v", err)
|
||||||
|
|||||||
@@ -332,8 +332,6 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("fatalf", stub.ExpectArgs{"invalid op at index %d", []any{0}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"invalid op at index %d", []any{0}}, nil, nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
@@ -372,8 +370,6 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("fatalf", stub.ExpectArgs{"invalid op at index %d", []any{0}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"invalid op at index %d", []any{0}}, nil, nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
@@ -412,8 +408,6 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", stub.UniqueError(61)),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", stub.UniqueError(61)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot prepare op at index %d: %v", []any{0, stub.UniqueError(61)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot prepare op at index %d: %v", []any{0, stub.UniqueError(61)}}, nil, nil),
|
||||||
@@ -453,8 +447,6 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", &os.PathError{Op: "readlink", Path: "/", Err: stub.UniqueError(60)}),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", &os.PathError{Op: "readlink", Path: "/", Err: stub.UniqueError(60)}),
|
||||||
call("fatal", stub.ExpectArgs{[]any{"cannot readlink /: unique error 60 injected by the test suite"}}, nil, nil),
|
call("fatal", stub.ExpectArgs{[]any{"cannot readlink /: unique error 60 injected by the test suite"}}, nil, nil),
|
||||||
@@ -494,6 +486,9 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
|
/* begin early */
|
||||||
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
|
/* end early */
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, stub.UniqueError(58)),
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, stub.UniqueError(58)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot mount intermediate root: %v", []any{stub.UniqueError(58)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot mount intermediate root: %v", []any{stub.UniqueError(58)}}, nil, nil),
|
||||||
},
|
},
|
||||||
@@ -531,6 +526,9 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
|
/* begin early */
|
||||||
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
|
/* end early */
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, stub.UniqueError(56)),
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, stub.UniqueError(56)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot enter intermediate host path: %v", []any{stub.UniqueError(56)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot enter intermediate host path: %v", []any{stub.UniqueError(56)}}, nil, nil),
|
||||||
@@ -569,11 +567,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, stub.UniqueError(54)),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, stub.UniqueError(54)),
|
||||||
call("fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(54)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(54)}}, nil, nil),
|
||||||
},
|
},
|
||||||
@@ -611,11 +609,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, stub.UniqueError(52)),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, stub.UniqueError(52)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot bind sysroot: %v", []any{stub.UniqueError(52)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot bind sysroot: %v", []any{stub.UniqueError(52)}}, nil, nil),
|
||||||
@@ -654,11 +652,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, stub.UniqueError(50)),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, stub.UniqueError(50)),
|
||||||
@@ -698,11 +696,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -743,11 +741,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -789,11 +787,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -844,11 +842,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -899,11 +897,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -955,11 +953,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1012,11 +1010,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1071,11 +1069,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1131,11 +1129,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1192,11 +1190,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1254,11 +1252,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1317,11 +1315,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1381,11 +1379,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1446,11 +1444,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1512,11 +1510,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1586,11 +1584,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1624,6 +1622,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
||||||
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
||||||
@@ -1655,9 +1654,8 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
||||||
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0x200100, 0x200100, 0x200100}, {0, 0, 0}}}, nil, nil),
|
|
||||||
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, stub.UniqueError(19)),
|
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, stub.UniqueError(19)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot raise %#x: %v", []any{uintptr(0x15), stub.UniqueError(19)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot raise CAP_SYS_ADMIN: %v", []any{stub.UniqueError(19)}}, nil, nil),
|
||||||
},
|
},
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|
||||||
@@ -1693,11 +1691,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1731,6 +1729,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
||||||
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
||||||
@@ -1762,7 +1761,8 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
||||||
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0x200100, 0x200100, 0x200100}, {0, 0, 0}}}, nil, stub.UniqueError(17)),
|
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil),
|
||||||
|
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, stub.UniqueError(17)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot capset: %v", []any{stub.UniqueError(17)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot capset: %v", []any{stub.UniqueError(17)}}, nil, nil),
|
||||||
},
|
},
|
||||||
}, nil},
|
}, nil},
|
||||||
@@ -1799,11 +1799,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -1837,6 +1837,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
||||||
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
||||||
@@ -1868,9 +1869,8 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
||||||
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0x200100, 0x200100, 0x200100}, {0, 0, 0}}}, nil, nil),
|
|
||||||
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil),
|
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil),
|
||||||
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x8)}, nil, nil),
|
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"resolving presets %#x", []any{std.FilterPreset(0xf)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"resolving presets %#x", []any{std.FilterPreset(0xf)}}, nil, nil),
|
||||||
call("seccompLoad", stub.ExpectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, stub.UniqueError(15)),
|
call("seccompLoad", stub.ExpectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, stub.UniqueError(15)),
|
||||||
call("fatalf", stub.ExpectArgs{"cannot load syscall filter: %v", []any{stub.UniqueError(15)}}, nil, nil),
|
call("fatalf", stub.ExpectArgs{"cannot load syscall filter: %v", []any{stub.UniqueError(15)}}, nil, nil),
|
||||||
@@ -1908,11 +1908,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2032,11 +2032,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2132,11 +2132,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2232,11 +2232,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2323,11 +2323,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2418,11 +2418,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(4), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2520,11 +2520,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2659,11 +2659,11 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
call("sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil),
|
||||||
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
call("lastcap", stub.ExpectArgs{}, uintptr(40), nil),
|
||||||
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
|
||||||
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
|
||||||
/* begin early */
|
/* begin early */
|
||||||
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/"}, "/", nil),
|
||||||
/* end early */
|
/* end early */
|
||||||
|
call("mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil),
|
||||||
|
call("chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil),
|
||||||
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
call("mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil),
|
||||||
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
call("mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil),
|
||||||
@@ -2697,6 +2697,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil),
|
||||||
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil),
|
||||||
@@ -2728,9 +2729,8 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil),
|
||||||
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
call("capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil),
|
||||||
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0x200100, 0x200100, 0x200100}, {0, 0, 0}}}, nil, nil),
|
|
||||||
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil),
|
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil),
|
||||||
call("capAmbientRaise", stub.ExpectArgs{uintptr(0x8)}, nil, nil),
|
call("capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"resolving presets %#x", []any{std.FilterPreset(0xf)}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"resolving presets %#x", []any{std.FilterPreset(0xf)}}, nil, nil),
|
||||||
call("seccompLoad", stub.ExpectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, nil),
|
call("seccompLoad", stub.ExpectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, nil),
|
||||||
call("verbosef", stub.ExpectArgs{"%d filter rules loaded", []any{73}}, nil, nil),
|
call("verbosef", stub.ExpectArgs{"%d filter rules loaded", []any{73}}, nil, nil),
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/ext"
|
|
||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ func (o *MountOverlayOp) early(_ *setupState, k syscallDispatcher) error {
|
|||||||
if v, err := k.evalSymlinks(o.Upper.String()); err != nil {
|
if v, err := k.evalSymlinks(o.Upper.String()); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
o.upper = toHost(v)
|
o.upper = check.EscapeOverlayDataSegment(toHost(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ func (o *MountOverlayOp) early(_ *setupState, k syscallDispatcher) error {
|
|||||||
if v, err := k.evalSymlinks(o.Work.String()); err != nil {
|
if v, err := k.evalSymlinks(o.Work.String()); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
o.work = toHost(v)
|
o.work = check.EscapeOverlayDataSegment(toHost(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,39 +168,12 @@ func (o *MountOverlayOp) early(_ *setupState, k syscallDispatcher) error {
|
|||||||
if v, err := k.evalSymlinks(a.String()); err != nil {
|
if v, err := k.evalSymlinks(a.String()); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
o.lower[i] = toHost(v)
|
o.lower[i] = check.EscapeOverlayDataSegment(toHost(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// mountOverlay sets up an overlay mount via [ext.FS].
|
|
||||||
func mountOverlay(target string, options [][2]string) error {
|
|
||||||
fs, err := ext.OpenFS(SourceOverlay, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = fs.SetString("source", SourceOverlay); err != nil {
|
|
||||||
_ = fs.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, option := range options {
|
|
||||||
if err = fs.SetString(option[0], option[1]); err != nil {
|
|
||||||
_ = fs.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = fs.SetFlag(OptionOverlayUserxattr); err != nil {
|
|
||||||
_ = fs.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = fs.Mount(target, 0); err != nil {
|
|
||||||
_ = fs.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return fs.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *MountOverlayOp) apply(state *setupState, k syscallDispatcher) error {
|
func (o *MountOverlayOp) apply(state *setupState, k syscallDispatcher) error {
|
||||||
target := o.Target.String()
|
target := o.Target.String()
|
||||||
if !o.noPrefix {
|
if !o.noPrefix {
|
||||||
@@ -221,7 +194,7 @@ func (o *MountOverlayOp) apply(state *setupState, k syscallDispatcher) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
options := make([][2]string, 0, 2+len(o.lower))
|
options := make([]string, 0, 4)
|
||||||
|
|
||||||
if o.upper == zeroString && o.work == zeroString { // readonly
|
if o.upper == zeroString && o.work == zeroString { // readonly
|
||||||
if len(o.Lower) < 2 {
|
if len(o.Lower) < 2 {
|
||||||
@@ -232,16 +205,15 @@ func (o *MountOverlayOp) apply(state *setupState, k syscallDispatcher) error {
|
|||||||
if len(o.Lower) == 0 {
|
if len(o.Lower) == 0 {
|
||||||
return &OverlayArgumentError{OverlayEmptyLower, zeroString}
|
return &OverlayArgumentError{OverlayEmptyLower, zeroString}
|
||||||
}
|
}
|
||||||
options = append(options, [][2]string{
|
options = append(options,
|
||||||
{OptionOverlayUpperdir, o.upper},
|
OptionOverlayUpperdir+"="+o.upper,
|
||||||
{OptionOverlayWorkdir, o.work},
|
OptionOverlayWorkdir+"="+o.work)
|
||||||
}...)
|
|
||||||
}
|
|
||||||
for _, lower := range o.lower {
|
|
||||||
options = append(options, [2]string{OptionOverlayLowerdir + "+", lower})
|
|
||||||
}
|
}
|
||||||
|
options = append(options,
|
||||||
|
OptionOverlayLowerdir+"="+strings.Join(o.lower, check.SpecialOverlayPath),
|
||||||
|
OptionOverlayUserxattr)
|
||||||
|
|
||||||
return k.mountOverlay(target, options)
|
return k.mount(SourceOverlay, target, FstypeOverlay, 0, strings.Join(options, check.SpecialOverlayOption))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *MountOverlayOp) late(*setupState, syscallDispatcher) error { return nil }
|
func (o *MountOverlayOp) late(*setupState, syscallDispatcher) error { return nil }
|
||||||
|
|||||||
@@ -97,12 +97,13 @@ func TestMountOverlayOp(t *testing.T) {
|
|||||||
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0705)}, nil, nil),
|
call("mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0705)}, nil, nil),
|
||||||
call("mkdirTemp", stub.ExpectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil),
|
call("mkdirTemp", stub.ExpectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil),
|
||||||
call("mkdirTemp", stub.ExpectArgs{"/", "overlay.work.*"}, "overlay.work.32768", nil),
|
call("mkdirTemp", stub.ExpectArgs{"/", "overlay.work.*"}, "overlay.work.32768", nil),
|
||||||
call("mountOverlay", stub.ExpectArgs{"/sysroot", [][2]string{
|
call("mount", stub.ExpectArgs{"overlay", "/sysroot", "overlay", uintptr(0), "" +
|
||||||
{"upperdir", "overlay.upper.32768"},
|
"upperdir=overlay.upper.32768," +
|
||||||
{"workdir", "overlay.work.32768"},
|
"workdir=overlay.work.32768," +
|
||||||
{"lowerdir+", `/host/var/lib/planterette/base/debian:f92c9052`},
|
"lowerdir=" +
|
||||||
{"lowerdir+", `/host/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052`},
|
`/host/var/lib/planterette/base/debian\:f92c9052:` +
|
||||||
}}, nil, nil),
|
`/host/var/lib/planterette/app/org.chromium.Chromium@debian\:f92c9052,` +
|
||||||
|
"userxattr"}, nil, nil),
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|
||||||
{"short lower ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
{"short lower ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||||
@@ -128,10 +129,11 @@ func TestMountOverlayOp(t *testing.T) {
|
|||||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil),
|
||||||
}, nil, []stub.Call{
|
}, nil, []stub.Call{
|
||||||
call("mkdirAll", stub.ExpectArgs{"/nix/store", os.FileMode(0755)}, nil, nil),
|
call("mkdirAll", stub.ExpectArgs{"/nix/store", os.FileMode(0755)}, nil, nil),
|
||||||
call("mountOverlay", stub.ExpectArgs{"/nix/store", [][2]string{
|
call("mount", stub.ExpectArgs{"overlay", "/nix/store", "overlay", uintptr(0), "" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/.ro-store"},
|
"lowerdir=" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/.ro-store0"},
|
"/host/mnt-root/nix/.ro-store:" +
|
||||||
}}, nil, nil),
|
"/host/mnt-root/nix/.ro-store0," +
|
||||||
|
"userxattr"}, nil, nil),
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|
||||||
{"success ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
{"success ro", &Params{ParentPerm: 0755}, &MountOverlayOp{
|
||||||
@@ -145,10 +147,11 @@ func TestMountOverlayOp(t *testing.T) {
|
|||||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil),
|
||||||
}, nil, []stub.Call{
|
}, nil, []stub.Call{
|
||||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil),
|
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil),
|
||||||
call("mountOverlay", stub.ExpectArgs{"/sysroot/nix/store", [][2]string{
|
call("mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/.ro-store"},
|
"lowerdir=" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/.ro-store0"},
|
"/host/mnt-root/nix/.ro-store:" +
|
||||||
}}, nil, nil),
|
"/host/mnt-root/nix/.ro-store0," +
|
||||||
|
"userxattr"}, nil, nil),
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|
||||||
{"nil lower", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
{"nil lower", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||||
@@ -216,11 +219,7 @@ func TestMountOverlayOp(t *testing.T) {
|
|||||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil),
|
||||||
}, nil, []stub.Call{
|
}, nil, []stub.Call{
|
||||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil),
|
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil),
|
||||||
call("mountOverlay", stub.ExpectArgs{"/sysroot/nix/store", [][2]string{
|
call("mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "upperdir=/host/mnt-root/nix/.rw-store/.upper,workdir=/host/mnt-root/nix/.rw-store/.work,lowerdir=/host/mnt-root/nix/ro-store,userxattr"}, nil, stub.UniqueError(0)),
|
||||||
{"upperdir", "/host/mnt-root/nix/.rw-store/.upper"},
|
|
||||||
{"workdir", "/host/mnt-root/nix/.rw-store/.work"},
|
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store"},
|
|
||||||
}}, nil, stub.UniqueError(0)),
|
|
||||||
}, stub.UniqueError(0)},
|
}, stub.UniqueError(0)},
|
||||||
|
|
||||||
{"success single layer", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
{"success single layer", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||||
@@ -234,11 +233,11 @@ func TestMountOverlayOp(t *testing.T) {
|
|||||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil),
|
||||||
}, nil, []stub.Call{
|
}, nil, []stub.Call{
|
||||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil),
|
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil),
|
||||||
call("mountOverlay", stub.ExpectArgs{"/sysroot/nix/store", [][2]string{
|
call("mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" +
|
||||||
{"upperdir", "/host/mnt-root/nix/.rw-store/.upper"},
|
"upperdir=/host/mnt-root/nix/.rw-store/.upper," +
|
||||||
{"workdir", "/host/mnt-root/nix/.rw-store/.work"},
|
"workdir=/host/mnt-root/nix/.rw-store/.work," +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store"},
|
"lowerdir=/host/mnt-root/nix/ro-store," +
|
||||||
}}, nil, nil),
|
"userxattr"}, nil, nil),
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|
||||||
{"success", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
{"success", &Params{ParentPerm: 0700}, &MountOverlayOp{
|
||||||
@@ -262,15 +261,16 @@ func TestMountOverlayOp(t *testing.T) {
|
|||||||
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store3"}, "/mnt-root/nix/ro-store3", nil),
|
call("evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store3"}, "/mnt-root/nix/ro-store3", nil),
|
||||||
}, nil, []stub.Call{
|
}, nil, []stub.Call{
|
||||||
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil),
|
call("mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil),
|
||||||
call("mountOverlay", stub.ExpectArgs{"/sysroot/nix/store", [][2]string{
|
call("mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" +
|
||||||
{"upperdir", "/host/mnt-root/nix/.rw-store/.upper"},
|
"upperdir=/host/mnt-root/nix/.rw-store/.upper," +
|
||||||
{"workdir", "/host/mnt-root/nix/.rw-store/.work"},
|
"workdir=/host/mnt-root/nix/.rw-store/.work," +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store"},
|
"lowerdir=" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store0"},
|
"/host/mnt-root/nix/ro-store:" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store1"},
|
"/host/mnt-root/nix/ro-store0:" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store2"},
|
"/host/mnt-root/nix/ro-store1:" +
|
||||||
{"lowerdir+", "/host/mnt-root/nix/ro-store3"},
|
"/host/mnt-root/nix/ro-store2:" +
|
||||||
}}, nil, nil),
|
"/host/mnt-root/nix/ro-store3," +
|
||||||
|
"userxattr"}, nil, nil),
|
||||||
}, nil},
|
}, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ const (
|
|||||||
// SourceMqueue is used when mounting mqueue.
|
// SourceMqueue is used when mounting mqueue.
|
||||||
// Note that any source value is allowed when fstype is [FstypeMqueue].
|
// Note that any source value is allowed when fstype is [FstypeMqueue].
|
||||||
SourceMqueue = "mqueue"
|
SourceMqueue = "mqueue"
|
||||||
// SourceBinfmtMisc is used when mounting binfmt_misc.
|
|
||||||
// Note that any source value is allowed when fstype is [SourceBinfmtMisc].
|
|
||||||
SourceBinfmtMisc = "binfmt_misc"
|
|
||||||
// SourceOverlay is used when mounting overlay.
|
// SourceOverlay is used when mounting overlay.
|
||||||
// Note that any source value is allowed when fstype is [FstypeOverlay].
|
// Note that any source value is allowed when fstype is [FstypeOverlay].
|
||||||
SourceOverlay = "overlay"
|
SourceOverlay = "overlay"
|
||||||
@@ -73,9 +70,6 @@ const (
|
|||||||
// FstypeMqueue represents the mqueue pseudo-filesystem.
|
// FstypeMqueue represents the mqueue pseudo-filesystem.
|
||||||
// This filesystem type is usually mounted on /dev/mqueue.
|
// This filesystem type is usually mounted on /dev/mqueue.
|
||||||
FstypeMqueue = "mqueue"
|
FstypeMqueue = "mqueue"
|
||||||
// FstypeBinfmtMisc represents the binfmt_misc pseudo-filesystem.
|
|
||||||
// This filesystem type is usually mounted on /proc/sys/fs/binfmt_misc.
|
|
||||||
FstypeBinfmtMisc = "binfmt_misc"
|
|
||||||
// FstypeOverlay represents the overlay pseudo-filesystem.
|
// FstypeOverlay represents the overlay pseudo-filesystem.
|
||||||
// This filesystem type can be mounted anywhere in the container filesystem.
|
// This filesystem type can be mounted anywhere in the container filesystem.
|
||||||
FstypeOverlay = "overlay"
|
FstypeOverlay = "overlay"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"hakurei.app/check"
|
||||||
"hakurei.app/vfs"
|
"hakurei.app/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,6 +50,9 @@ func TestToHost(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalToHostOvlEscape exports toHost passed to [check.EscapeOverlayDataSegment].
|
||||||
|
func InternalToHostOvlEscape(s string) string { return check.EscapeOverlayDataSegment(toHost(s)) }
|
||||||
|
|
||||||
func TestCreateFile(t *testing.T) {
|
func TestCreateFile(t *testing.T) {
|
||||||
t.Run("nonexistent", func(t *testing.T) {
|
t.Run("nonexistent", func(t *testing.T) {
|
||||||
t.Run("mkdir", func(t *testing.T) {
|
t.Run("mkdir", func(t *testing.T) {
|
||||||
|
|||||||
267
ext/fs.go
267
ext/fs.go
@@ -1,267 +0,0 @@
|
|||||||
package ext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// include/uapi/linux/mount.h
|
|
||||||
|
|
||||||
/*
|
|
||||||
* move_mount() flags.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
MOVE_MOUNT_F_SYMLINKS = 1 << iota /* Follow symlinks on from path */
|
|
||||||
MOVE_MOUNT_F_AUTOMOUNTS /* Follow automounts on from path */
|
|
||||||
MOVE_MOUNT_F_EMPTY_PATH /* Empty from path permitted */
|
|
||||||
_
|
|
||||||
MOVE_MOUNT_T_SYMLINKS /* Follow symlinks on to path */
|
|
||||||
MOVE_MOUNT_T_AUTOMOUNTS /* Follow automounts on to path */
|
|
||||||
MOVE_MOUNT_T_EMPTY_PATH /* Empty to path permitted */
|
|
||||||
_
|
|
||||||
MOVE_MOUNT_SET_GROUP /* Set sharing group instead */
|
|
||||||
MOVE_MOUNT_BENEATH /* Mount beneath top mount */
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fsopen() flags.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
FSOPEN_CLOEXEC = 1 << iota
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fspick() flags.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
FSPICK_CLOEXEC = 1 << iota
|
|
||||||
FSPICK_SYMLINK_NOFOLLOW
|
|
||||||
FSPICK_NO_AUTOMOUNT
|
|
||||||
FSPICK_EMPTY_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The type of fsconfig() call made.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
FSCONFIG_SET_FLAG = iota /* Set parameter, supplying no value */
|
|
||||||
FSCONFIG_SET_STRING /* Set parameter, supplying a string value */
|
|
||||||
FSCONFIG_SET_BINARY /* Set parameter, supplying a binary blob value */
|
|
||||||
FSCONFIG_SET_PATH /* Set parameter, supplying an object by path */
|
|
||||||
FSCONFIG_SET_PATH_EMPTY /* Set parameter, supplying an object by (empty) path */
|
|
||||||
FSCONFIG_SET_FD /* Set parameter, supplying an object by fd */
|
|
||||||
FSCONFIG_CMD_CREATE /* Create new or reuse existing superblock */
|
|
||||||
FSCONFIG_CMD_RECONFIGURE /* Invoke superblock reconfiguration */
|
|
||||||
FSCONFIG_CMD_CREATE_EXCL /* Create new superblock, fail if reusing existing superblock */
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fsmount() flags.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
FSMOUNT_CLOEXEC = 1 << iota
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mount attributes.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
MOUNT_ATTR_RDONLY = 0x00000001 /* Mount read-only */
|
|
||||||
MOUNT_ATTR_NOSUID = 0x00000002 /* Ignore suid and sgid bits */
|
|
||||||
MOUNT_ATTR_NODEV = 0x00000004 /* Disallow access to device special files */
|
|
||||||
MOUNT_ATTR_NOEXEC = 0x00000008 /* Disallow program execution */
|
|
||||||
MOUNT_ATTR__ATIME = 0x00000070 /* Setting on how atime should be updated */
|
|
||||||
MOUNT_ATTR_RELATIME = 0x00000000 /* - Update atime relative to mtime/ctime. */
|
|
||||||
MOUNT_ATTR_NOATIME = 0x00000010 /* - Do not update access times. */
|
|
||||||
MOUNT_ATTR_STRICTATIME = 0x00000020 /* - Always perform atime updates */
|
|
||||||
MOUNT_ATTR_NODIRATIME = 0x00000080 /* Do not update directory access times */
|
|
||||||
MOUNT_ATTR_IDMAP = 0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
|
|
||||||
MOUNT_ATTR_NOSYMFOLLOW = 0x00200000 /* Do not follow symlinks */
|
|
||||||
)
|
|
||||||
|
|
||||||
// FS provides low-level wrappers around the suite of file-descriptor-based
|
|
||||||
// mount facilities in Linux.
|
|
||||||
type FS struct {
|
|
||||||
fd uintptr
|
|
||||||
c runtime.Cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
// newFS allocates a new [FS] for the specified fd.
|
|
||||||
func newFS(fd uintptr) *FS {
|
|
||||||
fs := FS{fd: fd}
|
|
||||||
fs.c = runtime.AddCleanup(&fs, func(fd uintptr) {
|
|
||||||
_ = syscall.Close(int(fd))
|
|
||||||
}, fd)
|
|
||||||
return &fs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the underlying filesystem context.
|
|
||||||
func (fs *FS) Close() error {
|
|
||||||
if fs == nil {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
err := syscall.Close(int(fs.fd))
|
|
||||||
fs.c.Stop()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenFS creates a new filesystem context.
|
|
||||||
func OpenFS(fsname string, flags int) (fs *FS, err error) {
|
|
||||||
var s *byte
|
|
||||||
s, err = syscall.BytePtrFromString(fsname)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fd, _, errno := syscall.Syscall(
|
|
||||||
SYS_FSOPEN,
|
|
||||||
uintptr(unsafe.Pointer(s)),
|
|
||||||
uintptr(flags|FSOPEN_CLOEXEC),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
err = os.NewSyscallError("fsopen", errno)
|
|
||||||
} else {
|
|
||||||
fs = newFS(fd)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// PickFS selects filesystem for reconfiguration.
|
|
||||||
func PickFS(dirfd int, pathname string, flags int) (fs *FS, err error) {
|
|
||||||
var s *byte
|
|
||||||
s, err = syscall.BytePtrFromString(pathname)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fd, _, errno := syscall.Syscall(
|
|
||||||
SYS_FSPICK,
|
|
||||||
uintptr(dirfd),
|
|
||||||
uintptr(unsafe.Pointer(s)),
|
|
||||||
uintptr(flags|FSPICK_CLOEXEC),
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
err = os.NewSyscallError("fspick", errno)
|
|
||||||
} else {
|
|
||||||
fs = newFS(fd)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// config configures new or existing filesystem context.
|
|
||||||
func (fs *FS) config(cmd uint, key *byte, value unsafe.Pointer, aux int) (err error) {
|
|
||||||
_, _, errno := syscall.Syscall6(
|
|
||||||
SYS_FSCONFIG,
|
|
||||||
fs.fd,
|
|
||||||
uintptr(cmd),
|
|
||||||
uintptr(unsafe.Pointer(key)),
|
|
||||||
uintptr(value),
|
|
||||||
uintptr(aux),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
err = os.NewSyscallError("fsconfig", errno)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFlag sets the flag parameter named by key. ([FSCONFIG_SET_FLAG])
|
|
||||||
func (fs *FS) SetFlag(key string) (err error) {
|
|
||||||
var s *byte
|
|
||||||
s, err = syscall.BytePtrFromString(key)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs.config(FSCONFIG_SET_FLAG, s, nil, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetString sets the string parameter named by key to the value specified by
|
|
||||||
// value. ([FSCONFIG_SET_STRING])
|
|
||||||
func (fs *FS) SetString(key, value string) (err error) {
|
|
||||||
var s0 *byte
|
|
||||||
s0, err = syscall.BytePtrFromString(key)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var s1 *byte
|
|
||||||
s1, err = syscall.BytePtrFromString(value)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs.config(FSCONFIG_SET_STRING, s0, unsafe.Pointer(s1), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mount instantiates mount object from filesystem context.
|
|
||||||
func (fs *FS) mount(flags, attrFlags int) (fsfd int, err error) {
|
|
||||||
r, _, errno := syscall.Syscall(
|
|
||||||
SYS_FSMOUNT,
|
|
||||||
fs.fd,
|
|
||||||
uintptr(flags|FSMOUNT_CLOEXEC),
|
|
||||||
uintptr(attrFlags),
|
|
||||||
)
|
|
||||||
fsfd = int(r)
|
|
||||||
if errno != 0 {
|
|
||||||
err = os.NewSyscallError("fsmount", errno)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveMount moves or attaches mount object to filesystem.
|
|
||||||
func MoveMount(
|
|
||||||
fromDirfd int,
|
|
||||||
fromPathname string,
|
|
||||||
toDirfd int,
|
|
||||||
toPathname string,
|
|
||||||
flags int,
|
|
||||||
) (err error) {
|
|
||||||
var s0 *byte
|
|
||||||
s0, err = syscall.BytePtrFromString(fromPathname)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var s1 *byte
|
|
||||||
s1, err = syscall.BytePtrFromString(toPathname)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, errno := syscall.Syscall6(
|
|
||||||
SYS_MOVE_MOUNT,
|
|
||||||
uintptr(fromDirfd),
|
|
||||||
uintptr(unsafe.Pointer(s0)),
|
|
||||||
uintptr(toDirfd),
|
|
||||||
uintptr(unsafe.Pointer(s1)),
|
|
||||||
uintptr(flags),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
if errno != 0 {
|
|
||||||
err = os.NewSyscallError("move_mount", errno)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mount attaches the underlying filesystem context to the specified pathname.
|
|
||||||
func (fs *FS) Mount(pathname string, attrFlags int) error {
|
|
||||||
if err := fs.config(FSCONFIG_CMD_CREATE_EXCL, nil, nil, 0); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fd, err := fs.mount(0, attrFlags)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = MoveMount(
|
|
||||||
fd, "",
|
|
||||||
-1, pathname,
|
|
||||||
MOVE_MOUNT_F_EMPTY_PATH,
|
|
||||||
)
|
|
||||||
closeErr := syscall.Close(fd)
|
|
||||||
if err == nil {
|
|
||||||
err = closeErr
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -42,8 +42,6 @@ var (
|
|||||||
AbsDevShm = unsafeAbs(DevShm)
|
AbsDevShm = unsafeAbs(DevShm)
|
||||||
// AbsProc is [Proc] as [check.Absolute].
|
// AbsProc is [Proc] as [check.Absolute].
|
||||||
AbsProc = unsafeAbs(Proc)
|
AbsProc = unsafeAbs(Proc)
|
||||||
// AbsProcSys is [ProcSys] as [check.Absolute].
|
|
||||||
AbsProcSys = unsafeAbs(ProcSys)
|
|
||||||
// AbsProcSelfExe is [ProcSelfExe] as [check.Absolute].
|
// AbsProcSelfExe is [ProcSelfExe] as [check.Absolute].
|
||||||
AbsProcSelfExe = unsafeAbs(ProcSelfExe)
|
AbsProcSelfExe = unsafeAbs(ProcSelfExe)
|
||||||
// AbsSys is [Sys] as [check.Absolute].
|
// AbsSys is [Sys] as [check.Absolute].
|
||||||
|
|||||||
216
internal/pkg/asm.go
Normal file
216
internal/pkg/asm.go
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
package pkg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type asmOutLine struct {
|
||||||
|
pos int
|
||||||
|
word int
|
||||||
|
kindData int64
|
||||||
|
valueData []byte
|
||||||
|
indent int
|
||||||
|
kind string
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
|
var spacingLine = asmOutLine{
|
||||||
|
pos: -1,
|
||||||
|
kindData: -1,
|
||||||
|
valueData: nil,
|
||||||
|
indent: 0,
|
||||||
|
kind: "",
|
||||||
|
value: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool) (s string, err error) {
|
||||||
|
var lines []asmOutLine
|
||||||
|
sb := new(strings.Builder)
|
||||||
|
header := true
|
||||||
|
pos := new(int)
|
||||||
|
|
||||||
|
for err == nil {
|
||||||
|
if header {
|
||||||
|
var kind uint64
|
||||||
|
var size uint64
|
||||||
|
var bsize []byte
|
||||||
|
p := *pos
|
||||||
|
if _, kind, err = nextUint64(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if bsize, size, err = nextUint64(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if showHeader {
|
||||||
|
lines = append(lines, asmOutLine{p, 8, int64(kind), bsize, 0, "head " + intToKind(kind), ""})
|
||||||
|
}
|
||||||
|
for i := 0; uint64(i) < size; i++ {
|
||||||
|
var did Checksum
|
||||||
|
var dkind uint64
|
||||||
|
p := *pos
|
||||||
|
if _, dkind, err = nextUint64(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if _, did, err = nextIdent(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if showHeader {
|
||||||
|
lines = append(lines, asmOutLine{p, 8, int64(dkind), nil, 1, intToKind(dkind), Encode(did)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header = false
|
||||||
|
}
|
||||||
|
var k uint32
|
||||||
|
p := *pos
|
||||||
|
if _, k, err = nextUint32(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
kind := IRValueKind(k)
|
||||||
|
switch kind {
|
||||||
|
case IRKindEnd:
|
||||||
|
var a uint32
|
||||||
|
var ba []byte
|
||||||
|
if ba, a, err = nextUint32(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if a&1 != 0 {
|
||||||
|
var sum Checksum
|
||||||
|
if _, sum, err = nextIdent(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
lines = append(lines, asmOutLine{p, 4, int64(kind), ba, 1, "end ", Encode(sum)})
|
||||||
|
} else {
|
||||||
|
lines = append(lines, asmOutLine{p, 4, int64(kind), []byte{0, 0, 0, 0}, 1, "end ", ""})
|
||||||
|
}
|
||||||
|
lines = append(lines, spacingLine)
|
||||||
|
header = true
|
||||||
|
continue
|
||||||
|
|
||||||
|
case IRKindIdent:
|
||||||
|
var a []byte
|
||||||
|
// discard ancillary
|
||||||
|
if a, _, err = nextUint32(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var sum Checksum
|
||||||
|
if _, sum, err = nextIdent(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = append(lines, asmOutLine{p, 4, int64(kind), a, 1, "id ", Encode(sum)})
|
||||||
|
continue
|
||||||
|
case IRKindUint32:
|
||||||
|
var i uint32
|
||||||
|
var bi []byte
|
||||||
|
if bi, i, err = nextUint32(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "int ", strconv.FormatUint(uint64(i), 10)})
|
||||||
|
case IRKindString:
|
||||||
|
var l uint32
|
||||||
|
var bl []byte
|
||||||
|
if bl, l, err = nextUint32(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
s := make([]byte, l+(wordSize-(l)%wordSize)%wordSize)
|
||||||
|
var n int
|
||||||
|
if n, err = r.Read(s); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
*pos = *pos + n
|
||||||
|
|
||||||
|
lines = append(lines, asmOutLine{p, 4, int64(kind), bl, 1, "str ", strconv.Quote(string(s[:l]))})
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
var bi []byte
|
||||||
|
if bi, _, err = nextUint32(r, pos); err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "????", ""})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = nil
|
||||||
|
for _, line := range lines {
|
||||||
|
if raw {
|
||||||
|
if line.pos != -1 {
|
||||||
|
sb.WriteString(fmt.Sprintf("%s\t%s\n", line.kind, line.value))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if line.pos == -1 {
|
||||||
|
sb.WriteString("\n")
|
||||||
|
} else if line.word == 4 {
|
||||||
|
sb.WriteString(fmt.Sprintf("%06x: %04x %04x%s %s %s\n", line.pos, binary.LittleEndian.AppendUint32(nil, uint32(line.kindData)), line.valueData, headerSpacing(showHeader), line.kind, line.value))
|
||||||
|
} else {
|
||||||
|
kind := binary.LittleEndian.AppendUint64(nil, uint64(line.kindData))
|
||||||
|
value := line.valueData
|
||||||
|
if len(value) == 8 {
|
||||||
|
sb.WriteString(fmt.Sprintf("%06x: %04x %04x %04x %04x %s %s\n", line.pos, kind[:4], kind[4:], value[:4], value[4:], line.kind, line.value))
|
||||||
|
} else {
|
||||||
|
sb.WriteString(fmt.Sprintf("%06x: %04x %04x %s %s\n", line.pos, kind[:4], kind[4:], line.kind, line.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return sb.String(), err
|
||||||
|
}
|
||||||
|
func nextUint32(r io.Reader, pos *int) ([]byte, uint32, error) {
|
||||||
|
i := make([]byte, 4)
|
||||||
|
_, err := r.Read(i)
|
||||||
|
if err != nil {
|
||||||
|
return i, 0, err
|
||||||
|
}
|
||||||
|
p := *pos + 4
|
||||||
|
*pos = p
|
||||||
|
return i, binary.LittleEndian.Uint32(i), nil
|
||||||
|
}
|
||||||
|
func nextUint64(r io.Reader, pos *int) ([]byte, uint64, error) {
|
||||||
|
i := make([]byte, 8)
|
||||||
|
_, err := r.Read(i)
|
||||||
|
if err != nil {
|
||||||
|
return i, 0, err
|
||||||
|
}
|
||||||
|
p := *pos + 8
|
||||||
|
*pos = p
|
||||||
|
return i, binary.LittleEndian.Uint64(i), nil
|
||||||
|
}
|
||||||
|
func nextIdent(r io.Reader, pos *int) ([]byte, Checksum, error) {
|
||||||
|
i := make([]byte, 48)
|
||||||
|
if _, err := r.Read(i); err != nil {
|
||||||
|
return i, Checksum{}, err
|
||||||
|
}
|
||||||
|
p := *pos + 48
|
||||||
|
*pos = p
|
||||||
|
return i, Checksum(i), nil
|
||||||
|
}
|
||||||
|
func intToKind(i uint64) string {
|
||||||
|
switch Kind(i) {
|
||||||
|
case KindHTTPGet:
|
||||||
|
return "http"
|
||||||
|
case KindTar:
|
||||||
|
return "tar "
|
||||||
|
case KindExec:
|
||||||
|
return "exec"
|
||||||
|
case KindExecNet:
|
||||||
|
return "exen"
|
||||||
|
case KindFile:
|
||||||
|
return "file"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("$%d ", i-KindCustomOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func headerSpacing(showHeader bool) string {
|
||||||
|
if showHeader {
|
||||||
|
return " "
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
@@ -64,6 +64,78 @@ func TestFlatten(t *testing.T) {
|
|||||||
{Mode: fs.ModeDir | 0700, Path: "work"},
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C"), nil},
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C"), nil},
|
||||||
|
|
||||||
|
{"sample cache file", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: 0400, Data: []byte{0}},
|
||||||
|
"checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq": {Mode: 0400, Data: []byte{0, 0, 0, 0, 0xad, 0xb, 0, 4, 0xfe, 0xfe, 0, 0, 0xfe, 0xca, 0, 0}},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
||||||
|
"identifier/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
||||||
|
"identifier/cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
||||||
|
"identifier/deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
||||||
|
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: 0400, Path: "checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq", Data: []byte{0, 0, 0, 0, 0xad, 0xb, 0, 4, 0xfe, 0xfe, 0, 0, 0xfe, 0xca, 0, 0}},
|
||||||
|
{Mode: 0400, Path: "checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX", Data: []byte{0}},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq", Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe", Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX", Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("St9rlE-mGZ5gXwiv_hzQ_B8bZP-UUvSNmf4nHUZzCMOumb6hKnheZSe0dmnuc4Q2"), nil},
|
||||||
|
|
||||||
|
{"sample http get cure", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU": {Mode: 0400, Data: []byte("\x7f\xe1\x69\xa2\xdd\x63\x96\x26\x83\x79\x61\x8b\xf0\x3f\xd5\x16\x9a\x39\x3a\xdb\xcf\xb1\xbc\x8d\x33\xff\x75\xee\x62\x56\xa9\xf0\x27\xac\x13\x94\x69")},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/oM-2pUlk-mOxK1t3aMWZer69UdOQlAXiAgMrpZ1476VoOqpYVP1aGFS9_HYy-D8_": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU")},
|
||||||
|
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: 0400, Path: "checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU", Data: []byte("\x7f\xe1\x69\xa2\xdd\x63\x96\x26\x83\x79\x61\x8b\xf0\x3f\xd5\x16\x9a\x39\x3a\xdb\xcf\xb1\xbc\x8d\x33\xff\x75\xee\x62\x56\xa9\xf0\x27\xac\x13\x94\x69")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/oM-2pUlk-mOxK1t3aMWZer69UdOQlAXiAgMrpZ1476VoOqpYVP1aGFS9_HYy-D8_", Data: []byte("../checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("L_0RFHpr9JUS4Zp14rz2dESSRvfLzpvqsLhR1-YjQt8hYlmEdVl7vI3_-v8UNPKs"), nil},
|
||||||
|
|
||||||
|
{"sample directory step simple", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"check": {Mode: 0400, Data: []byte{0, 0}},
|
||||||
|
|
||||||
|
"lib": {Mode: fs.ModeDir | 0700},
|
||||||
|
"lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
|
"lib/pkgconfig": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "."},
|
||||||
|
|
||||||
|
{Mode: 0400, Path: "check", Data: []byte{0, 0}},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "lib"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "lib/libedac.so", Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "lib/pkgconfig"},
|
||||||
|
}, pkg.MustDecode("qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b"), nil},
|
||||||
|
|
||||||
{"sample directory step garbage", fstest.MapFS{
|
{"sample directory step garbage", fstest.MapFS{
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
".": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
@@ -79,6 +151,421 @@ func TestFlatten(t *testing.T) {
|
|||||||
|
|
||||||
{Mode: fs.ModeDir | 0500, Path: "lib/pkgconfig"},
|
{Mode: fs.ModeDir | 0500, Path: "lib/pkgconfig"},
|
||||||
}, pkg.MustDecode("CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT"), nil},
|
}, pkg.MustDecode("CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT"), nil},
|
||||||
|
|
||||||
|
{"sample directory", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/check": {Mode: 0400, Data: []byte{0, 0}},
|
||||||
|
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/pkgconfig": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
|
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
|
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b"},
|
||||||
|
{Mode: 0400, Path: "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/check", Data: []byte{0, 0}},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/libedac.so", Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/pkgconfig"},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY", Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa", Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("WVpvsVqVKg9Nsh744x57h51AuWUoUR2nnh8Md-EYBQpk6ziyTuUn6PLtF2e0Eu_d"), nil},
|
||||||
|
|
||||||
|
{"sample no assume checksum", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M/check": {Mode: 0400, Data: []byte{}},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/_wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
|
||||||
|
"identifier/_wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
|
||||||
|
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M"},
|
||||||
|
{Mode: 0400, Path: "checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M/check", Data: []byte{}},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/_wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/_wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("OC290t23aimNo2Rp2pPwan5GI2KRLRdOwYxXQMD9jw0QROgHnNXWodoWdV0hwu2w"), nil},
|
||||||
|
|
||||||
|
{"sample tar step unpack", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}},
|
||||||
|
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0500},
|
||||||
|
"identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
|
||||||
|
"work": {Mode: fs.ModeDir | 0500},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP"},
|
||||||
|
{Mode: 0400, Path: "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check", Data: []byte{0, 0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so", Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig"},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY", Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa", Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "work"},
|
||||||
|
}, pkg.MustDecode("cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM"), nil},
|
||||||
|
|
||||||
|
{"sample tar", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/identifier": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
"checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/work": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM")},
|
||||||
|
"identifier/rg7F1D5hwv6o4xctjD5zDq4i5MD0mArTsUIWfhUbik8xC6Bsyt3mjXXOm3goojTz": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP"},
|
||||||
|
{Mode: 0400, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check", Data: []byte{0, 0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so", Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY", Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa", Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM/work"},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw", Data: []byte("../checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/rg7F1D5hwv6o4xctjD5zDq4i5MD0mArTsUIWfhUbik8xC6Bsyt3mjXXOm3goojTz", Data: []byte("../checksum/cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("NQTlc466JmSVLIyWklm_u8_g95jEEb98PxJU-kjwxLpfdjwMWJq0G8ze9R4Vo1Vu"), nil},
|
||||||
|
|
||||||
|
{"sample tar expand step unpack", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "libedac.so", Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
}, pkg.MustDecode("CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN"), nil},
|
||||||
|
|
||||||
|
{"sample tar expand", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")},
|
||||||
|
"identifier/_v1blm2h-_KA-dVaawdpLas6MjHc6rbhhFS8JWwx8iJxZGUu8EBbRrhr5AaZ9PJL": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN/libedac.so", Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw", Data: []byte("../checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/_v1blm2h-_KA-dVaawdpLas6MjHc6rbhhFS8JWwx8iJxZGUu8EBbRrhr5AaZ9PJL", Data: []byte("../checksum/CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("hSoSSgCYTNonX3Q8FjvjD1fBl-E-BQyA6OTXro2OadXqbST4tZ-akGXszdeqphRe"), nil},
|
||||||
|
|
||||||
|
{"testtool", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"check": {Mode: 0400, Data: []byte{0}},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "."},
|
||||||
|
|
||||||
|
{Mode: 0400, Path: "check", Data: []byte{0}},
|
||||||
|
}, pkg.MustDecode("GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"), nil},
|
||||||
|
|
||||||
|
{"sample exec container", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check": {Mode: 0400, Data: []byte{0}},
|
||||||
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
"identifier/dztPS6jRjiZtCF4_p8AzfnxGp6obkhrgFVsxdodbKWUoAEVtDz3MykepJB4kI_ks": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"},
|
||||||
|
{Mode: 0400, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check", Data: []byte{0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"},
|
||||||
|
{Mode: 0400, Path: "checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb", Data: []byte{}},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/dztPS6jRjiZtCF4_p8AzfnxGp6obkhrgFVsxdodbKWUoAEVtDz3MykepJB4kI_ks", Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("Q5DluWQCAeohLoiGRImurwFp3vdz9IfQCoj7Fuhh73s4KQPRHpEQEnHTdNHmB8Fx"), nil},
|
||||||
|
|
||||||
|
{"testtool net", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"check": {Mode: 0400, Data: []byte("net")},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "."},
|
||||||
|
|
||||||
|
{Mode: 0400, Path: "check", Data: []byte("net")},
|
||||||
|
}, pkg.MustDecode("a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W"), nil},
|
||||||
|
|
||||||
|
{"sample exec net container", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
||||||
|
"checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W/check": {Mode: 0400, Data: []byte("net")},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/G8qPxD9puvvoOVV7lrT80eyDeIl3G_CCFoKw12c8mCjMdG1zF7NEPkwYpNubClK3": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W")},
|
||||||
|
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"},
|
||||||
|
{Mode: 0400, Path: "checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb", Data: []byte{}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W"},
|
||||||
|
{Mode: 0400, Path: "checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W/check", Data: []byte("net")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/G8qPxD9puvvoOVV7lrT80eyDeIl3G_CCFoKw12c8mCjMdG1zF7NEPkwYpNubClK3", Data: []byte("../checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("bPYvvqxpfV7xcC1EptqyKNK1klLJgYHMDkzBcoOyK6j_Aj5hb0mXNPwTwPSK5F6Z"), nil},
|
||||||
|
|
||||||
|
{"sample exec container overlay root", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check": {Mode: 0400, Data: []byte{0}},
|
||||||
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/RdMA-mubnrHuu3Ky1wWyxauSYCO0ZH_zCPUj3uDHqkfwv5sGcByoF_g5PjlGiClb": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"},
|
||||||
|
{Mode: 0400, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check", Data: []byte{0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/RdMA-mubnrHuu3Ky1wWyxauSYCO0ZH_zCPUj3uDHqkfwv5sGcByoF_g5PjlGiClb", Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("PO2DSSCa4yoSgEYRcCSZfQfwow1yRigL3Ry-hI0RDI4aGuFBha-EfXeSJnG_5_Rl"), nil},
|
||||||
|
|
||||||
|
{"sample exec container overlay work", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check": {Mode: 0400, Data: []byte{0}},
|
||||||
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/5hlaukCirnXE4W_RSLJFOZN47Z5RiHnacXzdFp_70cLgiJUGR6cSb_HaFftkzi0-": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"},
|
||||||
|
{Mode: 0400, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check", Data: []byte{0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/5hlaukCirnXE4W_RSLJFOZN47Z5RiHnacXzdFp_70cLgiJUGR6cSb_HaFftkzi0-", Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("iaRt6l_Wm2n-h5UsDewZxQkCmjZjyL8r7wv32QT2kyV55-Lx09Dq4gfg9BiwPnKs"), nil},
|
||||||
|
|
||||||
|
{"sample exec container multiple layers", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check": {Mode: 0400, Data: []byte{0}},
|
||||||
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
||||||
|
"checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK/check": {Mode: 0400, Data: []byte("layers")},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
"identifier/B-kc5iJMx8GtlCua4dz6BiJHnDAOUfPjgpbKq4e-QEn0_CZkSYs3fOA1ve06qMs2": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK")},
|
||||||
|
"identifier/p1t_drXr34i-jZNuxDMLaMOdL6tZvQqhavNafGynGqxOZoXAUTSn7kqNh3Ovv3DT": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"},
|
||||||
|
{Mode: 0400, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check", Data: []byte{0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"},
|
||||||
|
{Mode: 0400, Path: "checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb", Data: []byte{}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK"},
|
||||||
|
{Mode: 0400, Path: "checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK/check", Data: []byte("layers")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/B-kc5iJMx8GtlCua4dz6BiJHnDAOUfPjgpbKq4e-QEn0_CZkSYs3fOA1ve06qMs2", Data: []byte("../checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/p1t_drXr34i-jZNuxDMLaMOdL6tZvQqhavNafGynGqxOZoXAUTSn7kqNh3Ovv3DT", Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("O2YzyR7IUGU5J2CADy0hUZ3A5NkP_Vwzs4UadEdn2oMZZVWRtH0xZGJ3HXiimTnZ"), nil},
|
||||||
|
|
||||||
|
{"sample exec container layer promotion", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9": {Mode: fs.ModeDir | 0500},
|
||||||
|
"checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check": {Mode: 0400, Data: []byte{0}},
|
||||||
|
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/kvJIqZo5DKFOxC2ZQ-8_nPaQzEAz9cIm3p6guO-uLqm-xaiPu7oRkSnsu411jd_U": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
"identifier/xXTIYcXmgJWNLC91c417RRrNM9cjELwEZHpGvf8Fk_GNP5agRJp_SicD0w9aMeLJ": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
|
||||||
|
"temp": {Mode: fs.ModeDir | 0700},
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"},
|
||||||
|
{Mode: 0400, Path: "checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9/check", Data: []byte{0}},
|
||||||
|
{Mode: fs.ModeDir | 0500, Path: "checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/kvJIqZo5DKFOxC2ZQ-8_nPaQzEAz9cIm3p6guO-uLqm-xaiPu7oRkSnsu411jd_U", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK", Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/xXTIYcXmgJWNLC91c417RRrNM9cjELwEZHpGvf8Fk_GNP5agRJp_SicD0w9aMeLJ", Data: []byte("../checksum/GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "temp"},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("3EaW6WibLi9gl03_UieiFPaFcPy5p4x3JPxrnLJxGaTI-bh3HU9DK9IMx7c3rrNm"), nil},
|
||||||
|
|
||||||
|
{"sample file short", fstest.MapFS{
|
||||||
|
".": {Mode: fs.ModeDir | 0700},
|
||||||
|
|
||||||
|
"checksum": {Mode: fs.ModeDir | 0700},
|
||||||
|
"checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: 0400, Data: []byte{0}},
|
||||||
|
|
||||||
|
"identifier": {Mode: fs.ModeDir | 0700},
|
||||||
|
"identifier/3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
||||||
|
|
||||||
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
|
}, []pkg.FlatEntry{
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "."},
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "checksum"},
|
||||||
|
{Mode: 0400, Path: "checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX", Data: []byte{0}},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "identifier"},
|
||||||
|
{Mode: fs.ModeSymlink | 0777, Path: "identifier/3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi", Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
||||||
|
|
||||||
|
{Mode: fs.ModeDir | 0700, Path: "work"},
|
||||||
|
}, pkg.MustDecode("iR6H5OIsyOW4EwEgtm9rGzGF6DVtyHLySEtwnFE8bnus9VJcoCbR4JIek7Lw-vwT"), nil},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unique"
|
"unique"
|
||||||
@@ -96,32 +94,6 @@ func MustPath(pathname string, writable bool, a ...Artifact) ExecPath {
|
|||||||
return ExecPath{check.MustAbs(pathname), a, writable}
|
return ExecPath{check.MustAbs(pathname), a, writable}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
binfmt map[string]container.BinfmtEntry
|
|
||||||
binfmtMu sync.RWMutex
|
|
||||||
)
|
|
||||||
|
|
||||||
// RegisterArch arranges for [KindExec] and [KindExecNet] to support a new
|
|
||||||
// architecture via a binfmt_misc entry. Each architecture must be registered
|
|
||||||
// at most once.
|
|
||||||
func RegisterArch(arch string, e container.BinfmtEntry) {
|
|
||||||
if arch == "" {
|
|
||||||
panic(UnsupportedArchError(arch))
|
|
||||||
}
|
|
||||||
|
|
||||||
binfmtMu.Lock()
|
|
||||||
defer binfmtMu.Unlock()
|
|
||||||
|
|
||||||
if binfmt == nil {
|
|
||||||
binfmt = make(map[string]container.BinfmtEntry)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := binfmt[arch]; ok {
|
|
||||||
panic("attempting to register " + strconv.Quote(arch) + " twice")
|
|
||||||
}
|
|
||||||
binfmt[arch] = e
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ExecTimeoutDefault replaces out of range [NewExec] timeout values.
|
// ExecTimeoutDefault replaces out of range [NewExec] timeout values.
|
||||||
ExecTimeoutDefault = 15 * time.Minute
|
ExecTimeoutDefault = 15 * time.Minute
|
||||||
@@ -138,8 +110,6 @@ type execArtifact struct {
|
|||||||
// Caller-supplied user-facing reporting name, guaranteed to be nonzero
|
// Caller-supplied user-facing reporting name, guaranteed to be nonzero
|
||||||
// during initialisation.
|
// during initialisation.
|
||||||
name string
|
name string
|
||||||
// Target architecture.
|
|
||||||
arch string
|
|
||||||
// Caller-supplied inner mount points.
|
// Caller-supplied inner mount points.
|
||||||
paths []ExecPath
|
paths []ExecPath
|
||||||
|
|
||||||
@@ -208,7 +178,7 @@ func (a *execNetArtifact) Cure(f *FContext) error {
|
|||||||
// container and does not affect curing outcome. Because of this, it is omitted
|
// container and does not affect curing outcome. Because of this, it is omitted
|
||||||
// from parameter data for computing identifier.
|
// from parameter data for computing identifier.
|
||||||
func NewExec(
|
func NewExec(
|
||||||
name, arch string,
|
name string,
|
||||||
checksum *Checksum,
|
checksum *Checksum,
|
||||||
timeout time.Duration,
|
timeout time.Duration,
|
||||||
exclusive bool,
|
exclusive bool,
|
||||||
@@ -223,16 +193,13 @@ func NewExec(
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
name = "exec-" + filepath.Base(pathname.String())
|
name = "exec-" + filepath.Base(pathname.String())
|
||||||
}
|
}
|
||||||
if arch == "" {
|
|
||||||
arch = runtime.GOARCH
|
|
||||||
}
|
|
||||||
if timeout <= 0 {
|
if timeout <= 0 {
|
||||||
timeout = ExecTimeoutDefault
|
timeout = ExecTimeoutDefault
|
||||||
}
|
}
|
||||||
if timeout > ExecTimeoutMax {
|
if timeout > ExecTimeoutMax {
|
||||||
timeout = ExecTimeoutMax
|
timeout = ExecTimeoutMax
|
||||||
}
|
}
|
||||||
a := execArtifact{name, arch, paths, dir, env, pathname, args, timeout, exclusive}
|
a := execArtifact{name, paths, dir, env, pathname, args, timeout, exclusive}
|
||||||
if checksum == nil {
|
if checksum == nil {
|
||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
@@ -244,7 +211,6 @@ func (*execArtifact) Kind() Kind { return KindExec }
|
|||||||
|
|
||||||
// Params writes paths, executable pathname and args.
|
// Params writes paths, executable pathname and args.
|
||||||
func (a *execArtifact) Params(ctx *IContext) {
|
func (a *execArtifact) Params(ctx *IContext) {
|
||||||
ctx.WriteString(a.arch)
|
|
||||||
ctx.WriteString(a.name)
|
ctx.WriteString(a.name)
|
||||||
|
|
||||||
ctx.WriteUint32(uint32(len(a.paths)))
|
ctx.WriteUint32(uint32(len(a.paths)))
|
||||||
@@ -291,26 +257,11 @@ func (a *execArtifact) Params(ctx *IContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsupportedArchError describes an unsupported or invalid architecture.
|
|
||||||
type UnsupportedArchError string
|
|
||||||
|
|
||||||
func (e UnsupportedArchError) Error() string {
|
|
||||||
if e == "" {
|
|
||||||
return "invalid architecture name"
|
|
||||||
}
|
|
||||||
return "unsupported architecture " + string(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// readExecArtifact interprets IR values and returns the address of execArtifact
|
// readExecArtifact interprets IR values and returns the address of execArtifact
|
||||||
// or execNetArtifact.
|
// or execNetArtifact.
|
||||||
func readExecArtifact(r *IRReader, net bool) Artifact {
|
func readExecArtifact(r *IRReader, net bool) Artifact {
|
||||||
r.DiscardAll()
|
r.DiscardAll()
|
||||||
|
|
||||||
arch := r.ReadString()
|
|
||||||
if arch == "" {
|
|
||||||
panic(UnsupportedArchError(arch))
|
|
||||||
}
|
|
||||||
|
|
||||||
name := r.ReadString()
|
name := r.ReadString()
|
||||||
|
|
||||||
sz := r.ReadUint32()
|
sz := r.ReadUint32()
|
||||||
@@ -376,7 +327,7 @@ func readExecArtifact(r *IRReader, net bool) Artifact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return NewExec(
|
return NewExec(
|
||||||
name, arch, checksumP, timeout, exclusive, dir, env, pathname, args, paths...,
|
name, checksumP, timeout, exclusive, dir, env, pathname, args, paths...,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,23 +436,11 @@ func (a *execArtifact) makeContainer(
|
|||||||
if z.HostNet {
|
if z.HostNet {
|
||||||
z.Hostname = "cure-net"
|
z.Hostname = "cure-net"
|
||||||
}
|
}
|
||||||
z.Quiet = flags&CSuppressInit != 0
|
|
||||||
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
|
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
|
||||||
z.Dir, z.Path, z.Args = a.dir, a.path, a.args
|
z.Dir, z.Path, z.Args = a.dir, a.path, a.args
|
||||||
z.Env = slices.Concat(a.env, []string{EnvJobs + "=" + strconv.Itoa(jobs)})
|
z.Env = slices.Concat(a.env, []string{EnvJobs + "=" + strconv.Itoa(jobs)})
|
||||||
z.Grow(len(a.paths) + 4)
|
z.Grow(len(a.paths) + 4)
|
||||||
|
|
||||||
if a.arch != runtime.GOARCH {
|
|
||||||
binfmtMu.RLock()
|
|
||||||
e, ok := binfmt[a.arch]
|
|
||||||
binfmtMu.RUnlock()
|
|
||||||
if !ok {
|
|
||||||
return nil, UnsupportedArchError(a.arch)
|
|
||||||
}
|
|
||||||
z.Binfmt = []container.BinfmtEntry{e}
|
|
||||||
z.InitAsRoot = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, b := range a.paths {
|
for i, b := range a.paths {
|
||||||
if i == overlayWorkIndex {
|
if i == overlayWorkIndex {
|
||||||
if err = os.MkdirAll(work.String(), 0700); err != nil {
|
if err = os.MkdirAll(work.String(), 0700); err != nil {
|
||||||
@@ -691,6 +630,12 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
|
|||||||
_ = stdout.Close()
|
_ = stdout.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil && !errors.As(err, new(*exec.ExitError)) {
|
||||||
|
_ = stdout.Close()
|
||||||
|
_ = stderr.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
brStdout, brStderr := f.cache.getReader(stdout), f.cache.getReader(stderr)
|
brStdout, brStderr := f.cache.getReader(stdout), f.cache.getReader(stderr)
|
||||||
stdoutDone, stderrDone := make(chan struct{}), make(chan struct{})
|
stdoutDone, stderrDone := make(chan struct{}), make(chan struct{})
|
||||||
@@ -705,11 +650,6 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
|
|||||||
io.TeeReader(brStderr, status),
|
io.TeeReader(brStderr, status),
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && !errors.As(err, new(*exec.ExitError)) {
|
|
||||||
_ = stdout.Close()
|
|
||||||
_ = stderr.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
<-stdoutDone
|
<-stdoutDone
|
||||||
<-stderrDone
|
<-stderrDone
|
||||||
f.cache.putReader(brStdout)
|
f.cache.putReader(brStdout)
|
||||||
|
|||||||
@@ -1,55 +1,36 @@
|
|||||||
package pkg_test
|
package pkg_test
|
||||||
|
|
||||||
|
//go:generate env CGO_ENABLED=0 go build -tags testtool -o testdata/testtool ./testdata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"errors"
|
"errors"
|
||||||
"io/fs"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
|
||||||
"slices"
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
"unique"
|
"unique"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
"hakurei.app/container"
|
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/internal/info"
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
"hakurei.app/internal/stub"
|
"hakurei.app/internal/stub"
|
||||||
|
|
||||||
"hakurei.app/internal/pkg/internal/testtool/expected"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// testtoolBin is the container test tool binary made available to the
|
// testtoolBin is the container test tool binary made available to the
|
||||||
// execArtifact for testing its curing environment.
|
// execArtifact for testing its curing environment.
|
||||||
//
|
//
|
||||||
//go:generate env CGO_ENABLED=0 go build -tags testtool -o internal/testtool ./internal/testtool
|
//go:embed testdata/testtool
|
||||||
//go:embed internal/testtool/testtool
|
|
||||||
var testtoolBin []byte
|
var testtoolBin []byte
|
||||||
|
|
||||||
func init() {
|
|
||||||
pathname, err := filepath.Abs("internal/testtool/testtool")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
pkg.RegisterArch("cafe", container.BinfmtEntry{
|
|
||||||
Magic: expected.Magic,
|
|
||||||
Interpreter: check.MustAbs(pathname),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExec(t *testing.T) {
|
func TestExec(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
wantOffline := expectsFS{
|
wantChecksumOffline := pkg.MustDecode(
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
"GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9",
|
||||||
|
)
|
||||||
"check": {Mode: 0400, Data: []byte{0}},
|
|
||||||
}
|
|
||||||
wantOfflineEncode := pkg.Encode(wantOffline.hash())
|
|
||||||
|
|
||||||
checkWithCache(t, []cacheTestCase{
|
checkWithCache(t, []cacheTestCase{
|
||||||
{"offline", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"offline", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
@@ -57,7 +38,7 @@ func TestExec(t *testing.T) {
|
|||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"container", pkg.NewExec(
|
{"container", pkg.NewExec(
|
||||||
"exec-offline", "", nil, 0, false,
|
"exec-offline", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1"},
|
[]string{"HAKUREI_TEST=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -77,10 +58,10 @@ func TestExec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pkg.MustPath("/opt", false, testtool),
|
pkg.MustPath("/opt", false, testtool),
|
||||||
), ignorePathname, wantOffline, nil},
|
), ignorePathname, wantChecksumOffline, nil},
|
||||||
|
|
||||||
{"error passthrough", pkg.NewExec(
|
{"error passthrough", pkg.NewExec(
|
||||||
"", "", nil, 0, true,
|
"", nil, 0, true,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1"},
|
[]string{"HAKUREI_TEST=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -93,7 +74,7 @@ func TestExec(t *testing.T) {
|
|||||||
return stub.UniqueError(0xcafe)
|
return stub.UniqueError(0xcafe)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
), nil, nil, &pkg.DependencyCureError{
|
), nil, pkg.Checksum{}, &pkg.DependencyCureError{
|
||||||
{
|
{
|
||||||
Ident: unique.Make(pkg.ID(pkg.MustDecode(
|
Ident: unique.Make(pkg.ID(pkg.MustDecode(
|
||||||
"Sowo6oZRmG6xVtUaxB6bDWZhVsqAJsIJWUp0OPKlE103cY0lodx7dem8J-qQF0Z1",
|
"Sowo6oZRmG6xVtUaxB6bDWZhVsqAJsIJWUp0OPKlE103cY0lodx7dem8J-qQF0Z1",
|
||||||
@@ -103,20 +84,20 @@ func TestExec(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
|
|
||||||
{"invalid paths", pkg.NewExec(
|
{"invalid paths", pkg.NewExec(
|
||||||
"", "", nil, 0, false,
|
"", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1"},
|
[]string{"HAKUREI_TEST=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
[]string{"testtool"},
|
[]string{"testtool"},
|
||||||
|
|
||||||
pkg.ExecPath{},
|
pkg.ExecPath{},
|
||||||
), nil, nil, pkg.ErrInvalidPaths},
|
), nil, pkg.Checksum{}, pkg.ErrInvalidPaths},
|
||||||
})
|
})
|
||||||
|
|
||||||
// check init failure passthrough
|
// check init failure passthrough
|
||||||
var exitError *exec.ExitError
|
var exitError *exec.ExitError
|
||||||
if _, _, err := c.Cure(pkg.NewExec(
|
if _, _, err := c.Cure(pkg.NewExec(
|
||||||
"", "", nil, 0, false,
|
"", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
nil,
|
nil,
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -127,35 +108,17 @@ func TestExec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testtoolDestroy(t, base, c)
|
testtoolDestroy(t, base, c)
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("Q5DluWQCAeohLoiGRImurwFp3vdz9IfQCoj7Fuhh73s4KQPRHpEQEnHTdNHmB8Fx")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantOfflineEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantOfflineEncode + "/check": {Mode: 0400, Data: []byte{0}},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
|
||||||
"identifier/" + expected.Offline: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"net", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"net", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
testtool, testtoolDestroy := newTesttool()
|
testtool, testtoolDestroy := newTesttool()
|
||||||
|
|
||||||
wantNet := expectsFS{
|
wantChecksum := pkg.MustDecode(
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
"a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W",
|
||||||
|
)
|
||||||
"check": {Mode: 0400, Data: []byte("net")},
|
|
||||||
}
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"container", pkg.NewExec(
|
{"container", pkg.NewExec(
|
||||||
"exec-net", "", new(wantNet.hash()), 0, false,
|
"exec-net", &wantChecksum, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1"},
|
[]string{"HAKUREI_TEST=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -175,34 +138,18 @@ func TestExec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pkg.MustPath("/opt", false, testtool),
|
pkg.MustPath("/opt", false, testtool),
|
||||||
), ignorePathname, wantNet, nil},
|
), ignorePathname, wantChecksum, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
testtoolDestroy(t, base, c)
|
testtoolDestroy(t, base, c)
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("bPYvvqxpfV7xcC1EptqyKNK1klLJgYHMDkzBcoOyK6j_Aj5hb0mXNPwTwPSK5F6Z")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
|
||||||
"checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W/check": {Mode: 0400, Data: []byte("net")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/" + expected.Net: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W")},
|
|
||||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"overlay root", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"overlay root", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
testtool, testtoolDestroy := newTesttool()
|
testtool, testtoolDestroy := newTesttool()
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"container", pkg.NewExec(
|
{"container", pkg.NewExec(
|
||||||
"exec-overlay-root", "", nil, 0, false,
|
"exec-overlay-root", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -216,32 +163,18 @@ func TestExec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pkg.MustPath("/opt", false, testtool),
|
pkg.MustPath("/opt", false, testtool),
|
||||||
), ignorePathname, wantOffline, nil},
|
), ignorePathname, wantChecksumOffline, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
testtoolDestroy(t, base, c)
|
testtoolDestroy(t, base, c)
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("PO2DSSCa4yoSgEYRcCSZfQfwow1yRigL3Ry-hI0RDI4aGuFBha-EfXeSJnG_5_Rl")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantOfflineEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantOfflineEncode + "/check": {Mode: 0400, Data: []byte{0}},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/" + expected.OvlRoot: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"overlay work", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"overlay work", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
testtool, testtoolDestroy := newTesttool()
|
testtool, testtoolDestroy := newTesttool()
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"container", pkg.NewExec(
|
{"container", pkg.NewExec(
|
||||||
"exec-overlay-work", "", nil, 0, false,
|
"exec-overlay-work", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
||||||
check.MustAbs("/work/bin/testtool"),
|
check.MustAbs("/work/bin/testtool"),
|
||||||
@@ -260,32 +193,18 @@ func TestExec(t *testing.T) {
|
|||||||
return os.MkdirAll(t.GetWorkDir().String(), 0700)
|
return os.MkdirAll(t.GetWorkDir().String(), 0700)
|
||||||
},
|
},
|
||||||
}), pkg.Path(pkg.AbsWork, false /* ignored */, testtool),
|
}), pkg.Path(pkg.AbsWork, false /* ignored */, testtool),
|
||||||
), ignorePathname, wantOffline, nil},
|
), ignorePathname, wantChecksumOffline, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
testtoolDestroy(t, base, c)
|
testtoolDestroy(t, base, c)
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("iaRt6l_Wm2n-h5UsDewZxQkCmjZjyL8r7wv32QT2kyV55-Lx09Dq4gfg9BiwPnKs")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantOfflineEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantOfflineEncode + "/check": {Mode: 0400, Data: []byte{0}},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/" + expected.Work: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"multiple layers", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"multiple layers", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
testtool, testtoolDestroy := newTesttool()
|
testtool, testtoolDestroy := newTesttool()
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"container", pkg.NewExec(
|
{"container", pkg.NewExec(
|
||||||
"exec-multiple-layers", "", nil, 0, false,
|
"exec-multiple-layers", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -326,37 +245,18 @@ func TestExec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pkg.MustPath("/opt", false, testtool),
|
pkg.MustPath("/opt", false, testtool),
|
||||||
), ignorePathname, wantOffline, nil},
|
), ignorePathname, wantChecksumOffline, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
testtoolDestroy(t, base, c)
|
testtoolDestroy(t, base, c)
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("O2YzyR7IUGU5J2CADy0hUZ3A5NkP_Vwzs4UadEdn2oMZZVWRtH0xZGJ3HXiimTnZ")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantOfflineEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantOfflineEncode + "/check": {Mode: 0400, Data: []byte{0}},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb": {Mode: 0400, Data: []byte{}},
|
|
||||||
"checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK/check": {Mode: 0400, Data: []byte("layers")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/_gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/OLBgp1GsljhM2TJ-sbHjaiH9txEUvgdDTAzHv2P24donTt6_529l-9Ua0vFImLlb")},
|
|
||||||
"identifier/B-kc5iJMx8GtlCua4dz6BiJHnDAOUfPjgpbKq4e-QEn0_CZkSYs3fOA1ve06qMs2": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK")},
|
|
||||||
"identifier/" + expected.Layers: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"overlay layer promotion", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"overlay layer promotion", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
testtool, testtoolDestroy := newTesttool()
|
testtool, testtoolDestroy := newTesttool()
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"container", pkg.NewExec(
|
{"container", pkg.NewExec(
|
||||||
"exec-layer-promotion", "", nil, 0, true,
|
"exec-layer-promotion", nil, 0, true,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
[]string{"HAKUREI_TEST=1", "HAKUREI_ROOT=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -376,89 +276,11 @@ func TestExec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pkg.MustPath("/opt", false, testtool),
|
pkg.MustPath("/opt", false, testtool),
|
||||||
), ignorePathname, wantOffline, nil},
|
), ignorePathname, wantChecksumOffline, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
testtoolDestroy(t, base, c)
|
testtoolDestroy(t, base, c)
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("3EaW6WibLi9gl03_UieiFPaFcPy5p4x3JPxrnLJxGaTI-bh3HU9DK9IMx7c3rrNm")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantOfflineEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantOfflineEncode + "/check": {Mode: 0400, Data: []byte{0}},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/kvJIqZo5DKFOxC2ZQ-8_nPaQzEAz9cIm3p6guO-uLqm-xaiPu7oRkSnsu411jd_U": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
"identifier/" + expected.Promote: {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantOfflineEncode)},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"binfmt", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
|
||||||
if info.CanDegrade && os.Getenv("ROSA_SKIP_BINFMT") != "" {
|
|
||||||
t.Skip("binfmt_misc test explicitly skipped")
|
|
||||||
}
|
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
|
||||||
{"container", pkg.NewExec(
|
|
||||||
"exec-binfmt", "cafe", nil, 0, true,
|
|
||||||
pkg.AbsWork,
|
|
||||||
[]string{"HAKUREI_TEST=1", "HAKUREI_BINFMT=1"},
|
|
||||||
check.MustAbs("/opt/bin/sample"),
|
|
||||||
[]string{"sample"},
|
|
||||||
|
|
||||||
pkg.MustPath("/", true, &stubArtifact{
|
|
||||||
kind: pkg.KindTar,
|
|
||||||
params: []byte("empty directory"),
|
|
||||||
cure: func(t *pkg.TContext) error {
|
|
||||||
return os.MkdirAll(t.GetWorkDir().String(), 0700)
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
pkg.MustPath("/opt", false, overrideIdent{pkg.ID{0xfe, 0xff}, &stubArtifact{
|
|
||||||
kind: pkg.KindTar,
|
|
||||||
cure: func(t *pkg.TContext) error {
|
|
||||||
work := t.GetWorkDir()
|
|
||||||
if err := os.MkdirAll(
|
|
||||||
work.Append("bin").String(),
|
|
||||||
0700,
|
|
||||||
); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.WriteFile(t.GetWorkDir().Append(
|
|
||||||
"bin",
|
|
||||||
"sample",
|
|
||||||
).String(), []byte(expected.Full), 0500)
|
|
||||||
},
|
|
||||||
}}),
|
|
||||||
), ignorePathname, expectsFS{
|
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"check": {Mode: 0400, Data: []byte("binfmt")},
|
|
||||||
}, nil},
|
|
||||||
})
|
|
||||||
}, expectsFS{
|
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/5aevg3YpDxjqQZ-pdvXK7YqgkL5JKqcoStYQxeD96kuYar6K2mRQWMHib6NQRnpV": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/5aevg3YpDxjqQZ-pdvXK7YqgkL5JKqcoStYQxeD96kuYar6K2mRQWMHib6NQRnpV/bin": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/5aevg3YpDxjqQZ-pdvXK7YqgkL5JKqcoStYQxeD96kuYar6K2mRQWMHib6NQRnpV/bin/sample": {Mode: 0500, Data: []byte("\xca\xfe\xba\xbe\xfd\xfd:3")},
|
|
||||||
"checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3/check": {Mode: 0400, Data: []byte("binfmt")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/6VQTJ1lI5BmVuI1YFYJ8ClO3MRORvTTrcWFDcUU-l5Ga8EofxCxGlSTYN-u8dKj_": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/UnDo4B5KneEUY5b4vRUk_y9MWgkWuw2N8f8a2XayO686xXur-aZmX2-7n_8tKMe3")},
|
|
||||||
"identifier/_v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/5aevg3YpDxjqQZ-pdvXK7YqgkL5JKqcoStYQxeD96kuYar6K2mRQWMHib6NQRnpV")},
|
|
||||||
"identifier/vjz1MHPcGBKV7sjcs8jQP3cqxJ1hgPTiQBMCEHP9BGXjGxd-tJmEmXKaStObo5gK": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU")},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package pkg_test
|
package pkg_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/fs"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
@@ -11,25 +10,18 @@ import (
|
|||||||
func TestFile(t *testing.T) {
|
func TestFile(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
want := expectsFile{0}
|
|
||||||
checkWithCache(t, []cacheTestCase{
|
checkWithCache(t, []cacheTestCase{
|
||||||
{"file", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"file", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"short", pkg.NewFile("null", []byte{0}), base.Append(
|
{"short", pkg.NewFile("null", []byte{0}), base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi",
|
"3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi",
|
||||||
), want, nil},
|
), pkg.MustDecode(
|
||||||
|
"vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX",
|
||||||
|
), nil},
|
||||||
})
|
})
|
||||||
}, expectsFS{
|
}, pkg.MustDecode(
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
"iR6H5OIsyOW4EwEgtm9rGzGF6DVtyHLySEtwnFE8bnus9VJcoCbR4JIek7Lw-vwT",
|
||||||
|
)},
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + pkg.Encode(want.hash()): {Mode: 0400, Data: []byte{0}},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/3376ALA7hIUm2LbzH2fDvRezgzod1eTK_G6XjyOgbM2u-6swvkFaF0BOwSl_juBi": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
// Package expected contains data shared between test helper and test harness.
|
|
||||||
package expected
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Magic are magic bytes in the binfmt test case.
|
|
||||||
Magic = "\xca\xfe\xba\xbe\xfd\xfd"
|
|
||||||
// Full is the full content of the binfmt test case executable.
|
|
||||||
Full = Magic + ":3"
|
|
||||||
)
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package expected
|
|
||||||
|
|
||||||
const (
|
|
||||||
Offline = "oe7Uv1u5BwxcuX3HLQzZRg1Q5oetJo6jWiKGMOeqLiqBkaVgyKzvx82N81_IzUAz"
|
|
||||||
OvlRoot = "NacZGXwuRkTvcHaG08a22ujJ8qCWN0RSoFlRSR5FSt0ZcBbJ28FRvkYsHEtX7G8i"
|
|
||||||
Layers = "WBJDrATtX6rIE5yAu8ePX3WmDF0Tt9kFiue0m3cRnyRoVx1my8a67fh3CAW486oP"
|
|
||||||
Net = "CmYtj2sNB3LHtqiDuck_Lz3MjLLIiwyP8N4NDitQ1Icvv__LVP9p8tm-sHeQaKKp"
|
|
||||||
Promote = "TX3eCloaQFkV-SZIH6Jg6E5WKH--rcXY1P0jnZKmLFKWrNqnOzd4G9eIBh6i5ywN"
|
|
||||||
Work = "OuNiLSC68pZhAOr1YQ4WbV1tzASA0nxLEBcK7lO7MqxDY_j8dmP_C612RTuF23Lu"
|
|
||||||
)
|
|
||||||
@@ -432,12 +432,6 @@ func (e InvalidKindError) Error() string {
|
|||||||
// register is not safe for concurrent use. register must not be called after
|
// register is not safe for concurrent use. register must not be called after
|
||||||
// the first instance of [Cache] has been opened.
|
// the first instance of [Cache] has been opened.
|
||||||
func register(k Kind, f IRReadFunc) {
|
func register(k Kind, f IRReadFunc) {
|
||||||
openMu.Lock()
|
|
||||||
defer openMu.Unlock()
|
|
||||||
|
|
||||||
if opened {
|
|
||||||
panic("attempting to register after open")
|
|
||||||
}
|
|
||||||
if _, ok := irArtifact[k]; ok {
|
if _, ok := irArtifact[k]; ok {
|
||||||
panic("attempting to register " + strconv.Itoa(int(k)) + " twice")
|
panic("attempting to register " + strconv.Itoa(int(k)) + " twice")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package pkg_test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -39,7 +38,7 @@ func TestIRRoundtrip(t *testing.T) {
|
|||||||
)},
|
)},
|
||||||
|
|
||||||
{"exec offline", pkg.NewExec(
|
{"exec offline", pkg.NewExec(
|
||||||
"exec-offline", "", nil, 0, false,
|
"exec-offline", nil, 0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
[]string{"HAKUREI_TEST=1"},
|
[]string{"HAKUREI_TEST=1"},
|
||||||
check.MustAbs("/opt/bin/testtool"),
|
check.MustAbs("/opt/bin/testtool"),
|
||||||
@@ -59,7 +58,7 @@ func TestIRRoundtrip(t *testing.T) {
|
|||||||
)},
|
)},
|
||||||
|
|
||||||
{"exec net", pkg.NewExec(
|
{"exec net", pkg.NewExec(
|
||||||
"exec-net", "",
|
"exec-net",
|
||||||
(*pkg.Checksum)(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
|
(*pkg.Checksum)(bytes.Repeat([]byte{0xfc}, len(pkg.Checksum{}))),
|
||||||
0, false,
|
0, false,
|
||||||
pkg.AbsWork,
|
pkg.AbsWork,
|
||||||
@@ -106,12 +105,9 @@ func TestIRRoundtrip(t *testing.T) {
|
|||||||
if err := <-done; err != nil {
|
if err := <-done; err != nil {
|
||||||
t.Fatalf("EncodeAll: error = %v", err)
|
t.Fatalf("EncodeAll: error = %v", err)
|
||||||
}
|
}
|
||||||
}, expectsFS{
|
}, pkg.MustDecode(
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
"E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C",
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
),
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkWithCache(t, testCasesCache)
|
checkWithCache(t, testCasesCache)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package pkg_test
|
|||||||
import (
|
import (
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -86,12 +85,7 @@ func TestHTTPGet(t *testing.T) {
|
|||||||
if _, err := f.Cure(r); !reflect.DeepEqual(err, wantErrNotFound) {
|
if _, err := f.Cure(r); !reflect.DeepEqual(err, wantErrNotFound) {
|
||||||
t.Fatalf("Cure: error = %#v, want %#v", err, wantErrNotFound)
|
t.Fatalf("Cure: error = %#v, want %#v", err, wantErrNotFound)
|
||||||
}
|
}
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"cure", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"cure", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
r := newRContext(t, c)
|
r := newRContext(t, c)
|
||||||
@@ -150,16 +144,6 @@ func TestHTTPGet(t *testing.T) {
|
|||||||
if _, _, err := c.Cure(f); !reflect.DeepEqual(err, wantErrNotFound) {
|
if _, _, err := c.Cure(f); !reflect.DeepEqual(err, wantErrNotFound) {
|
||||||
t.Fatalf("Pathname: error = %#v, want %#v", err, wantErrNotFound)
|
t.Fatalf("Pathname: error = %#v, want %#v", err, wantErrNotFound)
|
||||||
}
|
}
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("L_0RFHpr9JUS4Zp14rz2dESSRvfLzpvqsLhR1-YjQt8hYlmEdVl7vI3_-v8UNPKs")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU": {Mode: 0400, Data: []byte("\x7f\xe1\x69\xa2\xdd\x63\x96\x26\x83\x79\x61\x8b\xf0\x3f\xd5\x16\x9a\x39\x3a\xdb\xcf\xb1\xbc\x8d\x33\xff\x75\xee\x62\x56\xa9\xf0\x27\xac\x13\x94\x69")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/oM-2pUlk-mOxK1t3aMWZer69UdOQlAXiAgMrpZ1476VoOqpYVP1aGFS9_HYy-D8_": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU")},
|
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -71,64 +70,6 @@ func MustDecode(s string) (checksum Checksum) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// extension is a string uniquely identifying a set of custom [Artifact]
|
|
||||||
// implementations registered by calling [Register].
|
|
||||||
extension string
|
|
||||||
|
|
||||||
// openMu synchronises access to global state for initialisation.
|
|
||||||
openMu sync.Mutex
|
|
||||||
// opened is false if [Open] was never called.
|
|
||||||
opened bool
|
|
||||||
)
|
|
||||||
|
|
||||||
// Extension returns a string uniquely identifying the currently registered set
|
|
||||||
// of custom [Artifact], or the zero value if none was registered.
|
|
||||||
func Extension() string { return extension }
|
|
||||||
|
|
||||||
// ValidExtension returns whether s is valid for use in a call to SetExtension.
|
|
||||||
func ValidExtension(s string) bool {
|
|
||||||
if l := len(s); l == 0 || l > 128 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, v := range s {
|
|
||||||
if v < 'a' || v > 'z' {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrInvalidExtension is returned for a variant identification string for which
|
|
||||||
// [ValidExtension] returns false.
|
|
||||||
var ErrInvalidExtension = errors.New("invalid extension variant identification string")
|
|
||||||
|
|
||||||
// SetExtension sets the extension variant identification string. SetExtension
|
|
||||||
// must be called before [Open] if custom [Artifact] implementations had been
|
|
||||||
// recorded by calling [Register].
|
|
||||||
//
|
|
||||||
// The variant identification string must be between 1 and 128 bytes long and
|
|
||||||
// consists of only bytes between 'a' and 'z'.
|
|
||||||
//
|
|
||||||
// SetExtension is not safe for concurrent use. SetExtension is called at most
|
|
||||||
// once and must not be called after the first instance of Cache has been opened.
|
|
||||||
func SetExtension(s string) {
|
|
||||||
openMu.Lock()
|
|
||||||
defer openMu.Unlock()
|
|
||||||
|
|
||||||
if opened {
|
|
||||||
panic("attempting to set extension after open")
|
|
||||||
}
|
|
||||||
if extension != "" {
|
|
||||||
panic("attempting to set extension twice")
|
|
||||||
}
|
|
||||||
if !ValidExtension(s) {
|
|
||||||
panic(ErrInvalidExtension)
|
|
||||||
}
|
|
||||||
extension = s
|
|
||||||
statusHeader = makeStatusHeader(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// common holds elements and receives methods shared between different contexts.
|
// common holds elements and receives methods shared between different contexts.
|
||||||
type common struct {
|
type common struct {
|
||||||
// Context specific to this [Artifact]. The toplevel context in [Cache] must
|
// Context specific to this [Artifact]. The toplevel context in [Cache] must
|
||||||
@@ -161,27 +102,19 @@ type TContext struct {
|
|||||||
common
|
common
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeStatusHeader creates the header written to every status file. This should
|
// statusHeader is the header written to all status files in dirStatus.
|
||||||
// not be called directly, its result is stored in statusHeader and will not
|
var statusHeader = func() string {
|
||||||
// change after the first [Cache] is opened.
|
|
||||||
func makeStatusHeader(extension string) string {
|
|
||||||
s := programName
|
s := programName
|
||||||
if v := info.Version(); v != info.FallbackVersion {
|
if v := info.Version(); v != info.FallbackVersion {
|
||||||
s += " " + v
|
s += " " + v
|
||||||
}
|
}
|
||||||
if extension != "" {
|
|
||||||
s += " with " + extension + " extensions"
|
|
||||||
}
|
|
||||||
s += " (" + runtime.GOARCH + ")"
|
s += " (" + runtime.GOARCH + ")"
|
||||||
if name, err := os.Hostname(); err == nil {
|
if name, err := os.Hostname(); err == nil {
|
||||||
s += " on " + name
|
s += " on " + name
|
||||||
}
|
}
|
||||||
s += "\n\n"
|
s += "\n\n"
|
||||||
return s
|
return s
|
||||||
}
|
}()
|
||||||
|
|
||||||
// statusHeader is the header written to all status files in dirStatus.
|
|
||||||
var statusHeader = makeStatusHeader("")
|
|
||||||
|
|
||||||
// prepareStatus initialises the status file once.
|
// prepareStatus initialises the status file once.
|
||||||
func (t *TContext) prepareStatus() error {
|
func (t *TContext) prepareStatus() error {
|
||||||
@@ -494,9 +427,6 @@ const (
|
|||||||
// KindFile is the kind of [Artifact] returned by [NewFile].
|
// KindFile is the kind of [Artifact] returned by [NewFile].
|
||||||
KindFile
|
KindFile
|
||||||
|
|
||||||
// _kindEnd is the total number of kinds and does not denote a kind.
|
|
||||||
_kindEnd
|
|
||||||
|
|
||||||
// KindCustomOffset is the first [Kind] value reserved for implementations
|
// KindCustomOffset is the first [Kind] value reserved for implementations
|
||||||
// not from this package.
|
// not from this package.
|
||||||
KindCustomOffset = 1 << 31
|
KindCustomOffset = 1 << 31
|
||||||
@@ -511,9 +441,6 @@ const (
|
|||||||
// fileLock is the file name appended to Cache.base for guaranteeing
|
// fileLock is the file name appended to Cache.base for guaranteeing
|
||||||
// exclusive access to the cache directory.
|
// exclusive access to the cache directory.
|
||||||
fileLock = "lock"
|
fileLock = "lock"
|
||||||
// fileVariant is the file name appended to Cache.base holding the variant
|
|
||||||
// identification string set by a prior call to [SetExtension].
|
|
||||||
fileVariant = "variant"
|
|
||||||
|
|
||||||
// dirIdentifier is the directory name appended to Cache.base for storing
|
// dirIdentifier is the directory name appended to Cache.base for storing
|
||||||
// artifacts named after their [ID].
|
// artifacts named after their [ID].
|
||||||
@@ -613,14 +540,6 @@ const (
|
|||||||
// impurity due to [KindExecNet] being [KnownChecksum]. This flag exists
|
// impurity due to [KindExecNet] being [KnownChecksum]. This flag exists
|
||||||
// to support kernels without Landlock LSM enabled.
|
// to support kernels without Landlock LSM enabled.
|
||||||
CHostAbstract
|
CHostAbstract
|
||||||
|
|
||||||
// CPromoteVariant allows [pkg.Open] to promote an unextended on-disk cache
|
|
||||||
// to the current extension variant. This is a one-way operation.
|
|
||||||
CPromoteVariant
|
|
||||||
|
|
||||||
// CSuppressInit arranges for verbose output of the container init to be
|
|
||||||
// suppressed regardless of [message.Msg] state.
|
|
||||||
CSuppressInit
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// toplevel holds [context.WithCancel] over caller-supplied context, where all
|
// toplevel holds [context.WithCancel] over caller-supplied context, where all
|
||||||
@@ -2011,20 +1930,6 @@ func (c *Cache) Close() {
|
|||||||
c.unlock()
|
c.unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsupportedVariantError describes an on-disk cache with an extension variant
|
|
||||||
// identification string that differs from the value returned by [Extension].
|
|
||||||
type UnsupportedVariantError string
|
|
||||||
|
|
||||||
func (e UnsupportedVariantError) Error() string {
|
|
||||||
return "unsupported variant " + strconv.Quote(string(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrWouldPromote is returned by [Open] if the [CPromoteVariant] bit is not
|
|
||||||
// set and the on-disk cache requires variant promotion.
|
|
||||||
ErrWouldPromote = errors.New("operation would promote unextended cache")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Open returns the address of a newly opened instance of [Cache].
|
// Open returns the address of a newly opened instance of [Cache].
|
||||||
//
|
//
|
||||||
// Concurrent cures of a [FloodArtifact] dependency graph is limited to the
|
// Concurrent cures of a [FloodArtifact] dependency graph is limited to the
|
||||||
@@ -2056,14 +1961,6 @@ func open(
|
|||||||
base *check.Absolute,
|
base *check.Absolute,
|
||||||
lock bool,
|
lock bool,
|
||||||
) (*Cache, error) {
|
) (*Cache, error) {
|
||||||
openMu.Lock()
|
|
||||||
defer openMu.Unlock()
|
|
||||||
opened = true
|
|
||||||
|
|
||||||
if extension == "" && len(irArtifact) != int(_kindEnd) {
|
|
||||||
panic("attempting to open cache with incomplete variant setup")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cures < 1 {
|
if cures < 1 {
|
||||||
cures = runtime.NumCPU()
|
cures = runtime.NumCPU()
|
||||||
}
|
}
|
||||||
@@ -2077,10 +1974,8 @@ func open(
|
|||||||
dirStatus,
|
dirStatus,
|
||||||
dirWork,
|
dirWork,
|
||||||
} {
|
} {
|
||||||
if err := os.MkdirAll(
|
if err := os.MkdirAll(base.Append(name).String(), 0700); err != nil &&
|
||||||
base.Append(name).String(),
|
!errors.Is(err, os.ErrExist) {
|
||||||
0700,
|
|
||||||
); err != nil && !errors.Is(err, os.ErrExist) {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2118,45 +2013,6 @@ func open(
|
|||||||
c.unlock = func() {}
|
c.unlock = func() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
variantPath := base.Append(fileVariant).String()
|
|
||||||
if p, err := os.ReadFile(variantPath); err != nil {
|
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
|
||||||
c.unlock()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// nonexistence implies newly created cache, or a cache predating
|
|
||||||
// variant identification strings, in which case it is silently promoted
|
|
||||||
if err = os.WriteFile(
|
|
||||||
variantPath,
|
|
||||||
[]byte(extension),
|
|
||||||
0400,
|
|
||||||
); err != nil {
|
|
||||||
c.unlock()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else if s := string(p); s == "" {
|
|
||||||
if extension != "" {
|
|
||||||
if flags&CPromoteVariant == 0 {
|
|
||||||
c.unlock()
|
|
||||||
return nil, ErrWouldPromote
|
|
||||||
}
|
|
||||||
if err = os.WriteFile(
|
|
||||||
variantPath,
|
|
||||||
[]byte(extension),
|
|
||||||
0400,
|
|
||||||
); err != nil {
|
|
||||||
c.unlock()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if !ValidExtension(s) {
|
|
||||||
c.unlock()
|
|
||||||
return nil, ErrInvalidExtension
|
|
||||||
} else if s != extension {
|
|
||||||
c.unlock()
|
|
||||||
return nil, UnsupportedVariantError(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"testing/fstest"
|
|
||||||
"unique"
|
"unique"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@@ -43,25 +41,6 @@ func unsafeOpen(
|
|||||||
lock bool,
|
lock bool,
|
||||||
) (*pkg.Cache, error)
|
) (*pkg.Cache, error)
|
||||||
|
|
||||||
var (
|
|
||||||
// extension is a string uniquely identifying a set of custom [Artifact]
|
|
||||||
// implementations registered by calling [Register].
|
|
||||||
//
|
|
||||||
//go:linkname extension hakurei.app/internal/pkg.extension
|
|
||||||
extension string
|
|
||||||
|
|
||||||
// opened is false if [Open] was never called.
|
|
||||||
//
|
|
||||||
//go:linkname opened hakurei.app/internal/pkg.opened
|
|
||||||
opened bool
|
|
||||||
|
|
||||||
// irArtifact refers to artifact IR interpretation functions and must not be
|
|
||||||
// written to directly.
|
|
||||||
//
|
|
||||||
//go:linkname irArtifact hakurei.app/internal/pkg.irArtifact
|
|
||||||
irArtifact map[pkg.Kind]pkg.IRReadFunc
|
|
||||||
)
|
|
||||||
|
|
||||||
// newRContext returns the address of a new [pkg.RContext] unsafely created for
|
// newRContext returns the address of a new [pkg.RContext] unsafely created for
|
||||||
// the specified [testing.TB].
|
// the specified [testing.TB].
|
||||||
func newRContext(tb testing.TB, c *pkg.Cache) *pkg.RContext {
|
func newRContext(tb testing.TB, c *pkg.Cache) *pkg.RContext {
|
||||||
@@ -288,99 +267,6 @@ func TestIdent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An expectsKnown describes an expected file or directory.
|
|
||||||
type expectsKnown interface {
|
|
||||||
// hash returns the checksum of the represented data.
|
|
||||||
hash() (checksum pkg.Checksum)
|
|
||||||
}
|
|
||||||
|
|
||||||
// An expectsChecksum is a prepared checksum value.
|
|
||||||
type expectsChecksum pkg.Checksum
|
|
||||||
|
|
||||||
// hash returns e.
|
|
||||||
func (e expectsChecksum) hash() pkg.Checksum { return e }
|
|
||||||
|
|
||||||
// An expectsFile is the contents of a file expected by the test suite.
|
|
||||||
type expectsFile []byte
|
|
||||||
|
|
||||||
// hash computes the checksum of e.
|
|
||||||
func (e expectsFile) hash() (checksum pkg.Checksum) {
|
|
||||||
h := sha512.New384()
|
|
||||||
h.Write(e)
|
|
||||||
h.Sum(checksum[:0])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// An expectsFS describes the state of a filesystem expected by the test suite.
|
|
||||||
type expectsFS fstest.MapFS
|
|
||||||
|
|
||||||
// hash computes the checksum of e.
|
|
||||||
func (e expectsFS) hash() (checksum pkg.Checksum) {
|
|
||||||
if err := pkg.HashFS(&checksum, fstest.MapFS(e), "."); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// expectsFrom generates expectsFS for a filesystem directory.
|
|
||||||
func expectsFrom(pathname string) string {
|
|
||||||
var buf strings.Builder
|
|
||||||
buf.WriteString("expectsFS{\n")
|
|
||||||
if err := filepath.WalkDir(pathname, func(path string, d fs.DirEntry, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var rel string
|
|
||||||
if rel, err = filepath.Rel(pathname, path); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
buf.WriteString("\t" + strconv.Quote(rel) + ": {Mode: ")
|
|
||||||
|
|
||||||
var fi fs.FileInfo
|
|
||||||
if fi, err = d.Info(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
mode := fi.Mode()
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case mode.IsDir():
|
|
||||||
buf.WriteString("fs.ModeDir | 0" +
|
|
||||||
strconv.FormatInt(int64(mode&^fs.ModeDir), 8))
|
|
||||||
|
|
||||||
case mode&fs.ModeSymlink != 0:
|
|
||||||
buf.WriteString("fs.ModeSymlink | 0" +
|
|
||||||
strconv.FormatInt(int64(mode&^fs.ModeSymlink), 8) +
|
|
||||||
", Data: []byte(")
|
|
||||||
var linkname string
|
|
||||||
if linkname, err = os.Readlink(path); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
buf.WriteString(strconv.Quote(linkname))
|
|
||||||
buf.WriteByte(')')
|
|
||||||
|
|
||||||
case mode.IsRegular():
|
|
||||||
buf.WriteString("0" + strconv.FormatInt(int64(mode), 8))
|
|
||||||
var p []byte
|
|
||||||
if p, err = os.ReadFile(path); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p) > 0 {
|
|
||||||
buf.WriteString(", Data: []byte(")
|
|
||||||
buf.WriteString(strconv.Quote(unsafe.String(unsafe.SliceData(p), len(p))))
|
|
||||||
buf.WriteByte(')')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf.WriteString("},\n")
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
buf.WriteString("}")
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// cacheTestCase is a test case passed to checkWithCache where a new instance
|
// cacheTestCase is a test case passed to checkWithCache where a new instance
|
||||||
// of [pkg.Cache] is prepared for the test case, and is validated and removed
|
// of [pkg.Cache] is prepared for the test case, and is validated and removed
|
||||||
// on test completion.
|
// on test completion.
|
||||||
@@ -389,7 +275,7 @@ type cacheTestCase struct {
|
|||||||
flags int
|
flags int
|
||||||
early func(t *testing.T, base *check.Absolute)
|
early func(t *testing.T, base *check.Absolute)
|
||||||
f func(t *testing.T, base *check.Absolute, c *pkg.Cache)
|
f func(t *testing.T, base *check.Absolute, c *pkg.Cache)
|
||||||
want expectsFS
|
want pkg.Checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkWithCache runs a slice of cacheTestCase.
|
// checkWithCache runs a slice of cacheTestCase.
|
||||||
@@ -423,7 +309,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
|
|||||||
msg := message.New(log.New(os.Stderr, "cache: ", 0))
|
msg := message.New(log.New(os.Stderr, "cache: ", 0))
|
||||||
msg.SwapVerbose(testing.Verbose())
|
msg.SwapVerbose(testing.Verbose())
|
||||||
|
|
||||||
flags := tc.flags | pkg.CSuppressInit
|
flags := tc.flags
|
||||||
|
|
||||||
if info.CanDegrade {
|
if info.CanDegrade {
|
||||||
if _, err := landlock.GetABI(); err != nil {
|
if _, err := landlock.GetABI(); err != nil {
|
||||||
@@ -456,33 +342,24 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
|
|||||||
restoreTemp = true
|
restoreTemp = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy lock and variant file to avoid changing cache checksums
|
// destroy lock file to avoid changing cache checksums
|
||||||
for _, s := range []string{
|
if err := os.Remove(base.Append("lock").String()); err != nil {
|
||||||
"lock",
|
|
||||||
"variant",
|
|
||||||
} {
|
|
||||||
pathname := base.Append(s)
|
|
||||||
if p, err := os.ReadFile(pathname.String()); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
} else if len(p) != 0 {
|
|
||||||
t.Fatalf("file %q: %q", s, string(p))
|
|
||||||
}
|
|
||||||
if err := os.Remove(pathname.String()); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy non-deterministic status files
|
// destroy non-deterministic status files
|
||||||
if err := os.RemoveAll(base.Append("status").String()); err != nil {
|
if err := os.RemoveAll(base.Append("status").String()); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := tc.want.hash()
|
|
||||||
|
|
||||||
var checksum pkg.Checksum
|
var checksum pkg.Checksum
|
||||||
if err := pkg.HashDir(&checksum, base); err != nil {
|
if err := pkg.HashDir(&checksum, base); err != nil {
|
||||||
t.Fatalf("HashDir: error = %v", err)
|
t.Fatalf("HashDir: error = %v", err)
|
||||||
} else if checksum != want {
|
} else if checksum != tc.want {
|
||||||
t.Fatal(expectsFrom(base.String()))
|
t.Fatalf("HashDir: %v", &pkg.ChecksumMismatchError{
|
||||||
|
Got: checksum,
|
||||||
|
Want: tc.want,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scrubFunc(); err != nil {
|
if err := scrubFunc(); err != nil {
|
||||||
@@ -501,10 +378,10 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
|
|||||||
// validate again to make sure scrub did not condemn anything
|
// validate again to make sure scrub did not condemn anything
|
||||||
if err := pkg.HashDir(&checksum, base); err != nil {
|
if err := pkg.HashDir(&checksum, base); err != nil {
|
||||||
t.Fatalf("HashDir: error = %v", err)
|
t.Fatalf("HashDir: error = %v", err)
|
||||||
} else if checksum != want {
|
} else if checksum != tc.want {
|
||||||
t.Fatalf("(scrubbed) HashDir: %v", &pkg.ChecksumMismatchError{
|
t.Fatalf("(scrubbed) HashDir: %v", &pkg.ChecksumMismatchError{
|
||||||
Got: checksum,
|
Got: checksum,
|
||||||
Want: want,
|
Want: tc.want,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -518,7 +395,7 @@ type cureStep struct {
|
|||||||
a pkg.Artifact
|
a pkg.Artifact
|
||||||
|
|
||||||
pathname *check.Absolute
|
pathname *check.Absolute
|
||||||
output expectsKnown
|
checksum pkg.Checksum
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,16 +419,14 @@ func cureMany(t *testing.T, c *pkg.Cache, steps []cureStep) {
|
|||||||
t.Fatalf("Cure: error = %v, want %v", err, step.err)
|
t.Fatalf("Cure: error = %v, want %v", err, step.err)
|
||||||
} else if step.pathname != ignorePathname && !pathname.Is(step.pathname) {
|
} else if step.pathname != ignorePathname && !pathname.Is(step.pathname) {
|
||||||
t.Fatalf("Cure: pathname = %q, want %q", pathname, step.pathname)
|
t.Fatalf("Cure: pathname = %q, want %q", pathname, step.pathname)
|
||||||
} else if step.output == nil || checksum != makeChecksumH(step.output.hash()) {
|
} else if checksum != makeChecksumH(step.checksum) {
|
||||||
if pathname != nil {
|
if checksum == (unique.Handle[pkg.Checksum]{}) {
|
||||||
if name, _err := filepath.EvalSymlinks(pathname.String()); _err != nil {
|
checksum = unique.Make(pkg.Checksum{})
|
||||||
t.Fatal(_err)
|
|
||||||
} else {
|
|
||||||
t.Fatal(expectsFrom(name))
|
|
||||||
}
|
|
||||||
} else if checksum != (unique.Handle[pkg.Checksum]{}) {
|
|
||||||
t.Fatalf("Cure: unexpected checksum %s", pkg.Encode(checksum.Value()))
|
|
||||||
}
|
}
|
||||||
|
t.Fatalf(
|
||||||
|
"Cure: checksum = %s, want %s",
|
||||||
|
pkg.Encode(checksum.Value()), pkg.Encode(step.checksum),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
v := any(err)
|
v := any(err)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -612,12 +487,18 @@ func newWantScrubError(base *check.Absolute) *pkg.ScrubError {
|
|||||||
func TestCache(t *testing.T) {
|
func TestCache(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testdata := expectsFile("" +
|
const testdata = "" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\xad\x0b\x00" +
|
"\xad\x0b\x00" +
|
||||||
"\x04" +
|
"\x04" +
|
||||||
"\xfe\xfe\x00\x00" +
|
"\xfe\xfe\x00\x00" +
|
||||||
"\xfe\xca\x00\x00")
|
"\xfe\xca\x00\x00"
|
||||||
|
|
||||||
|
testdataChecksum := func() pkg.Checksum {
|
||||||
|
h := sha512.New384()
|
||||||
|
h.Write([]byte(testdata))
|
||||||
|
return (pkg.Checksum)(h.Sum(nil))
|
||||||
|
}()
|
||||||
|
|
||||||
testCases := []cacheTestCase{
|
testCases := []cacheTestCase{
|
||||||
{"file", pkg.CValidateKnown | pkg.CAssumeChecksum, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"file", pkg.CValidateKnown | pkg.CAssumeChecksum, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
@@ -640,31 +521,31 @@ func TestCache(t *testing.T) {
|
|||||||
{"initial file", newStubFile(
|
{"initial file", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
identifier,
|
identifier,
|
||||||
new(testdata.hash()),
|
&testdataChecksum,
|
||||||
testdata, nil,
|
[]byte(testdata), nil,
|
||||||
), wantPathname, testdata, nil},
|
), wantPathname, testdataChecksum, nil},
|
||||||
|
|
||||||
{"identical content", newStubFile(
|
{"identical content", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
identifier0,
|
identifier0,
|
||||||
new(testdata.hash()),
|
&testdataChecksum,
|
||||||
testdata, nil,
|
[]byte(testdata), nil,
|
||||||
), wantPathname0, testdata, nil},
|
), wantPathname0, testdataChecksum, nil},
|
||||||
|
|
||||||
{"existing entry", newStubFile(
|
{"existing entry", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
identifier,
|
identifier,
|
||||||
new(testdata.hash()),
|
&testdataChecksum,
|
||||||
testdata, nil,
|
[]byte(testdata), nil,
|
||||||
), wantPathname, testdata, nil},
|
), wantPathname, testdataChecksum, nil},
|
||||||
|
|
||||||
{"checksum mismatch", newStubFile(
|
{"checksum mismatch", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
pkg.ID{0xff, 0},
|
pkg.ID{0xff, 0},
|
||||||
new(pkg.Checksum),
|
new(pkg.Checksum),
|
||||||
testdata, nil,
|
[]byte(testdata), nil,
|
||||||
), nil, nil, &pkg.ChecksumMismatchError{
|
), nil, pkg.Checksum{}, &pkg.ChecksumMismatchError{
|
||||||
Got: testdata.hash(),
|
Got: testdataChecksum,
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"store without validation", newStubFile(
|
{"store without validation", newStubFile(
|
||||||
@@ -675,7 +556,7 @@ func TestCache(t *testing.T) {
|
|||||||
), base.Append(
|
), base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
"vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX",
|
"vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX",
|
||||||
), expectsChecksum{
|
), pkg.Checksum{
|
||||||
0xbe, 0xc0, 0x21, 0xb4, 0xf3, 0x68,
|
0xbe, 0xc0, 0x21, 0xb4, 0xf3, 0x68,
|
||||||
0xe3, 0x06, 0x91, 0x34, 0xe0, 0x12,
|
0xe3, 0x06, 0x91, 0x34, 0xe0, 0x12,
|
||||||
0xc2, 0xb4, 0x30, 0x70, 0x83, 0xd3,
|
0xc2, 0xb4, 0x30, 0x70, 0x83, 0xd3,
|
||||||
@@ -689,7 +570,7 @@ func TestCache(t *testing.T) {
|
|||||||
{"incomplete implementation", struct{ pkg.Artifact }{&stubArtifact{
|
{"incomplete implementation", struct{ pkg.Artifact }{&stubArtifact{
|
||||||
kind: pkg.KindExec,
|
kind: pkg.KindExec,
|
||||||
params: []byte("artifact overridden to be incomplete"),
|
params: []byte("artifact overridden to be incomplete"),
|
||||||
}}, nil, nil, pkg.InvalidArtifactError(pkg.MustDecode(
|
}}, nil, pkg.Checksum{}, pkg.InvalidArtifactError(pkg.MustDecode(
|
||||||
"E__uZ1sLIvb84vzSm5Uezb03RogsiaeTt1nfIVv8TKnnf4LqwtSi-smdHhlkZrUJ",
|
"E__uZ1sLIvb84vzSm5Uezb03RogsiaeTt1nfIVv8TKnnf4LqwtSi-smdHhlkZrUJ",
|
||||||
))},
|
))},
|
||||||
|
|
||||||
@@ -698,18 +579,18 @@ func TestCache(t *testing.T) {
|
|||||||
pkg.ID{0xff, 1},
|
pkg.ID{0xff, 1},
|
||||||
nil,
|
nil,
|
||||||
nil, stub.UniqueError(0xcafe),
|
nil, stub.UniqueError(0xcafe),
|
||||||
), nil, nil, stub.UniqueError(0xcafe)},
|
), nil, pkg.Checksum{}, stub.UniqueError(0xcafe)},
|
||||||
|
|
||||||
{"error caching", newStubFile(
|
{"error caching", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
pkg.ID{0xff, 1},
|
pkg.ID{0xff, 1},
|
||||||
nil,
|
nil,
|
||||||
nil, nil,
|
nil, nil,
|
||||||
), nil, nil, stub.UniqueError(0xcafe)},
|
), nil, pkg.Checksum{}, stub.UniqueError(0xcafe)},
|
||||||
|
|
||||||
{"cache hit bad type", overrideChecksum{testdata.hash(), overrideIdent{pkg.ID{0xff, 2}, &stubArtifact{
|
{"cache hit bad type", overrideChecksum{testdataChecksum, overrideIdent{pkg.ID{0xff, 2}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
}}}, nil, nil, pkg.InvalidFileModeError(
|
}}}, nil, pkg.Checksum{}, pkg.InvalidFileModeError(
|
||||||
0400,
|
0400,
|
||||||
)},
|
)},
|
||||||
|
|
||||||
@@ -729,7 +610,7 @@ func TestCache(t *testing.T) {
|
|||||||
cure: func(f *pkg.FContext) error {
|
cure: func(f *pkg.FContext) error {
|
||||||
panic("attempting to cure impossible artifact")
|
panic("attempting to cure impossible artifact")
|
||||||
},
|
},
|
||||||
}, nil, nil, &pkg.DependencyCureError{
|
}, nil, pkg.Checksum{}, &pkg.DependencyCureError{
|
||||||
{
|
{
|
||||||
Ident: unique.Make(pkg.ID{0xff, 3}),
|
Ident: unique.Make(pkg.ID{0xff, 3}),
|
||||||
Err: struct {
|
Err: struct {
|
||||||
@@ -751,18 +632,18 @@ func TestCache(t *testing.T) {
|
|||||||
cureMany(t, c0, []cureStep{
|
cureMany(t, c0, []cureStep{
|
||||||
{"cache hit ident", overrideIdent{
|
{"cache hit ident", overrideIdent{
|
||||||
id: identifier,
|
id: identifier,
|
||||||
}, wantPathname, testdata, nil},
|
}, wantPathname, testdataChecksum, nil},
|
||||||
|
|
||||||
{"cache miss checksum match", newStubFile(
|
{"cache miss checksum match", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
testdata.hash(),
|
testdataChecksum,
|
||||||
nil,
|
nil,
|
||||||
testdata,
|
[]byte(testdata),
|
||||||
nil,
|
nil,
|
||||||
), base.Append(
|
), base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
pkg.Encode(testdata.hash()),
|
pkg.Encode(testdataChecksum),
|
||||||
), testdata, nil},
|
), testdataChecksum, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
// cure after close
|
// cure after close
|
||||||
@@ -775,21 +656,7 @@ func TestCache(t *testing.T) {
|
|||||||
t.Fatalf("(closed) Cure: error = %v", err)
|
t.Fatalf("(closed) Cure: error = %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("St9rlE-mGZ5gXwiv_hzQ_B8bZP-UUvSNmf4nHUZzCMOumb6hKnheZSe0dmnuc4Q2")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: 0400, Data: []byte{0}},
|
|
||||||
"checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq": {Mode: 0400, Data: []byte{0, 0, 0, 0, 0xad, 0xb, 0, 4, 0xfe, 0xfe, 0, 0, 0xfe, 0xca, 0, 0}},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")},
|
|
||||||
"identifier/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
|
||||||
"identifier/cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
|
||||||
"identifier/deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/0bSFPu5Tnd-2Jj0Mv6co23PW2t3BmHc7eLFj9TgY3eIBg8zislo7xZYNBqovVLcq")},
|
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"directory", pkg.CAssumeChecksum, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"directory", pkg.CAssumeChecksum, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
id := pkg.MustDecode(
|
id := pkg.MustDecode(
|
||||||
@@ -824,16 +691,9 @@ func TestCache(t *testing.T) {
|
|||||||
).String(),
|
).String(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
want := expectsFS{
|
wantChecksum := pkg.MustDecode(
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
"qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b",
|
||||||
|
)
|
||||||
"check": {Mode: 0400, Data: []byte{0, 0}},
|
|
||||||
|
|
||||||
"lib": {Mode: fs.ModeDir | 0700},
|
|
||||||
"lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
|
||||||
|
|
||||||
"lib/pkgconfig": {Mode: fs.ModeDir | 0700},
|
|
||||||
}
|
|
||||||
wantPathname := base.Append(
|
wantPathname := base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
pkg.Encode(id),
|
pkg.Encode(id),
|
||||||
@@ -887,33 +747,33 @@ func TestCache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"initial directory", overrideChecksum{want.hash(), overrideIdent{id, &stubArtifact{
|
{"initial directory", overrideChecksum{wantChecksum, overrideIdent{id, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: makeSample,
|
cure: makeSample,
|
||||||
}}}, wantPathname, want, nil},
|
}}}, wantPathname, wantChecksum, nil},
|
||||||
|
|
||||||
{"identical identifier", overrideChecksum{want.hash(), overrideIdent{id, &stubArtifact{
|
{"identical identifier", overrideChecksum{wantChecksum, overrideIdent{id, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
}}}, wantPathname, want, nil},
|
}}}, wantPathname, wantChecksum, nil},
|
||||||
|
|
||||||
{"identical checksum", overrideIdent{id0, &stubArtifact{
|
{"identical checksum", overrideIdent{id0, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: makeSample,
|
cure: makeSample,
|
||||||
}}, wantPathname0, want, nil},
|
}}, wantPathname0, wantChecksum, nil},
|
||||||
|
|
||||||
{"cure fault", overrideIdent{pkg.ID{0xff, 0}, &stubArtifact{
|
{"cure fault", overrideIdent{pkg.ID{0xff, 0}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return makeGarbage(t.GetWorkDir(), stub.UniqueError(0xcafe))
|
return makeGarbage(t.GetWorkDir(), stub.UniqueError(0xcafe))
|
||||||
},
|
},
|
||||||
}}, nil, nil, stub.UniqueError(0xcafe)},
|
}}, nil, pkg.Checksum{}, stub.UniqueError(0xcafe)},
|
||||||
|
|
||||||
{"checksum mismatch", overrideChecksum{pkg.Checksum{}, overrideIdent{pkg.ID{0xff, 1}, &stubArtifact{
|
{"checksum mismatch", overrideChecksum{pkg.Checksum{}, overrideIdent{pkg.ID{0xff, 1}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return makeGarbage(t.GetWorkDir(), nil)
|
return makeGarbage(t.GetWorkDir(), nil)
|
||||||
},
|
},
|
||||||
}}}, nil, nil, &pkg.ChecksumMismatchError{
|
}}}, nil, pkg.Checksum{}, &pkg.ChecksumMismatchError{
|
||||||
Got: pkg.MustDecode(
|
Got: pkg.MustDecode(
|
||||||
"CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT",
|
"CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT",
|
||||||
),
|
),
|
||||||
@@ -922,27 +782,27 @@ func TestCache(t *testing.T) {
|
|||||||
{"cache hit bad type", newStubFile(
|
{"cache hit bad type", newStubFile(
|
||||||
pkg.KindHTTPGet,
|
pkg.KindHTTPGet,
|
||||||
pkg.ID{0xff, 2},
|
pkg.ID{0xff, 2},
|
||||||
new(want.hash()),
|
&wantChecksum,
|
||||||
testdata, nil,
|
[]byte(testdata), nil,
|
||||||
), nil, nil, pkg.InvalidFileModeError(
|
), nil, pkg.Checksum{}, pkg.InvalidFileModeError(
|
||||||
fs.ModeDir | 0500,
|
fs.ModeDir | 0500,
|
||||||
)},
|
)},
|
||||||
|
|
||||||
{"openFile directory", overrideIdent{pkg.ID{0xff, 3}, &stubArtifact{
|
{"openFile directory", overrideIdent{pkg.ID{0xff, 3}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
r, err := t.Open(overrideChecksumFile{checksum: want.hash()})
|
r, err := t.Open(overrideChecksumFile{checksum: wantChecksum})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
_, err = io.ReadAll(r)
|
_, err = io.ReadAll(r)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
}}, nil, nil, &os.PathError{
|
}}, nil, pkg.Checksum{}, &os.PathError{
|
||||||
Op: "read",
|
Op: "read",
|
||||||
Path: base.Append(
|
Path: base.Append(
|
||||||
"checksum",
|
"checksum",
|
||||||
pkg.Encode(want.hash()),
|
pkg.Encode(wantChecksum),
|
||||||
).String(),
|
).String(),
|
||||||
Err: syscall.EISDIR,
|
Err: syscall.EISDIR,
|
||||||
}},
|
}},
|
||||||
@@ -952,14 +812,14 @@ func TestCache(t *testing.T) {
|
|||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}}, nil, nil, pkg.NoOutputError{}},
|
}}, nil, pkg.Checksum{}, pkg.NoOutputError{}},
|
||||||
|
|
||||||
{"file output", overrideIdent{pkg.ID{0xff, 5}, &stubArtifact{
|
{"file output", overrideIdent{pkg.ID{0xff, 5}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return os.WriteFile(t.GetWorkDir().String(), []byte{0}, 0400)
|
return os.WriteFile(t.GetWorkDir().String(), []byte{0}, 0400)
|
||||||
},
|
},
|
||||||
}}, nil, nil, errors.New("non-file artifact produced regular file")},
|
}}, nil, pkg.Checksum{}, errors.New("non-file artifact produced regular file")},
|
||||||
|
|
||||||
{"symlink output", overrideIdent{pkg.ID{0xff, 6}, &stubArtifact{
|
{"symlink output", overrideIdent{pkg.ID{0xff, 6}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
@@ -969,26 +829,11 @@ func TestCache(t *testing.T) {
|
|||||||
t.GetWorkDir().String(),
|
t.GetWorkDir().String(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}}, nil, nil, pkg.InvalidFileModeError(
|
}}, nil, pkg.Checksum{}, pkg.InvalidFileModeError(
|
||||||
fs.ModeSymlink | 0777,
|
fs.ModeSymlink | 0777,
|
||||||
)},
|
)},
|
||||||
})
|
})
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("WVpvsVqVKg9Nsh744x57h51AuWUoUR2nnh8Md-EYBQpk6ziyTuUn6PLtF2e0Eu_d")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/check": {Mode: 0400, Data: []byte{0, 0}},
|
|
||||||
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/pkgconfig": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
|
||||||
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")},
|
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"pending", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"pending", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
wantErr := stub.UniqueError(0xcafe)
|
wantErr := stub.UniqueError(0xcafe)
|
||||||
@@ -1024,7 +869,7 @@ func TestCache(t *testing.T) {
|
|||||||
pkg.ID{0xff, 1},
|
pkg.ID{0xff, 1},
|
||||||
nil,
|
nil,
|
||||||
nil, stub.UniqueError(0xbad),
|
nil, stub.UniqueError(0xbad),
|
||||||
), nil, nil, stub.UniqueError(0xbad)},
|
), nil, pkg.Checksum{}, stub.UniqueError(0xbad)},
|
||||||
|
|
||||||
{"file output", overrideIdent{pkg.ID{0xff, 2}, &stubArtifact{
|
{"file output", overrideIdent{pkg.ID{0xff, 2}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
@@ -1035,7 +880,7 @@ func TestCache(t *testing.T) {
|
|||||||
0400,
|
0400,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}}, nil, nil, errors.New(
|
}}, nil, pkg.Checksum{}, errors.New(
|
||||||
"non-file artifact produced regular file",
|
"non-file artifact produced regular file",
|
||||||
)},
|
)},
|
||||||
})
|
})
|
||||||
@@ -1057,12 +902,7 @@ func TestCache(t *testing.T) {
|
|||||||
for c.Done(unique.Make(pkg.ID{0xff})) != nil {
|
for c.Done(unique.Make(pkg.ID{0xff})) != nil {
|
||||||
}
|
}
|
||||||
<-wCureDone
|
<-wCureDone
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"cancel abort block", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"cancel abort block", pkg.CValidateKnown, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@@ -1115,12 +955,7 @@ func TestCache(t *testing.T) {
|
|||||||
|
|
||||||
c.Close()
|
c.Close()
|
||||||
c.Abort()
|
c.Abort()
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"no assume checksum", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"no assume checksum", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
makeGarbage := func(work *check.Absolute, wantErr error) error {
|
makeGarbage := func(work *check.Absolute, wantErr error) error {
|
||||||
@@ -1137,12 +972,10 @@ func TestCache(t *testing.T) {
|
|||||||
return wantErr
|
return wantErr
|
||||||
}
|
}
|
||||||
|
|
||||||
want := expectsChecksum(pkg.MustDecode(
|
wantChecksum := pkg.MustDecode("Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")
|
||||||
"Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M",
|
|
||||||
))
|
|
||||||
|
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
{"create", overrideChecksum{want.hash(), overrideIdent{pkg.ID{0xff, 0}, &stubArtifact{
|
{"create", overrideChecksum{wantChecksum, overrideIdent{pkg.ID{0xff, 0}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return makeGarbage(t.GetWorkDir(), nil)
|
return makeGarbage(t.GetWorkDir(), nil)
|
||||||
@@ -1150,16 +983,16 @@ func TestCache(t *testing.T) {
|
|||||||
}}}, base.Append(
|
}}}, base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
pkg.Encode(pkg.ID{0xff, 0}),
|
pkg.Encode(pkg.ID{0xff, 0}),
|
||||||
), want, nil},
|
), wantChecksum, nil},
|
||||||
|
|
||||||
{"reject", overrideChecksum{want.hash(), overrideIdent{pkg.ID{0xfe, 1}, &stubArtifact{
|
{"reject", overrideChecksum{wantChecksum, overrideIdent{pkg.ID{0xfe, 1}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return makeGarbage(t.GetWorkDir(), stub.UniqueError(0xbad))
|
return makeGarbage(t.GetWorkDir(), stub.UniqueError(0xbad))
|
||||||
},
|
},
|
||||||
}}}, nil, nil, stub.UniqueError(0xbad)},
|
}}}, nil, pkg.Checksum{}, stub.UniqueError(0xbad)},
|
||||||
|
|
||||||
{"match", overrideChecksum{want.hash(), overrideIdent{pkg.ID{0xff, 1}, &stubArtifact{
|
{"match", overrideChecksum{wantChecksum, overrideIdent{pkg.ID{0xff, 1}, &stubArtifact{
|
||||||
kind: pkg.KindTar,
|
kind: pkg.KindTar,
|
||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return makeGarbage(t.GetWorkDir(), nil)
|
return makeGarbage(t.GetWorkDir(), nil)
|
||||||
@@ -1167,21 +1000,9 @@ func TestCache(t *testing.T) {
|
|||||||
}}}, base.Append(
|
}}}, base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
pkg.Encode(pkg.ID{0xff, 1}),
|
pkg.Encode(pkg.ID{0xff, 1}),
|
||||||
), want, nil},
|
), wantChecksum, nil},
|
||||||
})
|
})
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("OC290t23aimNo2Rp2pPwan5GI2KRLRdOwYxXQMD9jw0QROgHnNXWodoWdV0hwu2w")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M/check": {Mode: 0400, Data: []byte{}},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/_wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
|
|
||||||
"identifier/_wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/Aubi5EG4_Y8DhL9bQ3Q4HFBhLRF7X5gt9D3CNCQfT-TeBtlRXc7Zi_JYZEMoCC7M")},
|
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"scrub", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"scrub", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
cureMany(t, c, []cureStep{
|
cureMany(t, c, []cureStep{
|
||||||
@@ -1193,7 +1014,7 @@ func TestCache(t *testing.T) {
|
|||||||
), base.Append(
|
), base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
pkg.Encode(pkg.Checksum{0xfe, 0}),
|
pkg.Encode(pkg.Checksum{0xfe, 0}),
|
||||||
), expectsChecksum{0xff, 0}, nil},
|
), pkg.Checksum{0xff, 0}, nil},
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, p := range [][]string{
|
for _, p := range [][]string{
|
||||||
@@ -1226,12 +1047,7 @@ func TestCache(t *testing.T) {
|
|||||||
if err := c.Scrub(1 << 6); !reflect.DeepEqual(err, wantErr) {
|
if err := c.Scrub(1 << 6); !reflect.DeepEqual(err, wantErr) {
|
||||||
t.Fatalf("Scrub: error =\n%s\nwant\n%s", err, wantErr)
|
t.Fatalf("Scrub: error =\n%s\nwant\n%s", err, wantErr)
|
||||||
}
|
}
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
}
|
}
|
||||||
checkWithCache(t, testCases)
|
checkWithCache(t, testCases)
|
||||||
}
|
}
|
||||||
@@ -1285,15 +1101,6 @@ func TestErrors(t *testing.T) {
|
|||||||
Want: pkg.IRKindIdent,
|
Want: pkg.IRKindIdent,
|
||||||
Ancillary: 0xcafe,
|
Ancillary: 0xcafe,
|
||||||
}, "got invalid kind 48879 IR value (0xcafe) instead of ident"},
|
}, "got invalid kind 48879 IR value (0xcafe) instead of ident"},
|
||||||
|
|
||||||
{"UnsupportedVariantError", pkg.UnsupportedVariantError(
|
|
||||||
"rosa",
|
|
||||||
), `unsupported variant "rosa"`},
|
|
||||||
|
|
||||||
{"UnsupportedArchError zero", pkg.UnsupportedArchError(""),
|
|
||||||
"invalid architecture name"},
|
|
||||||
{"UnsupportedArchError", pkg.UnsupportedArchError("riscv64"),
|
|
||||||
"unsupported architecture riscv64"},
|
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
@@ -1502,24 +1309,17 @@ func (a earlyFailureF) Cure(*pkg.FContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDependencyCureErrorEarly(t *testing.T) {
|
func TestDependencyCureErrorEarly(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
checkWithCache(t, []cacheTestCase{
|
checkWithCache(t, []cacheTestCase{
|
||||||
{"early", 0, nil, func(t *testing.T, _ *check.Absolute, c *pkg.Cache) {
|
{"early", 0, nil, func(t *testing.T, _ *check.Absolute, c *pkg.Cache) {
|
||||||
_, _, err := c.Cure(earlyFailureF(8))
|
_, _, err := c.Cure(earlyFailureF(8))
|
||||||
if !errors.Is(err, stub.UniqueError(0xcafe)) {
|
if !errors.Is(err, stub.UniqueError(0xcafe)) {
|
||||||
t.Fatalf("Cure: error = %v", err)
|
t.Fatalf("Cure: error = %v", err)
|
||||||
}
|
}
|
||||||
}, expectsFS{
|
}, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")},
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOpen(t *testing.T) {
|
func TestNew(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("nonexistent", func(t *testing.T) {
|
t.Run("nonexistent", func(t *testing.T) {
|
||||||
@@ -1567,219 +1367,3 @@ func TestOpen(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtensionRegister(t *testing.T) {
|
|
||||||
extensionOld := extension
|
|
||||||
openedOld := opened
|
|
||||||
t.Cleanup(func() { extension = extensionOld; opened = openedOld })
|
|
||||||
extension = ""
|
|
||||||
opened = false
|
|
||||||
|
|
||||||
t.Run("set", func(t *testing.T) {
|
|
||||||
t.Cleanup(func() { extension = "" })
|
|
||||||
|
|
||||||
const want = "rosa"
|
|
||||||
pkg.SetExtension(want)
|
|
||||||
if got := pkg.Extension(); got != want {
|
|
||||||
t.Fatalf("Extension: %q, want %q", got, want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("twice", func(t *testing.T) {
|
|
||||||
t.Cleanup(func() { extension = "" })
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
const wantPanic = "attempting to set extension twice"
|
|
||||||
if r := recover(); r != wantPanic {
|
|
||||||
t.Errorf("panic: %#v, want %q", r, wantPanic)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
pkg.SetExtension("rosa")
|
|
||||||
pkg.SetExtension("rosa")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("invalid", func(t *testing.T) {
|
|
||||||
defer func() {
|
|
||||||
var wantPanic = pkg.ErrInvalidExtension
|
|
||||||
if r := recover(); r != wantPanic {
|
|
||||||
t.Errorf("panic: %#v, want %#v", r, wantPanic)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
pkg.SetExtension(" ")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("opened", func(t *testing.T) {
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
|
|
||||||
if _, err := pkg.Open(
|
|
||||||
t.Context(),
|
|
||||||
message.New(log.Default()),
|
|
||||||
0, 0, 0,
|
|
||||||
check.MustAbs(container.Nonexistent),
|
|
||||||
); !errors.Is(err, os.ErrNotExist) {
|
|
||||||
t.Fatalf("Open: error = %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("variant", func(t *testing.T) {
|
|
||||||
defer func() {
|
|
||||||
const wantPanic = "attempting to set extension after open"
|
|
||||||
if r := recover(); r != wantPanic {
|
|
||||||
t.Errorf("panic: %#v, want %q", r, wantPanic)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
pkg.SetExtension("rosa")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("register", func(t *testing.T) {
|
|
||||||
defer func() {
|
|
||||||
const wantPanic = "attempting to register after open"
|
|
||||||
if r := recover(); r != wantPanic {
|
|
||||||
t.Errorf("panic: %#v, want %q", r, wantPanic)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
pkg.Register(pkg.KindCustomOffset, nil)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("incomplete", func(t *testing.T) {
|
|
||||||
t.Cleanup(func() { delete(irArtifact, pkg.KindCustomOffset) })
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
const wantPanic = "attempting to open cache with incomplete variant setup"
|
|
||||||
if r := recover(); r != wantPanic {
|
|
||||||
t.Errorf("panic: %#v, want %q", r, wantPanic)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
pkg.Register(pkg.KindCustomOffset, nil)
|
|
||||||
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
_, _ = pkg.Open(nil, nil, 0, 0, 0, nil)
|
|
||||||
panic("unreachable")
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("create", func(t *testing.T) {
|
|
||||||
t.Cleanup(func() { extension = "" })
|
|
||||||
const want = "rosa"
|
|
||||||
pkg.SetExtension(want)
|
|
||||||
|
|
||||||
base := check.MustAbs(t.TempDir())
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
if c, err := pkg.Open(
|
|
||||||
t.Context(), nil,
|
|
||||||
0, 0, 0,
|
|
||||||
base,
|
|
||||||
); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
if got, err := os.ReadFile(base.Append("variant").String()); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if string(got) != want {
|
|
||||||
t.Fatalf("variant: %q", string(got))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("access", func(t *testing.T) {
|
|
||||||
base := check.MustAbs(t.TempDir())
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
|
|
||||||
if err := os.WriteFile(base.Append("variant").String(), nil, 0); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wantErr := &os.PathError{
|
|
||||||
Op: "open",
|
|
||||||
Path: base.Append("variant").String(),
|
|
||||||
Err: syscall.EACCES,
|
|
||||||
}
|
|
||||||
if _, err := pkg.Open(
|
|
||||||
t.Context(), nil,
|
|
||||||
0, 0, 0,
|
|
||||||
base,
|
|
||||||
); !reflect.DeepEqual(err, wantErr) {
|
|
||||||
t.Fatalf("Open: error = %v, want %v", err, wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("promote", func(t *testing.T) {
|
|
||||||
t.Cleanup(func() { extension = "" })
|
|
||||||
const want = "rosa"
|
|
||||||
pkg.SetExtension(want)
|
|
||||||
|
|
||||||
base := check.MustAbs(t.TempDir())
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
|
|
||||||
variantPath := base.Append("variant")
|
|
||||||
if err := os.WriteFile(variantPath.String(), nil, 0600); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := pkg.Open(
|
|
||||||
t.Context(), nil,
|
|
||||||
0, 0, 0,
|
|
||||||
base,
|
|
||||||
); !reflect.DeepEqual(err, pkg.ErrWouldPromote) {
|
|
||||||
t.Fatalf("Open: error = %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p, err := os.ReadFile(variantPath.String()); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if len(p) != 0 {
|
|
||||||
t.Fatalf("variant: %q", string(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
if c, err := pkg.Open(
|
|
||||||
t.Context(), nil,
|
|
||||||
pkg.CPromoteVariant, 0, 0,
|
|
||||||
base,
|
|
||||||
); err != nil {
|
|
||||||
t.Fatalf("Open: error = %v", err)
|
|
||||||
} else {
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
if p, err := os.ReadFile(variantPath.String()); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if string(p) != want {
|
|
||||||
t.Fatalf("variant: %q, want %q", string(p), want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("open invalid", func(t *testing.T) {
|
|
||||||
base := check.MustAbs(t.TempDir())
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
|
|
||||||
variantPath := base.Append("variant")
|
|
||||||
if err := os.WriteFile(variantPath.String(), make([]byte, 129), 0400); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := pkg.Open(
|
|
||||||
t.Context(), nil,
|
|
||||||
0, 0, 0,
|
|
||||||
base,
|
|
||||||
); !reflect.DeepEqual(err, pkg.ErrInvalidExtension) {
|
|
||||||
t.Fatalf("Open: error = %v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("unsupported", func(t *testing.T) {
|
|
||||||
base := check.MustAbs(t.TempDir())
|
|
||||||
t.Cleanup(func() { opened = false })
|
|
||||||
|
|
||||||
variantPath := base.Append("variant")
|
|
||||||
if err := os.WriteFile(variantPath.String(), []byte("rosa"), 0400); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := pkg.Open(
|
|
||||||
t.Context(), nil,
|
|
||||||
0, 0, 0,
|
|
||||||
base,
|
|
||||||
); !reflect.DeepEqual(err, pkg.UnsupportedVariantError("rosa")) {
|
|
||||||
t.Fatalf("Open: error = %v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,31 +20,6 @@ import (
|
|||||||
func TestTar(t *testing.T) {
|
func TestTar(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
want := expectsFS{
|
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"checksum": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}},
|
|
||||||
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0500},
|
|
||||||
"identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
|
||||||
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0500},
|
|
||||||
}
|
|
||||||
wantEncode := pkg.Encode(want.hash())
|
|
||||||
|
|
||||||
wantExpand := expectsFS{
|
|
||||||
".": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
|
||||||
}
|
|
||||||
wantExpandEncode := pkg.Encode(wantExpand.hash())
|
|
||||||
|
|
||||||
checkWithCache(t, []cacheTestCase{
|
checkWithCache(t, []cacheTestCase{
|
||||||
{"http", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"http", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
checkTarHTTP(t, base, c, fstest.MapFS{
|
checkTarHTTP(t, base, c, fstest.MapFS{
|
||||||
@@ -62,30 +37,10 @@ func TestTar(t *testing.T) {
|
|||||||
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
"identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
||||||
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
"work": {Mode: fs.ModeDir | 0700},
|
||||||
}, want)
|
}, pkg.MustDecode(
|
||||||
}, expectsFS{
|
"cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM",
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
))
|
||||||
|
}, pkg.MustDecode("NQTlc466JmSVLIyWklm_u8_g95jEEb98PxJU-kjwxLpfdjwMWJq0G8ze9R4Vo1Vu")},
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantEncode + "/checksum": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/check": {Mode: 0400, Data: []byte{0, 0}},
|
|
||||||
"checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
|
||||||
"checksum/" + wantEncode + "/checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP/lib/pkgconfig": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantEncode + "/identifier": {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantEncode + "/identifier/HnySzeLQvSBZuTUcvfmLEX_OmH4yJWWH788NxuLuv7kVn8_uPM6Ks4rqFWM2NZJY": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
|
||||||
"checksum/" + wantEncode + "/identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")},
|
|
||||||
"checksum/" + wantEncode + "/work": {Mode: fs.ModeDir | 0500},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
|
|
||||||
"identifier/rg7F1D5hwv6o4xctjD5zDq4i5MD0mArTsUIWfhUbik8xC6Bsyt3mjXXOm3goojTz": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantEncode)},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"http expand", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
{"http expand", 0, nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) {
|
||||||
checkTarHTTP(t, base, c, fstest.MapFS{
|
checkTarHTTP(t, base, c, fstest.MapFS{
|
||||||
@@ -93,21 +48,10 @@ func TestTar(t *testing.T) {
|
|||||||
|
|
||||||
"lib": {Mode: fs.ModeDir | 0700},
|
"lib": {Mode: fs.ModeDir | 0700},
|
||||||
"lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
"lib/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
||||||
}, wantExpand)
|
}, pkg.MustDecode(
|
||||||
}, expectsFS{
|
"CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN",
|
||||||
".": {Mode: fs.ModeDir | 0700},
|
))
|
||||||
|
}, pkg.MustDecode("hSoSSgCYTNonX3Q8FjvjD1fBl-E-BQyA6OTXro2OadXqbST4tZ-akGXszdeqphRe")},
|
||||||
"checksum": {Mode: fs.ModeDir | 0700},
|
|
||||||
"checksum/" + wantExpandEncode: {Mode: fs.ModeDir | 0500},
|
|
||||||
"checksum/" + wantExpandEncode + "/libedac.so": {Mode: fs.ModeSymlink | 0777, Data: []byte("/proc/nonexistent/libedac.so")},
|
|
||||||
|
|
||||||
"identifier": {Mode: fs.ModeDir | 0700},
|
|
||||||
"identifier/W5S65DEhawz_WKaok5NjUKLmnD9dNl5RPauNJjcOVcB3VM4eGhSaLGmXbL8vZpiw": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
|
|
||||||
"identifier/_v1blm2h-_KA-dVaawdpLas6MjHc6rbhhFS8JWwx8iJxZGUu8EBbRrhr5AaZ9PJL": {Mode: fs.ModeSymlink | 0777, Data: []byte("../checksum/" + wantExpandEncode)},
|
|
||||||
|
|
||||||
"temp": {Mode: fs.ModeDir | 0700},
|
|
||||||
"work": {Mode: fs.ModeDir | 0700},
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +60,7 @@ func checkTarHTTP(
|
|||||||
base *check.Absolute,
|
base *check.Absolute,
|
||||||
c *pkg.Cache,
|
c *pkg.Cache,
|
||||||
testdataFsys fs.FS,
|
testdataFsys fs.FS,
|
||||||
want expectsKnown,
|
wantChecksum pkg.Checksum,
|
||||||
) {
|
) {
|
||||||
var testdata string
|
var testdata string
|
||||||
{
|
{
|
||||||
@@ -250,24 +194,24 @@ func checkTarHTTP(
|
|||||||
{"file", a, base.Append(
|
{"file", a, base.Append(
|
||||||
"identifier",
|
"identifier",
|
||||||
pkg.Encode(wantIdent),
|
pkg.Encode(wantIdent),
|
||||||
), want, nil},
|
), wantChecksum, nil},
|
||||||
|
|
||||||
{"directory", pkg.NewTar(
|
{"directory", pkg.NewTar(
|
||||||
&tarDir,
|
&tarDir,
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), ignorePathname, want, nil},
|
), ignorePathname, wantChecksum, nil},
|
||||||
|
|
||||||
{"multiple entries", pkg.NewTar(
|
{"multiple entries", pkg.NewTar(
|
||||||
&tarDirMulti,
|
&tarDirMulti,
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), nil, nil, errors.New(
|
), nil, pkg.Checksum{}, errors.New(
|
||||||
"input directory does not contain a single regular file",
|
"input directory does not contain a single regular file",
|
||||||
)},
|
)},
|
||||||
|
|
||||||
{"bad type", pkg.NewTar(
|
{"bad type", pkg.NewTar(
|
||||||
&tarDirType,
|
&tarDirType,
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), nil, nil, errors.New(
|
), nil, pkg.Checksum{}, errors.New(
|
||||||
"input directory does not contain a single regular file",
|
"input directory does not contain a single regular file",
|
||||||
)},
|
)},
|
||||||
|
|
||||||
@@ -277,6 +221,6 @@ func checkTarHTTP(
|
|||||||
cure: func(t *pkg.TContext) error {
|
cure: func(t *pkg.TContext) error {
|
||||||
return stub.UniqueError(0xcafe)
|
return stub.UniqueError(0xcafe)
|
||||||
},
|
},
|
||||||
}, pkg.TarGzip), nil, nil, stub.UniqueError(0xcafe)},
|
}, pkg.TarGzip), nil, pkg.Checksum{}, stub.UniqueError(0xcafe)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,29 +14,15 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"hakurei.app/check"
|
||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
"hakurei.app/vfs"
|
"hakurei.app/vfs"
|
||||||
|
|
||||||
"hakurei.app/internal/pkg/internal/testtool/expected"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
log.SetPrefix("testtool: ")
|
log.SetPrefix("testtool: ")
|
||||||
|
|
||||||
if os.Getenv("HAKUREI_BINFMT") == "1" {
|
|
||||||
wantArgs := []string{"/interpreter", "/opt/bin/sample"}
|
|
||||||
if !slices.Equal(os.Args, wantArgs) {
|
|
||||||
log.Fatalf("Args: %q, want %q", os.Args, wantArgs)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.WriteFile("check", []byte("binfmt"), 0400); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
environ := slices.DeleteFunc(slices.Clone(os.Environ()), func(s string) bool {
|
environ := slices.DeleteFunc(slices.Clone(os.Environ()), func(s string) bool {
|
||||||
return s == "CURE_JOBS="+strconv.Itoa(runtime.NumCPU())
|
return s == "CURE_JOBS="+strconv.Itoa(runtime.NumCPU())
|
||||||
})
|
})
|
||||||
@@ -162,40 +148,59 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const checksumEmptyDir = "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"
|
const checksumEmptyDir = "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU"
|
||||||
ident := expected.Offline
|
ident := "dztPS6jRjiZtCF4_p8AzfnxGp6obkhrgFVsxdodbKWUoAEVtDz3MykepJB4kI_ks"
|
||||||
log.Println(m)
|
log.Println(m)
|
||||||
next := func() { m = m.Next; log.Println(m) }
|
next := func() { m = m.Next; log.Println(m) }
|
||||||
|
|
||||||
if overlayRoot {
|
if overlayRoot {
|
||||||
ident = expected.OvlRoot
|
ident = "RdMA-mubnrHuu3Ky1wWyxauSYCO0ZH_zCPUj3uDHqkfwv5sGcByoF_g5PjlGiClb"
|
||||||
|
|
||||||
if m.Root != "/" || m.Target != "/" ||
|
if m.Root != "/" || m.Target != "/" ||
|
||||||
m.Source != "overlay" || m.FsType != "overlay" {
|
m.Source != "overlay" || m.FsType != "overlay" {
|
||||||
log.Fatal("unexpected root mount entry")
|
log.Fatal("unexpected root mount entry")
|
||||||
}
|
}
|
||||||
var lowerdir []string
|
var lowerdir string
|
||||||
for _, o := range strings.Split(m.FsOptstr, ",") {
|
for _, o := range strings.Split(m.FsOptstr, ",") {
|
||||||
const lowerdirKey = "lowerdir+="
|
const lowerdirKey = "lowerdir="
|
||||||
if strings.HasPrefix(o, lowerdirKey) {
|
if strings.HasPrefix(o, lowerdirKey) {
|
||||||
lowerdir = append(lowerdir, o[len(lowerdirKey):])
|
lowerdir = o[len(lowerdirKey):]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !layers {
|
if !layers {
|
||||||
if len(lowerdir) != 1 || filepath.Base(lowerdir[0]) != checksumEmptyDir {
|
if filepath.Base(lowerdir) != checksumEmptyDir {
|
||||||
log.Fatal("unexpected artifact checksum")
|
log.Fatal("unexpected artifact checksum")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ident = expected.Layers
|
ident = "p1t_drXr34i-jZNuxDMLaMOdL6tZvQqhavNafGynGqxOZoXAUTSn7kqNh3Ovv3DT"
|
||||||
|
|
||||||
if len(lowerdir) != 2 ||
|
lowerdirsEscaped := strings.Split(lowerdir, ":")
|
||||||
filepath.Base(lowerdir[0]) != "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU" ||
|
lowerdirs := lowerdirsEscaped[:0]
|
||||||
filepath.Base(lowerdir[1]) != "nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK" {
|
// ignore the option separator since it does not appear in ident
|
||||||
log.Fatalf("unexpected lowerdirs %s", strings.Join(lowerdir, ", "))
|
for i, e := range lowerdirsEscaped {
|
||||||
|
if len(e) > 0 &&
|
||||||
|
e[len(e)-1] == check.SpecialOverlayEscape[0] &&
|
||||||
|
(len(e) == 1 || e[len(e)-2] != check.SpecialOverlayEscape[0]) {
|
||||||
|
// ignore escaped pathname separator since it does not
|
||||||
|
// appear in ident
|
||||||
|
|
||||||
|
e = e[:len(e)-1]
|
||||||
|
if len(lowerdirsEscaped) != i {
|
||||||
|
lowerdirsEscaped[i+1] = e + lowerdirsEscaped[i+1]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lowerdirs = append(lowerdirs, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lowerdirs) != 2 ||
|
||||||
|
filepath.Base(lowerdirs[0]) != "MGWmEfjut2QE2xPJwTsmUzpff4BN_FEnQ7T0j7gvUCCiugJQNwqt9m151fm9D1yU" ||
|
||||||
|
filepath.Base(lowerdirs[1]) != "nY_CUdiaUM1OL4cPr5TS92FCJ3rCRV7Hm5oVTzAvMXwC03_QnTRfQ5PPs7mOU9fK" {
|
||||||
|
log.Fatalf("unexpected lowerdirs %s", strings.Join(lowerdirs, ", "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if hostNet {
|
if hostNet {
|
||||||
ident = expected.Net
|
ident = "G8qPxD9puvvoOVV7lrT80eyDeIl3G_CCFoKw12c8mCjMdG1zF7NEPkwYpNubClK3"
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Root != "/sysroot" || m.Target != "/" {
|
if m.Root != "/sysroot" || m.Target != "/" {
|
||||||
@@ -214,14 +219,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if promote {
|
if promote {
|
||||||
ident = expected.Promote
|
ident = "xXTIYcXmgJWNLC91c417RRrNM9cjELwEZHpGvf8Fk_GNP5agRJp_SicD0w9aMeLJ"
|
||||||
}
|
}
|
||||||
|
|
||||||
next() // testtool artifact
|
next() // testtool artifact
|
||||||
|
|
||||||
next()
|
next()
|
||||||
if overlayWork {
|
if overlayWork {
|
||||||
ident = expected.Work
|
ident = "5hlaukCirnXE4W_RSLJFOZN47Z5RiHnacXzdFp_70cLgiJUGR6cSb_HaFftkzi0-"
|
||||||
if m.Root != "/" || m.Target != "/work" ||
|
if m.Root != "/" || m.Target != "/work" ||
|
||||||
m.Source != "overlay" || m.FsType != "overlay" {
|
m.Source != "overlay" || m.FsType != "overlay" {
|
||||||
log.Fatal("unexpected work mount entry")
|
log.Fatal("unexpected work mount entry")
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -17,7 +16,9 @@ import (
|
|||||||
type PArtifact int
|
type PArtifact int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLVM PArtifact = iota
|
CompilerRT PArtifact = iota
|
||||||
|
LLVMRuntimes
|
||||||
|
Clang
|
||||||
|
|
||||||
// EarlyInit is the Rosa OS init program.
|
// EarlyInit is the Rosa OS init program.
|
||||||
EarlyInit
|
EarlyInit
|
||||||
@@ -71,21 +72,12 @@ const (
|
|||||||
Gzip
|
Gzip
|
||||||
Hakurei
|
Hakurei
|
||||||
HakureiDist
|
HakureiDist
|
||||||
Hwdata
|
|
||||||
IPTables
|
IPTables
|
||||||
Kmod
|
Kmod
|
||||||
LIT
|
|
||||||
LibX11
|
|
||||||
LibXau
|
LibXau
|
||||||
LibXext
|
|
||||||
LibXrandr
|
|
||||||
LibXrender
|
|
||||||
LibXxf86vm
|
|
||||||
Libarchive
|
|
||||||
Libbsd
|
Libbsd
|
||||||
Libcap
|
Libcap
|
||||||
Libconfig
|
Libclc
|
||||||
LibdisplayInfo
|
|
||||||
Libdrm
|
Libdrm
|
||||||
Libev
|
Libev
|
||||||
Libexpat
|
Libexpat
|
||||||
@@ -95,19 +87,16 @@ const (
|
|||||||
Libiconv
|
Libiconv
|
||||||
Libmd
|
Libmd
|
||||||
Libmnl
|
Libmnl
|
||||||
Libnftnl
|
|
||||||
Libpciaccess
|
Libpciaccess
|
||||||
Libpng
|
Libnftnl
|
||||||
Libpsl
|
Libpsl
|
||||||
Libseccomp
|
Libseccomp
|
||||||
Libtasn1
|
Libtasn1
|
||||||
Libtool
|
Libtool
|
||||||
Libucontext
|
Libucontext
|
||||||
Libunistring
|
Libunistring
|
||||||
Libxshmfence
|
|
||||||
Libxml2
|
Libxml2
|
||||||
Libxslt
|
Libxslt
|
||||||
Libxtrans
|
|
||||||
M4
|
M4
|
||||||
MPC
|
MPC
|
||||||
MPFR
|
MPFR
|
||||||
@@ -140,30 +129,21 @@ const (
|
|||||||
PkgConfig
|
PkgConfig
|
||||||
Procps
|
Procps
|
||||||
Python
|
Python
|
||||||
PythonFlitCore
|
|
||||||
PythonHatchling
|
|
||||||
PythonIniConfig
|
PythonIniConfig
|
||||||
PythonMako
|
PythonMako
|
||||||
PythonMarkupSafe
|
PythonMarkupSafe
|
||||||
PythonPackaging
|
PythonPackaging
|
||||||
PythonPathspec
|
|
||||||
PythonPluggy
|
PythonPluggy
|
||||||
PythonPyTest
|
PythonPyTest
|
||||||
PythonPyYAML
|
PythonPyYAML
|
||||||
PythonPycparser
|
|
||||||
PythonPygments
|
PythonPygments
|
||||||
PythonSetuptools
|
|
||||||
PythonSetuptoolsSCM
|
|
||||||
PythonTroveClassifiers
|
|
||||||
PythonVCSVersioning
|
|
||||||
PythonWheel
|
|
||||||
QEMU
|
QEMU
|
||||||
Rdfind
|
Rdfind
|
||||||
Readline
|
Readline
|
||||||
Rsync
|
Rsync
|
||||||
Sed
|
Sed
|
||||||
|
Setuptools
|
||||||
SPIRVHeaders
|
SPIRVHeaders
|
||||||
SPIRVLLVMTranslator
|
|
||||||
SPIRVTools
|
SPIRVTools
|
||||||
SquashfsTools
|
SquashfsTools
|
||||||
Strace
|
Strace
|
||||||
@@ -178,37 +158,21 @@ const (
|
|||||||
WaylandProtocols
|
WaylandProtocols
|
||||||
XCB
|
XCB
|
||||||
XCBProto
|
XCBProto
|
||||||
XCBUtilKeysyms
|
|
||||||
XDGDBusProxy
|
XDGDBusProxy
|
||||||
XZ
|
XZ
|
||||||
XorgProto
|
Xproto
|
||||||
Zlib
|
Zlib
|
||||||
Zstd
|
Zstd
|
||||||
|
|
||||||
// PresetUnexportedStart is the first unexported preset.
|
// PresetUnexportedStart is the first unexported preset.
|
||||||
PresetUnexportedStart
|
PresetUnexportedStart
|
||||||
|
|
||||||
stage0Dist = iota - 1
|
llvmSource = iota - 1
|
||||||
llvmSource
|
|
||||||
// earlyCompilerRT is an early, standalone compiler-rt installation for the
|
|
||||||
// standalone runtimes build.
|
|
||||||
//
|
|
||||||
// earlyCompilerRT must only be loaded by [LLVM].
|
|
||||||
earlyCompilerRT
|
|
||||||
// earlyRuntimes is an early, standalone installation of LLVM runtimes to
|
|
||||||
// work around the cmake build system leaking the system LLVM installation
|
|
||||||
// when invoking the newly built toolchain.
|
|
||||||
//
|
|
||||||
// earlyRuntimes must only be loaded by [LLVM].
|
|
||||||
earlyRuntimes
|
|
||||||
|
|
||||||
buildcatrust
|
buildcatrust
|
||||||
utilMacros
|
utilMacros
|
||||||
|
|
||||||
// Musl is a standalone libc that does not depend on the toolchain.
|
// Musl is a standalone libc that does not depend on the toolchain.
|
||||||
Musl
|
Musl
|
||||||
// muslHeaders is a system installation of [Musl] headers.
|
|
||||||
muslHeaders
|
|
||||||
|
|
||||||
// gcc is a hacked-to-pieces GCC toolchain meant for use in intermediate
|
// gcc is a hacked-to-pieces GCC toolchain meant for use in intermediate
|
||||||
// stages only. This preset and its direct output must never be exposed.
|
// stages only. This preset and its direct output must never be exposed.
|
||||||
@@ -353,40 +317,15 @@ var (
|
|||||||
}
|
}
|
||||||
// artifactsOnce is for lazy initialisation of artifacts.
|
// artifactsOnce is for lazy initialisation of artifacts.
|
||||||
artifactsOnce [_toolchainEnd][len(artifactsM)]sync.Once
|
artifactsOnce [_toolchainEnd][len(artifactsM)]sync.Once
|
||||||
|
|
||||||
// arch is the target architecture.
|
|
||||||
arch = runtime.GOARCH
|
|
||||||
|
|
||||||
// presetOpts globally modifies behaviour of presets.
|
|
||||||
presetOpts int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// OptSkipCheck skips running all test suites.
|
|
||||||
OptSkipCheck = 1 << iota
|
|
||||||
// OptLLVMNoLTO disables LTO in all [LLVM] stages.
|
|
||||||
OptLLVMNoLTO
|
|
||||||
)
|
|
||||||
|
|
||||||
// Arch returns the target architecture.
|
|
||||||
func Arch() string { return arch }
|
|
||||||
|
|
||||||
// Flags returns the current preset flags
|
|
||||||
func Flags() int { return presetOpts }
|
|
||||||
|
|
||||||
// zero zeros the value pointed to by p.
|
// zero zeros the value pointed to by p.
|
||||||
func zero[T any](p *T) { var v T; *p = v }
|
func zero[T any](p *T) { var v T; *p = v }
|
||||||
|
|
||||||
// DropCaches arranges for all cached [pkg.Artifact] to be freed some time after
|
// DropCaches arranges for all cached [pkg.Artifact] to be freed some time after
|
||||||
// it returns. Must not be used concurrently with any other function from this
|
// it returns. Must not be used concurrently with any other function from this
|
||||||
// package.
|
// package.
|
||||||
func DropCaches(targetArch string, flags int) {
|
func DropCaches() {
|
||||||
if targetArch == "" {
|
|
||||||
targetArch = runtime.GOARCH
|
|
||||||
}
|
|
||||||
|
|
||||||
arch = targetArch
|
|
||||||
presetOpts = flags
|
|
||||||
zero(&artifacts)
|
zero(&artifacts)
|
||||||
zero(&artifactsOnce)
|
zero(&artifactsOnce)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,16 +20,13 @@ func TestLoad(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkAll(b *testing.B) {
|
func BenchmarkAll(b *testing.B) {
|
||||||
arch, flags := rosa.Arch(), rosa.Flags()
|
|
||||||
b.Cleanup(func() { rosa.DropCaches(arch, flags) })
|
|
||||||
|
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
for i := range rosa.PresetEnd {
|
for i := range rosa.PresetEnd {
|
||||||
rosa.Std.Load(rosa.PArtifact(i))
|
rosa.Std.Load(rosa.PArtifact(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
rosa.DropCaches("", 0)
|
rosa.DropCaches()
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hakurei.app/fhs"
|
"hakurei.app/fhs"
|
||||||
@@ -87,7 +88,7 @@ func (a busyboxBin) Cure(t *pkg.TContext) (err error) {
|
|||||||
// the https://busybox.net/downloads/binaries/ binary release.
|
// the https://busybox.net/downloads/binaries/ binary release.
|
||||||
func newBusyboxBin() pkg.Artifact {
|
func newBusyboxBin() pkg.Artifact {
|
||||||
var version, url, checksum string
|
var version, url, checksum string
|
||||||
switch arch {
|
switch runtime.GOARCH {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
version = "1.35.0"
|
version = "1.35.0"
|
||||||
url = "https://busybox.net/downloads/binaries/" +
|
url = "https://busybox.net/downloads/binaries/" +
|
||||||
@@ -100,11 +101,11 @@ func newBusyboxBin() pkg.Artifact {
|
|||||||
checksum = "npJjBO7iwhjW6Kx2aXeSxf8kXhVgTCDChOZTTsI8ZfFfa3tbsklxRiidZQdrVERg"
|
checksum = "npJjBO7iwhjW6Kx2aXeSxf8kXhVgTCDChOZTTsI8ZfFfa3tbsklxRiidZQdrVERg"
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("unsupported target " + arch)
|
panic("unsupported target " + runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkg.NewExec(
|
return pkg.NewExec(
|
||||||
"busybox-bin-"+version, arch, nil, pkg.ExecTimeoutMax, false,
|
"busybox-bin-"+version, nil, pkg.ExecTimeoutMax, false,
|
||||||
fhs.AbsRoot, []string{
|
fhs.AbsRoot, []string{
|
||||||
"PATH=/system/bin",
|
"PATH=/system/bin",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
|
|
||||||
func (t Toolchain) newCMake() (pkg.Artifact, string) {
|
func (t Toolchain) newCMake() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "4.3.2"
|
version = "4.3.1"
|
||||||
checksum = "6QylwRVKletndTSkZTV2YBRwgd_9rUVgav_QW23HpjUgV21AVYZOUOal8tdBDmO7"
|
checksum = "RHpzZiM1kJ5bwLjo9CpXSeHJJg3hTtV9QxBYpQoYwKFtRh5YhGWpShrqZCSOzQN6"
|
||||||
)
|
)
|
||||||
return t.NewPackage("cmake", version, newFromGitHubRelease(
|
return t.NewPackage("cmake", version, newFromGitHubRelease(
|
||||||
"Kitware/CMake",
|
"Kitware/CMake",
|
||||||
@@ -122,18 +122,11 @@ type CMakeHelper struct {
|
|||||||
// Path elements joined with source.
|
// Path elements joined with source.
|
||||||
Append []string
|
Append []string
|
||||||
|
|
||||||
// Value of CMAKE_BUILD_TYPE. The zero value is equivalent to "Release".
|
|
||||||
BuildType string
|
|
||||||
// CMake CACHE entries.
|
// CMake CACHE entries.
|
||||||
Cache []KV
|
Cache []KV
|
||||||
// Runs after install.
|
// Runs after install.
|
||||||
Script string
|
Script string
|
||||||
|
|
||||||
// Replaces the default test command.
|
|
||||||
Test string
|
|
||||||
// Whether to skip running tests.
|
|
||||||
SkipTest bool
|
|
||||||
|
|
||||||
// Whether to generate Makefile instead.
|
// Whether to generate Makefile instead.
|
||||||
Make bool
|
Make bool
|
||||||
}
|
}
|
||||||
@@ -166,30 +159,20 @@ func (*CMakeHelper) wantsDir() string { return "/cure/" }
|
|||||||
// script generates the cure script.
|
// script generates the cure script.
|
||||||
func (attr *CMakeHelper) script(name string) string {
|
func (attr *CMakeHelper) script(name string) string {
|
||||||
if attr == nil {
|
if attr == nil {
|
||||||
attr = new(CMakeHelper)
|
attr = &CMakeHelper{
|
||||||
|
Cache: []KV{
|
||||||
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(attr.Cache) == 0 {
|
||||||
|
panic("CACHE must be non-empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
generate := "Ninja"
|
generate := "Ninja"
|
||||||
test := "ninja " + jobsFlagE + " test"
|
|
||||||
if attr.Make {
|
if attr.Make {
|
||||||
generate = "'Unix Makefiles'"
|
generate = "'Unix Makefiles'"
|
||||||
test = "make " + jobsFlagE + " test"
|
|
||||||
}
|
}
|
||||||
if attr.Test != "" {
|
|
||||||
test = attr.Test
|
|
||||||
}
|
|
||||||
|
|
||||||
script := attr.Script
|
|
||||||
if !attr.SkipTest && presetOpts&OptSkipCheck == 0 {
|
|
||||||
script += "\n" + test
|
|
||||||
}
|
|
||||||
|
|
||||||
cache := make([]KV, 1, 1+len(attr.Cache))
|
|
||||||
cache[0] = KV{"CMAKE_BUILD_TYPE", "Release"}
|
|
||||||
if attr.BuildType != "" {
|
|
||||||
cache[0][1] = attr.BuildType
|
|
||||||
}
|
|
||||||
cache = append(cache, attr.Cache...)
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
cmake -G ` + generate + ` \
|
cmake -G ` + generate + ` \
|
||||||
@@ -198,7 +181,7 @@ cmake -G ` + generate + ` \
|
|||||||
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
-DCMAKE_ASM_COMPILER_TARGET="${ROSA_TRIPLE}" \
|
||||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||||
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
||||||
for _, v := range cache {
|
for _, v := range attr.Cache {
|
||||||
if !yield("-D" + v[0] + "=" + v[1]) {
|
if !yield("-D" + v[0] + "=" + v[1]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -208,5 +191,5 @@ cmake -G ` + generate + ` \
|
|||||||
'/usr/src/` + name + `/` + filepath.Join(attr.Append...) + `'
|
'/usr/src/` + name + `/` + filepath.Join(attr.Append...) + `'
|
||||||
cmake --build . --parallel=` + jobsE + `
|
cmake --build . --parallel=` + jobsE + `
|
||||||
cmake --install . --prefix=/work/system
|
cmake --install . --prefix=/work/system
|
||||||
` + script
|
` + attr.Script
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
|
|
||||||
func (t Toolchain) newGit() (pkg.Artifact, string) {
|
func (t Toolchain) newGit() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "2.54.0"
|
version = "2.53.0"
|
||||||
checksum = "7vGKtFOJGqY8DO4e8UMRax7dLgImXKQz5MMalec6MlgYrsarffSJjgOughwRFpSH"
|
checksum = "rlqSTeNgSeVKJA7nvzGqddFH8q3eFEPB4qRZft-4zth8wTHnbTbm7J90kp_obHGm"
|
||||||
)
|
)
|
||||||
return t.NewPackage("git", version, newTar(
|
return t.NewPackage("git", version, newTar(
|
||||||
"https://www.kernel.org/pub/software/scm/git/"+
|
"https://www.kernel.org/pub/software/scm/git/"+
|
||||||
@@ -20,9 +20,6 @@ func (t Toolchain) newGit() (pkg.Artifact, string) {
|
|||||||
), &PackageAttr{
|
), &PackageAttr{
|
||||||
ScriptEarly: `
|
ScriptEarly: `
|
||||||
ln -s ../../system/bin/perl /usr/bin/ || true
|
ln -s ../../system/bin/perl /usr/bin/ || true
|
||||||
|
|
||||||
# test suite assumes apache
|
|
||||||
rm -f /system/bin/httpd
|
|
||||||
`,
|
`,
|
||||||
|
|
||||||
// uses source tree as scratch space
|
// uses source tree as scratch space
|
||||||
@@ -41,7 +38,6 @@ function disable_test {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_test t1800-hook
|
|
||||||
disable_test t5319-multi-pack-index
|
disable_test t5319-multi-pack-index
|
||||||
disable_test t1305-config-include
|
disable_test t1305-config-include
|
||||||
disable_test t3900-i18n-commit
|
disable_test t3900-i18n-commit
|
||||||
@@ -55,9 +51,6 @@ disable_test t9300-fast-import
|
|||||||
disable_test t0211-trace2-perf
|
disable_test t0211-trace2-perf
|
||||||
disable_test t1517-outside-repo
|
disable_test t1517-outside-repo
|
||||||
disable_test t2200-add-update
|
disable_test t2200-add-update
|
||||||
disable_test t0027-auto-crlf
|
|
||||||
disable_test t7513-interpret-trailers
|
|
||||||
disable_test t7703-repack-geometric
|
|
||||||
`,
|
`,
|
||||||
Check: []string{
|
Check: []string{
|
||||||
"-C t",
|
"-C t",
|
||||||
@@ -70,9 +63,6 @@ disable_test t7703-repack-geometric
|
|||||||
NO_INSTALL_HARDLINKS=1 \
|
NO_INSTALL_HARDLINKS=1 \
|
||||||
install`,
|
install`,
|
||||||
},
|
},
|
||||||
// test suite hangs on mksh
|
|
||||||
Bash,
|
|
||||||
|
|
||||||
Diffutils,
|
Diffutils,
|
||||||
Autoconf,
|
Autoconf,
|
||||||
Gettext,
|
Gettext,
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ func (t Toolchain) newSPIRVHeaders() (pkg.Artifact, string) {
|
|||||||
"vulkan-sdk-"+version,
|
"vulkan-sdk-"+version,
|
||||||
checksum,
|
checksum,
|
||||||
), nil, &CMakeHelper{
|
), nil, &CMakeHelper{
|
||||||
// upstream has no tests
|
Cache: []KV{
|
||||||
SkipTest: true,
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
|
},
|
||||||
}), version
|
}), version
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
@@ -63,6 +64,7 @@ func (t Toolchain) newSPIRVTools() (pkg.Artifact, string) {
|
|||||||
checksum,
|
checksum,
|
||||||
), nil, &CMakeHelper{
|
), nil, &CMakeHelper{
|
||||||
Cache: []KV{
|
Cache: []KV{
|
||||||
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
{"SPIRV-Headers_SOURCE_DIR", "/system"},
|
{"SPIRV-Headers_SOURCE_DIR", "/system"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -84,8 +86,6 @@ func init() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ID: 14894,
|
ID: 14894,
|
||||||
|
|
||||||
latest: (*Versions).getStable,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,9 +104,11 @@ func (t Toolchain) newGlslang() (pkg.Artifact, string) {
|
|||||||
Chmod: true,
|
Chmod: true,
|
||||||
}, &CMakeHelper{
|
}, &CMakeHelper{
|
||||||
Cache: []KV{
|
Cache: []KV{
|
||||||
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
{"BUILD_SHARED_LIBS", "ON"},
|
{"BUILD_SHARED_LIBS", "ON"},
|
||||||
{"ALLOW_EXTERNAL_SPIRV_TOOLS", "ON"},
|
{"ALLOW_EXTERNAL_SPIRV_TOOLS", "ON"},
|
||||||
},
|
},
|
||||||
|
Script: "ctest",
|
||||||
},
|
},
|
||||||
Python,
|
Python,
|
||||||
Bash,
|
Bash,
|
||||||
@@ -126,114 +128,3 @@ func init() {
|
|||||||
ID: 205796,
|
ID: 205796,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Toolchain) newSPIRVLLVMTranslator() (pkg.Artifact, string) {
|
|
||||||
const (
|
|
||||||
version = "22.1.2"
|
|
||||||
checksum = "JZAaV5ewYcm-35YA_U2BM2IcsQouZtX1BLZR0zh2vSlfEXMsT5OCtY4Gh5RJkcGy"
|
|
||||||
)
|
|
||||||
skipChecks := []string{
|
|
||||||
// error: line 13: OpTypeCooperativeMatrixKHR Scope is limited to Workgroup and Subgroup
|
|
||||||
"cooperative_matrix_constant_null.spvasm",
|
|
||||||
}
|
|
||||||
|
|
||||||
switch arch {
|
|
||||||
case "arm64":
|
|
||||||
skipChecks = append(skipChecks,
|
|
||||||
// LLVM ERROR: unsupported calling convention
|
|
||||||
"DebugInfo/COFF/no-cus.ll",
|
|
||||||
"DebugInfo/Generic/2009-11-05-DeadGlobalVariable.ll",
|
|
||||||
"DebugInfo/Generic/2009-11-10-CurrentFn.ll",
|
|
||||||
"DebugInfo/Generic/2010-01-05-DbgScope.ll",
|
|
||||||
"DebugInfo/Generic/2010-03-12-llc-crash.ll",
|
|
||||||
"DebugInfo/Generic/2010-03-24-MemberFn.ll",
|
|
||||||
"DebugInfo/Generic/2010-04-19-FramePtr.ll",
|
|
||||||
"DebugInfo/Generic/2010-06-29-InlinedFnLocalVar.ll",
|
|
||||||
"DebugInfo/Generic/2010-10-01-crash.ll",
|
|
||||||
"DebugInfo/Generic/PR20038.ll",
|
|
||||||
"DebugInfo/Generic/constant-pointers.ll",
|
|
||||||
"DebugInfo/Generic/dead-argument-order.ll",
|
|
||||||
"DebugInfo/Generic/debug-info-eis-option.ll",
|
|
||||||
"DebugInfo/Generic/def-line.ll",
|
|
||||||
"DebugInfo/Generic/discriminator.ll",
|
|
||||||
"DebugInfo/Generic/dwarf-public-names.ll",
|
|
||||||
"DebugInfo/Generic/enum.ll",
|
|
||||||
"DebugInfo/Generic/func-using-decl.ll",
|
|
||||||
"DebugInfo/Generic/global.ll",
|
|
||||||
"DebugInfo/Generic/imported-name-inlined.ll",
|
|
||||||
"DebugInfo/Generic/incorrect-variable-debugloc1.ll",
|
|
||||||
"DebugInfo/Generic/inline-scopes.ll",
|
|
||||||
"DebugInfo/Generic/inlined-arguments.ll",
|
|
||||||
"DebugInfo/Generic/inlined-vars.ll",
|
|
||||||
"DebugInfo/Generic/linear-dbg-value.ll",
|
|
||||||
"DebugInfo/Generic/linkage-name-abstract.ll",
|
|
||||||
"DebugInfo/Generic/member-order.ll",
|
|
||||||
"DebugInfo/Generic/missing-abstract-variable.ll",
|
|
||||||
"DebugInfo/Generic/multiline.ll",
|
|
||||||
"DebugInfo/Generic/namespace_function_definition.ll",
|
|
||||||
"DebugInfo/Generic/namespace_inline_function_definition.ll",
|
|
||||||
"DebugInfo/Generic/noscopes.ll",
|
|
||||||
"DebugInfo/Generic/ptrsize.ll",
|
|
||||||
"DebugInfo/Generic/restrict.ll",
|
|
||||||
"DebugInfo/Generic/two-cus-from-same-file.ll",
|
|
||||||
"DebugInfo/Generic/version.ll",
|
|
||||||
"DebugInfo/LocalAddressSpace.ll",
|
|
||||||
"DebugInfo/UnknownBaseType.ll",
|
|
||||||
"DebugInfo/expr-opcode.ll",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.NewPackage("spirv-llvm-translator", version, newFromGitHub(
|
|
||||||
"KhronosGroup/SPIRV-LLVM-Translator",
|
|
||||||
"v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Patches: []KV{
|
|
||||||
{"remove-early-prefix", `diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
||||||
index c000a77e..86f79b03 100644
|
|
||||||
--- a/CMakeLists.txt
|
|
||||||
+++ b/CMakeLists.txt
|
|
||||||
@@ -172,5 +172,5 @@ install(
|
|
||||||
FILES
|
|
||||||
${CMAKE_BINARY_DIR}/LLVMSPIRVLib.pc
|
|
||||||
DESTINATION
|
|
||||||
- ${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}/pkgconfig
|
|
||||||
+ lib${LLVM_LIBDIR_SUFFIX}/pkgconfig
|
|
||||||
)
|
|
||||||
`},
|
|
||||||
},
|
|
||||||
|
|
||||||
// litArgs emits shell syntax
|
|
||||||
ScriptEarly: `
|
|
||||||
export LIT_OPTS=` + litArgs(true, skipChecks...) + `
|
|
||||||
`,
|
|
||||||
}, &CMakeHelper{
|
|
||||||
Cache: []KV{
|
|
||||||
{"CMAKE_SKIP_BUILD_RPATH", "ON"},
|
|
||||||
{"BUILD_SHARED_LIBS", "ON"},
|
|
||||||
{"LLVM_SPIRV_ENABLE_LIBSPIRV_DIS", "ON"},
|
|
||||||
{"LLVM_EXTERNAL_SPIRV_HEADERS_SOURCE_DIR", "/system"},
|
|
||||||
{"LLVM_EXTERNAL_LIT", "/system/bin/lit"},
|
|
||||||
{"LLVM_INCLUDE_TESTS", "ON"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Bash,
|
|
||||||
LIT,
|
|
||||||
|
|
||||||
SPIRVTools,
|
|
||||||
), version
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
artifactsM[SPIRVLLVMTranslator] = Metadata{
|
|
||||||
f: Toolchain.newSPIRVLLVMTranslator,
|
|
||||||
|
|
||||||
Name: "spirv-llvm-translator",
|
|
||||||
Description: "bi-directional translation between SPIR-V and LLVM IR",
|
|
||||||
Website: "https://github.com/KhronosGroup/SPIRV-LLVM-Translator",
|
|
||||||
|
|
||||||
Dependencies: P{
|
|
||||||
SPIRVTools,
|
|
||||||
},
|
|
||||||
|
|
||||||
ID: 227273,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,47 +1,11 @@
|
|||||||
package rosa
|
package rosa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"slices"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// skipGNUTests generates a string for skipping specific tests by number in a
|
|
||||||
// GNU test suite. This is nontrivial because the test suite does not support
|
|
||||||
// excluding tests in any way, so ranges for all but the skipped tests have to
|
|
||||||
// be specified instead.
|
|
||||||
//
|
|
||||||
// For example, to skip test 764, ranges around the skipped test must be
|
|
||||||
// specified:
|
|
||||||
//
|
|
||||||
// 1-763 765-
|
|
||||||
//
|
|
||||||
// Tests are numbered starting from 1. The resulting string is unquoted.
|
|
||||||
func skipGNUTests(tests ...int) string {
|
|
||||||
tests = slices.Clone(tests)
|
|
||||||
slices.Sort(tests)
|
|
||||||
|
|
||||||
var buf strings.Builder
|
|
||||||
|
|
||||||
if tests[0] != 1 {
|
|
||||||
buf.WriteString("1-")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range tests {
|
|
||||||
if n != 1 && (i == 0 || tests[i-1] != n-1) {
|
|
||||||
buf.WriteString(strconv.Itoa(n - 1))
|
|
||||||
buf.WriteString(" ")
|
|
||||||
}
|
|
||||||
if i == len(tests)-1 || tests[i+1] != n+1 {
|
|
||||||
buf.WriteString(strconv.Itoa(n + 1))
|
|
||||||
buf.WriteString("-")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t Toolchain) newM4() (pkg.Artifact, string) {
|
func (t Toolchain) newM4() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "1.4.21"
|
version = "1.4.21"
|
||||||
@@ -83,15 +47,7 @@ func (t Toolchain) newBison() (pkg.Artifact, string) {
|
|||||||
"https://ftpmirror.gnu.org/gnu/bison/bison-"+version+".tar.gz",
|
"https://ftpmirror.gnu.org/gnu/bison/bison-"+version+".tar.gz",
|
||||||
checksum,
|
checksum,
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), nil, &MakeHelper{
|
), nil, (*MakeHelper)(nil),
|
||||||
Check: []string{
|
|
||||||
"TESTSUITEFLAGS=" + jobsFlagE + "' " + skipGNUTests(
|
|
||||||
// clang miscompiles (SIGILL)
|
|
||||||
764,
|
|
||||||
) + "'",
|
|
||||||
"check",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
M4,
|
M4,
|
||||||
Diffutils,
|
Diffutils,
|
||||||
Sed,
|
Sed,
|
||||||
@@ -111,8 +67,8 @@ func init() {
|
|||||||
|
|
||||||
func (t Toolchain) newSed() (pkg.Artifact, string) {
|
func (t Toolchain) newSed() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "4.10"
|
version = "4.9"
|
||||||
checksum = "TXTRFQJCyflb-bpBRI2S5Y1DpplwvT7-KfXtpqN4AdZgZ5OtI6yStn1-bkhDKx51"
|
checksum = "pe7HWH4PHNYrazOTlUoE1fXmhn2GOPFN_xE62i0llOr3kYGrH1g2_orDz0UtZ9Nt"
|
||||||
)
|
)
|
||||||
return t.NewPackage("sed", version, newTar(
|
return t.NewPackage("sed", version, newTar(
|
||||||
"https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz",
|
"https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz",
|
||||||
@@ -120,8 +76,6 @@ func (t Toolchain) newSed() (pkg.Artifact, string) {
|
|||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), nil, (*MakeHelper)(nil),
|
), nil, (*MakeHelper)(nil),
|
||||||
Diffutils,
|
Diffutils,
|
||||||
|
|
||||||
KernelHeaders,
|
|
||||||
), version
|
), version
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
@@ -230,9 +184,6 @@ func (t Toolchain) newLibtool() (pkg.Artifact, string) {
|
|||||||
checksum,
|
checksum,
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), nil, &MakeHelper{
|
), nil, &MakeHelper{
|
||||||
// _Z2a2c: symbol not found
|
|
||||||
SkipCheck: t.isStage0(),
|
|
||||||
|
|
||||||
Check: []string{
|
Check: []string{
|
||||||
"TESTSUITEFLAGS=" + jobsFlagE,
|
"TESTSUITEFLAGS=" + jobsFlagE,
|
||||||
"check",
|
"check",
|
||||||
@@ -423,8 +374,8 @@ func init() {
|
|||||||
|
|
||||||
func (t Toolchain) newCoreutils() (pkg.Artifact, string) {
|
func (t Toolchain) newCoreutils() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "9.11"
|
version = "9.10"
|
||||||
checksum = "t8UMed5wpFEoC56aa42_yidfOAaRGzOfj7MRtQkkqgGbpXiskNA8bd-EmVSQkZie"
|
checksum = "o-B9wssRnZySzJUI1ZJAgw-bZtj1RC67R9po2AcM2OjjS8FQIl16IRHpC6IwO30i"
|
||||||
)
|
)
|
||||||
return t.NewPackage("coreutils", version, newTar(
|
return t.NewPackage("coreutils", version, newTar(
|
||||||
"https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz",
|
"https://ftpmirror.gnu.org/gnu/coreutils/coreutils-"+version+".tar.gz",
|
||||||
@@ -436,13 +387,106 @@ func (t Toolchain) newCoreutils() (pkg.Artifact, string) {
|
|||||||
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
|
test_disable() { chmod +w "$2" && echo "$1" > "$2"; }
|
||||||
|
|
||||||
test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh
|
test_disable '#!/bin/sh' gnulib-tests/test-c32ispunct.sh
|
||||||
|
test_disable '#!/bin/sh' tests/split/line-bytes.sh
|
||||||
test_disable '#!/bin/sh' tests/ls/hyperlink.sh
|
test_disable '#!/bin/sh' tests/ls/hyperlink.sh
|
||||||
test_disable '#!/bin/sh' tests/misc/user.sh
|
|
||||||
test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c
|
test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c
|
||||||
test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c
|
test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c
|
||||||
test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
|
test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
|
||||||
`,
|
`,
|
||||||
|
|
||||||
|
Patches: []KV{
|
||||||
|
{"tests-fix-job-control", `From 21d287324aa43aa3a31f39619ade0deac7fd6013 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
|
||||||
|
Date: Tue, 24 Feb 2026 15:44:41 +0000
|
||||||
|
Subject: [PATCH] tests: fix job control triggering test termination
|
||||||
|
|
||||||
|
This avoids the test harness being terminated like:
|
||||||
|
make[1]: *** [Makefile:24419: check-recursive] Hangup
|
||||||
|
make[3]: *** [Makefile:24668: check-TESTS] Hangup
|
||||||
|
make: *** [Makefile:24922: check] Hangup
|
||||||
|
make[2]: *** [Makefile:24920: check-am] Hangup
|
||||||
|
make[4]: *** [Makefile:24685: tests/misc/usage_vs_refs.log] Error 129
|
||||||
|
...
|
||||||
|
|
||||||
|
This happened sometimes when the tests were being run non interactively.
|
||||||
|
For example when run like:
|
||||||
|
|
||||||
|
setsid make TESTS="tests/timeout/timeout.sh \
|
||||||
|
tests/tail/overlay-headers.sh" SUBDIRS=. -j2 check
|
||||||
|
|
||||||
|
Note the race window can be made bigger by adding a sleep
|
||||||
|
after tail is stopped in overlay-headers.sh
|
||||||
|
|
||||||
|
The race can trigger the kernel to induce its job control
|
||||||
|
mechanism to prevent stuck processes.
|
||||||
|
I.e. where it sends SIGHUP + SIGCONT to a process group
|
||||||
|
when it determines that group may become orphaned,
|
||||||
|
and there are stopped processes in that group.
|
||||||
|
|
||||||
|
* tests/tail/overlay-headers.sh: Use setsid(1) to keep the stopped
|
||||||
|
tail process in a separate process group, thus avoiding any kernel
|
||||||
|
job control protection mechanism.
|
||||||
|
* tests/timeout/timeout.sh: Use setsid(1) to avoid the kernel
|
||||||
|
checking the main process group when sleep(1) is reparented.
|
||||||
|
Fixes https://bugs.gnu.org/80477
|
||||||
|
---
|
||||||
|
tests/tail/overlay-headers.sh | 8 +++++++-
|
||||||
|
tests/timeout/timeout.sh | 11 ++++++++---
|
||||||
|
2 files changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/tail/overlay-headers.sh b/tests/tail/overlay-headers.sh
|
||||||
|
index be9b6a7df..1e6da0a3f 100755
|
||||||
|
--- a/tests/tail/overlay-headers.sh
|
||||||
|
+++ b/tests/tail/overlay-headers.sh
|
||||||
|
@@ -20,6 +20,8 @@
|
||||||
|
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||||
|
print_ver_ tail sleep
|
||||||
|
|
||||||
|
+setsid true || skip_ 'setsid required to control groups'
|
||||||
|
+
|
||||||
|
# Function to count number of lines from tail
|
||||||
|
# while ignoring transient errors due to resource limits
|
||||||
|
countlines_ ()
|
||||||
|
@@ -54,7 +56,11 @@ echo start > file2 || framework_failure_
|
||||||
|
env sleep 60 & sleep=$!
|
||||||
|
|
||||||
|
# Note don't use timeout(1) here as it currently
|
||||||
|
-# does not propagate SIGCONT
|
||||||
|
+# does not propagate SIGCONT.
|
||||||
|
+# Note use setsid here to ensure we're in a separate process group
|
||||||
|
+# as we're going to STOP this tail process, and this can trigger
|
||||||
|
+# the kernel to send SIGHUP to a group if other tests have
|
||||||
|
+# processes that are reparented. (See tests/timeout/timeout.sh).
|
||||||
|
tail $fastpoll --pid=$sleep -f file1 file2 > out & pid=$!
|
||||||
|
|
||||||
|
# Ensure tail is running
|
||||||
|
diff --git a/tests/timeout/timeout.sh b/tests/timeout/timeout.sh
|
||||||
|
index 9a395416b..fbb043312 100755
|
||||||
|
--- a/tests/timeout/timeout.sh
|
||||||
|
+++ b/tests/timeout/timeout.sh
|
||||||
|
@@ -56,9 +56,14 @@ returns_ 124 timeout --foreground -s0 -k1 .1 sleep 10 && fail=1
|
||||||
|
) || fail=1
|
||||||
|
|
||||||
|
# Don't be confused when starting off with a child (Bug#9098).
|
||||||
|
-out=$(sleep .1 & exec timeout .5 sh -c 'sleep 2; echo foo')
|
||||||
|
-status=$?
|
||||||
|
-test "$out" = "" && test $status = 124 || fail=1
|
||||||
|
+# Use setsid to avoid sleep being in the test's process group, as
|
||||||
|
+# upon reparenting it can trigger an orphaned process group SIGHUP
|
||||||
|
+# (if there were stopped processes in other tests).
|
||||||
|
+if setsid true; then
|
||||||
|
+ out=$(setsid sleep .1 & exec timeout .5 sh -c 'sleep 2; echo foo')
|
||||||
|
+ status=$?
|
||||||
|
+ test "$out" = "" && test $status = 124 || fail=1
|
||||||
|
+fi
|
||||||
|
|
||||||
|
# Verify --verbose output
|
||||||
|
cat > exp <<\EOF
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
`},
|
||||||
|
},
|
||||||
|
|
||||||
Flag: TEarly,
|
Flag: TEarly,
|
||||||
}, &MakeHelper{
|
}, &MakeHelper{
|
||||||
Configure: []KV{
|
Configure: []KV{
|
||||||
@@ -713,20 +757,15 @@ func init() {
|
|||||||
|
|
||||||
func (t Toolchain) newParallel() (pkg.Artifact, string) {
|
func (t Toolchain) newParallel() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "20260422"
|
version = "20260322"
|
||||||
checksum = "eTsepxgqhXpMEhPd55qh-W5y4vjKn0x9TD2mzbJCNZYtFf4lT4Wzoqr74HGJYBEH"
|
checksum = "gHoPmFkOO62ev4xW59HqyMlodhjp8LvTsBOwsVKHUUdfrt7KwB8koXmSVqQ4VOrB"
|
||||||
)
|
)
|
||||||
return t.NewPackage("parallel", version, newTar(
|
return t.NewPackage("parallel", version, newTar(
|
||||||
"https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
|
"https://ftpmirror.gnu.org/gnu/parallel/parallel-"+version+".tar.bz2",
|
||||||
checksum,
|
checksum,
|
||||||
pkg.TarBzip2,
|
pkg.TarBzip2,
|
||||||
), &PackageAttr{
|
), nil, (*MakeHelper)(nil),
|
||||||
ScriptEarly: `
|
|
||||||
ln -s ../system/bin/bash /bin/
|
|
||||||
`,
|
|
||||||
}, (*MakeHelper)(nil),
|
|
||||||
Perl,
|
Perl,
|
||||||
Bash,
|
|
||||||
), version
|
), version
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
@@ -842,7 +881,7 @@ func (t Toolchain) newGnuTLS() (pkg.Artifact, string) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var configureExtra []KV
|
var configureExtra []KV
|
||||||
switch arch {
|
switch runtime.GOARCH {
|
||||||
case "arm64":
|
case "arm64":
|
||||||
configureExtra = []KV{
|
configureExtra = []KV{
|
||||||
{"disable-hardware-acceleration"},
|
{"disable-hardware-acceleration"},
|
||||||
@@ -1104,11 +1143,10 @@ func init() {
|
|||||||
func (t Toolchain) newMPC() (pkg.Artifact, string) {
|
func (t Toolchain) newMPC() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
checksum = "ZffaZyWkvIw0iPvRe5EJ7O-VvHtSkbbb3K_7SgPtK810NvGan7nbF0T5-6tozjQN"
|
checksum = "wdXAhplnS89FjVp20m2nC2CmLFQeyQqLpQAfViTy4vPxFdv2WYOTtfBKeIk5_Rec"
|
||||||
)
|
)
|
||||||
return t.NewPackage("mpc", version, newFromGitLab(
|
return t.NewPackage("mpc", version, t.newTagRemote(
|
||||||
"gitlab.inria.fr",
|
"https://gitlab.inria.fr/mpc/mpc.git",
|
||||||
"mpc/mpc",
|
|
||||||
version, checksum,
|
version, checksum,
|
||||||
), &PackageAttr{
|
), &PackageAttr{
|
||||||
// does not find mpc-impl.h otherwise
|
// does not find mpc-impl.h otherwise
|
||||||
@@ -1147,7 +1185,7 @@ func (t Toolchain) newGCC() (pkg.Artifact, string) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var configureExtra []KV
|
var configureExtra []KV
|
||||||
switch arch {
|
switch runtime.GOARCH {
|
||||||
case "amd64", "arm64":
|
case "amd64", "arm64":
|
||||||
configureExtra = append(configureExtra, KV{"with-multilib-list", "''"})
|
configureExtra = append(configureExtra, KV{"with-multilib-list", "''"})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import (
|
|
||||||
"slices"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSkipGNUTests(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
tests []int
|
|
||||||
want string
|
|
||||||
}{
|
|
||||||
{[]int{764}, "1-763 765-"},
|
|
||||||
{[]int{764, 0xcafe, 37, 9}, "1-8 10-36 38-763 765-51965 51967-"},
|
|
||||||
{[]int{1, 2, 0xbed}, "3-3052 3054-"},
|
|
||||||
{[]int{3, 4}, "1-2 5-"},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(strings.Join(slices.Collect(func(yield func(string) bool) {
|
|
||||||
for _, n := range tc.tests {
|
|
||||||
yield(strconv.Itoa(n))
|
|
||||||
}
|
|
||||||
}), ","), func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
if got := skipGNUTests(tc.tests...); got != tc.want {
|
|
||||||
t.Errorf("skipGNUTests: %q, want %q", got, tc.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package rosa
|
package rosa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
@@ -9,9 +10,9 @@ import (
|
|||||||
// newGoBootstrap returns the Go bootstrap toolchain.
|
// newGoBootstrap returns the Go bootstrap toolchain.
|
||||||
func (t Toolchain) newGoBootstrap() pkg.Artifact {
|
func (t Toolchain) newGoBootstrap() pkg.Artifact {
|
||||||
const checksum = "8o9JL_ToiQKadCTb04nvBDkp8O1xiWOolAxVEqaTGodieNe4lOFEjlOxN3bwwe23"
|
const checksum = "8o9JL_ToiQKadCTb04nvBDkp8O1xiWOolAxVEqaTGodieNe4lOFEjlOxN3bwwe23"
|
||||||
return t.New("go1.4-bootstrap", 0, t.AppendPresets(nil,
|
return t.New("go1.4-bootstrap", 0, []pkg.Artifact{
|
||||||
Bash,
|
t.Load(Bash),
|
||||||
), nil, []string{
|
}, nil, []string{
|
||||||
"CGO_ENABLED=0",
|
"CGO_ENABLED=0",
|
||||||
}, `
|
}, `
|
||||||
mkdir -p /var/tmp/ /work/system/
|
mkdir -p /var/tmp/ /work/system/
|
||||||
@@ -34,13 +35,9 @@ func (t Toolchain) newGo(
|
|||||||
script string,
|
script string,
|
||||||
extra ...pkg.Artifact,
|
extra ...pkg.Artifact,
|
||||||
) pkg.Artifact {
|
) pkg.Artifact {
|
||||||
name := "all"
|
return t.New("go"+version, 0, slices.Concat([]pkg.Artifact{
|
||||||
if presetOpts&OptSkipCheck != 0 {
|
t.Load(Bash),
|
||||||
name = "make"
|
}, extra), nil, slices.Concat([]string{
|
||||||
}
|
|
||||||
return t.New("go"+version, 0, t.AppendPresets(extra,
|
|
||||||
Bash,
|
|
||||||
), nil, slices.Concat([]string{
|
|
||||||
"CC=cc",
|
"CC=cc",
|
||||||
"GOCACHE=/tmp/gocache",
|
"GOCACHE=/tmp/gocache",
|
||||||
"GOROOT_BOOTSTRAP=/system/go",
|
"GOROOT_BOOTSTRAP=/system/go",
|
||||||
@@ -51,7 +48,7 @@ cp -r /usr/src/go /work/system
|
|||||||
cd /work/system/go/src
|
cd /work/system/go/src
|
||||||
chmod -R +w ..
|
chmod -R +w ..
|
||||||
`+script+`
|
`+script+`
|
||||||
./`+name+`.bash
|
./all.bash
|
||||||
|
|
||||||
mkdir /work/system/bin
|
mkdir /work/system/bin
|
||||||
ln -s \
|
ln -s \
|
||||||
@@ -72,7 +69,7 @@ func (t Toolchain) newGoLatest() (pkg.Artifact, string) {
|
|||||||
|
|
||||||
finalEnv []string
|
finalEnv []string
|
||||||
)
|
)
|
||||||
switch arch {
|
switch runtime.GOARCH {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
bootstrapExtra = append(bootstrapExtra, t.newGoBootstrap())
|
bootstrapExtra = append(bootstrapExtra, t.newGoBootstrap())
|
||||||
|
|
||||||
@@ -82,7 +79,7 @@ func (t Toolchain) newGoLatest() (pkg.Artifact, string) {
|
|||||||
finalEnv = append(finalEnv, "CGO_ENABLED=0")
|
finalEnv = append(finalEnv, "CGO_ENABLED=0")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("unsupported target " + arch)
|
panic("unsupported target " + runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
go119 := t.newGo(
|
go119 := t.newGo(
|
||||||
@@ -107,7 +104,7 @@ echo \
|
|||||||
[]string{"CGO_ENABLED=0"}, `
|
[]string{"CGO_ENABLED=0"}, `
|
||||||
sed -i \
|
sed -i \
|
||||||
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
||||||
cmd/link/internal/`+arch+`/obj.go
|
cmd/link/internal/`+runtime.GOARCH+`/obj.go
|
||||||
|
|
||||||
rm \
|
rm \
|
||||||
crypto/tls/handshake_client_test.go \
|
crypto/tls/handshake_client_test.go \
|
||||||
@@ -125,17 +122,17 @@ echo \
|
|||||||
[]string{"CGO_ENABLED=0"}, `
|
[]string{"CGO_ENABLED=0"}, `
|
||||||
sed -i \
|
sed -i \
|
||||||
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
||||||
cmd/link/internal/`+arch+`/obj.go
|
cmd/link/internal/`+runtime.GOARCH+`/obj.go
|
||||||
`, go121,
|
`, go121,
|
||||||
)
|
)
|
||||||
|
|
||||||
go125 := t.newGo(
|
go125 := t.newGo(
|
||||||
"1.25.10",
|
"1.25.7",
|
||||||
"TwKwatkpwal-j9U2sDSRPEdM3YesI4Gm88YgGV59wtU-L85K9gA7UPy9SCxn6PMb",
|
"fyylHdBVRUobnBjYj3NKBaYPUw3kGmo2mEELiZonOYurPfbarNU1x77B99Fjut7Q",
|
||||||
[]string{"CGO_ENABLED=0"}, `
|
[]string{"CGO_ENABLED=0"}, `
|
||||||
sed -i \
|
sed -i \
|
||||||
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
||||||
cmd/link/internal/`+arch+`/obj.go
|
cmd/link/internal/`+runtime.GOARCH+`/obj.go
|
||||||
|
|
||||||
rm \
|
rm \
|
||||||
os/root_unix_test.go \
|
os/root_unix_test.go \
|
||||||
@@ -144,8 +141,8 @@ rm \
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
version = "1.26.3"
|
version = "1.26.2"
|
||||||
checksum = "lEiFocZFnN5fKvZzmwVdqc9pYUjAuhzqZGbuiOqxUP4XdcY8yECisKcqsQ_eNn1N"
|
checksum = "v-6BE89_1g3xYf-9oIYpJKFXlo3xKHYJj2_VGkaUq8ZVkIVQmLwrto-xGG03OISH"
|
||||||
)
|
)
|
||||||
return t.newGo(
|
return t.newGo(
|
||||||
version,
|
version,
|
||||||
@@ -153,15 +150,10 @@ rm \
|
|||||||
finalEnv, `
|
finalEnv, `
|
||||||
sed -i \
|
sed -i \
|
||||||
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \
|
||||||
cmd/link/internal/`+arch+`/obj.go
|
cmd/link/internal/`+runtime.GOARCH+`/obj.go
|
||||||
sed -i \
|
|
||||||
's/cpu.X86.HasAVX512VBMI/& \&\& cpu.X86.HasPOPCNT/' \
|
|
||||||
internal/runtime/gc/scan/scan_amd64.go
|
|
||||||
|
|
||||||
rm \
|
rm \
|
||||||
os/root_unix_test.go \
|
os/root_unix_test.go
|
||||||
cmd/cgo/internal/testsanitizers/tsan_test.go \
|
|
||||||
cmd/cgo/internal/testsanitizers/cshared_test.go
|
|
||||||
`, go125,
|
`, go125,
|
||||||
), version
|
), version
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ func (t Toolchain) newHakurei(
|
|||||||
withHostname bool,
|
withHostname bool,
|
||||||
) pkg.Artifact {
|
) pkg.Artifact {
|
||||||
hostname := `
|
hostname := `
|
||||||
echo 'Building test helper (hostname).'
|
echo '# Building test helper (hostname).'
|
||||||
go build -o /bin/hostname /usr/src/hostname/main.go
|
go build -v -o /bin/hostname /usr/src/hostname/main.go
|
||||||
|
echo
|
||||||
`
|
`
|
||||||
if !withHostname {
|
if !withHostname {
|
||||||
hostname = ""
|
hostname = ""
|
||||||
@@ -63,9 +64,9 @@ func init() {
|
|||||||
return t.newHakurei("", `
|
return t.newHakurei("", `
|
||||||
mkdir -p /work/system/libexec/hakurei/
|
mkdir -p /work/system/libexec/hakurei/
|
||||||
|
|
||||||
echo "Building hakurei for $(go env GOOS)/$(go env GOARCH)."
|
echo '# Building hakurei.'
|
||||||
go generate ./...
|
go generate -v ./...
|
||||||
go build -trimpath -tags=rosa -o /work/system/libexec/hakurei -ldflags="-s -w
|
go build -trimpath -v -tags=rosa -o /work/system/libexec/hakurei -ldflags="-s -w
|
||||||
-buildid=
|
-buildid=
|
||||||
-linkmode external
|
-linkmode external
|
||||||
-extldflags=-static
|
-extldflags=-static
|
||||||
@@ -76,7 +77,7 @@ go build -trimpath -tags=rosa -o /work/system/libexec/hakurei -ldflags="-s -w
|
|||||||
" ./...
|
" ./...
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo '##### Testing hakurei.'
|
echo '# Testing hakurei.'
|
||||||
go test -ldflags='-buildid= -linkmode external -extldflags=-static' ./...
|
go test -ldflags='-buildid= -linkmode external -extldflags=-static' ./...
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ package rosa
|
|||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
import "hakurei.app/internal/pkg"
|
||||||
|
|
||||||
const hakureiVersion = "0.4.1"
|
const hakureiVersion = "0.4.0"
|
||||||
|
|
||||||
// hakureiSource is the source code of a hakurei release.
|
// hakureiSource is the source code of a hakurei release.
|
||||||
var hakureiSource = newTar(
|
var hakureiSource = newTar(
|
||||||
"https://git.gensokyo.uk/rosa/hakurei/archive/"+
|
"https://git.gensokyo.uk/rosa/hakurei/archive/"+
|
||||||
"v"+hakureiVersion+".tar.gz",
|
"v"+hakureiVersion+".tar.gz",
|
||||||
"8bHvZcjUQOXUPbKL-qq99pHFTPnn-h7j1fkJudbGs8waLm3OmkI6eHfQev5bug2y",
|
"wfQ9DqCW0Fw9o91wj-I55waoqzB-UqzzuC0_2h-P-1M78SgZ1WHSPCDJMth6EyC2",
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
|
||||||
|
|
||||||
func (t Toolchain) newHwdata() (pkg.Artifact, string) {
|
|
||||||
const (
|
|
||||||
version = "0.407"
|
|
||||||
checksum = "6p1XD0CRuzt6hLfjv4ShKBW934BexmoPkRrmwxD4J63fBVCzVBRHyF8pVJdW_Xjm"
|
|
||||||
)
|
|
||||||
return t.NewPackage("hwdata", version, newFromGitHub(
|
|
||||||
"vcrhonek/hwdata",
|
|
||||||
"v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Writable: true,
|
|
||||||
EnterSource: true,
|
|
||||||
}, &MakeHelper{
|
|
||||||
// awk: fatal: cannot open file `hwdata.spec' for reading: No such file or directory
|
|
||||||
InPlace: true,
|
|
||||||
|
|
||||||
// lspci: Unknown option 'A' (see "lspci --help")
|
|
||||||
SkipCheck: true,
|
|
||||||
}), version
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
artifactsM[Hwdata] = Metadata{
|
|
||||||
f: Toolchain.newHwdata,
|
|
||||||
|
|
||||||
Name: "hwdata",
|
|
||||||
Description: "contains various hardware identification and configuration data",
|
|
||||||
Website: "https://github.com/vcrhonek/hwdata",
|
|
||||||
|
|
||||||
ID: 5387,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,12 @@ package rosa
|
|||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
import "hakurei.app/internal/pkg"
|
||||||
|
|
||||||
const kernelVersion = "6.12.84"
|
const kernelVersion = "6.12.81"
|
||||||
|
|
||||||
var kernelSource = newTar(
|
var kernelSource = newTar(
|
||||||
"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+
|
"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+
|
||||||
"snapshot/linux-"+kernelVersion+".tar.gz",
|
"snapshot/linux-"+kernelVersion+".tar.gz",
|
||||||
"GJLUEu68r3DpLYoTcMl4wA_ThMBs_Zwc0gZsp82ii_3AOfcVxpI639IKfq2jAAY2",
|
"fBkNwf82DQXh74in6gaF2Jot7Vg-Vlcp9BUtCEipL9mvcM1EXLVFdV7FcrO20Eve",
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/x86 6.12.84 Kernel Configuration
|
# Linux/x86 6.12.80 Kernel Configuration
|
||||||
#
|
#
|
||||||
CONFIG_CC_VERSION_TEXT="clang version 22.1.4"
|
CONFIG_CC_VERSION_TEXT="clang version 22.1.2"
|
||||||
CONFIG_GCC_VERSION=0
|
CONFIG_GCC_VERSION=0
|
||||||
CONFIG_CC_IS_CLANG=y
|
CONFIG_CC_IS_CLANG=y
|
||||||
CONFIG_CLANG_VERSION=220104
|
CONFIG_CLANG_VERSION=220102
|
||||||
CONFIG_AS_IS_LLVM=y
|
CONFIG_AS_IS_LLVM=y
|
||||||
CONFIG_AS_VERSION=220104
|
CONFIG_AS_VERSION=220102
|
||||||
CONFIG_LD_VERSION=0
|
CONFIG_LD_VERSION=0
|
||||||
CONFIG_LD_IS_LLD=y
|
CONFIG_LD_IS_LLD=y
|
||||||
CONFIG_LLD_VERSION=220104
|
CONFIG_LLD_VERSION=220102
|
||||||
CONFIG_RUSTC_VERSION=0
|
CONFIG_RUSTC_VERSION=0
|
||||||
CONFIG_RUSTC_LLVM_VERSION=0
|
CONFIG_RUSTC_LLVM_VERSION=0
|
||||||
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
|
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
|
||||||
@@ -3175,8 +3175,14 @@ CONFIG_PATA_ACPI=y
|
|||||||
CONFIG_ATA_GENERIC=y
|
CONFIG_ATA_GENERIC=y
|
||||||
CONFIG_PATA_LEGACY=m
|
CONFIG_PATA_LEGACY=m
|
||||||
CONFIG_MD=y
|
CONFIG_MD=y
|
||||||
# CONFIG_BLK_DEV_MD is not set
|
CONFIG_BLK_DEV_MD=m
|
||||||
CONFIG_MD_BITMAP_FILE=y
|
CONFIG_MD_BITMAP_FILE=y
|
||||||
|
CONFIG_MD_LINEAR=m
|
||||||
|
CONFIG_MD_RAID0=m
|
||||||
|
CONFIG_MD_RAID1=m
|
||||||
|
CONFIG_MD_RAID10=m
|
||||||
|
CONFIG_MD_RAID456=m
|
||||||
|
CONFIG_MD_CLUSTER=m
|
||||||
CONFIG_BCACHE=m
|
CONFIG_BCACHE=m
|
||||||
# CONFIG_BCACHE_DEBUG is not set
|
# CONFIG_BCACHE_DEBUG is not set
|
||||||
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
|
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
|
||||||
@@ -3199,7 +3205,7 @@ CONFIG_DM_ERA=m
|
|||||||
CONFIG_DM_CLONE=m
|
CONFIG_DM_CLONE=m
|
||||||
CONFIG_DM_MIRROR=m
|
CONFIG_DM_MIRROR=m
|
||||||
CONFIG_DM_LOG_USERSPACE=m
|
CONFIG_DM_LOG_USERSPACE=m
|
||||||
# CONFIG_DM_RAID is not set
|
CONFIG_DM_RAID=m
|
||||||
CONFIG_DM_ZERO=m
|
CONFIG_DM_ZERO=m
|
||||||
CONFIG_DM_MULTIPATH=m
|
CONFIG_DM_MULTIPATH=m
|
||||||
CONFIG_DM_MULTIPATH_QL=m
|
CONFIG_DM_MULTIPATH_QL=m
|
||||||
@@ -11630,7 +11636,10 @@ CONFIG_RANDSTRUCT_NONE=y
|
|||||||
|
|
||||||
CONFIG_XOR_BLOCKS=m
|
CONFIG_XOR_BLOCKS=m
|
||||||
CONFIG_ASYNC_CORE=m
|
CONFIG_ASYNC_CORE=m
|
||||||
|
CONFIG_ASYNC_MEMCPY=m
|
||||||
CONFIG_ASYNC_XOR=m
|
CONFIG_ASYNC_XOR=m
|
||||||
|
CONFIG_ASYNC_PQ=m
|
||||||
|
CONFIG_ASYNC_RAID6_RECOV=m
|
||||||
CONFIG_CRYPTO=y
|
CONFIG_CRYPTO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -11916,6 +11925,8 @@ CONFIG_BINARY_PRINTF=y
|
|||||||
#
|
#
|
||||||
# Library routines
|
# Library routines
|
||||||
#
|
#
|
||||||
|
CONFIG_RAID6_PQ=m
|
||||||
|
CONFIG_RAID6_PQ_BENCHMARK=y
|
||||||
CONFIG_LINEAR_RANGES=y
|
CONFIG_LINEAR_RANGES=y
|
||||||
CONFIG_PACKING=y
|
CONFIG_PACKING=y
|
||||||
CONFIG_BITREVERSE=y
|
CONFIG_BITREVERSE=y
|
||||||
@@ -12460,6 +12471,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
|
|||||||
# CONFIG_INTERVAL_TREE_TEST is not set
|
# CONFIG_INTERVAL_TREE_TEST is not set
|
||||||
# CONFIG_PERCPU_TEST is not set
|
# CONFIG_PERCPU_TEST is not set
|
||||||
# CONFIG_ATOMIC64_SELFTEST is not set
|
# CONFIG_ATOMIC64_SELFTEST is not set
|
||||||
|
# CONFIG_ASYNC_RAID6_TEST is not set
|
||||||
# CONFIG_TEST_HEXDUMP is not set
|
# CONFIG_TEST_HEXDUMP is not set
|
||||||
# CONFIG_TEST_KSTRTOX is not set
|
# CONFIG_TEST_KSTRTOX is not set
|
||||||
# CONFIG_TEST_PRINTF is not set
|
# CONFIG_TEST_PRINTF is not set
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/arm64 6.12.83 Kernel Configuration
|
# Linux/arm64 6.12.80 Kernel Configuration
|
||||||
#
|
#
|
||||||
CONFIG_CC_VERSION_TEXT="clang version 22.1.4"
|
CONFIG_CC_VERSION_TEXT="clang version 21.1.8"
|
||||||
CONFIG_GCC_VERSION=0
|
CONFIG_GCC_VERSION=0
|
||||||
CONFIG_CC_IS_CLANG=y
|
CONFIG_CC_IS_CLANG=y
|
||||||
CONFIG_CLANG_VERSION=220104
|
CONFIG_CLANG_VERSION=210108
|
||||||
CONFIG_AS_IS_LLVM=y
|
CONFIG_AS_IS_LLVM=y
|
||||||
CONFIG_AS_VERSION=220104
|
CONFIG_AS_VERSION=210108
|
||||||
CONFIG_LD_VERSION=0
|
CONFIG_LD_VERSION=0
|
||||||
CONFIG_LD_IS_LLD=y
|
CONFIG_LD_IS_LLD=y
|
||||||
CONFIG_LLD_VERSION=220104
|
CONFIG_LLD_VERSION=210108
|
||||||
CONFIG_RUSTC_VERSION=0
|
CONFIG_RUSTC_VERSION=0
|
||||||
CONFIG_RUSTC_LLVM_VERSION=0
|
CONFIG_RUSTC_LLVM_VERSION=0
|
||||||
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
|
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
|
||||||
@@ -3253,8 +3253,14 @@ CONFIG_PATA_ACPI=y
|
|||||||
CONFIG_ATA_GENERIC=y
|
CONFIG_ATA_GENERIC=y
|
||||||
CONFIG_PATA_LEGACY=m
|
CONFIG_PATA_LEGACY=m
|
||||||
CONFIG_MD=y
|
CONFIG_MD=y
|
||||||
# CONFIG_BLK_DEV_MD is not set
|
CONFIG_BLK_DEV_MD=m
|
||||||
CONFIG_MD_BITMAP_FILE=y
|
CONFIG_MD_BITMAP_FILE=y
|
||||||
|
CONFIG_MD_LINEAR=m
|
||||||
|
CONFIG_MD_RAID0=m
|
||||||
|
CONFIG_MD_RAID1=m
|
||||||
|
CONFIG_MD_RAID10=m
|
||||||
|
CONFIG_MD_RAID456=m
|
||||||
|
CONFIG_MD_CLUSTER=m
|
||||||
CONFIG_BCACHE=m
|
CONFIG_BCACHE=m
|
||||||
# CONFIG_BCACHE_DEBUG is not set
|
# CONFIG_BCACHE_DEBUG is not set
|
||||||
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
|
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
|
||||||
@@ -3277,7 +3283,7 @@ CONFIG_DM_ERA=m
|
|||||||
CONFIG_DM_CLONE=m
|
CONFIG_DM_CLONE=m
|
||||||
CONFIG_DM_MIRROR=m
|
CONFIG_DM_MIRROR=m
|
||||||
CONFIG_DM_LOG_USERSPACE=m
|
CONFIG_DM_LOG_USERSPACE=m
|
||||||
# CONFIG_DM_RAID is not set
|
CONFIG_DM_RAID=m
|
||||||
CONFIG_DM_ZERO=m
|
CONFIG_DM_ZERO=m
|
||||||
CONFIG_DM_MULTIPATH=m
|
CONFIG_DM_MULTIPATH=m
|
||||||
CONFIG_DM_MULTIPATH_QL=m
|
CONFIG_DM_MULTIPATH_QL=m
|
||||||
@@ -10294,6 +10300,7 @@ CONFIG_ALTERA_MSGDMA=m
|
|||||||
# CONFIG_AMBA_PL08X is not set
|
# CONFIG_AMBA_PL08X is not set
|
||||||
CONFIG_APPLE_ADMAC=m
|
CONFIG_APPLE_ADMAC=m
|
||||||
CONFIG_AXI_DMAC=m
|
CONFIG_AXI_DMAC=m
|
||||||
|
CONFIG_BCM_SBA_RAID=m
|
||||||
CONFIG_DMA_BCM2835=m
|
CONFIG_DMA_BCM2835=m
|
||||||
CONFIG_DMA_SUN6I=m
|
CONFIG_DMA_SUN6I=m
|
||||||
CONFIG_DW_AXI_DMAC=m
|
CONFIG_DW_AXI_DMAC=m
|
||||||
@@ -13285,7 +13292,12 @@ CONFIG_RANDSTRUCT_NONE=y
|
|||||||
|
|
||||||
CONFIG_XOR_BLOCKS=m
|
CONFIG_XOR_BLOCKS=m
|
||||||
CONFIG_ASYNC_CORE=m
|
CONFIG_ASYNC_CORE=m
|
||||||
|
CONFIG_ASYNC_MEMCPY=m
|
||||||
CONFIG_ASYNC_XOR=m
|
CONFIG_ASYNC_XOR=m
|
||||||
|
CONFIG_ASYNC_PQ=m
|
||||||
|
CONFIG_ASYNC_RAID6_RECOV=m
|
||||||
|
CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y
|
||||||
|
CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y
|
||||||
CONFIG_CRYPTO=y
|
CONFIG_CRYPTO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -13628,6 +13640,8 @@ CONFIG_BINARY_PRINTF=y
|
|||||||
#
|
#
|
||||||
# Library routines
|
# Library routines
|
||||||
#
|
#
|
||||||
|
CONFIG_RAID6_PQ=m
|
||||||
|
CONFIG_RAID6_PQ_BENCHMARK=y
|
||||||
CONFIG_LINEAR_RANGES=y
|
CONFIG_LINEAR_RANGES=y
|
||||||
CONFIG_PACKING=y
|
CONFIG_PACKING=y
|
||||||
CONFIG_BITREVERSE=y
|
CONFIG_BITREVERSE=y
|
||||||
@@ -14158,6 +14172,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
|
|||||||
# CONFIG_INTERVAL_TREE_TEST is not set
|
# CONFIG_INTERVAL_TREE_TEST is not set
|
||||||
# CONFIG_PERCPU_TEST is not set
|
# CONFIG_PERCPU_TEST is not set
|
||||||
# CONFIG_ATOMIC64_SELFTEST is not set
|
# CONFIG_ATOMIC64_SELFTEST is not set
|
||||||
|
# CONFIG_ASYNC_RAID6_TEST is not set
|
||||||
# CONFIG_TEST_HEXDUMP is not set
|
# CONFIG_TEST_HEXDUMP is not set
|
||||||
# CONFIG_TEST_KSTRTOX is not set
|
# CONFIG_TEST_KSTRTOX is not set
|
||||||
# CONFIG_TEST_PRINTF is not set
|
# CONFIG_TEST_PRINTF is not set
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/riscv 6.12.80 Kernel Configuration
|
# Linux/riscv 6.12.77 Kernel Configuration
|
||||||
#
|
#
|
||||||
CONFIG_CC_VERSION_TEXT="clang version 22.1.2"
|
CONFIG_CC_VERSION_TEXT="clang version 22.1.2"
|
||||||
CONFIG_GCC_VERSION=0
|
CONFIG_GCC_VERSION=0
|
||||||
@@ -37,6 +37,11 @@ CONFIG_BUILD_SALT=""
|
|||||||
CONFIG_HAVE_KERNEL_GZIP=y
|
CONFIG_HAVE_KERNEL_GZIP=y
|
||||||
CONFIG_HAVE_KERNEL_ZSTD=y
|
CONFIG_HAVE_KERNEL_ZSTD=y
|
||||||
# CONFIG_KERNEL_GZIP is not set
|
# CONFIG_KERNEL_GZIP is not set
|
||||||
|
# CONFIG_KERNEL_BZIP2 is not set
|
||||||
|
# CONFIG_KERNEL_LZMA is not set
|
||||||
|
# CONFIG_KERNEL_XZ is not set
|
||||||
|
# CONFIG_KERNEL_LZO is not set
|
||||||
|
# CONFIG_KERNEL_LZ4 is not set
|
||||||
CONFIG_KERNEL_ZSTD=y
|
CONFIG_KERNEL_ZSTD=y
|
||||||
CONFIG_DEFAULT_INIT=""
|
CONFIG_DEFAULT_INIT=""
|
||||||
CONFIG_DEFAULT_HOSTNAME="rosa-early"
|
CONFIG_DEFAULT_HOSTNAME="rosa-early"
|
||||||
@@ -2843,8 +2848,14 @@ CONFIG_PATA_ACPI=y
|
|||||||
CONFIG_ATA_GENERIC=y
|
CONFIG_ATA_GENERIC=y
|
||||||
CONFIG_PATA_LEGACY=m
|
CONFIG_PATA_LEGACY=m
|
||||||
CONFIG_MD=y
|
CONFIG_MD=y
|
||||||
# CONFIG_BLK_DEV_MD is not set
|
CONFIG_BLK_DEV_MD=m
|
||||||
CONFIG_MD_BITMAP_FILE=y
|
CONFIG_MD_BITMAP_FILE=y
|
||||||
|
CONFIG_MD_LINEAR=m
|
||||||
|
CONFIG_MD_RAID0=m
|
||||||
|
CONFIG_MD_RAID1=m
|
||||||
|
CONFIG_MD_RAID10=m
|
||||||
|
CONFIG_MD_RAID456=m
|
||||||
|
CONFIG_MD_CLUSTER=m
|
||||||
CONFIG_BCACHE=m
|
CONFIG_BCACHE=m
|
||||||
# CONFIG_BCACHE_DEBUG is not set
|
# CONFIG_BCACHE_DEBUG is not set
|
||||||
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
|
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
|
||||||
@@ -2867,7 +2878,7 @@ CONFIG_DM_ERA=m
|
|||||||
CONFIG_DM_CLONE=m
|
CONFIG_DM_CLONE=m
|
||||||
CONFIG_DM_MIRROR=m
|
CONFIG_DM_MIRROR=m
|
||||||
CONFIG_DM_LOG_USERSPACE=m
|
CONFIG_DM_LOG_USERSPACE=m
|
||||||
# CONFIG_DM_RAID is not set
|
CONFIG_DM_RAID=m
|
||||||
CONFIG_DM_ZERO=m
|
CONFIG_DM_ZERO=m
|
||||||
CONFIG_DM_MULTIPATH=m
|
CONFIG_DM_MULTIPATH=m
|
||||||
CONFIG_DM_MULTIPATH_QL=m
|
CONFIG_DM_MULTIPATH_QL=m
|
||||||
@@ -10644,7 +10655,10 @@ CONFIG_RANDSTRUCT_NONE=y
|
|||||||
|
|
||||||
CONFIG_XOR_BLOCKS=m
|
CONFIG_XOR_BLOCKS=m
|
||||||
CONFIG_ASYNC_CORE=m
|
CONFIG_ASYNC_CORE=m
|
||||||
|
CONFIG_ASYNC_MEMCPY=m
|
||||||
CONFIG_ASYNC_XOR=m
|
CONFIG_ASYNC_XOR=m
|
||||||
|
CONFIG_ASYNC_PQ=m
|
||||||
|
CONFIG_ASYNC_RAID6_RECOV=m
|
||||||
CONFIG_CRYPTO=y
|
CONFIG_CRYPTO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -10904,6 +10918,8 @@ CONFIG_BINARY_PRINTF=y
|
|||||||
#
|
#
|
||||||
# Library routines
|
# Library routines
|
||||||
#
|
#
|
||||||
|
CONFIG_RAID6_PQ=m
|
||||||
|
CONFIG_RAID6_PQ_BENCHMARK=y
|
||||||
CONFIG_LINEAR_RANGES=y
|
CONFIG_LINEAR_RANGES=y
|
||||||
CONFIG_PACKING=y
|
CONFIG_PACKING=y
|
||||||
CONFIG_BITREVERSE=y
|
CONFIG_BITREVERSE=y
|
||||||
@@ -11392,6 +11408,7 @@ CONFIG_RUNTIME_TESTING_MENU=y
|
|||||||
# CONFIG_INTERVAL_TREE_TEST is not set
|
# CONFIG_INTERVAL_TREE_TEST is not set
|
||||||
# CONFIG_PERCPU_TEST is not set
|
# CONFIG_PERCPU_TEST is not set
|
||||||
# CONFIG_ATOMIC64_SELFTEST is not set
|
# CONFIG_ATOMIC64_SELFTEST is not set
|
||||||
|
# CONFIG_ASYNC_RAID6_TEST is not set
|
||||||
# CONFIG_TEST_HEXDUMP is not set
|
# CONFIG_TEST_HEXDUMP is not set
|
||||||
# CONFIG_TEST_KSTRTOX is not set
|
# CONFIG_TEST_KSTRTOX is not set
|
||||||
# CONFIG_TEST_PRINTF is not set
|
# CONFIG_TEST_PRINTF is not set
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
|
||||||
|
|
||||||
func (t Toolchain) newLibarchive() (pkg.Artifact, string) {
|
|
||||||
const (
|
|
||||||
version = "3.8.7"
|
|
||||||
checksum = "CUJK4MDQmZmATClgQBH2Wt-7Ts4iiSUlg1J_TVb6-5IK3rVUgVLIMc5k-bnWB9w3"
|
|
||||||
)
|
|
||||||
return t.NewPackage("libarchive", version, newFromGitHub(
|
|
||||||
"libarchive/libarchive",
|
|
||||||
"v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Paths: []pkg.ExecPath{
|
|
||||||
pkg.Path(AbsUsrSrc.Append(
|
|
||||||
"CTestCustom.cmake",
|
|
||||||
), false, pkg.NewFile("CTestCustom.cmake", []byte(`
|
|
||||||
list(APPEND CTEST_CUSTOM_TESTS_IGNORE
|
|
||||||
"libarchive_test_archive_string_conversion_fail_c"
|
|
||||||
"libarchive_test_archive_string_conversion_fail_latin1"
|
|
||||||
"libarchive_test_archive_string_update_utf8_koi8"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_KOI8R_UTF8"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_KOI8R_CP866"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_CP1251_UTF8"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_Russian_Russia"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_EUCJP_UTF8"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_EUCJP_CP932"
|
|
||||||
"libarchive_test_gnutar_filename_encoding_CP932_UTF8"
|
|
||||||
"libarchive_test_pax_filename_encoding_KOI8R"
|
|
||||||
"libarchive_test_pax_filename_encoding_CP1251"
|
|
||||||
"libarchive_test_pax_filename_encoding_EUCJP"
|
|
||||||
"libarchive_test_pax_filename_encoding_CP932"
|
|
||||||
"libarchive_test_read_format_cpio_filename_UTF8_eucJP"
|
|
||||||
"libarchive_test_read_format_cpio_filename_CP866_KOI8R"
|
|
||||||
"libarchive_test_read_format_cpio_filename_KOI8R_CP866"
|
|
||||||
"libarchive_test_read_format_cpio_filename_UTF8_KOI8R"
|
|
||||||
"libarchive_test_read_format_cpio_filename_UTF8_CP866"
|
|
||||||
"libarchive_test_read_format_cpio_filename_eucJP_CP932"
|
|
||||||
"libarchive_test_read_format_cpio_filename_UTF8_CP932"
|
|
||||||
"libarchive_test_read_format_cpio_filename_CP866_CP1251"
|
|
||||||
"libarchive_test_read_format_cpio_filename_CP866_CP1251_win"
|
|
||||||
"libarchive_test_read_format_cpio_filename_KOI8R_CP1251"
|
|
||||||
"libarchive_test_read_format_cpio_filename_UTF8_CP1251"
|
|
||||||
"libarchive_test_read_format_gtar_filename_CP866_KOI8R"
|
|
||||||
"libarchive_test_read_format_gtar_filename_KOI8R_CP866"
|
|
||||||
"libarchive_test_read_format_gtar_filename_eucJP_CP932"
|
|
||||||
"libarchive_test_read_format_gtar_filename_CP866_CP1251"
|
|
||||||
"libarchive_test_read_format_gtar_filename_CP866_CP1251_win"
|
|
||||||
"libarchive_test_read_format_gtar_filename_KOI8R_CP1251"
|
|
||||||
"libarchive_test_read_format_rar_unicode_CP932"
|
|
||||||
"libarchive_test_read_format_zip_filename_CP932_eucJP"
|
|
||||||
"libarchive_test_read_format_zip_filename_UTF8_eucJP"
|
|
||||||
"libarchive_test_read_format_zip_filename_CP866_KOI8R"
|
|
||||||
"libarchive_test_read_format_zip_filename_KOI8R_CP866"
|
|
||||||
"libarchive_test_read_format_zip_filename_UTF8_KOI8R"
|
|
||||||
"libarchive_test_read_format_zip_filename_UTF8_CP866"
|
|
||||||
"libarchive_test_read_format_zip_filename_CP932_CP932"
|
|
||||||
"libarchive_test_read_format_zip_filename_UTF8_CP932"
|
|
||||||
"libarchive_test_read_format_zip_filename_CP866_CP1251"
|
|
||||||
"libarchive_test_read_format_zip_filename_CP866_CP1251_win"
|
|
||||||
"libarchive_test_read_format_zip_filename_KOI8R_CP1251"
|
|
||||||
"libarchive_test_read_format_zip_filename_UTF8_CP1251"
|
|
||||||
"libarchive_test_ustar_filename_encoding_KOI8R_UTF8"
|
|
||||||
"libarchive_test_ustar_filename_encoding_KOI8R_CP866"
|
|
||||||
"libarchive_test_ustar_filename_encoding_CP1251_UTF8"
|
|
||||||
"libarchive_test_ustar_filename_encoding_Russian_Russia"
|
|
||||||
"libarchive_test_ustar_filename_encoding_EUCJP_UTF8"
|
|
||||||
"libarchive_test_ustar_filename_encoding_EUCJP_CP932"
|
|
||||||
"libarchive_test_ustar_filename_encoding_CP932_UTF8"
|
|
||||||
"libarchive_test_zip_filename_encoding_KOI8R"
|
|
||||||
"libarchive_test_zip_filename_encoding_ru_RU_CP1251"
|
|
||||||
"libarchive_test_zip_filename_encoding_Russian_Russia"
|
|
||||||
"libarchive_test_zip_filename_encoding_EUCJP"
|
|
||||||
"libarchive_test_zip_filename_encoding_CP932"
|
|
||||||
"libarchive_test_read_format_cab_filename"
|
|
||||||
"libarchive_test_read_format_lha_filename"
|
|
||||||
"libarchive_test_read_format_tar_filename"
|
|
||||||
"libarchive_test_read_format_ustar_filename"
|
|
||||||
"libarchive_test_read_append_wrong_filter"
|
|
||||||
)
|
|
||||||
`))),
|
|
||||||
},
|
|
||||||
|
|
||||||
Writable: true,
|
|
||||||
ScriptEarly: `
|
|
||||||
install -Dv /usr/src/CTestCustom.cmake /cure/
|
|
||||||
`,
|
|
||||||
}, (*CMakeHelper)(nil)), version
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
artifactsM[Libarchive] = Metadata{
|
|
||||||
f: Toolchain.newLibarchive,
|
|
||||||
|
|
||||||
Name: "libarchive",
|
|
||||||
Description: "multi-format archive and compression library",
|
|
||||||
Website: "https://www.libarchive.org/",
|
|
||||||
|
|
||||||
ID: 1558,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
|
||||||
|
|
||||||
func (t Toolchain) newLibconfig() (pkg.Artifact, string) {
|
|
||||||
const (
|
|
||||||
version = "1.8.2"
|
|
||||||
checksum = "fD32hjeAZuTz98g6WYHRwsxphrgrEFqxi5Z1jlJemPckPBfxpS3i5HgshAuA6vmT"
|
|
||||||
)
|
|
||||||
return t.NewPackage("libconfig", version, newFromGitHub(
|
|
||||||
"hyperrealm/libconfig",
|
|
||||||
"v"+version,
|
|
||||||
checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Patches: []KV{
|
|
||||||
{"disable-broken-tests", `diff --git a/tests/tests.c b/tests/tests.c
|
|
||||||
index eba7eae..f916d2e 100644
|
|
||||||
--- a/tests/tests.c
|
|
||||||
+++ b/tests/tests.c
|
|
||||||
@@ -753,7 +753,6 @@ int main(int argc, char **argv)
|
|
||||||
int failures;
|
|
||||||
|
|
||||||
TT_SUITE_START(LibConfigTests);
|
|
||||||
- TT_SUITE_TEST(LibConfigTests, ParsingAndFormatting);
|
|
||||||
TT_SUITE_TEST(LibConfigTests, ParseInvalidFiles);
|
|
||||||
TT_SUITE_TEST(LibConfigTests, ParseInvalidStrings);
|
|
||||||
TT_SUITE_TEST(LibConfigTests, BigInt1);
|
|
||||||
@@ -768,7 +767,6 @@ int main(int argc, char **argv)
|
|
||||||
TT_SUITE_TEST(LibConfigTests, OverrideSetting);
|
|
||||||
TT_SUITE_TEST(LibConfigTests, SettingLookups);
|
|
||||||
TT_SUITE_TEST(LibConfigTests, ReadStream);
|
|
||||||
- TT_SUITE_TEST(LibConfigTests, BinaryAndHex);
|
|
||||||
TT_SUITE_RUN(LibConfigTests);
|
|
||||||
failures = TT_SUITE_NUM_FAILURES(LibConfigTests);
|
|
||||||
TT_SUITE_END(LibConfigTests);
|
|
||||||
`},
|
|
||||||
},
|
|
||||||
}, (*CMakeHelper)(nil)), version
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
artifactsM[Libconfig] = Metadata{
|
|
||||||
f: Toolchain.newLibconfig,
|
|
||||||
|
|
||||||
Name: "libconfig",
|
|
||||||
Description: "a simple library for processing structured configuration files",
|
|
||||||
Website: "https://hyperrealm.github.io/libconfig/",
|
|
||||||
|
|
||||||
ID: 1580,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
|
||||||
|
|
||||||
func (t Toolchain) newLibdisplayInfo() (pkg.Artifact, string) {
|
|
||||||
const (
|
|
||||||
version = "0.3.0"
|
|
||||||
checksum = "yjOqPUHHYgRtpqGw5RI1n2Q1_hO5j0LiFNMbjcRWV4Nf71XwwoC9fZMlKBDeLchT"
|
|
||||||
)
|
|
||||||
return t.NewPackage("libdisplay-info", version, newFromGitLab(
|
|
||||||
"gitlab.freedesktop.org",
|
|
||||||
"emersion/libdisplay-info",
|
|
||||||
version, checksum,
|
|
||||||
), nil, (*MesonHelper)(nil),
|
|
||||||
Diffutils,
|
|
||||||
|
|
||||||
Hwdata,
|
|
||||||
), version
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
artifactsM[LibdisplayInfo] = Metadata{
|
|
||||||
f: Toolchain.newLibdisplayInfo,
|
|
||||||
|
|
||||||
Name: "libdisplay-info",
|
|
||||||
Description: "EDID and DisplayID library",
|
|
||||||
Website: "https://gitlab.freedesktop.org/emersion/libdisplay-info",
|
|
||||||
|
|
||||||
ID: 326668,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
func (t Toolchain) newLibexpat() (pkg.Artifact, string) {
|
func (t Toolchain) newLibexpat() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "2.8.0"
|
version = "2.7.5"
|
||||||
checksum = "pnwZ_JSif-OfoWIwk2JYXWHagOWMA3Sh-Ea0p-4Rz9U9mDEeAebhyvnfD7OYOMCk"
|
checksum = "vTRUjjg-qbHSXUBYKXgzVHkUO7UNyuhrkSYrE7ikApQm0g-OvQ8tspw4w55M-1Tp"
|
||||||
)
|
)
|
||||||
return t.NewPackage("libexpat", version, newFromGitHubRelease(
|
return t.NewPackage("libexpat", version, newFromGitHubRelease(
|
||||||
"libexpat/libexpat",
|
"libexpat/libexpat",
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package rosa
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t Toolchain) newLibpng() (pkg.Artifact, string) {
|
|
||||||
const (
|
|
||||||
version = "1.6.58"
|
|
||||||
checksum = "m_a5lROJH7vmF3cMjqwTUqURuQLhV1JQx2ySPzcN3VPdgDB9pG3UINsIx_mtkr-t"
|
|
||||||
)
|
|
||||||
return t.NewPackage("libpng", version, newTar(
|
|
||||||
"https://downloads.sourceforge.net/project/libpng/libpng"+
|
|
||||||
strings.Join(strings.SplitN(version, ".", 3)[:2], "")+
|
|
||||||
"/"+version+"/libpng-"+version+".tar.gz",
|
|
||||||
checksum,
|
|
||||||
pkg.TarGzip,
|
|
||||||
), nil, (*MakeHelper)(nil),
|
|
||||||
Zlib,
|
|
||||||
), version
|
|
||||||
}
|
|
||||||
func init() {
|
|
||||||
artifactsM[Libpng] = Metadata{
|
|
||||||
f: Toolchain.newLibpng,
|
|
||||||
|
|
||||||
Name: "libpng",
|
|
||||||
Description: "the official PNG reference library",
|
|
||||||
Website: "https://www.libpng.org/pub/png/libpng.html",
|
|
||||||
|
|
||||||
Dependencies: P{
|
|
||||||
Zlib,
|
|
||||||
},
|
|
||||||
|
|
||||||
ID: 1705,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,11 +5,10 @@ import "hakurei.app/internal/pkg"
|
|||||||
func (t Toolchain) newLibxml2() (pkg.Artifact, string) {
|
func (t Toolchain) newLibxml2() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "2.15.3"
|
version = "2.15.3"
|
||||||
checksum = "oJy74htGlEpf70KPvpW18fYJo0RQQkCXZRwqUz6NoXborS3HCq3Nm4gsyaSeNmUH"
|
checksum = "oWkNe53c3d4Lt4OzrXPHBcOLHJ3TWqpa0x7B7bh_DyZ-uIMiplpdZjQRgRWVal2h"
|
||||||
)
|
)
|
||||||
return t.NewPackage("libxml2", version, newFromGitLab(
|
return t.NewPackage("libxml2", version, t.newTagRemote(
|
||||||
"gitlab.gnome.org",
|
"https://gitlab.gnome.org/GNOME/libxml2.git",
|
||||||
"GNOME/libxml2",
|
|
||||||
"v"+version, checksum,
|
"v"+version, checksum,
|
||||||
), &PackageAttr{
|
), &PackageAttr{
|
||||||
// can't create shell.out: Read-only file system
|
// can't create shell.out: Read-only file system
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import "hakurei.app/internal/pkg"
|
|||||||
func (t Toolchain) newLibxslt() (pkg.Artifact, string) {
|
func (t Toolchain) newLibxslt() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "1.1.45"
|
version = "1.1.45"
|
||||||
checksum = "67ks7v8od2oWaEGf23Sst_Xbn_8brQyolQjqxPoO-lK35k_WJhi2Px5JJgbk-nfn"
|
checksum = "MZc_dyUWpHChkWDKa5iycrECxBsRd4ZMbYfL4VojTbung593mlH2tHGmxYB6NFYT"
|
||||||
)
|
)
|
||||||
return t.NewPackage("libxslt", version, newFromGitLab(
|
return t.NewPackage("libxslt", version, t.newTagRemote(
|
||||||
"gitlab.gnome.org",
|
"https://gitlab.gnome.org/GNOME/libxslt.git",
|
||||||
"GNOME/libxslt",
|
|
||||||
"v"+version, checksum,
|
"v"+version, checksum,
|
||||||
), nil, &MakeHelper{
|
), nil, &MakeHelper{
|
||||||
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
Generate: "NOCONFIGURE=1 ./autogen.sh",
|
||||||
|
|||||||
@@ -1,60 +1,50 @@
|
|||||||
package rosa
|
package rosa
|
||||||
|
|
||||||
import (
|
import "hakurei.app/internal/pkg"
|
||||||
"regexp"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
func init() {
|
||||||
)
|
artifactsM[llvmSource] = Metadata{
|
||||||
|
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||||
|
return t.NewPatchedSource("llvm", llvmVersion, newFromGitHub(
|
||||||
|
"llvm/llvm-project",
|
||||||
|
"llvmorg-"+llvmVersion,
|
||||||
|
llvmChecksum,
|
||||||
|
), true, llvmPatches...), llvmVersion
|
||||||
|
},
|
||||||
|
|
||||||
// litArgs returns [LIT] arguments for optional verbosity and check skipping.
|
Name: "llvm-project",
|
||||||
func litArgs(verbose bool, skipChecks ...string) string {
|
Description: "LLVM monorepo with Rosa OS patches",
|
||||||
args := []string{"-sv"}
|
|
||||||
if verbose {
|
ID: 1830,
|
||||||
args[0] = "--verbose"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(skipChecks) > 0 {
|
|
||||||
skipChecks = slices.Clone(skipChecks)
|
|
||||||
for i, s := range skipChecks {
|
|
||||||
s = regexp.QuoteMeta(s)
|
|
||||||
s = strings.ReplaceAll(s, "/", "\\/")
|
|
||||||
skipChecks[i] = s
|
|
||||||
}
|
|
||||||
args = append(args,
|
|
||||||
"--filter-out='\\''"+strings.Join(skipChecks, "|")+"'\\''")
|
|
||||||
}
|
|
||||||
|
|
||||||
return "'" + strings.Join(args, " ") + "'"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Toolchain) newEarlyCompilerRT() (pkg.Artifact, string) {
|
func (t Toolchain) newCompilerRT() (pkg.Artifact, string) {
|
||||||
version := t.Version(llvmSource)
|
muslHeaders, _ := t.newMusl(true)
|
||||||
major, _, _ := strings.Cut(version, ".")
|
return t.NewPackage("compiler-rt", llvmVersion, t.Load(llvmSource), &PackageAttr{
|
||||||
return t.NewPackage("early-compiler-rt", version, t.Load(llvmSource), &PackageAttr{
|
NonStage0: []pkg.Artifact{
|
||||||
|
muslHeaders,
|
||||||
|
},
|
||||||
|
Env: stage0ExclConcat(t, []string{},
|
||||||
|
"LDFLAGS="+earlyLDFLAGS(false),
|
||||||
|
),
|
||||||
Flag: TExclusive,
|
Flag: TExclusive,
|
||||||
}, &CMakeHelper{
|
}, &CMakeHelper{
|
||||||
Append: []string{"compiler-rt"},
|
Append: []string{"compiler-rt"},
|
||||||
|
|
||||||
Cache: []KV{
|
Cache: []KV{
|
||||||
{"ENABLE_LINKER_BUILD_ID", "ON"},
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
|
|
||||||
|
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
|
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
|
|
||||||
// libc++ not yet available
|
// libc++ not yet available
|
||||||
{"CMAKE_CXX_COMPILER_TARGET", ""},
|
{"CMAKE_CXX_COMPILER_TARGET", ""},
|
||||||
|
|
||||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_ENABLE_RTTI", "ON"},
|
|
||||||
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_LINK_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"},
|
|
||||||
|
|
||||||
{"COMPILER_RT_BUILD_BUILTINS", "ON"},
|
{"COMPILER_RT_BUILD_BUILTINS", "ON"},
|
||||||
{"COMPILER_RT_DEFAULT_TARGET_ONLY", "ON"},
|
{"COMPILER_RT_DEFAULT_TARGET_ONLY", "OFF"},
|
||||||
{"COMPILER_RT_USE_BUILTINS_LIBRARY", "ON"},
|
|
||||||
{"COMPILER_RT_SANITIZERS_TO_BUILD", "asan"},
|
{"COMPILER_RT_SANITIZERS_TO_BUILD", "asan"},
|
||||||
{"COMPILER_RT_BUILD_GWP_ASAN", "OFF"},
|
{"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"},
|
||||||
|
|
||||||
// does not work without libunwind
|
// does not work without libunwind
|
||||||
{"COMPILER_RT_BUILD_CTX_PROFILE", "OFF"},
|
{"COMPILER_RT_BUILD_CTX_PROFILE", "OFF"},
|
||||||
@@ -63,12 +53,11 @@ func (t Toolchain) newEarlyCompilerRT() (pkg.Artifact, string) {
|
|||||||
{"COMPILER_RT_BUILD_PROFILE", "OFF"},
|
{"COMPILER_RT_BUILD_PROFILE", "OFF"},
|
||||||
{"COMPILER_RT_BUILD_XRAY", "OFF"},
|
{"COMPILER_RT_BUILD_XRAY", "OFF"},
|
||||||
},
|
},
|
||||||
SkipTest: true,
|
|
||||||
Script: `
|
Script: `
|
||||||
mkdir -p "/work/system/lib/clang/` + major + `/lib/"
|
mkdir -p "/work/system/lib/clang/` + llvmVersionMajor + `/lib/"
|
||||||
ln -s \
|
ln -s \
|
||||||
"../../../${ROSA_TRIPLE}" \
|
"../../../${ROSA_TRIPLE}" \
|
||||||
"/work/system/lib/clang/` + major + `/lib/"
|
"/work/system/lib/clang/` + llvmVersionMajor + `/lib/"
|
||||||
|
|
||||||
ln -s \
|
ln -s \
|
||||||
"clang_rt.crtbegin-` + linuxArch() + `.o" \
|
"clang_rt.crtbegin-` + linuxArch() + `.o" \
|
||||||
@@ -80,16 +69,16 @@ ln -s \
|
|||||||
},
|
},
|
||||||
Python,
|
Python,
|
||||||
|
|
||||||
muslHeaders,
|
|
||||||
KernelHeaders,
|
KernelHeaders,
|
||||||
), version
|
), llvmVersion
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
artifactsM[earlyCompilerRT] = Metadata{
|
artifactsM[CompilerRT] = Metadata{
|
||||||
f: Toolchain.newEarlyCompilerRT,
|
f: Toolchain.newCompilerRT,
|
||||||
|
|
||||||
Name: "early-compiler-rt",
|
Name: "compiler-rt",
|
||||||
Description: "early LLVM runtime: compiler-rt",
|
Description: "LLVM runtime: compiler-rt",
|
||||||
|
Website: "https://llvm.org/",
|
||||||
|
|
||||||
Dependencies: P{
|
Dependencies: P{
|
||||||
Musl,
|
Musl,
|
||||||
@@ -97,208 +86,110 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Toolchain) newEarlyRuntimes() (pkg.Artifact, string) {
|
func (t Toolchain) newLLVMRuntimes() (pkg.Artifact, string) {
|
||||||
version := t.Version(llvmSource)
|
return t.NewPackage("llvm-runtimes", llvmVersion, t.Load(llvmSource), &PackageAttr{
|
||||||
return t.NewPackage("early-runtimes", version, t.Load(llvmSource), &PackageAttr{
|
NonStage0: t.AppendPresets(nil, CompilerRT),
|
||||||
|
Env: stage0ExclConcat(t, []string{},
|
||||||
|
"LDFLAGS="+earlyLDFLAGS(false),
|
||||||
|
),
|
||||||
Flag: TExclusive,
|
Flag: TExclusive,
|
||||||
}, &CMakeHelper{
|
}, &CMakeHelper{
|
||||||
Append: []string{"runtimes"},
|
Append: []string{"runtimes"},
|
||||||
|
|
||||||
Cache: []KV{
|
Cache: []KV{
|
||||||
{"ENABLE_LINKER_BUILD_ID", "ON"},
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
|
|
||||||
|
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
|
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
|
{"LLVM_ENABLE_RUNTIMES", "'libunwind;libcxx;libcxxabi'"},
|
||||||
|
|
||||||
|
{"LIBUNWIND_USE_COMPILER_RT", "ON"},
|
||||||
|
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
||||||
|
{"LIBCXX_USE_COMPILER_RT", "ON"},
|
||||||
|
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
||||||
|
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
||||||
|
|
||||||
// libc++ not yet available
|
// libc++ not yet available
|
||||||
{"CMAKE_CXX_COMPILER_WORKS", "ON"},
|
{"CMAKE_CXX_COMPILER_WORKS", "ON"},
|
||||||
|
|
||||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
|
||||||
{"LLVM_ENABLE_RTTI", "ON"},
|
|
||||||
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_LINK_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_ENABLE_RUNTIMES", "'libunwind;libcxx;libcxxabi'"},
|
|
||||||
|
|
||||||
{"LIBUNWIND_ENABLE_ASSERTIONS", "OFF"},
|
|
||||||
{"LIBUNWIND_USE_COMPILER_RT", "ON"},
|
|
||||||
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
|
||||||
{"LIBCXX_USE_COMPILER_RT", "ON"},
|
|
||||||
{"LIBCXX_CXX_ABI", "libcxxabi"},
|
|
||||||
{"LIBCXX_ENABLE_STATIC_ABI_LIBRARY", "OFF"},
|
|
||||||
{"LIBCXX_HARDENING_MODE", "fast"},
|
|
||||||
{"LIBCXX_HAS_ATOMIC_LIB", "OFF"},
|
{"LIBCXX_HAS_ATOMIC_LIB", "OFF"},
|
||||||
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
|
||||||
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
|
||||||
{"LIBCXXABI_ENABLE_STATIC_UNWINDER", "OFF"},
|
|
||||||
{"LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL", "OFF"},
|
{"LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL", "OFF"},
|
||||||
|
|
||||||
{"LLVM_ENABLE_ZLIB", "FORCE_ON"},
|
{"LLVM_ENABLE_ZLIB", "OFF"},
|
||||||
{"LLVM_ENABLE_ZSTD", "FORCE_ON"},
|
{"LLVM_ENABLE_ZSTD", "OFF"},
|
||||||
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
||||||
},
|
},
|
||||||
SkipTest: true,
|
|
||||||
},
|
},
|
||||||
Python,
|
Python,
|
||||||
|
|
||||||
Zlib,
|
|
||||||
Zstd,
|
|
||||||
earlyCompilerRT,
|
|
||||||
KernelHeaders,
|
KernelHeaders,
|
||||||
), version
|
), llvmVersion
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
artifactsM[earlyRuntimes] = Metadata{
|
artifactsM[LLVMRuntimes] = Metadata{
|
||||||
f: Toolchain.newEarlyRuntimes,
|
f: Toolchain.newLLVMRuntimes,
|
||||||
|
|
||||||
Name: "early-runtimes",
|
Name: "llvm-runtimes",
|
||||||
Description: "early LLVM runtimes: libunwind, libcxx, libcxxabi",
|
Description: "LLVM runtimes: libunwind, libcxx, libcxxabi",
|
||||||
|
Website: "https://llvm.org/",
|
||||||
|
|
||||||
Dependencies: P{
|
Dependencies: P{
|
||||||
earlyCompilerRT,
|
CompilerRT,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Toolchain) newLLVM() (pkg.Artifact, string) {
|
func (t Toolchain) newClang() (pkg.Artifact, string) {
|
||||||
var early PArtifact = muslHeaders
|
target := "'AArch64;RISCV;X86'"
|
||||||
if t.isStage0() {
|
if t.isStage0() {
|
||||||
// The LLVM build system uses the system installation when building with
|
target = "Native"
|
||||||
// LLVM_LINK_LLVM_DYLIB, since it builds runtimes after the fact, using
|
|
||||||
// the just-built toolchain. This is unacceptable in stage0 due to the
|
|
||||||
// potential version difference. Later stages bootstrap off of runtimes
|
|
||||||
// of its previous stage via 3-stage determinism.
|
|
||||||
early = earlyRuntimes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cache := []KV{
|
return t.NewPackage("clang", llvmVersion, t.Load(llvmSource), &PackageAttr{
|
||||||
{"ENABLE_LINKER_BUILD_ID", "ON"},
|
NonStage0: t.AppendPresets(nil, LLVMRuntimes),
|
||||||
{"COMPILER_RT_USE_BUILTINS_LIBRARY", "ON"},
|
Env: stage0ExclConcat(t, []string{},
|
||||||
{"COMPILER_RT_DEFAULT_TARGET_ONLY", "ON"},
|
"CFLAGS="+earlyCFLAGS,
|
||||||
{"COMPILER_RT_BUILD_GWP_ASAN", "OFF"},
|
"CXXFLAGS="+earlyCXXFLAGS(),
|
||||||
{"LIBCXX_CXX_ABI", "libcxxabi"},
|
"LDFLAGS="+earlyLDFLAGS(false),
|
||||||
{"LIBCXX_USE_COMPILER_RT", "ON"},
|
),
|
||||||
{"LIBCXX_ENABLE_STATIC_ABI_LIBRARY", "OFF"},
|
Flag: TExclusive,
|
||||||
{"LIBCXX_HAS_MUSL_LIBC", "ON"},
|
}, &CMakeHelper{
|
||||||
{"LIBCXX_HARDENING_MODE", "fast"},
|
Append: []string{"llvm"},
|
||||||
{"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
|
|
||||||
{"LIBCXXABI_ENABLE_STATIC_UNWINDER", "OFF"},
|
Cache: []KV{
|
||||||
{"LIBCXXABI_USE_COMPILER_RT", "ON"},
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
{"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"},
|
|
||||||
{"LLVM_INSTALL_UTILS", "ON"},
|
|
||||||
{"LLVM_BUILD_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_LINK_LLVM_DYLIB", "ON"},
|
|
||||||
{"LLVM_APPEND_VC_REV", "OFF"},
|
|
||||||
{"LLVM_ENABLE_RTTI", "ON"},
|
|
||||||
{"LLVM_ENABLE_ZLIB", "FORCE_ON"},
|
|
||||||
{"LLVM_ENABLE_ZSTD", "FORCE_ON"},
|
|
||||||
{"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"},
|
|
||||||
{"LLVM_INCLUDE_BENCHMARKS", "OFF"},
|
|
||||||
{"CLANG_DEFAULT_RTLIB", "compiler-rt"},
|
|
||||||
{"CLANG_DEFAULT_UNWINDLIB", "libunwind"},
|
|
||||||
{"CLANG_DEFAULT_CXX_STDLIB", "libc++"},
|
|
||||||
{"CLANG_CONFIG_FILE_SYSTEM_DIR", "/system/etc/clang"},
|
|
||||||
{"LLVM_ENABLE_FFI", "OFF"},
|
|
||||||
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
|
||||||
{"LLVM_ENABLE_LIBCXX", "ON"},
|
|
||||||
{"LLVM_ENABLE_LLD", "ON"},
|
|
||||||
{"LIBUNWIND_ENABLE_ASSERTIONS", "OFF"},
|
|
||||||
{"LIBUNWIND_USE_COMPILER_RT", "ON"},
|
|
||||||
|
|
||||||
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
{"LLVM_ENABLE_PROJECTS", "'" + strings.Join([]string{
|
{"LLVM_ENABLE_PROJECTS", "'clang;lld'"},
|
||||||
"clang",
|
|
||||||
"lld",
|
|
||||||
}, ";") + "'"},
|
|
||||||
{"LLVM_ENABLE_RUNTIMES", "'" + strings.Join([]string{
|
|
||||||
"compiler-rt",
|
|
||||||
"libcxx",
|
|
||||||
"libcxxabi",
|
|
||||||
"libunwind",
|
|
||||||
"libclc",
|
|
||||||
}, ";") + "'"},
|
|
||||||
}
|
|
||||||
|
|
||||||
if !t.isStage0() {
|
{"LLVM_ENABLE_LIBCXX", "ON"},
|
||||||
skipChecks := []string{
|
{"LLVM_USE_LINKER", "lld"},
|
||||||
// expensive, pointless to run here
|
|
||||||
"benchmarks",
|
|
||||||
// LLVM ERROR: Tried to execute an unknown external function: roundevenf
|
|
||||||
"ExecutionEngine/Interpreter/intrinsics.ll",
|
|
||||||
// clang: deadlocks with LLVM_BUILD_LLVM_DYLIB
|
|
||||||
"crash-recovery-modules",
|
|
||||||
// clang: fatal error: '__config_site' file not found
|
|
||||||
"CodeGen/PowerPC/ppc-xmmintrin.c",
|
|
||||||
"CodeGen/PowerPC/ppc-mmintrin.c",
|
|
||||||
"CodeGen/PowerPC/ppc-emmintrin.c",
|
|
||||||
"CodeGen/PowerPC/ppc-pmmintrin.c",
|
|
||||||
"CodeGen/PowerPC/ppc-tmmintrin.c",
|
|
||||||
"CodeGen/PowerPC/ppc-smmintrin.c",
|
|
||||||
"CodeGenCUDA/amdgpu-alias-undef-symbols.cu",
|
|
||||||
// cxx: fails on musl
|
|
||||||
"close.dont-get-rid-of-buffer",
|
|
||||||
"re/re.traits",
|
|
||||||
"std/time",
|
|
||||||
"localization/locales",
|
|
||||||
"localization/locale.categories",
|
|
||||||
"selftest/dsl/dsl.sh.py",
|
|
||||||
"input.output/iostream.format",
|
|
||||||
"locale-specific_form",
|
|
||||||
// cxx: deadlocks
|
|
||||||
"std/thread/thread.jthread",
|
|
||||||
// unwind: fails on musl
|
|
||||||
"eh_frame_fde_pc_range",
|
|
||||||
}
|
|
||||||
switch arch {
|
|
||||||
case "arm64":
|
|
||||||
skipChecks = append(skipChecks,
|
|
||||||
// LLVM: intermittently crashes
|
|
||||||
"ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll",
|
|
||||||
// unwind: unexpectedly passes
|
|
||||||
"unwind_leaffunction",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if presetOpts&OptLLVMNoLTO == 0 {
|
{"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"},
|
||||||
cache = append(cache, []KV{
|
{"LLVM_INSTALL_CCTOOLS_SYMLINKS", "ON"},
|
||||||
// very expensive
|
|
||||||
{"LLVM_ENABLE_LTO", "Thin"},
|
|
||||||
}...)
|
|
||||||
}
|
|
||||||
|
|
||||||
cache = append(cache, []KV{
|
{"LLVM_LIT_ARGS", "'--verbose'"},
|
||||||
// symbols: clock_gettime, mallopt
|
|
||||||
{"COMPILER_RT_INCLUDE_TESTS", "OFF"},
|
|
||||||
|
|
||||||
{"LLVM_BUILD_TESTS", "ON"},
|
{"CLANG_DEFAULT_LINKER", "lld"},
|
||||||
{"LLVM_LIT_ARGS", litArgs(true, skipChecks...)},
|
{"CLANG_DEFAULT_CXX_STDLIB", "libc++"},
|
||||||
}...)
|
{"CLANG_DEFAULT_RTLIB", "compiler-rt"},
|
||||||
}
|
{"CLANG_DEFAULT_UNWINDLIB", "libunwind"},
|
||||||
|
|
||||||
version := t.Version(llvmSource)
|
{"LLVM_TARGETS_TO_BUILD", target},
|
||||||
return t.NewPackage("llvm", version, t.Load(llvmSource), nil, &CMakeHelper{
|
{"CMAKE_CROSSCOMPILING", "OFF"},
|
||||||
Append: []string{"llvm"},
|
{"CXX_SUPPORTS_CUSTOM_LINKER", "ON"},
|
||||||
|
|
||||||
Cache: cache,
|
{"LLVM_ENABLE_ZLIB", "OFF"},
|
||||||
|
{"LLVM_ENABLE_ZSTD", "OFF"},
|
||||||
|
{"LLVM_ENABLE_LIBXML2", "OFF"},
|
||||||
|
},
|
||||||
Script: `
|
Script: `
|
||||||
ln -s ld.lld /work/system/bin/ld
|
ln -s ld.lld /work/system/bin/ld
|
||||||
|
|
||||||
ln -s clang /work/system/bin/cc
|
ln -s clang /work/system/bin/cc
|
||||||
ln -s clang /work/system/bin/cpp
|
|
||||||
ln -s clang++ /work/system/bin/c++
|
ln -s clang++ /work/system/bin/c++
|
||||||
`,
|
|
||||||
|
|
||||||
// LLVM_LINK_LLVM_DYLIB causes llvm test suite to leak system
|
|
||||||
// installation into test environment, and the tests end up testing the
|
|
||||||
// system installation instead. Tests are disabled on stage0 and relies
|
|
||||||
// on 3-stage determinism to test later stages.
|
|
||||||
SkipTest: t.isStage0(),
|
|
||||||
|
|
||||||
Test: `
|
|
||||||
chmod +w /bin && ln -s \
|
|
||||||
../system/bin/chmod \
|
|
||||||
../system/bin/mkdir \
|
|
||||||
../system/bin/rm \
|
|
||||||
../system/bin/tr \
|
|
||||||
../system/bin/awk \
|
|
||||||
/bin
|
|
||||||
ninja ` + jobsFlagE + ` check-all
|
ninja ` + jobsFlagE + ` check-all
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
@@ -310,44 +201,44 @@ ninja ` + jobsFlagE + ` check-all
|
|||||||
Coreutils,
|
Coreutils,
|
||||||
Findutils,
|
Findutils,
|
||||||
|
|
||||||
Zlib,
|
|
||||||
Zstd,
|
|
||||||
early,
|
|
||||||
KernelHeaders,
|
KernelHeaders,
|
||||||
), version
|
), llvmVersion
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
const (
|
artifactsM[Clang] = Metadata{
|
||||||
version = "22.1.4"
|
f: Toolchain.newClang,
|
||||||
checksum = "Bk3t-tV5sD5T0bqefFMcLeFuAwXnhFipywZmqst5hAZs97QQWGKB_5XyAFjj5tDB"
|
|
||||||
)
|
|
||||||
|
|
||||||
artifactsM[llvmSource] = Metadata{
|
Name: "clang",
|
||||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
Description: `an "LLVM native" C/C++/Objective-C compiler`,
|
||||||
return t.NewPatchedSource("llvm", version, newFromGitHub(
|
Website: "https://llvm.org/",
|
||||||
"llvm/llvm-project",
|
|
||||||
"llvmorg-"+version,
|
|
||||||
checksum,
|
|
||||||
), true, llvmPatches...), version
|
|
||||||
},
|
|
||||||
|
|
||||||
Name: "llvm-project",
|
|
||||||
Description: "LLVM monorepo with Rosa OS patches",
|
|
||||||
|
|
||||||
ID: 1830,
|
|
||||||
}
|
|
||||||
|
|
||||||
artifactsM[LLVM] = Metadata{
|
|
||||||
f: Toolchain.newLLVM,
|
|
||||||
|
|
||||||
Name: "llvm",
|
|
||||||
Description: "a collection of modular and reusable compiler and toolchain technologies",
|
|
||||||
Website: "https://llvm.org",
|
|
||||||
|
|
||||||
Dependencies: P{
|
Dependencies: P{
|
||||||
Zlib,
|
LLVMRuntimes,
|
||||||
Zstd,
|
|
||||||
Musl,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t Toolchain) newLibclc() (pkg.Artifact, string) {
|
||||||
|
return t.NewPackage("libclc", llvmVersion, t.Load(llvmSource), nil, &CMakeHelper{
|
||||||
|
Append: []string{"libclc"},
|
||||||
|
|
||||||
|
Cache: []KV{
|
||||||
|
{"CMAKE_BUILD_TYPE", "Release"},
|
||||||
|
|
||||||
|
{"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
|
{"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
|
||||||
|
|
||||||
|
{"LIBCLC_TARGETS_TO_BUILD", "all"},
|
||||||
|
},
|
||||||
|
Script: "ninja " + jobsFlagE + " test",
|
||||||
|
}), llvmVersion
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
artifactsM[Libclc] = Metadata{
|
||||||
|
f: Toolchain.newLibclc,
|
||||||
|
|
||||||
|
Name: "libclc",
|
||||||
|
Description: "an open source, BSD/MIT dual licensed implementation of the library requirements of the OpenCL C programming language",
|
||||||
|
Website: "https://libclc.llvm.org/",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
9
internal/rosa/llvm_latest.go
Normal file
9
internal/rosa/llvm_latest.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package rosa
|
||||||
|
|
||||||
|
// latest version of LLVM, conditional to temporarily avoid broken new releases
|
||||||
|
const (
|
||||||
|
llvmVersionMajor = "22"
|
||||||
|
llvmVersion = llvmVersionMajor + ".1.3"
|
||||||
|
|
||||||
|
llvmChecksum = "CUwnpzua_y28HZ9oI0NmcKL2wClsSjFpgY9do5-7cCZJHI5KNF64vfwGvY0TYyR3"
|
||||||
|
)
|
||||||
@@ -90,26 +90,11 @@ index 8ac8d4eb9181..e46b04a898ca 100644
|
|||||||
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
|
addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
|
||||||
`},
|
`},
|
||||||
|
|
||||||
{"path-system-libraries", `diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
|
{"path-system-libraries", `diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||||
index cb6a9b242421..b8d31690d1af 100644
|
index 8ac8d4eb9181..f4d1347ab64d 100644
|
||||||
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
|
|
||||||
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
|
|
||||||
@@ -2314,6 +2314,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
|
|
||||||
Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (TargetTriple.getVendor() == llvm::Triple::Rosa) {
|
|
||||||
+ Prefixes.push_back(concat(SysRoot, "/system"));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Fall back to /usr which is used by most non-Solaris systems.
|
|
||||||
Prefixes.push_back(concat(SysRoot, "/usr"));
|
|
||||||
}
|
|
||||||
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
|
|
||||||
index d525b417b4ea..2b93f401733e 100644
|
|
||||||
--- a/clang/lib/Driver/ToolChains/Linux.cpp
|
--- a/clang/lib/Driver/ToolChains/Linux.cpp
|
||||||
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
|
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
|
||||||
@@ -302,6 +302,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
@@ -282,6 +282,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||||
const bool IsHexagon = Arch == llvm::Triple::hexagon;
|
const bool IsHexagon = Arch == llvm::Triple::hexagon;
|
||||||
const bool IsRISCV = Triple.isRISCV();
|
const bool IsRISCV = Triple.isRISCV();
|
||||||
const bool IsCSKY = Triple.isCSKY();
|
const bool IsCSKY = Triple.isCSKY();
|
||||||
@@ -117,7 +102,18 @@ index d525b417b4ea..2b93f401733e 100644
|
|||||||
|
|
||||||
if (IsCSKY && !SelectedMultilibs.empty())
|
if (IsCSKY && !SelectedMultilibs.empty())
|
||||||
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
|
SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
|
||||||
@@ -341,8 +342,12 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
@@ -318,12 +319,23 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||||
|
const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
|
||||||
|
const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
|
||||||
|
|
||||||
|
+ if (IsRosa) {
|
||||||
|
+ ExtraOpts.push_back("-rpath");
|
||||||
|
+ ExtraOpts.push_back("/system/lib");
|
||||||
|
+ ExtraOpts.push_back("-rpath");
|
||||||
|
+ ExtraOpts.push_back(concat("/system/lib", MultiarchTriple));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// mips32: Debian multilib, we use /libo32, while in other case, /lib is
|
||||||
// used. We need add both libo32 and /lib.
|
// used. We need add both libo32 and /lib.
|
||||||
if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {
|
if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {
|
||||||
Generic_GCC::AddMultilibPaths(D, SysRoot, "libo32", MultiarchTriple, Paths);
|
Generic_GCC::AddMultilibPaths(D, SysRoot, "libo32", MultiarchTriple, Paths);
|
||||||
@@ -132,7 +128,7 @@ index d525b417b4ea..2b93f401733e 100644
|
|||||||
}
|
}
|
||||||
Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
|
Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
|
||||||
|
|
||||||
@@ -360,18 +365,30 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
@@ -341,18 +353,30 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
|
||||||
Paths);
|
Paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +164,7 @@ index d525b417b4ea..2b93f401733e 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {
|
ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {
|
||||||
@@ -572,6 +589,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
|
@@ -457,6 +481,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
|
||||||
return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
|
return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
|
||||||
}
|
}
|
||||||
if (Triple.isMusl()) {
|
if (Triple.isMusl()) {
|
||||||
@@ -178,5 +174,18 @@ index d525b417b4ea..2b93f401733e 100644
|
|||||||
std::string ArchName;
|
std::string ArchName;
|
||||||
bool IsArm = false;
|
bool IsArm = false;
|
||||||
|
|
||||||
|
diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp
|
||||||
|
index 64324a3f8b01..15ce70b68217 100644
|
||||||
|
--- a/clang/tools/clang-installapi/Options.cpp
|
||||||
|
+++ b/clang/tools/clang-installapi/Options.cpp
|
||||||
|
@@ -515,7 +515,7 @@ bool Options::processFrontendOptions(InputArgList &Args) {
|
||||||
|
FEOpts.FwkPaths = std::move(FrameworkPaths);
|
||||||
|
|
||||||
|
// Add default framework/library paths.
|
||||||
|
- PathSeq DefaultLibraryPaths = {"/usr/lib", "/usr/local/lib"};
|
||||||
|
+ PathSeq DefaultLibraryPaths = {"/usr/lib", "/system/lib", "/usr/local/lib"};
|
||||||
|
PathSeq DefaultFrameworkPaths = {"/Library/Frameworks",
|
||||||
|
"/System/Library/Frameworks"};
|
||||||
|
|
||||||
`},
|
`},
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ cd "$(mktemp -d)"
|
|||||||
--build="${ROSA_TRIPLE}" \
|
--build="${ROSA_TRIPLE}" \
|
||||||
--disable-dependency-tracking
|
--disable-dependency-tracking
|
||||||
./build.sh
|
./build.sh
|
||||||
./make DESTDIR=/work install
|
./make DESTDIR=/work install check
|
||||||
`, pkg.Path(AbsUsrSrc.Append("make"), false, newTar(
|
`, pkg.Path(AbsUsrSrc.Append("make"), false, newTar(
|
||||||
"https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz",
|
"https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz",
|
||||||
checksum,
|
checksum,
|
||||||
@@ -194,7 +194,7 @@ make \
|
|||||||
}
|
}
|
||||||
scriptMake += "\n"
|
scriptMake += "\n"
|
||||||
|
|
||||||
if !attr.SkipCheck && presetOpts&OptSkipCheck == 0 {
|
if !attr.SkipCheck {
|
||||||
scriptMake += attr.ScriptCheckEarly + `make \
|
scriptMake += attr.ScriptCheckEarly + `make \
|
||||||
` + jobsFlagE + ` \
|
` + jobsFlagE + ` \
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ func init() {
|
|||||||
|
|
||||||
func (t Toolchain) newLibdrm() (pkg.Artifact, string) {
|
func (t Toolchain) newLibdrm() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "2.4.133"
|
version = "2.4.131"
|
||||||
checksum = "bfj296NcR9DndO11hqDbSRFPqaweSLMqRk3dlCPZpM6FONX1WZ9J4JdbTDMUd1rU"
|
checksum = "riHPSpvTnvCPbR-iT4jt7_X-z4rpwm6oNh9ZN2zP6RBFkFVxBRKmedG4eEXSADIh"
|
||||||
)
|
)
|
||||||
return t.NewPackage("libdrm", version, newFromGitLab(
|
return t.NewPackage("libdrm", version, newFromGitLab(
|
||||||
"gitlab.freedesktop.org",
|
"gitlab.freedesktop.org",
|
||||||
|
|||||||
@@ -9,47 +9,27 @@ import (
|
|||||||
|
|
||||||
func (t Toolchain) newMeson() (pkg.Artifact, string) {
|
func (t Toolchain) newMeson() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "1.11.1"
|
version = "1.11.0"
|
||||||
checksum = "uvILRxdopwc6Dy17UbIeClcQr0qHqyTaqyk1M9OqWKN9PwB9N6UVAiyN8kSSz3r2"
|
checksum = "b7oo3U_cklhzsTfsyYsjPGyeEufiS-Pm06JPLzodseS125Ach62ZBly7R6dSDiAc"
|
||||||
)
|
)
|
||||||
return t.NewPackage("meson", version, newFromGitHub(
|
return t.New("meson-"+version, 0, []pkg.Artifact{
|
||||||
|
t.Load(Zlib),
|
||||||
|
t.Load(Python),
|
||||||
|
t.Load(Setuptools),
|
||||||
|
}, nil, nil, `
|
||||||
|
cd /usr/src/meson
|
||||||
|
chmod -R +w meson.egg-info
|
||||||
|
python3 setup.py \
|
||||||
|
install \
|
||||||
|
--prefix=/system \
|
||||||
|
--root=/work
|
||||||
|
`, pkg.Path(AbsUsrSrc.Append("meson"), true, newFromGitHubRelease(
|
||||||
"mesonbuild/meson",
|
"mesonbuild/meson",
|
||||||
version,
|
version,
|
||||||
|
"meson-"+version+".tar.gz",
|
||||||
checksum,
|
checksum,
|
||||||
), &PackageAttr{
|
pkg.TarGzip,
|
||||||
Env: []string{
|
))), version
|
||||||
"CMAKE_MAKE_PROGRAM=ninja",
|
|
||||||
},
|
|
||||||
}, &PipHelper{
|
|
||||||
EnterSource: true,
|
|
||||||
Check: `
|
|
||||||
cd 'test cases'
|
|
||||||
rm -rf \
|
|
||||||
'common/32 has header' \
|
|
||||||
'common/66 vcstag' \
|
|
||||||
'common/153 wrap file should not failed' \
|
|
||||||
'common/184 openmp' \
|
|
||||||
'common/189 check header' \
|
|
||||||
'linuxlike/6 subdir include order' \
|
|
||||||
'linuxlike/9 compiler checks with dependencies' \
|
|
||||||
'linuxlike/13 cmake dependency' \
|
|
||||||
'frameworks/15 llvm' \
|
|
||||||
'frameworks/29 blocks'
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
python3 ./run_project_tests.py \
|
|
||||||
-v \
|
|
||||||
` + jobsFlagE + ` \
|
|
||||||
--failfast \
|
|
||||||
--backend=ninja
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
PythonSetuptools,
|
|
||||||
PkgConfig,
|
|
||||||
CMake,
|
|
||||||
Ninja,
|
|
||||||
PythonPyTest,
|
|
||||||
), version
|
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
artifactsM[Meson] = Metadata{
|
artifactsM[Meson] = Metadata{
|
||||||
@@ -117,7 +97,7 @@ func (attr *MesonHelper) script(name string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var scriptTest string
|
var scriptTest string
|
||||||
if !attr.SkipTest && presetOpts&OptSkipCheck == 0 {
|
if !attr.SkipTest {
|
||||||
scriptTest = `
|
scriptTest = `
|
||||||
meson test \
|
meson test \
|
||||||
--print-errorlogs`
|
--print-errorlogs`
|
||||||
@@ -128,7 +108,7 @@ cd "$(mktemp -d)"
|
|||||||
meson setup \
|
meson setup \
|
||||||
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
` + strings.Join(slices.Collect(func(yield func(string) bool) {
|
||||||
for _, v := range append([]KV{
|
for _, v := range append([]KV{
|
||||||
{"wrap-mode", "nofallback"},
|
{"wrap-mode", "nodownload"},
|
||||||
{"prefix", "/system"},
|
{"prefix", "/system"},
|
||||||
{"buildtype", "release"},
|
{"buildtype", "release"},
|
||||||
}, attr.Setup...) {
|
}, attr.Setup...) {
|
||||||
|
|||||||
@@ -7,13 +7,9 @@ func (t Toolchain) newMksh() (pkg.Artifact, string) {
|
|||||||
version = "59c"
|
version = "59c"
|
||||||
checksum = "0Zj-k4nXEu3IuJY4lvwD2OrC2t27GdZj8SPy4DoaeuBRH1padWb7oREpYgwY8JNq"
|
checksum = "0Zj-k4nXEu3IuJY4lvwD2OrC2t27GdZj8SPy4DoaeuBRH1padWb7oREpYgwY8JNq"
|
||||||
)
|
)
|
||||||
scriptTest := "./test.sh -C regress:no-ctty\n"
|
return t.New("mksh-"+version, 0, stage0Concat(t, []pkg.Artifact{},
|
||||||
if presetOpts&OptSkipCheck != 0 {
|
t.Load(Perl),
|
||||||
scriptTest = ""
|
t.Load(Coreutils),
|
||||||
}
|
|
||||||
return t.New("mksh-"+version, 0, t.AppendPresets(nil,
|
|
||||||
Perl,
|
|
||||||
Coreutils,
|
|
||||||
), nil, []string{
|
), nil, []string{
|
||||||
"LDSTATIC=-static",
|
"LDSTATIC=-static",
|
||||||
"CPPFLAGS=-DMKSH_DEFAULT_PROFILEDIR=\\\"/system/etc\\\"",
|
"CPPFLAGS=-DMKSH_DEFAULT_PROFILEDIR=\\\"/system/etc\\\"",
|
||||||
@@ -22,7 +18,8 @@ cd "$(mktemp -d)"
|
|||||||
sh /usr/src/mksh/Build.sh -r
|
sh /usr/src/mksh/Build.sh -r
|
||||||
CPPFLAGS="${CPPFLAGS} -DMKSH_BINSHPOSIX -DMKSH_BINSHREDUCED" \
|
CPPFLAGS="${CPPFLAGS} -DMKSH_BINSHPOSIX -DMKSH_BINSHREDUCED" \
|
||||||
sh /usr/src/mksh/Build.sh -r -L
|
sh /usr/src/mksh/Build.sh -r -L
|
||||||
`+scriptTest+`
|
./test.sh -C regress:no-ctty
|
||||||
|
|
||||||
mkdir -p /work/system/bin/
|
mkdir -p /work/system/bin/
|
||||||
cp -v mksh /work/system/bin/
|
cp -v mksh /work/system/bin/
|
||||||
cp -v lksh /work/system/bin/sh
|
cp -v lksh /work/system/bin/sh
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package rosa
|
|||||||
|
|
||||||
import "hakurei.app/internal/pkg"
|
import "hakurei.app/internal/pkg"
|
||||||
|
|
||||||
func (t Toolchain) newMusl(headers bool) (pkg.Artifact, string) {
|
func (t Toolchain) newMusl(
|
||||||
|
headers bool,
|
||||||
|
extra ...pkg.Artifact,
|
||||||
|
) (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "1.2.6"
|
version = "1.2.6"
|
||||||
checksum = "WtWb_OV_XxLDAB5NerOL9loLlHVadV00MmGk65PPBU1evaolagoMHfvpZp_vxEzS"
|
checksum = "WtWb_OV_XxLDAB5NerOL9loLlHVadV00MmGk65PPBU1evaolagoMHfvpZp_vxEzS"
|
||||||
@@ -33,43 +36,25 @@ rmdir -v /work/lib
|
|||||||
helper.Script = ""
|
helper.Script = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
env := []string{
|
|
||||||
"LDFLAGS=" + earlyLDFLAGS(false),
|
|
||||||
}
|
|
||||||
if t.isStage0() {
|
|
||||||
env = append(env,
|
|
||||||
"CC=clang",
|
|
||||||
"AR=ar",
|
|
||||||
"RANLIB=ranlib",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.NewPackage(name, version, newTar(
|
return t.NewPackage(name, version, newTar(
|
||||||
"https://musl.libc.org/releases/musl-"+version+".tar.gz",
|
"https://musl.libc.org/releases/musl-"+version+".tar.gz",
|
||||||
checksum,
|
checksum,
|
||||||
pkg.TarGzip,
|
pkg.TarGzip,
|
||||||
), &PackageAttr{
|
), &PackageAttr{
|
||||||
|
NonStage0: extra,
|
||||||
|
|
||||||
// expected to be writable in copies
|
// expected to be writable in copies
|
||||||
Chmod: true,
|
Chmod: true,
|
||||||
|
|
||||||
Env: env,
|
Env: stage0ExclConcat(t, []string{
|
||||||
|
"CC=clang",
|
||||||
Patches: []KV{
|
"LIBCC=/system/lib/clang/" + llvmVersionMajor + "/lib/" +
|
||||||
{"ldso-rosa", `diff --git a/ldso/dynlink.c b/ldso/dynlink.c
|
triplet() + "/libclang_rt.builtins.a",
|
||||||
index 715948f4..c2fece68 100644
|
"AR=ar",
|
||||||
--- a/ldso/dynlink.c
|
"RANLIB=ranlib",
|
||||||
+++ b/ldso/dynlink.c
|
|
||||||
@@ -1157,7 +1157,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
|
|
||||||
sys_path = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
|
|
||||||
+ if (!sys_path) sys_path = "/system/lib:/system/lib/" LDSO_ARCH "-rosa-linux-musl:/lib:/usr/local/lib:/usr/lib";
|
|
||||||
fd = path_open(name, sys_path, buf, sizeof buf);
|
|
||||||
}
|
|
||||||
pathname = buf;
|
|
||||||
`},
|
|
||||||
},
|
},
|
||||||
|
"LDFLAGS="+earlyLDFLAGS(false),
|
||||||
|
),
|
||||||
}, &helper,
|
}, &helper,
|
||||||
Coreutils,
|
Coreutils,
|
||||||
), version
|
), version
|
||||||
@@ -77,7 +62,7 @@ index 715948f4..c2fece68 100644
|
|||||||
func init() {
|
func init() {
|
||||||
artifactsM[Musl] = Metadata{
|
artifactsM[Musl] = Metadata{
|
||||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||||
return t.newMusl(false)
|
return t.newMusl(false, t.Load(CompilerRT))
|
||||||
},
|
},
|
||||||
|
|
||||||
Name: "musl",
|
Name: "musl",
|
||||||
@@ -86,13 +71,4 @@ func init() {
|
|||||||
|
|
||||||
ID: 11688,
|
ID: 11688,
|
||||||
}
|
}
|
||||||
|
|
||||||
artifactsM[muslHeaders] = Metadata{
|
|
||||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
|
||||||
return t.newMusl(true)
|
|
||||||
},
|
|
||||||
|
|
||||||
Name: "musl-headers",
|
|
||||||
Description: "system installation of musl headers",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
func (t Toolchain) newNSS() (pkg.Artifact, string) {
|
func (t Toolchain) newNSS() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "3.123.1"
|
version = "3.123"
|
||||||
checksum = "g811Z_fc74ssg-s6BeXRG-ipSfJggD6hrxjVJxrOBIz98CE7piv0OLwzIRLMQpwR"
|
checksum = "pwBz0FO8jmhejPblfzNQLGsqBBGT0DwAw-z9yBJH3V3hVJBMKSc1l0R8GC0_BnzF"
|
||||||
|
|
||||||
version0 = "4_38_2"
|
version0 = "4_38_2"
|
||||||
checksum0 = "25x2uJeQnOHIiq_zj17b4sYqKgeoU8-IsySUptoPcdHZ52PohFZfGuIisBreWzx0"
|
checksum0 = "25x2uJeQnOHIiq_zj17b4sYqKgeoU8-IsySUptoPcdHZ52PohFZfGuIisBreWzx0"
|
||||||
@@ -82,24 +82,30 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func (t Toolchain) newBuildCATrust() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
checksum = "oxjnuIrPVMPvD6x8VFLqB7EdbfuhouGQdtPuHDpEHGzoyH5nkxqtYN9UthMY9noA"
|
checksum = "g9AqIksz-hvCUceSR7ZKwfqf8Y_UsJU_3_zLUIdc4IkxFVkgdv9kKVvhFjE4s1-7"
|
||||||
)
|
|
||||||
artifactsM[buildcatrust] = newPythonPackage(
|
|
||||||
"buildcatrust", 233988,
|
|
||||||
"transform certificate stores between formats",
|
|
||||||
"https://github.com/nix-community/buildcatrust",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"nix-community/buildcatrust",
|
|
||||||
"v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
ScriptEarly: `
|
|
||||||
rm buildcatrust/tests/test_nonhermetic.py
|
|
||||||
`,
|
|
||||||
}, nil, P{PythonFlitCore},
|
|
||||||
)
|
)
|
||||||
|
return t.newViaPip("buildcatrust", version,
|
||||||
|
"https://github.com/nix-community/buildcatrust/releases/"+
|
||||||
|
"download/v"+version+"/buildcatrust-"+version+"-py3-none-any.whl",
|
||||||
|
checksum), version
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
artifactsM[buildcatrust] = Metadata{
|
||||||
|
f: Toolchain.newBuildCATrust,
|
||||||
|
|
||||||
|
Name: "buildcatrust",
|
||||||
|
Description: "transform certificate stores between formats",
|
||||||
|
Website: "https://github.com/nix-community/buildcatrust",
|
||||||
|
|
||||||
|
Dependencies: P{
|
||||||
|
Python,
|
||||||
|
},
|
||||||
|
|
||||||
|
ID: 233988,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Toolchain) newNSSCACert() (pkg.Artifact, string) {
|
func (t Toolchain) newNSSCACert() (pkg.Artifact, string) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func (t Toolchain) newPerl() (pkg.Artifact, string) {
|
|||||||
|
|
||||||
ScriptEarly: `
|
ScriptEarly: `
|
||||||
echo 'print STDOUT "1..0 # Skip broken test\n";' > ext/Pod-Html/t/htmldir3.t
|
echo 'print STDOUT "1..0 # Skip broken test\n";' > ext/Pod-Html/t/htmldir3.t
|
||||||
chmod +w /system/bin && rm -f /system/bin/ps # perl does not like toybox ps
|
rm -f /system/bin/ps # perl does not like toybox ps
|
||||||
`,
|
`,
|
||||||
|
|
||||||
Flag: TEarly,
|
Flag: TEarly,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package rosa
|
package rosa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -22,32 +23,6 @@ func (t Toolchain) newPython() (pkg.Artifact, string) {
|
|||||||
Writable: true,
|
Writable: true,
|
||||||
Chmod: true,
|
Chmod: true,
|
||||||
|
|
||||||
Patches: []KV{
|
|
||||||
{"zipfile-no-default-strict_timestamps", `diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py
|
|
||||||
index 19aea290b58..51603ba9510 100644
|
|
||||||
--- a/Lib/zipfile/__init__.py
|
|
||||||
+++ b/Lib/zipfile/__init__.py
|
|
||||||
@@ -617,7 +617,7 @@ def _decodeExtra(self, filename_crc):
|
|
||||||
extra = extra[ln+4:]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
- def from_file(cls, filename, arcname=None, *, strict_timestamps=True):
|
|
||||||
+ 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
|
|
||||||
|
|
||||||
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'."""
|
|
||||||
if mode not in ('r', 'w', 'x', 'a'):
|
|
||||||
`},
|
|
||||||
},
|
|
||||||
|
|
||||||
Env: []string{
|
Env: []string{
|
||||||
"EXTRATESTOPTS=-j0 -x " + strings.Join([]string{
|
"EXTRATESTOPTS=-j0 -x " + strings.Join([]string{
|
||||||
// requires internet access (http://www.pythontest.net/)
|
// requires internet access (http://www.pythontest.net/)
|
||||||
@@ -61,7 +36,7 @@ index 19aea290b58..51603ba9510 100644
|
|||||||
"test_os",
|
"test_os",
|
||||||
"test_subprocess",
|
"test_subprocess",
|
||||||
|
|
||||||
// patched out insane strict_timestamps default
|
// somehow picks up mtime of source code
|
||||||
"test_zipfile",
|
"test_zipfile",
|
||||||
|
|
||||||
// requires gcc
|
// requires gcc
|
||||||
@@ -106,112 +81,47 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PipHelper is the [Python] pip packaging helper.
|
// newViaPip installs a pip wheel from a url.
|
||||||
type PipHelper struct {
|
func (t Toolchain) newViaPip(
|
||||||
// Path elements joined with source.
|
name, version, url, checksum string,
|
||||||
Append []string
|
extra ...PArtifact,
|
||||||
// Whether to omit --no-build-isolation.
|
) pkg.Artifact {
|
||||||
BuildIsolation bool
|
return t.New(name+"-"+version, 0, t.AppendPresets(nil,
|
||||||
// Whether to enter source after install.
|
slices.Concat(P{Python}, extra)...,
|
||||||
EnterSource bool
|
), nil, nil, `
|
||||||
// Whether to install to build environment after install.
|
|
||||||
Install bool
|
|
||||||
// Whether to skip running tests.
|
|
||||||
SkipCheck bool
|
|
||||||
// Replaces pytest if non-empty.
|
|
||||||
Check string
|
|
||||||
// Runs after install.
|
|
||||||
Script string
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ Helper = new(PipHelper)
|
|
||||||
|
|
||||||
// extra returns python, or pytest if defaults are assumed.
|
|
||||||
func (attr *PipHelper) extra(int) P {
|
|
||||||
if attr == nil || (!attr.SkipCheck && attr.Check == "") {
|
|
||||||
return P{PythonPyTest}
|
|
||||||
}
|
|
||||||
return P{Python}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wantsChmod returns true.
|
|
||||||
func (*PipHelper) wantsChmod() bool { return true }
|
|
||||||
|
|
||||||
// wantsWrite is equivalent to wantsChmod.
|
|
||||||
func (attr *PipHelper) wantsWrite() bool { return attr.wantsChmod() }
|
|
||||||
|
|
||||||
// scriptEarly is a noop.
|
|
||||||
func (*PipHelper) scriptEarly() string { return "" }
|
|
||||||
|
|
||||||
// createDir returns false.
|
|
||||||
func (*PipHelper) createDir() bool { return false }
|
|
||||||
|
|
||||||
// wantsDir requests a new directory in TMPDIR.
|
|
||||||
func (*PipHelper) wantsDir() string { return `"$(mktemp -d)"` }
|
|
||||||
|
|
||||||
// script generates the pip3 install command.
|
|
||||||
func (attr *PipHelper) script(name string) string {
|
|
||||||
if attr == nil {
|
|
||||||
attr = new(PipHelper)
|
|
||||||
}
|
|
||||||
sourcePath := AbsUsrSrc.Append(name).Append(attr.Append...)
|
|
||||||
|
|
||||||
var extra string
|
|
||||||
if !attr.BuildIsolation {
|
|
||||||
extra += `
|
|
||||||
--no-build-isolation \`
|
|
||||||
}
|
|
||||||
|
|
||||||
var script string
|
|
||||||
if attr.Install {
|
|
||||||
script += `pip3 install \
|
|
||||||
--no-index \
|
|
||||||
--prefix=/system \
|
|
||||||
--no-build-isolation \
|
|
||||||
'` + sourcePath.String() + `'
|
|
||||||
`
|
|
||||||
}
|
|
||||||
if attr.EnterSource {
|
|
||||||
script += "cd '/usr/src/" + name + "'\n"
|
|
||||||
}
|
|
||||||
if !attr.SkipCheck {
|
|
||||||
if attr.Check == "" {
|
|
||||||
// some test suites fall apart when ran out-of-tree
|
|
||||||
script += "(cd '" + sourcePath.String() + "' && pytest)\n"
|
|
||||||
} else {
|
|
||||||
script += attr.Check
|
|
||||||
}
|
|
||||||
}
|
|
||||||
script += attr.Script
|
|
||||||
|
|
||||||
return `
|
|
||||||
pip3 install \
|
pip3 install \
|
||||||
--no-index \
|
--no-index \
|
||||||
--prefix=/system \
|
--prefix=/system \
|
||||||
--root=/work \` + extra + `
|
--root=/work \
|
||||||
'` + sourcePath.String() + `'
|
'/usr/src/`+path.Base(url)+`'
|
||||||
` + script
|
`, pkg.Path(AbsUsrSrc.Append(path.Base(url)), false, pkg.NewHTTPGet(
|
||||||
|
nil, url,
|
||||||
|
mustDecode(checksum),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// newPythonPackage creates [Metadata] for a [Python] package.
|
// newPypi creates [Metadata] for a [pypi] package.
|
||||||
func newPythonPackage(
|
//
|
||||||
name string, id int, description, website, version string,
|
// [pypi]: https://pypi.org/
|
||||||
source pkg.Artifact, attrP *PackageAttr, attr *PipHelper,
|
func newPypi(
|
||||||
build P, extra ...PArtifact,
|
name string, id int,
|
||||||
|
description, version, interpreter, abi, platform, checksum string,
|
||||||
|
extra ...PArtifact,
|
||||||
) Metadata {
|
) Metadata {
|
||||||
name = "python-" + name
|
|
||||||
return Metadata{
|
return Metadata{
|
||||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
f: func(t Toolchain) (pkg.Artifact, string) {
|
||||||
return t.NewPackage(name, version, source, attrP, attr, slices.Concat(
|
return t.newViaPip(name, version, "https://files.pythonhosted.org/"+path.Join(
|
||||||
P{Python},
|
"packages",
|
||||||
extra,
|
interpreter,
|
||||||
build,
|
string(name[0]),
|
||||||
)...), version
|
name,
|
||||||
|
name+"-"+version+"-"+interpreter+"-"+abi+"-"+platform+".whl",
|
||||||
|
), checksum, extra...), version
|
||||||
},
|
},
|
||||||
|
|
||||||
Name: name,
|
Name: "python-" + name,
|
||||||
Description: description,
|
Description: description,
|
||||||
Website: website,
|
Website: "https://pypi.org/project/" + name + "/",
|
||||||
|
|
||||||
Dependencies: slices.Concat(P{Python}, extra),
|
Dependencies: slices.Concat(P{Python}, extra),
|
||||||
|
|
||||||
@@ -219,389 +129,106 @@ func newPythonPackage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func (t Toolchain) newSetuptools() (pkg.Artifact, string) {
|
||||||
const (
|
|
||||||
version = "0.47.0"
|
|
||||||
checksum = "HZ-MvkUP8mbbx2YmsRNswj_bbOCIiXckuHqL5Qbvb5NxN5DYfWnqwkGNyS7OrId0"
|
|
||||||
)
|
|
||||||
artifactsM[PythonWheel] = newPythonPackage(
|
|
||||||
"wheel", 11428,
|
|
||||||
"the official binary distribution format for Python",
|
|
||||||
"https://peps.python.org/pep-0427/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/wheel",
|
|
||||||
version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
Install: true,
|
|
||||||
}, P{PythonFlitCore, PythonSetuptools},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
const (
|
const (
|
||||||
version = "82.0.1"
|
version = "82.0.1"
|
||||||
checksum = "nznP46Tj539yqswtOrIM4nQgwLA1h-ApKX7z7ghazROCpyF5swtQGwsZoI93wkhc"
|
checksum = "nznP46Tj539yqswtOrIM4nQgwLA1h-ApKX7z7ghazROCpyF5swtQGwsZoI93wkhc"
|
||||||
)
|
)
|
||||||
artifactsM[PythonSetuptools] = newPythonPackage(
|
return t.New("setuptools-"+version, 0, t.AppendPresets(nil,
|
||||||
"setuptools", 4021,
|
Python,
|
||||||
"the autotools of the Python ecosystem",
|
), nil, nil, `
|
||||||
"https://pypi.org/project/setuptools/",
|
pip3 install \
|
||||||
version, newFromGitHub(
|
--no-index \
|
||||||
|
--prefix=/system \
|
||||||
|
--root=/work \
|
||||||
|
/usr/src/setuptools
|
||||||
|
`, pkg.Path(AbsUsrSrc.Append("setuptools"), true, newFromGitHub(
|
||||||
"pypa/setuptools",
|
"pypa/setuptools",
|
||||||
"v"+version, checksum,
|
"v"+version, checksum,
|
||||||
), nil, &PipHelper{
|
))), version
|
||||||
// error: invalid command 'dist_info'
|
|
||||||
BuildIsolation: true,
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
const (
|
artifactsM[Setuptools] = Metadata{
|
||||||
version = "1.1.1"
|
f: Toolchain.newSetuptools,
|
||||||
checksum = "rXZixTsZcRcIoUC1LvWrjySsiXSv5uhW6ng2P-yXZrbdj7FrSrDeJLCfC2b-ladV"
|
|
||||||
)
|
|
||||||
artifactsM[PythonVCSVersioning] = newPythonPackage(
|
|
||||||
"vcs-versioning", 389421,
|
|
||||||
"core VCS versioning functionality extracted as a standalone library",
|
|
||||||
"https://setuptools-scm.readthedocs.io/en/latest/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/setuptools-scm",
|
|
||||||
"vcs-versioning-v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Env: []string{
|
|
||||||
"SETUPTOOLS_SCM_PRETEND_VERSION=" + version,
|
|
||||||
},
|
|
||||||
}, &PipHelper{
|
|
||||||
// upstream is monorepo of two packages (setuptools-scm)
|
|
||||||
Append: []string{"vcs-versioning"},
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, nil,
|
|
||||||
PythonSetuptools,
|
|
||||||
PythonPackaging,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
Name: "python-setuptools",
|
||||||
const (
|
Description: "the autotools of the Python ecosystem",
|
||||||
version = "10.0.5"
|
Website: "https://pypi.org/project/setuptools/",
|
||||||
checksum = "vTN_TPd-b4Wbsw5WmAcsWjrs-FNXXznOeVTDnb54NtXve9Oy-eb2HPy-RG3FzNqp"
|
|
||||||
)
|
|
||||||
artifactsM[PythonSetuptoolsSCM] = newPythonPackage(
|
|
||||||
"setuptools-scm", 7874,
|
|
||||||
"extracts Python package versions from Git or Mercurial metadata",
|
|
||||||
"https://setuptools-scm.readthedocs.io/en/latest/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/setuptools-scm",
|
|
||||||
"setuptools-scm-v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Env: []string{
|
|
||||||
"SETUPTOOLS_SCM_PRETEND_VERSION=" + version,
|
|
||||||
},
|
|
||||||
}, &PipHelper{
|
|
||||||
// upstream is monorepo of two packages
|
|
||||||
Append: []string{"setuptools-scm"},
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, nil,
|
|
||||||
PythonSetuptools,
|
|
||||||
PythonVCSVersioning,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
const (
|
|
||||||
version = "3.12.0"
|
|
||||||
checksum = "VcTsiGiDU1aPLbjSPe38f9OjJDCLcxFz9loObJqUI1ZxDHXAaQMxBpNyLz_G1Rff"
|
|
||||||
)
|
|
||||||
artifactsM[PythonFlitCore] = newPythonPackage(
|
|
||||||
"flit-core", 44841,
|
|
||||||
"a PEP 517 build backend for packages using Flit",
|
|
||||||
"https://flit.pypa.io/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/flit",
|
|
||||||
version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
// upstream has other unused packages with many dependencies
|
|
||||||
Append: []string{"flit_core"},
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, nil,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
const (
|
|
||||||
version = "26.2"
|
|
||||||
checksum = "rdpGa2EkPFbj1mFtLKLnSwIX9gPfELcuneiICjRVDNw6By49szTFVoW8gtMMZ6ZS"
|
|
||||||
)
|
|
||||||
artifactsM[PythonPackaging] = newPythonPackage(
|
|
||||||
"packaging", 60461,
|
|
||||||
"reusable core utilities for various Python Packaging interoperability specifications",
|
|
||||||
"https://packaging.pypa.io/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/packaging",
|
|
||||||
version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonFlitCore},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
artifactsM[LIT] = Metadata{
|
|
||||||
f: func(t Toolchain) (pkg.Artifact, string) {
|
|
||||||
version := t.Version(LLVM)
|
|
||||||
return t.NewPackage("lit", version, t.Load(llvmSource), nil, &PipHelper{
|
|
||||||
Append: []string{"llvm", "utils", "lit"},
|
|
||||||
// already checked during llvm
|
|
||||||
SkipCheck: true,
|
|
||||||
},
|
|
||||||
PythonSetuptools,
|
|
||||||
), version
|
|
||||||
},
|
|
||||||
|
|
||||||
Name: "lit",
|
|
||||||
Description: "a portable tool for executing LLVM and Clang style test suites",
|
|
||||||
Website: "https://llvm.org/docs/CommandGuide/lit.html",
|
|
||||||
|
|
||||||
Dependencies: P{
|
Dependencies: P{
|
||||||
Python,
|
Python,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ID: 4021,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
const (
|
artifactsM[PythonPygments] = newPypi(
|
||||||
version = "1.1.1"
|
"pygments", 3986,
|
||||||
checksum = "1fVwoal6FoKXczoG3qRUi87TxSWESSGcgvnbEZDYuaOgsO25o36iF3SbAhwkr4Va"
|
" a syntax highlighting package written in Python",
|
||||||
|
"2.20.0", "py3", "none", "any",
|
||||||
|
"qlyqX2YSXcV0Z8XgGaPttc_gkq-xsu_nYs6NFOcYnk-CX7qmcj45gG-h6DpwPIcO",
|
||||||
)
|
)
|
||||||
artifactsM[PythonPathspec] = newPythonPackage(
|
|
||||||
"pathspec", 23424,
|
|
||||||
"utility library for gitignore style pattern matching of file paths",
|
|
||||||
"https://github.com/cpburnz/python-pathspec",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"cpburnz/python-pathspec",
|
|
||||||
"v"+version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonFlitCore},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonPluggy] = newPypi(
|
||||||
const (
|
|
||||||
version = "2026.4.28.13"
|
|
||||||
checksum = "Z3MbmMXtmWHCM3-EvJehb9MzDqX7Ce_Xg86D5g5nxFRWMKqwHwnQ8R-AlKf-32HU"
|
|
||||||
)
|
|
||||||
artifactsM[PythonTroveClassifiers] = newPythonPackage(
|
|
||||||
"trove-classifiers", 88298,
|
|
||||||
"canonical source for classifiers on PyPI",
|
|
||||||
"https://pypi.org/p/trove-classifiers/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/trove-classifiers",
|
|
||||||
version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonSetuptools},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
const (
|
|
||||||
version = "1.6.0"
|
|
||||||
checksum = "GiUgDkKjF8Xn1cmq6iMhTGXzcPIYeaJrvQpHBSAJapNVx4UyuiTXqd5eVlxSClJu"
|
|
||||||
)
|
|
||||||
artifactsM[PythonPluggy] = newPythonPackage(
|
|
||||||
"pluggy", 7500,
|
"pluggy", 7500,
|
||||||
"the core framework used by the pytest, tox, and devpi projects",
|
"the core framework used by the pytest, tox, and devpi projects",
|
||||||
"https://pluggy.readthedocs.io/en/latest/",
|
"1.6.0", "py3", "none", "any",
|
||||||
version, newFromGitHub(
|
"2HWYBaEwM66-y1hSUcWI1MyE7dVVuNNRW24XD6iJBey4YaUdAK8WeXdtFMQGC-4J",
|
||||||
"pytest-dev/pluggy",
|
|
||||||
version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Env: []string{
|
|
||||||
"SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PLUGGY=" + version,
|
|
||||||
},
|
|
||||||
}, &PipHelper{
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonSetuptoolsSCM},
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonPackaging] = newPypi(
|
||||||
const (
|
"packaging", 60461,
|
||||||
version = "1.16.5"
|
"reusable core utilities for various Python Packaging interoperability specifications",
|
||||||
checksum = "V2eREtqZLZeV85yb4O-bfAJCUluHcQP76Qfs0QH5s7RF_Oc8xIP8jD0jl85qFyWk"
|
"26.1", "py3", "none", "any",
|
||||||
|
"6WZjBJeRb0eZZavxM8cLPcgD-ch-1FblsHoCFKC_9VUC5XAmd397LwliVhsnQcSN",
|
||||||
)
|
)
|
||||||
artifactsM[PythonHatchling] = newPythonPackage(
|
|
||||||
"hatchling", 16137,
|
|
||||||
"the extensible, standards compliant build backend used by Hatch",
|
|
||||||
"https://hatch.pypa.io/latest/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pypa/hatch",
|
|
||||||
"hatch-v"+version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
// upstream has other unused packages with many dependencies
|
|
||||||
Append: []string{"backend"},
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, nil,
|
|
||||||
PythonPackaging,
|
|
||||||
PythonPathspec,
|
|
||||||
PythonTroveClassifiers,
|
|
||||||
PythonPluggy,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonIniConfig] = newPypi(
|
||||||
const (
|
|
||||||
version = "2.20.0"
|
|
||||||
checksum = "L-2P6vn7c_CNZYliE5CJAWLxO1ziDQVVkf8bnZbHj8aSCQ43oWv11wC9KzU9MeCa"
|
|
||||||
)
|
|
||||||
artifactsM[PythonPygments] = newPythonPackage(
|
|
||||||
"pygments", 3986,
|
|
||||||
"a syntax highlighting package written in Python",
|
|
||||||
"https://pygments.org/",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"pygments/pygments",
|
|
||||||
version, checksum,
|
|
||||||
), nil, &PipHelper{
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonHatchling},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
const (
|
|
||||||
version = "2.3.0"
|
|
||||||
checksum = "mH7VBZaXcYatBPE3RQQZvSzz_Ay8IPPek60NpPHZulPq4ReAFUUsA4EPWfiyMknZ"
|
|
||||||
)
|
|
||||||
artifactsM[PythonIniConfig] = newPythonPackage(
|
|
||||||
"iniconfig", 114778,
|
"iniconfig", 114778,
|
||||||
"a small and simple INI-file parser module",
|
"a small and simple INI-file parser module",
|
||||||
"https://github.com/pytest-dev/iniconfig",
|
"2.3.0", "py3", "none", "any",
|
||||||
version, newFromGitHub(
|
"SDgs4S5bXi77aVOeKTPv2TUrS3M9rduiK4DpU0hCmDsSBWqnZcWInq9lsx6INxut",
|
||||||
"pytest-dev/iniconfig",
|
|
||||||
"v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Env: []string{
|
|
||||||
"SETUPTOOLS_SCM_PRETEND_VERSION_FOR_INICONFIG=" + version,
|
|
||||||
},
|
|
||||||
}, &PipHelper{
|
|
||||||
// pytest circular dependency
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonSetuptoolsSCM},
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonPyTest] = newPypi(
|
||||||
const (
|
|
||||||
version = "9.0.3"
|
|
||||||
checksum = "qfLL_znWhbJCDbNJvrx9H3-orJ86z4ifhaW0bIn21jl2sDP-FVoX_1yieOypArQe"
|
|
||||||
)
|
|
||||||
artifactsM[PythonPyTest] = newPythonPackage(
|
|
||||||
"pytest", 3765,
|
"pytest", 3765,
|
||||||
"the pytest framework",
|
"the pytest framework",
|
||||||
"https://pytest.org",
|
"9.0.3", "py3", "none", "any",
|
||||||
version, newFromGitHub(
|
"57WLrIVOfyoRDjt5qD6LGOaDcDCtzQnKDSTUb7GzHyJDtry_nGHHs4-0tW0tiIJr",
|
||||||
"pytest-dev/pytest",
|
|
||||||
version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
Env: []string{
|
|
||||||
"SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST=" + version,
|
|
||||||
},
|
|
||||||
}, &PipHelper{
|
|
||||||
// many dependencies
|
|
||||||
SkipCheck: true,
|
|
||||||
}, P{PythonSetuptoolsSCM},
|
|
||||||
PythonIniConfig,
|
PythonIniConfig,
|
||||||
PythonPackaging,
|
PythonPackaging,
|
||||||
PythonPluggy,
|
PythonPluggy,
|
||||||
PythonPygments,
|
PythonPygments,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonMarkupSafe] = newPypi(
|
||||||
const (
|
|
||||||
version = "3.0.3"
|
|
||||||
checksum = "txRGYdWE3his1lHHRI-lZADw0-ILvUg2l5OGdFHtFXIb_QowGxwdxHCUSJIgmjQs"
|
|
||||||
)
|
|
||||||
artifactsM[PythonMarkupSafe] = newPythonPackage(
|
|
||||||
"markupsafe", 3918,
|
"markupsafe", 3918,
|
||||||
"implements a text object that escapes characters so it is safe to use in HTML and XML",
|
"implements a text object that escapes characters so it is safe to use in HTML and XML",
|
||||||
"https://markupsafe.palletsprojects.com/",
|
"3.0.3", "cp314", "cp314", "musllinux_1_2_"+linuxArch(),
|
||||||
version, newFromGitHub(
|
perArch[string]{
|
||||||
"pallets/markupsafe",
|
"amd64": "E2mo9ig_FKgTpGon_8qqviSEULwhnmxTIqd9vfyNxNpK4yofVYM7eLW_VE-LKbtO",
|
||||||
version, checksum,
|
"arm64": "iG_hqsncOs8fA7bCaAg0x9XenXWlo9sqblyPcSG7yA9sfGLvM9KZznCpwWfOCwFC",
|
||||||
), nil, &PipHelper{
|
"riscv64": "7DI7U0M3jvr7U4uZml25GLw3m3EvMubCtNukZmss1gkVJ_DVkhV5DgX3Wt_sztbv",
|
||||||
// ModuleNotFoundError: No module named 'markupsafe'
|
}.unwrap(),
|
||||||
Install: true,
|
|
||||||
}, P{PythonSetuptools},
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonMako] = newPypi(
|
||||||
const (
|
|
||||||
version = "1.3.12"
|
|
||||||
checksum = "OZbBsQe2MzRuAo5Mr4qRwWHGqU1EEZeBuSprDDIceAtMLIUJtO7SbERlxHIxNhLk"
|
|
||||||
)
|
|
||||||
artifactsM[PythonMako] = newPythonPackage(
|
|
||||||
"mako", 3915,
|
"mako", 3915,
|
||||||
"a template library written in Python",
|
"a template library written in Python",
|
||||||
"https://www.makotemplates.org/",
|
"1.3.11", "py3", "none", "any",
|
||||||
version, newFromGitHub(
|
"WJ_hxYI-nNiuDiM6QhfAG84uO5U-M2aneB0JS9AQ2J2Oi6YXAbBxIdOeOEng6CoS",
|
||||||
"sqlalchemy/mako",
|
|
||||||
"rel_"+strings.Join(strings.SplitN(version, ".", 3), "_"),
|
|
||||||
checksum,
|
|
||||||
), nil, nil, P{PythonSetuptools},
|
|
||||||
PythonMarkupSafe,
|
PythonMarkupSafe,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
artifactsM[PythonPyYAML] = newPypi(
|
||||||
const (
|
|
||||||
version = "6.0.3"
|
|
||||||
checksum = "7wDv0RW9chBdu9l5Q4Hun5F2HHdo105ZSIixwdFPKbEYbftW9YxmsegfL-zafnbJ"
|
|
||||||
)
|
|
||||||
artifactsM[PythonPyYAML] = newPythonPackage(
|
|
||||||
"pyyaml", 4123,
|
"pyyaml", 4123,
|
||||||
"a YAML parser and emitter for Python",
|
"a YAML parser and emitter for Python",
|
||||||
"https://pyyaml.org/",
|
"6.0.3", "cp314", "cp314", "musllinux_1_2_"+linuxArch(),
|
||||||
version, newFromGitHub(
|
perArch[string]{
|
||||||
"yaml/pyyaml",
|
"amd64": "4_jhCFpUNtyrFp2HOMqUisR005u90MHId53eS7rkUbcGXkoaJ7JRsY21dREHEfGN",
|
||||||
version, checksum,
|
"arm64": "sQ818ZYSmC7Vj9prIPx3sEYqSDhZlWvLbgHV9w4GjxsfQ63ZSzappctKM7Lb0Whw",
|
||||||
), nil, &PipHelper{
|
}.unwrap(),
|
||||||
// ModuleNotFoundError: No module named 'yaml'
|
|
||||||
Install: true,
|
|
||||||
}, P{PythonSetuptools},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
const (
|
|
||||||
version = "3.00"
|
|
||||||
checksum = "4qfCMFKp0fLsRsloOAF780tXX_Ce_68RwinCmjNGObAX32WpF_iBafIKW1S1bYlA"
|
|
||||||
)
|
|
||||||
artifactsM[PythonPycparser] = newPythonPackage(
|
|
||||||
"pycparser", 8175,
|
|
||||||
"complete C99 parser in pure Python",
|
|
||||||
"https://github.com/eliben/pycparser",
|
|
||||||
version, newFromGitHub(
|
|
||||||
"eliben/pycparser",
|
|
||||||
"release_v"+version, checksum,
|
|
||||||
), &PackageAttr{
|
|
||||||
// test case hard codes gcc
|
|
||||||
ScriptEarly: `
|
|
||||||
ln -s clang /system/bin/gcc
|
|
||||||
`,
|
|
||||||
}, nil, P{PythonSetuptools},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import "hakurei.app/internal/pkg"
|
|||||||
|
|
||||||
func (t Toolchain) newQEMU() (pkg.Artifact, string) {
|
func (t Toolchain) newQEMU() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "11.0.0"
|
version = "10.2.2"
|
||||||
checksum = "C64gdi_Tkdg2fTwD9ERxtWGcf8vNn_6UvczW0c-x0KW1NZtd3NbEOIrlDhYGn15n"
|
checksum = "uNzRxlrVoLWe-EmZmBp75SezymgE512iE5XN90Bl7wi6CjE_oQGQB-9ocs7E16QG"
|
||||||
)
|
)
|
||||||
return t.NewPackage("qemu", version, newTar(
|
return t.NewPackage("qemu", version, newTar(
|
||||||
"https://download.qemu.org/qemu-"+version+".tar.bz2",
|
"https://download.qemu.org/qemu-"+version+".tar.bz2",
|
||||||
@@ -62,7 +62,6 @@ EOF
|
|||||||
{"disable-download"},
|
{"disable-download"},
|
||||||
{"disable-docs"},
|
{"disable-docs"},
|
||||||
|
|
||||||
{"static"},
|
|
||||||
{"target-list-exclude", "" +
|
{"target-list-exclude", "" +
|
||||||
// fails to load firmware
|
// fails to load firmware
|
||||||
"ppc-linux-user," +
|
"ppc-linux-user," +
|
||||||
@@ -74,8 +73,6 @@ EOF
|
|||||||
},
|
},
|
||||||
Bash,
|
Bash,
|
||||||
Python,
|
Python,
|
||||||
PythonSetuptools,
|
|
||||||
PythonWheel,
|
|
||||||
Ninja,
|
Ninja,
|
||||||
PkgConfig,
|
PkgConfig,
|
||||||
Diffutils,
|
Diffutils,
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package rosa
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"log"
|
||||||
"path"
|
"path"
|
||||||
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -13,12 +15,6 @@ import (
|
|||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Extension is the variant identification string of custom artifact
|
|
||||||
// implementations registered by package rosa.
|
|
||||||
const Extension = "rosa"
|
|
||||||
|
|
||||||
func init() { pkg.SetExtension(Extension) }
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// kindEtc is the kind of [pkg.Artifact] of cureEtc.
|
// kindEtc is the kind of [pkg.Artifact] of cureEtc.
|
||||||
kindEtc = iota + pkg.KindCustomOffset
|
kindEtc = iota + pkg.KindCustomOffset
|
||||||
@@ -32,7 +28,7 @@ const (
|
|||||||
func mustDecode(s string) pkg.Checksum {
|
func mustDecode(s string) pkg.Checksum {
|
||||||
var fallback = pkg.Checksum{}
|
var fallback = pkg.Checksum{}
|
||||||
if s == "" {
|
if s == "" {
|
||||||
println(
|
log.Println(
|
||||||
"falling back to",
|
"falling back to",
|
||||||
pkg.Encode(fallback),
|
pkg.Encode(fallback),
|
||||||
"for unpopulated checksum",
|
"for unpopulated checksum",
|
||||||
@@ -53,9 +49,10 @@ var (
|
|||||||
AbsSystem = fhs.AbsRoot.Append("system")
|
AbsSystem = fhs.AbsRoot.Append("system")
|
||||||
)
|
)
|
||||||
|
|
||||||
// linuxArch returns the architecture name used by linux corresponding to arch.
|
// linuxArch returns the architecture name used by linux corresponding to
|
||||||
|
// [runtime.GOARCH].
|
||||||
func linuxArch() string {
|
func linuxArch() string {
|
||||||
switch arch {
|
switch runtime.GOARCH {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
return "x86_64"
|
return "x86_64"
|
||||||
case "arm64":
|
case "arm64":
|
||||||
@@ -64,11 +61,11 @@ func linuxArch() string {
|
|||||||
return "riscv64"
|
return "riscv64"
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("unsupported target " + arch)
|
panic("unsupported target " + runtime.GOARCH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// triplet returns the Rosa OS host triple corresponding to arch.
|
// triplet returns the Rosa OS host triple corresponding to [runtime.GOARCH].
|
||||||
func triplet() string {
|
func triplet() string {
|
||||||
return linuxArch() + "-rosa-linux-musl"
|
return linuxArch() + "-rosa-linux-musl"
|
||||||
}
|
}
|
||||||
@@ -78,9 +75,9 @@ type perArch[T any] map[string]T
|
|||||||
|
|
||||||
// unwrap returns the value for the current architecture.
|
// unwrap returns the value for the current architecture.
|
||||||
func (p perArch[T]) unwrap() T {
|
func (p perArch[T]) unwrap() T {
|
||||||
v, ok := p[arch]
|
v, ok := p[runtime.GOARCH]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("unsupported target " + arch)
|
panic("unsupported target " + runtime.GOARCH)
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
@@ -105,6 +102,21 @@ func earlyLDFLAGS(static bool) string {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// earlyCFLAGS is reference CFLAGS for the stage0 toolchain.
|
||||||
|
const earlyCFLAGS = "-Qunused-arguments " +
|
||||||
|
"-isystem/system/include"
|
||||||
|
|
||||||
|
// earlyCXXFLAGS returns reference CXXFLAGS for the stage0 toolchain
|
||||||
|
// corresponding to [runtime.GOARCH].
|
||||||
|
func earlyCXXFLAGS() string {
|
||||||
|
return "--start-no-unused-arguments " +
|
||||||
|
"-stdlib=libc++ " +
|
||||||
|
"--end-no-unused-arguments " +
|
||||||
|
"-isystem/system/include/c++/v1 " +
|
||||||
|
"-isystem/system/include/" + triplet() + "/c++/v1 " +
|
||||||
|
"-isystem/system/include "
|
||||||
|
}
|
||||||
|
|
||||||
// Toolchain denotes the infrastructure to compile a [pkg.Artifact] on.
|
// Toolchain denotes the infrastructure to compile a [pkg.Artifact] on.
|
||||||
type Toolchain uint32
|
type Toolchain uint32
|
||||||
|
|
||||||
@@ -174,6 +186,24 @@ func (t Toolchain) isStd() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stage0Concat concatenates s and values. If the current toolchain is
|
||||||
|
// toolchainStage0, stage0Concat returns s as is.
|
||||||
|
func stage0Concat[S ~[]E, E any](t Toolchain, s S, values ...E) S {
|
||||||
|
if t.isStage0() {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return slices.Concat(s, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
// stage0ExclConcat concatenates s and values. If the current toolchain is not
|
||||||
|
// toolchainStage0, stage0ExclConcat returns s as is.
|
||||||
|
func stage0ExclConcat[S ~[]E, E any](t Toolchain, s S, values ...E) S {
|
||||||
|
if t.isStage0() {
|
||||||
|
return slices.Concat(s, values)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// lastIndexFunc is like [strings.LastIndexFunc] but for [slices].
|
// lastIndexFunc is like [strings.LastIndexFunc] but for [slices].
|
||||||
func lastIndexFunc[S ~[]E, E any](s S, f func(E) bool) (i int) {
|
func lastIndexFunc[S ~[]E, E any](s S, f func(E) bool) (i int) {
|
||||||
if i = slices.IndexFunc(s, f); i < 0 {
|
if i = slices.IndexFunc(s, f); i < 0 {
|
||||||
@@ -263,10 +293,9 @@ func (t Toolchain) New(
|
|||||||
|
|
||||||
case toolchainGentoo, toolchainStage0:
|
case toolchainGentoo, toolchainStage0:
|
||||||
name += "-boot"
|
name += "-boot"
|
||||||
support = append(support, extra...)
|
|
||||||
support = append(support, cureEtc{})
|
support = append(support, cureEtc{})
|
||||||
if t == toolchainStage0 {
|
if t == toolchainStage0 {
|
||||||
support = append(support, t.Load(stage0Dist))
|
support = append(support, NewStage0())
|
||||||
} else {
|
} else {
|
||||||
support = append(support, _toolchainBusybox.New("gentoo", 0, nil, nil, nil, `
|
support = append(support, _toolchainBusybox.New("gentoo", 0, nil, nil, nil, `
|
||||||
tar -C /work -xf /usr/src/stage3.tar.xz
|
tar -C /work -xf /usr/src/stage3.tar.xz
|
||||||
@@ -284,6 +313,7 @@ mkdir -vp /work/system/bin
|
|||||||
),
|
),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
support = slices.Concat(support, extra)
|
||||||
env = fixupEnviron(env, []string{
|
env = fixupEnviron(env, []string{
|
||||||
EnvTriplet + "=" + triplet(),
|
EnvTriplet + "=" + triplet(),
|
||||||
lcMessages,
|
lcMessages,
|
||||||
@@ -303,7 +333,7 @@ mkdir -vp /work/system/bin
|
|||||||
toybox = toyboxEarly
|
toybox = toyboxEarly
|
||||||
}
|
}
|
||||||
|
|
||||||
base := LLVM
|
base := Clang
|
||||||
if flag&TNoToolchain != 0 {
|
if flag&TNoToolchain != 0 {
|
||||||
base = Musl
|
base = Musl
|
||||||
}
|
}
|
||||||
@@ -318,6 +348,11 @@ mkdir -vp /work/system/bin
|
|||||||
env = fixupEnviron(env, []string{
|
env = fixupEnviron(env, []string{
|
||||||
EnvTriplet + "=" + triplet(),
|
EnvTriplet + "=" + triplet(),
|
||||||
lcMessages,
|
lcMessages,
|
||||||
|
|
||||||
|
"AR=ar",
|
||||||
|
"RANLIB=ranlib",
|
||||||
|
"LIBCC=/system/lib/clang/" + llvmVersionMajor + "/lib/" + triplet() +
|
||||||
|
"/libclang_rt.builtins.a",
|
||||||
}, "/system/bin", "/bin")
|
}, "/system/bin", "/bin")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -325,7 +360,7 @@ mkdir -vp /work/system/bin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return pkg.NewExec(
|
return pkg.NewExec(
|
||||||
name, arch, knownChecksum, pkg.ExecTimeoutMax, flag&TExclusive != 0,
|
name, knownChecksum, pkg.ExecTimeoutMax, flag&TExclusive != 0,
|
||||||
fhs.AbsRoot, env,
|
fhs.AbsRoot, env,
|
||||||
AbsSystem.Append("bin", "sh"),
|
AbsSystem.Append("bin", "sh"),
|
||||||
[]string{"sh", absCureScript.String()},
|
[]string{"sh", absCureScript.String()},
|
||||||
@@ -375,8 +410,8 @@ cat /usr/src/` + name + `-patches/* | \
|
|||||||
`
|
`
|
||||||
aname += "-patched"
|
aname += "-patched"
|
||||||
}
|
}
|
||||||
return t.New(aname, 0, t.AppendPresets(nil,
|
return t.New(aname, 0, stage0Concat(t, []pkg.Artifact{},
|
||||||
Patch,
|
t.Load(Patch),
|
||||||
), nil, nil, script, paths...)
|
), nil, nil, script, paths...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,6 +458,9 @@ type PackageAttr struct {
|
|||||||
// Passed to [Toolchain.NewPatchedSource].
|
// Passed to [Toolchain.NewPatchedSource].
|
||||||
Patches []KV
|
Patches []KV
|
||||||
|
|
||||||
|
// Dependencies not provided by stage0.
|
||||||
|
NonStage0 []pkg.Artifact
|
||||||
|
|
||||||
// Passed through to [Toolchain.New], before source.
|
// Passed through to [Toolchain.New], before source.
|
||||||
Paths []pkg.ExecPath
|
Paths []pkg.ExecPath
|
||||||
// Passed through to [Toolchain.New].
|
// Passed through to [Toolchain.New].
|
||||||
@@ -490,8 +528,14 @@ func (t Toolchain) NewPackage(
|
|||||||
panic("source must be non-nil")
|
panic("source must be non-nil")
|
||||||
}
|
}
|
||||||
wantsChmod, wantsWrite := helper.wantsChmod(), helper.wantsWrite()
|
wantsChmod, wantsWrite := helper.wantsChmod(), helper.wantsWrite()
|
||||||
extraRes := make([]pkg.Artifact, 0, 1<<3+len(extra))
|
dc := len(attr.NonStage0)
|
||||||
{
|
if !t.isStage0() {
|
||||||
|
dc += 1<<3 + len(extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
extraRes := make([]pkg.Artifact, 0, dc)
|
||||||
|
extraRes = append(extraRes, attr.NonStage0...)
|
||||||
|
if !t.isStage0() {
|
||||||
pv := paGet()
|
pv := paGet()
|
||||||
for _, p := range helper.extra(attr.Flag) {
|
for _, p := range helper.extra(attr.Flag) {
|
||||||
extraRes = t.appendPreset(extraRes, pv, p)
|
extraRes = t.appendPreset(extraRes, pv, p)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
rosa.DropCaches("", rosa.OptLLVMNoLTO)
|
|
||||||
container.TryArgv0(nil)
|
container.TryArgv0(nil)
|
||||||
|
|
||||||
code := m.Run()
|
code := m.Run()
|
||||||
@@ -61,7 +60,7 @@ func getCache(t *testing.T) *pkg.Cache {
|
|||||||
msg := message.New(log.New(os.Stderr, "rosa: ", 0))
|
msg := message.New(log.New(os.Stderr, "rosa: ", 0))
|
||||||
msg.SwapVerbose(true)
|
msg.SwapVerbose(true)
|
||||||
|
|
||||||
if buildTestCache, err = pkg.Open(ctx, msg, pkg.CSuppressInit, 0, 0, a); err != nil {
|
if buildTestCache, err = pkg.Open(ctx, msg, 0, 0, 0, a); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,14 +93,11 @@ func TestCureAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkStage3(b *testing.B) {
|
func BenchmarkStage3(b *testing.B) {
|
||||||
arch, flags := rosa.Arch(), rosa.Flags()
|
|
||||||
b.Cleanup(func() { rosa.DropCaches(arch, flags) })
|
|
||||||
|
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
rosa.Std.Load(rosa.LLVM)
|
rosa.Std.Load(rosa.Clang)
|
||||||
|
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
rosa.DropCaches("", 0)
|
rosa.DropCaches()
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import "hakurei.app/internal/pkg"
|
|||||||
|
|
||||||
func (t Toolchain) newRsync() (pkg.Artifact, string) {
|
func (t Toolchain) newRsync() (pkg.Artifact, string) {
|
||||||
const (
|
const (
|
||||||
version = "3.4.2"
|
version = "3.4.1"
|
||||||
checksum = "t7PxS4WHXzefLMKKc_3hJgxUmlGG6KgHMZ8i4DZvCQAUAizxbclNKwfLyOHyq5BX"
|
checksum = "VBlTsBWd9z3r2-ex7GkWeWxkUc5OrlgDzikAC0pK7ufTjAJ0MbmC_N04oSVTGPiv"
|
||||||
)
|
)
|
||||||
return t.NewPackage("rsync", version, newTar(
|
return t.NewPackage("rsync", version, newTar(
|
||||||
"https://download.samba.org/pub/rsync/src/"+
|
"https://download.samba.org/pub/rsync/src/"+
|
||||||
|
|||||||
@@ -1,25 +1,44 @@
|
|||||||
package rosa
|
package rosa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hakurei.app/fhs"
|
"sync"
|
||||||
|
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t Toolchain) newStage0() (pkg.Artifact, string) {
|
func (t Toolchain) newStage0() (pkg.Artifact, string) {
|
||||||
return t.New("rosa-stage0", 0, t.AppendPresets(nil,
|
return t.New("rosa-stage0", 0, []pkg.Artifact{
|
||||||
Bzip2,
|
t.Load(Musl),
|
||||||
), nil, nil, `
|
t.Load(CompilerRT),
|
||||||
|
t.Load(LLVMRuntimes),
|
||||||
|
t.Load(Clang),
|
||||||
|
|
||||||
|
t.Load(Zlib),
|
||||||
|
t.Load(Bzip2),
|
||||||
|
|
||||||
|
t.Load(Patch),
|
||||||
|
t.Load(Make),
|
||||||
|
t.Load(CMake),
|
||||||
|
t.Load(Ninja),
|
||||||
|
|
||||||
|
t.Load(Libffi),
|
||||||
|
t.Load(Python),
|
||||||
|
t.Load(Perl),
|
||||||
|
t.Load(Diffutils),
|
||||||
|
t.Load(Bash),
|
||||||
|
t.Load(Gawk),
|
||||||
|
t.Load(Coreutils),
|
||||||
|
t.Load(Findutils),
|
||||||
|
|
||||||
|
t.Load(KernelHeaders),
|
||||||
|
}, nil, nil, `
|
||||||
umask 377
|
umask 377
|
||||||
tar \
|
tar \
|
||||||
-vjc \
|
-vjc \
|
||||||
-C /stage0 \
|
-C / \
|
||||||
-f /work/stage0-`+triplet()+`.tar.bz2 \
|
-f /work/stage0-`+triplet()+`.tar.bz2 \
|
||||||
.
|
system bin usr/bin/env
|
||||||
`, pkg.Path(fhs.AbsRoot.Append("stage0"), false, t.AppendPresets(nil,
|
`), Unversioned
|
||||||
LLVM,
|
|
||||||
Mksh,
|
|
||||||
toyboxEarly,
|
|
||||||
)...)), Unversioned
|
|
||||||
}
|
}
|
||||||
func init() {
|
func init() {
|
||||||
artifactsM[Stage0] = Metadata{
|
artifactsM[Stage0] = Metadata{
|
||||||
@@ -30,32 +49,26 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
var (
|
||||||
const version = "20260504"
|
// stage0 stores the tarball unpack artifact.
|
||||||
artifactsM[stage0Dist] = Metadata{
|
stage0 pkg.Artifact
|
||||||
f: func(Toolchain) (pkg.Artifact, string) {
|
// stage0Once is for lazy initialisation of stage0.
|
||||||
return newTar(
|
stage0Once sync.Once
|
||||||
"https://hakurei.app/seed/"+version+"/"+
|
)
|
||||||
|
|
||||||
|
// NewStage0 returns a stage0 distribution created from curing [Stage0].
|
||||||
|
func NewStage0() pkg.Artifact {
|
||||||
|
stage0Once.Do(func() {
|
||||||
|
stage0 = newTar(
|
||||||
|
"https://hakurei.app/seed/20260210/"+
|
||||||
"stage0-"+triplet()+".tar.bz2",
|
"stage0-"+triplet()+".tar.bz2",
|
||||||
perArch[string]{
|
perArch[string]{
|
||||||
"amd64": "IQjFDkiAVLo1XzflgMMiLP3gnVY2hhDMTzl-QqJDCQhcLQ3lLtRzjI5WCxGyW_lk",
|
"amd64": "tqM1Li15BJ-uFG8zU-XjgFxoN_kuzh1VxrSDVUVa0vGmo-NeWapSftH739sY8EAg",
|
||||||
"arm64": "6fmwl2Umx2QssKQvxxb1JOGkAjzfA_MXKku0jVdGjYGb35OvwEVA5NYtd0HIy3yH",
|
"arm64": "CJj3ZSnRyLmFHlWIQtTPQD9oikOZY4cD_mI3v_-LIYc2hhg-cq_CZFBLzQBAkFIn",
|
||||||
"riscv64": "Z2ODV0rIoo9iQRUIu35bsaOBeXc_9qQfGcyb2aGneatzNUJlXh5emSpEV2bOklUL",
|
"riscv64": "FcszJjcVWdKAnn-bt8qmUn5GUUTjv_xQjXOWkUpOplRkG3Ckob3StUoAi5KQ5-QF",
|
||||||
}.unwrap(),
|
}.unwrap(),
|
||||||
pkg.TarBzip2,
|
pkg.TarBzip2,
|
||||||
), version
|
)
|
||||||
},
|
})
|
||||||
|
return stage0
|
||||||
Name: "stage0-dist",
|
|
||||||
Description: "Rosa OS stage0 bootstrap seed",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasStage0 returns whether a stage0 distribution is available.
|
|
||||||
func HasStage0() (ok bool) {
|
|
||||||
func() {
|
|
||||||
defer func() { ok = recover() == nil }()
|
|
||||||
toolchainStage0.Load(stage0Dist)
|
|
||||||
}()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user