Some checks failed
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m26s
Test / Hakurei (push) Successful in 3m22s
Test / Sandbox (race detector) (push) Successful in 4m29s
Test / Hakurei (race detector) (push) Successful in 5m12s
Test / Flake checks (push) Has been cancelled
Test / Hpkg (push) Has been cancelled
This is simultaneously more efficient and less error-prone. This change caused minor API changes in multiple other packages. Signed-off-by: Ophestra <cat@gensokyo.uk>
68 lines
1.7 KiB
Go
68 lines
1.7 KiB
Go
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 *Absolute, prefix string) *Ops {
|
|
e := &AutoEtcOp{prefix}
|
|
f.Mkdir(AbsFHSEtc, 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 + FHSEtc
|
|
rel := e.hostRel() + "/"
|
|
|
|
if err := os.MkdirAll(target, 0755); err != nil {
|
|
return wrapErrSelf(err)
|
|
}
|
|
if d, err := os.ReadDir(toSysroot(e.hostPath().String())); 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(FHSProc+"mounts", target+n); err != nil {
|
|
return wrapErrSelf(err)
|
|
}
|
|
|
|
default:
|
|
if err = os.Symlink(rel+n, target+n); err != nil {
|
|
return wrapErrSelf(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// bypasses abs check, use with caution!
|
|
func (e *AutoEtcOp) hostPath() *Absolute { return &Absolute{FHSEtc + 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) }
|