package rosa import ( "errors" "io/fs" "os" "path/filepath" "hakurei.app/internal/pkg" ) // gentooOverlay are symlinks on top of a Gentoo LLVM stage3 tarball for // compatibility with the Rosa OS stage0 distribution. type gentooOverlay struct{ stage3 pkg.Artifact } // Kind returns the hardcoded [pkg.Kind] value. func (a gentooOverlay) Kind() pkg.Kind { return kindGentooOverlay } // Params is a noop. func (a gentooOverlay) Params(*pkg.IContext) {} // IsExclusive returns false: Cure performs a trivial filesystem write. func (gentooOverlay) IsExclusive() bool { return false } // Inputs returns the underlying Gentoo stage3. func (a gentooOverlay) Inputs() []pkg.Artifact { return []pkg.Artifact{a.stage3} } func init() { pkg.Register(kindGentooOverlay, func(r *pkg.IRReader) pkg.Artifact { a := gentooOverlay{r.Next()} if _, ok := r.Finalise(); ok { panic(pkg.ErrUnexpectedChecksum) } return a }) } // String returns a hardcoded name. func (a gentooOverlay) String() string { return "gentoo-overlay" } // Revision returns a hardcoded value incremented on layout changes. func (a gentooOverlay) Revision() uint64 { return 0 } // Cure installs the overlay. func (a gentooOverlay) Cure(f *pkg.FContext) (err error) { pathname, _ := f.GetArtifact(a.stage3) var stage3 *os.Root if stage3, err = os.OpenRoot(pathname.String()); err != nil { return err } defer func() { closeErr := stage3.Close() if err == nil { err = closeErr } }() fsys := stage3.FS() system := f.GetWorkDir().Append("system") bin := system.Append("bin") if err = os.MkdirAll(bin.String(), 0700); err != nil { return } linknames := []string{ "../../bin/sh", } var dents []os.DirEntry const llvm = "usr/lib/llvm" dents, err = fs.ReadDir(fsys, llvm) if err != nil { return } if len(dents) != 1 { return errors.New("stage3 /" + llvm + " contains more than one entry") } llvmBin := filepath.Join(llvm, dents[0].Name(), "bin") dents, err = fs.ReadDir(fsys, llvmBin) if err != nil { return } for _, dent := range dents { linknames = append(linknames, filepath.Join( "../..", llvmBin, dent.Name(), )) } for _, linkname := range linknames { if err = os.Symlink( linkname, bin.Append(filepath.Base(linkname)).String(), ); err != nil { return } } return }