aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cmd/mbf/cache.go15
-rw-r--r--cmd/mbf/daemon_test.go2
-rw-r--r--cmd/mbf/main.go8
-rw-r--r--internal/pkg/clean_test.go2
-rw-r--r--internal/pkg/exec.go6
-rw-r--r--internal/pkg/pkg.go69
-rw-r--r--internal/pkg/pkg_test.go68
-rw-r--r--internal/rosa/mirror_test.go2
-rw-r--r--internal/rosa/rosa_test.go4
9 files changed, 88 insertions, 88 deletions
diff --git a/cmd/mbf/cache.go b/cmd/mbf/cache.go
index aea54546..7134e5d2 100644
--- a/cmd/mbf/cache.go
+++ b/cmd/mbf/cache.go
@@ -21,7 +21,7 @@ type cache struct {
// Should generally not be used directly.
c *pkg.Cache
- cures, jobs int
+ attr pkg.CacheAttr
// Primarily to work around missing landlock LSM.
hostAbstract bool
// Set SCHED_IDLE.
@@ -49,18 +49,17 @@ func (cache *cache) open() (err error) {
return
}
- var flags int
if cache.idle {
- flags |= pkg.CSchedIdle
+ cache.attr.Flags |= pkg.CSchedIdle
}
if cache.hostAbstract {
- flags |= pkg.CHostAbstract
+ cache.attr.Flags |= pkg.CHostAbstract
}
if !cache.verboseInit {
- flags |= pkg.CSuppressInit
+ cache.attr.Flags |= pkg.CSuppressInit
}
if !cache.deep {
- flags |= pkg.CExternShallow
+ cache.attr.Flags |= pkg.CExternShallow
}
done := make(chan struct{})
@@ -82,10 +81,8 @@ func (cache *cache) open() (err error) {
cache.c, err = pkg.Open(
cache.ctx,
cache.msg,
- flags,
- cache.cures,
- cache.jobs,
base,
+ &cache.attr,
)
if err != nil {
return
diff --git a/cmd/mbf/daemon_test.go b/cmd/mbf/daemon_test.go
index 7b825d0b..5d4bbdfc 100644
--- a/cmd/mbf/daemon_test.go
+++ b/cmd/mbf/daemon_test.go
@@ -28,8 +28,8 @@ func TestNoReply(t *testing.T) {
c, err := pkg.Open(
t.Context(),
message.New(log.New(os.Stderr, "cir: ", 0)),
- 0, 0, 0,
check.MustAbs(t.TempDir()),
+ nil,
)
if err != nil {
t.Fatalf("Open: error = %v", err)
diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go
index b0f5495a..f3ca4eba 100644
--- a/cmd/mbf/main.go
+++ b/cmd/mbf/main.go
@@ -203,11 +203,11 @@ func main() {
"v", command.BoolFlag(false),
"Do not suppress verbose output from init",
).Flag(
- &cm.cures,
+ &cm.attr.Cures,
"cures", command.IntFlag(0),
"Maximum number of dependencies to cure at any given time",
).Flag(
- &cm.jobs,
+ &cm.attr.Jobs,
"jobs", command.IntFlag(0),
"Preferred number of jobs to run, when applicable",
).Flag(
@@ -934,8 +934,8 @@ func main() {
return fmt.Errorf("unknown artifact %q", args[1])
}
- if !a.IsExclusive() && cm.jobs < 1 {
- cm.jobs = runtime.NumCPU()/n + 1
+ if !a.IsExclusive() && cm.attr.Jobs < 1 {
+ cm.attr.Jobs = runtime.NumCPU()/n + 1
}
res := make([]unique.Handle[pkg.Checksum], n)
diff --git a/internal/pkg/clean_test.go b/internal/pkg/clean_test.go
index e9124ab4..3e21a683 100644
--- a/internal/pkg/clean_test.go
+++ b/internal/pkg/clean_test.go
@@ -238,7 +238,7 @@ func TestClean(t *testing.T) {
base := makeBase(t)
msg := message.New(log.New(os.Stderr, "clean: ", 0))
msg.SwapVerbose(testing.Verbose())
- c, err := pkg.Open(t.Context(), msg, 0, 0, 0, base)
+ c, err := pkg.Open(t.Context(), msg, base, nil)
if err != nil {
t.Fatal(err)
}
diff --git a/internal/pkg/exec.go b/internal/pkg/exec.go
index 3623c927..d9063c74 100644
--- a/internal/pkg/exec.go
+++ b/internal/pkg/exec.go
@@ -649,8 +649,8 @@ func (c *Cache) EnterExec(
var z *container.Container
z, err = e.makeContainer(
ctx, c.msg,
- c.flags,
- c.jobs,
+ c.attr.Flags,
+ c.attr.Jobs,
hostNet,
temp, work,
func(a Artifact) (*check.Absolute, unique.Handle[Checksum]) {
@@ -693,7 +693,7 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
msg := f.GetMessage()
var z *container.Container
if z, err = a.makeContainer(
- ctx, msg, f.cache.flags, f.GetJobs(), hostNet,
+ ctx, msg, f.cache.attr.Flags, f.GetJobs(), hostNet,
f.GetTempDir(), f.GetWorkDir(),
f.GetArtifact,
f.cache.Ident,
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 4d1d3f72..ea493d39 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -279,7 +279,7 @@ func (c *common) GetMessage() message.Msg { return c.cache.msg }
// GetJobs returns the preferred number of jobs to run, when applicable. Its
// value must not affect cure outcome.
-func (c *common) GetJobs() int { return c.cache.jobs }
+func (c *common) GetJobs() int { return c.cache.attr.Jobs }
// GetWorkDir returns a pathname to a directory which [Artifact] is expected to
// write its output to. This is not the final resting place of the [Artifact]
@@ -741,10 +741,8 @@ type Cache struct {
// Directory where all [Cache] related files are placed.
base *check.Absolute
- // Immutable cure options set by [Open].
- flags int
- // Immutable job count, when applicable.
- jobs int
+ // Immutable [CacheAttr] populated by [Open].
+ attr CacheAttr
// Must not be exposed directly.
irCache
@@ -1449,7 +1447,7 @@ func (c *Cache) openFile(
ctx context.Context,
f FileArtifact,
) (r io.ReadCloser, err error) {
- if kc, ok := f.(KnownChecksum); c.flags&CAssumeChecksum != 0 && ok {
+ if kc, ok := f.(KnownChecksum); c.attr.Flags&CAssumeChecksum != 0 && ok {
c.checksumMu.RLock()
r, err = os.Open(c.base.Append(
dirChecksum,
@@ -2141,7 +2139,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
checksums,
)
- if c.flags&CAssumeChecksum != 0 {
+ if c.attr.Flags&CAssumeChecksum != 0 {
c.checksumMu.RLock()
checksumFi, err = os.Stat(checksumPathname.String())
c.checksumMu.RUnlock()
@@ -2210,7 +2208,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
}
r, err = f.Cure(&RContext{common{ctx, c}})
if err == nil {
- if checksumPathname == nil || c.flags&CValidateKnown != 0 {
+ if checksumPathname == nil || c.attr.Flags&CValidateKnown != 0 {
h := sha512.New384()
hbw := c.getWriter(h)
_, err = io.Copy(w, io.TeeReader(r, hbw))
@@ -2227,7 +2225,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
if checksumPathname == nil {
checksum = unique.Make(Checksum(buf[:]))
checksums = Encode(Checksum(buf[:]))
- } else if c.flags&CValidateKnown != 0 {
+ } else if c.attr.Flags&CValidateKnown != 0 {
if got := Checksum(buf[:]); got != checksum.Value() {
err = &ChecksumMismatchError{
Got: got,
@@ -2319,7 +2317,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
return
}
extern := externChecksum != zeroChecksum
- shallow := extern && c.flags&CExternShallow != 0
+ shallow := extern && c.attr.Flags&CExternShallow != 0
inputs := a.Inputs()
f := FContext{t, make(map[Artifact]cureRes, len(inputs))}
@@ -2383,7 +2381,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
substitutes,
)
- if !rebuild && c.flags&CIgnoreSubstitutes == 0 {
+ if !rebuild && c.attr.Flags&CIgnoreSubstitutes == 0 {
var substituteChecksum unique.Handle[Checksum]
substituteChecksum, err = c.loadSubstitute(substitute)
if err != nil {
@@ -2677,6 +2675,20 @@ var (
ErrWouldPromote = errors.New("operation would promote unextended cache")
)
+// CacheAttr holds the attributes that will be applied to a new [Cache] opened
+// by [Open].
+type CacheAttr struct {
+ // Concurrent cures of a [FloodArtifact] dependency graph.
+ Cures int
+ // Options affecting [Cache] behaviour.
+ Flags int
+ // Preferred job count, when applicable.
+ Jobs int
+
+ // Omit the [lockedfile] lock.
+ skipLock bool
+}
+
// Open returns the address of a newly opened instance of [Cache].
//
// Concurrent cures of a [FloodArtifact] dependency graph is limited to the
@@ -2693,20 +2705,8 @@ var (
func Open(
ctx context.Context,
msg message.Msg,
- flags, cures, jobs int,
base *check.Absolute,
-) (*Cache, error) {
- return open(ctx, msg, flags, cures, jobs, base, true)
-}
-
-// open implements Open but allows omitting the [lockedfile] lock when called
-// from a test. This is used to simulate invalid states in the test suite.
-func open(
- ctx context.Context,
- msg message.Msg,
- flags, cures, jobs int,
- base *check.Absolute,
- lock bool,
+ attr *CacheAttr,
) (*Cache, error) {
openMu.Lock()
defer openMu.Unlock()
@@ -2716,11 +2716,15 @@ func open(
panic("attempting to open cache with incomplete variant setup")
}
- if cures < 1 {
- cures = runtime.NumCPU()
+ if attr == nil {
+ attr = new(CacheAttr)
+ }
+
+ if attr.Cures < 1 {
+ attr.Cures = runtime.NumCPU()
}
- if jobs < 1 {
- jobs = runtime.NumCPU()
+ if attr.Jobs < 1 {
+ attr.Jobs = runtime.NumCPU()
}
for _, name := range []string{
@@ -2742,9 +2746,8 @@ func open(
c := Cache{
parent: ctx,
- cures: make(chan struct{}, cures),
- flags: flags,
- jobs: jobs,
+ cures: make(chan struct{}, attr.Cures),
+ attr: *attr,
msg: msg,
base: base,
@@ -2761,7 +2764,7 @@ func open(
}
c.toplevel.Store(newToplevel(ctx))
- if lock || !testing.Testing() {
+ if !attr.skipLock || !testing.Testing() {
if unlock, err := lockedfile.MutexAt(
base.Append(fileLock).String(),
).Lock(); err != nil {
@@ -2822,7 +2825,7 @@ func open(
}
} else if s := string(p); s == "" {
if extension != "" {
- if flags&CPromoteVariant == 0 {
+ if attr.Flags&CPromoteVariant == 0 {
c.unlock()
return nil, ErrWouldPromote
}
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go
index ff51d583..a28578c3 100644
--- a/internal/pkg/pkg_test.go
+++ b/internal/pkg/pkg_test.go
@@ -35,14 +35,14 @@ import (
"hakurei.app/message"
)
-//go:linkname unsafeOpen hakurei.app/internal/pkg.open
-func unsafeOpen(
- ctx context.Context,
- msg message.Msg,
- flags, cures, jobs int,
- base *check.Absolute,
- lock bool,
-) (*pkg.Cache, error)
+var skipLock = func() pkg.CacheAttr {
+ var attr pkg.CacheAttr
+ *(*bool)(unsafe.Pointer(reflect.ValueOf(&attr).
+ Elem().
+ FieldByName("skipLock").
+ UnsafeAddr())) = true
+ return attr
+}()
var (
// extension is a string uniquely identifying a set of custom [Artifact]
@@ -339,7 +339,7 @@ func TestIdent(t *testing.T) {
var cache *pkg.Cache
if a, err := check.NewAbs(t.TempDir()); err != nil {
t.Fatal(err)
- } else if cache, err = pkg.Open(t.Context(), msg, 0, 0, 0, a); err != nil {
+ } else if cache, err = pkg.Open(t.Context(), msg, a, nil); err != nil {
t.Fatal(err)
}
t.Cleanup(cache.Close)
@@ -519,7 +519,10 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
}
var scrubFunc func() error // scrub after hashing
- if c, err := pkg.Open(t.Context(), msg, flags, 1<<4, 0, base); err != nil {
+ if c, err := pkg.Open(t.Context(), msg, base, &pkg.CacheAttr{
+ Cures: 1 << 4,
+ Flags: flags,
+ }); err != nil {
t.Fatalf("Open: error = %v", err)
} else {
t.Cleanup(c.Close)
@@ -867,10 +870,10 @@ func TestCache(t *testing.T) {
}},
})
- if c0, err := unsafeOpen(
+ if c0, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, 0, base, false,
+ base, &skipLock,
); err != nil {
t.Fatalf("open: error = %v", err)
} else {
@@ -1141,10 +1144,10 @@ func TestCache(t *testing.T) {
), want, pkg.WSubstitute, nil},
})
- if c0, err := unsafeOpen(
+ if c0, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, 0, base, false,
+ base, &skipLock,
); err != nil {
t.Fatalf("open: error = %v", err)
} else {
@@ -2050,7 +2053,7 @@ func (a earlyFailureF) Cure(*pkg.FContext) error {
func BenchmarkEarlyDCE(b *testing.B) {
msg := message.New(log.New(os.Stderr, "dce: ", 0))
msg.SwapVerbose(testing.Verbose())
- c, err := pkg.Open(b.Context(), msg, 0, 0, 0, check.MustAbs(b.TempDir()))
+ c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil)
if err != nil {
b.Fatal(err)
}
@@ -2099,7 +2102,8 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, 0, check.MustAbs(container.Nonexistent),
+ check.MustAbs(container.Nonexistent),
+ nil,
); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
}
@@ -2127,7 +2131,8 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, 0, tempDir.Append("cache"),
+ tempDir.Append("cache"),
+ nil,
); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
}
@@ -2149,7 +2154,8 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, 0, tempDir.Append("cache"),
+ tempDir.Append("cache"),
+ nil,
); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
}
@@ -2170,7 +2176,7 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, 0, tempDir.Append("cache"),
+ tempDir.Append("cache"), nil,
); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
}
@@ -2223,8 +2229,8 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(log.Default()),
- 0, 0, 0,
check.MustAbs(container.Nonexistent),
+ nil,
); !errors.Is(err, os.ErrNotExist) {
t.Fatalf("Open: error = %v", err)
}
@@ -2262,7 +2268,7 @@ func TestExtensionRegister(t *testing.T) {
pkg.Register(pkg.KindCustomOffset, nil)
t.Cleanup(func() { opened = false })
- _, _ = pkg.Open(nil, nil, 0, 0, 0, nil)
+ _, _ = pkg.Open(nil, nil, nil, nil)
panic("unreachable")
})
@@ -2273,11 +2279,7 @@ func TestExtensionRegister(t *testing.T) {
base := check.MustAbs(t.TempDir())
t.Cleanup(func() { opened = false })
- if c, err := pkg.Open(
- t.Context(), nil,
- 0, 0, 0,
- base,
- ); err != nil {
+ if c, err := pkg.Open(t.Context(), nil, base, nil); err != nil {
t.Fatal(err)
} else {
c.Close()
@@ -2305,8 +2307,7 @@ func TestExtensionRegister(t *testing.T) {
}
if _, err := pkg.Open(
t.Context(), nil,
- 0, 0, 0,
- base,
+ base, nil,
); !reflect.DeepEqual(err, wantErr) {
t.Fatalf("Open: error = %v, want %v", err, wantErr)
}
@@ -2327,8 +2328,8 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open(
t.Context(), nil,
- 0, 0, 0,
base,
+ nil,
); !reflect.DeepEqual(err, pkg.ErrWouldPromote) {
t.Fatalf("Open: error = %v", err)
}
@@ -2341,8 +2342,7 @@ func TestExtensionRegister(t *testing.T) {
if c, err := pkg.Open(
t.Context(), nil,
- pkg.CPromoteVariant, 0, 0,
- base,
+ base, &pkg.CacheAttr{Flags: pkg.CPromoteVariant},
); err != nil {
t.Fatalf("Open: error = %v", err)
} else {
@@ -2367,8 +2367,7 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open(
t.Context(), nil,
- 0, 0, 0,
- base,
+ base, nil,
); !reflect.DeepEqual(err, pkg.ErrInvalidExtension) {
t.Fatalf("Open: error = %v", err)
}
@@ -2385,8 +2384,7 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open(
t.Context(), nil,
- 0, 0, 0,
- base,
+ base, nil,
); !reflect.DeepEqual(err, pkg.UnsupportedVariantError("rosa")) {
t.Fatalf("Open: error = %v", err)
}
diff --git a/internal/rosa/mirror_test.go b/internal/rosa/mirror_test.go
index acd45c39..6c3ec92e 100644
--- a/internal/rosa/mirror_test.go
+++ b/internal/rosa/mirror_test.go
@@ -31,7 +31,7 @@ func TestMirror(t *testing.T) {
msg.SwapVerbose(testing.Verbose())
var c *pkg.Cache
- c, err = pkg.Open(t.Context(), msg, 0, 0, 0, base)
+ c, err = pkg.Open(t.Context(), msg, base, nil)
if err != nil {
t.Fatal(err)
}
diff --git a/internal/rosa/rosa_test.go b/internal/rosa/rosa_test.go
index e612c11d..c2a6451c 100644
--- a/internal/rosa/rosa_test.go
+++ b/internal/rosa/rosa_test.go
@@ -61,7 +61,9 @@ func getCache(t *testing.T) *pkg.Cache {
msg := message.New(log.New(os.Stderr, "rosa: ", 0))
msg.SwapVerbose(true)
- if buildTestCache, err = pkg.Open(ctx, msg, pkg.CSuppressInit, 0, 0, a); err != nil {
+ if buildTestCache, err = pkg.Open(ctx, msg, a, &pkg.CacheAttr{
+ Flags: pkg.CSuppressInit,
+ }); err != nil {
t.Fatal(err)
}
}