internal/pkg: standardise artifact IR
All checks were successful
Test / Create distribution (push) Successful in 1m0s
Test / Sandbox (push) Successful in 2m41s
Test / Hakurei (push) Successful in 4m1s
Test / ShareFS (push) Successful in 4m1s
Test / Hpkg (push) Successful in 4m35s
Test / Sandbox (race detector) (push) Successful in 5m4s
Test / Hakurei (race detector) (push) Successful in 6m0s
Test / Flake checks (push) Successful in 1m46s
All checks were successful
Test / Create distribution (push) Successful in 1m0s
Test / Sandbox (push) Successful in 2m41s
Test / Hakurei (push) Successful in 4m1s
Test / ShareFS (push) Successful in 4m1s
Test / Hpkg (push) Successful in 4m35s
Test / Sandbox (race detector) (push) Successful in 5m4s
Test / Hakurei (race detector) (push) Successful in 6m0s
Test / Flake checks (push) Successful in 1m46s
This should hopefully provide good separation between the artifact curing backend implementation and the (still work in progress) language. Making the IR parseable also guarantees uniqueness of the representation. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -103,8 +103,7 @@ type execArtifact struct {
|
||||
args []string
|
||||
|
||||
// Duration the initial process is allowed to run. The zero value is
|
||||
// equivalent to execTimeoutDefault. This value is never encoded in Params
|
||||
// because it cannot affect outcome.
|
||||
// equivalent to [ExecTimeoutDefault].
|
||||
timeout time.Duration
|
||||
|
||||
// Caller-supplied exclusivity value, returned as is by IsExclusive.
|
||||
@@ -129,12 +128,6 @@ func (a *execNetArtifact) Checksum() Checksum { return a.checksum }
|
||||
// Kind returns the hardcoded [Kind] constant.
|
||||
func (*execNetArtifact) Kind() Kind { return KindExecNet }
|
||||
|
||||
// Params is [Checksum] concatenated with [KindExec] params.
|
||||
func (a *execNetArtifact) Params(ctx *IContext) {
|
||||
ctx.GetHash().Write(a.checksum[:])
|
||||
a.execArtifact.Params(ctx)
|
||||
}
|
||||
|
||||
// Cure cures the [Artifact] in the container described by the caller. The
|
||||
// container retains host networking.
|
||||
func (a *execNetArtifact) Cure(f *FContext) error {
|
||||
@@ -198,38 +191,131 @@ func (*execArtifact) Kind() Kind { return KindExec }
|
||||
|
||||
// Params writes paths, executable pathname and args.
|
||||
func (a *execArtifact) Params(ctx *IContext) {
|
||||
h := ctx.GetHash()
|
||||
ctx.WriteString(a.name)
|
||||
|
||||
_0, _1 := []byte{0}, []byte{1}
|
||||
ctx.WriteUint32(uint32(len(a.paths)))
|
||||
for _, p := range a.paths {
|
||||
if p.W {
|
||||
h.Write(_1)
|
||||
} else {
|
||||
h.Write(_0)
|
||||
}
|
||||
if p.P != nil {
|
||||
h.Write([]byte(p.P.String()))
|
||||
ctx.WriteString(p.P.String())
|
||||
} else {
|
||||
h.Write([]byte("invalid P\x00"))
|
||||
ctx.WriteString("invalid P\x00")
|
||||
}
|
||||
h.Write(_0)
|
||||
|
||||
ctx.WriteUint32(uint32(len(p.A)))
|
||||
for _, d := range p.A {
|
||||
ctx.WriteIdent(d)
|
||||
}
|
||||
h.Write(_0)
|
||||
|
||||
if p.W {
|
||||
ctx.WriteUint32(1)
|
||||
} else {
|
||||
ctx.WriteUint32(0)
|
||||
}
|
||||
}
|
||||
h.Write(_0)
|
||||
h.Write([]byte(a.dir.String()))
|
||||
h.Write(_0)
|
||||
|
||||
ctx.WriteString(a.dir.String())
|
||||
|
||||
ctx.WriteUint32(uint32(len(a.env)))
|
||||
for _, e := range a.env {
|
||||
h.Write([]byte(e))
|
||||
ctx.WriteString(e)
|
||||
}
|
||||
h.Write(_0)
|
||||
h.Write([]byte(a.path.String()))
|
||||
h.Write(_0)
|
||||
|
||||
ctx.WriteString(a.path.String())
|
||||
|
||||
ctx.WriteUint32(uint32(len(a.args)))
|
||||
for _, arg := range a.args {
|
||||
h.Write([]byte(arg))
|
||||
ctx.WriteString(arg)
|
||||
}
|
||||
|
||||
ctx.WriteUint32(uint32(a.timeout & 0xffffffff))
|
||||
ctx.WriteUint32(uint32(a.timeout >> 32))
|
||||
|
||||
if a.exclusive {
|
||||
ctx.WriteUint32(1)
|
||||
} else {
|
||||
ctx.WriteUint32(0)
|
||||
}
|
||||
}
|
||||
|
||||
// readExecArtifact interprets IR values and returns the address of execArtifact
|
||||
// or execNetArtifact.
|
||||
func readExecArtifact(r *IRReader, net bool) Artifact {
|
||||
r.DiscardAll()
|
||||
|
||||
name := r.ReadString()
|
||||
|
||||
sz := r.ReadUint32()
|
||||
if sz > irMaxDeps {
|
||||
panic(ErrIRDepend)
|
||||
}
|
||||
paths := make([]ExecPath, sz)
|
||||
for i := range paths {
|
||||
paths[i].P = check.MustAbs(r.ReadString())
|
||||
|
||||
sz = r.ReadUint32()
|
||||
if sz > irMaxDeps {
|
||||
panic(ErrIRDepend)
|
||||
}
|
||||
paths[i].A = make([]Artifact, sz)
|
||||
for j := range paths[i].A {
|
||||
paths[i].A[j] = r.ReadIdent()
|
||||
}
|
||||
|
||||
paths[i].W = r.ReadUint32() != 0
|
||||
}
|
||||
|
||||
dir := check.MustAbs(r.ReadString())
|
||||
|
||||
sz = r.ReadUint32()
|
||||
if sz > irMaxValues {
|
||||
panic(ErrIRValues)
|
||||
}
|
||||
env := make([]string, sz)
|
||||
for i := range env {
|
||||
env[i] = r.ReadString()
|
||||
}
|
||||
|
||||
pathname := check.MustAbs(r.ReadString())
|
||||
|
||||
sz = r.ReadUint32()
|
||||
if sz > irMaxValues {
|
||||
panic(ErrIRValues)
|
||||
}
|
||||
args := make([]string, sz)
|
||||
for i := range args {
|
||||
args[i] = r.ReadString()
|
||||
}
|
||||
|
||||
timeout := time.Duration(r.ReadUint32())
|
||||
timeout |= time.Duration(r.ReadUint32()) << 32
|
||||
|
||||
exclusive := r.ReadUint32() != 0
|
||||
|
||||
checksum, ok := r.Finalise()
|
||||
|
||||
var checksumP *Checksum
|
||||
if net {
|
||||
if !ok {
|
||||
panic(ErrExpectedChecksum)
|
||||
}
|
||||
checksumVal := checksum.Value()
|
||||
checksumP = &checksumVal
|
||||
} else {
|
||||
if ok {
|
||||
panic(ErrUnexpectedChecksum)
|
||||
}
|
||||
}
|
||||
|
||||
return NewExec(
|
||||
name, checksumP, timeout, exclusive, dir, env, pathname, args, paths...,
|
||||
)
|
||||
}
|
||||
|
||||
func init() {
|
||||
register(KindExec,
|
||||
func(r *IRReader) Artifact { return readExecArtifact(r, false) })
|
||||
register(KindExecNet,
|
||||
func(r *IRReader) Artifact { return readExecArtifact(r, true) })
|
||||
}
|
||||
|
||||
// Dependencies returns a slice of all artifacts collected from caller-supplied
|
||||
|
||||
Reference in New Issue
Block a user