From cc89dbdf63dd8d6025a2158562295a74f923765e Mon Sep 17 00:00:00 2001 From: Ophestra Date: Mon, 17 Mar 2025 22:13:22 +0900 Subject: sandbox: place files with content Signed-off-by: Ophestra --- sandbox/sequential.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'sandbox/sequential.go') diff --git a/sandbox/sequential.go b/sandbox/sequential.go index f9c2e29d..153de0a0 100644 --- a/sandbox/sequential.go +++ b/sandbox/sequential.go @@ -6,6 +6,7 @@ import ( "math" "os" "path" + "slices" "syscall" "unsafe" ) @@ -262,3 +263,55 @@ func (f *Ops) Mkdir(dest string) *Ops { *f = append(*f, Mkdir(dest)) return f } + +func init() { gob.Register(new(Tmpfile)) } + +// Tmpfile places a file in container Path containing Data. +type Tmpfile struct { + Path string + Data []byte +} + +func (t *Tmpfile) apply(*Params) error { + if !path.IsAbs(t.Path) { + return msg.WrapErr(syscall.EBADE, + fmt.Sprintf("path %q is not absolute", t.Path)) + } + + var tmpPath string + if f, err := os.CreateTemp("/", "tmp.*"); err != nil { + return msg.WrapErr(err, err.Error()) + } else if _, err = f.Write(t.Data); err != nil { + return wrapErrSuffix(err, + "cannot write to intermediate file:") + } else if err = f.Close(); err != nil { + return wrapErrSuffix(err, + "cannot close intermediate file:") + } else { + tmpPath = f.Name() + } + + if err := bindMount(tmpPath, t.Path, BindSource|bindAbsolute); err != nil { + return err + } else if err = os.Remove(tmpPath); err != nil { + return msg.WrapErr(err, err.Error()) + } + return nil +} + +func (t *Tmpfile) Is(op Op) bool { + vt, ok := op.(*Tmpfile) + return ok && t.Path == vt.Path && slices.Equal(t.Data, vt.Data) +} +func (*Tmpfile) prefix() string { return "placing" } +func (t *Tmpfile) String() string { + return fmt.Sprintf("tmpfile %q (%d bytes)", t.Path, len(t.Data)) +} +func (f *Ops) Place(name string, data []byte) *Ops { *f = append(*f, &Tmpfile{name, data}); return f } +func (f *Ops) PlaceP(name string, dataP **[]byte) *Ops { + t := &Tmpfile{Path: name} + *dataP = &t.Data + + *f = append(*f, t) + return f +} -- cgit v1.3.1