diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-07-31 19:54:03 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-07-31 19:54:03 +0900 |
| commit | 4e518f11d8b28d13ab23b7126ef87f882042bf0a (patch) | |
| tree | 1582e4a6cb47ceaf39e4b2063d70a557d8cd8129 /container/autoetc.go | |
| parent | cb513bb1cd7b098bbe8a60cd105cc764648db410 (diff) | |
container/ops: autoetc implementation to separate file
This is not a general purpose setup Op. Separate it so it is easier to find.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'container/autoetc.go')
| -rw-r--r-- | container/autoetc.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/container/autoetc.go b/container/autoetc.go new file mode 100644 index 00000000..103bd35b --- /dev/null +++ b/container/autoetc.go @@ -0,0 +1,65 @@ +package container + +import ( + "encoding/gob" + "fmt" + "os" +) + +func init() { gob.Register(new(AutoEtcOp)) } + +// Etc appends an [Op] that expands host /etc into a toplevel symlink mirror with /etc semantics. +// This is not a generic setup op. It is implemented here to reduce ipc overhead. +func (f *Ops) Etc(host, prefix string) *Ops { + e := &AutoEtcOp{prefix} + f.Mkdir("/etc", 0755) + f.Bind(host, e.hostPath(), 0) + *f = append(*f, e) + return f +} + +type AutoEtcOp struct{ Prefix string } + +func (e *AutoEtcOp) early(*Params) error { return nil } +func (e *AutoEtcOp) apply(*Params) error { + const target = sysrootPath + "/etc/" + rel := e.hostRel() + "/" + + if err := os.MkdirAll(target, 0755); err != nil { + return wrapErrSelf(err) + } + if d, err := os.ReadDir(toSysroot(e.hostPath())); err != nil { + return wrapErrSelf(err) + } else { + for _, ent := range d { + n := ent.Name() + switch n { + case ".host": + + case "passwd": + case "group": + + case "mtab": + if err = os.Symlink("/proc/mounts", target+n); err != nil { + return wrapErrSelf(err) + } + + default: + if err = os.Symlink(rel+n, target+n); err != nil { + return wrapErrSelf(err) + } + } + } + } + + return nil +} +func (e *AutoEtcOp) hostPath() string { return "/etc/" + e.hostRel() } +func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix } + +func (e *AutoEtcOp) Is(op Op) bool { + ve, ok := op.(*AutoEtcOp) + return ok && ((e == nil && ve == nil) || (e != nil && ve != nil && *e == *ve)) +} +func (*AutoEtcOp) prefix() string { return "setting up" } +func (e *AutoEtcOp) String() string { return fmt.Sprintf("auto etc %s", e.Prefix) } |
