internal/rosa: remove xz utils hack
Test / Create distribution (push) Successful in 56s
Test / Sandbox (push) Successful in 2m54s
Test / Hakurei (push) Successful in 4m33s
Test / Sandbox (race detector) (push) Successful in 6m5s
Test / Hakurei (race detector) (push) Successful in 8m0s
Test / ShareFS (push) Successful in 8m32s
Test / Flake checks (push) Successful in 1m27s

This replaces all xz invocations with the native decompressor. This also significantly cleans up the Gentoo stage3 bootstrap path.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
cat
2026-07-25 14:14:34 +09:00
parent 35147f6dfb
commit 0d3efeb456
6 changed files with 131 additions and 176 deletions
-124
View File
@@ -1,124 +0,0 @@
package rosa
import (
"fmt"
"io"
"net/http"
"os"
"time"
"hakurei.app/fhs"
"hakurei.app/internal/pkg"
)
// busyboxBin is a busybox binary distribution installed under bin/busybox.
type busyboxBin struct {
// Underlying busybox binary.
bin pkg.FileArtifact
}
// Kind returns the hardcoded [pkg.Kind] value.
func (a busyboxBin) Kind() pkg.Kind { return kindBusyboxBin }
// Params is a noop.
func (a busyboxBin) Params(*pkg.IContext) {}
// IsExclusive returns false: Cure performs a trivial filesystem write.
func (busyboxBin) IsExclusive() bool { return false }
// Inputs returns the underlying busybox [pkg.FileArtifact].
func (a busyboxBin) Inputs() []pkg.Artifact {
return []pkg.Artifact{a.bin}
}
func init() {
pkg.Register(kindBusyboxBin, func(r *pkg.IRReader) pkg.Artifact {
a := busyboxBin{r.Next().(pkg.FileArtifact)}
if _, ok := r.Finalise(); ok {
panic(pkg.ErrUnexpectedChecksum)
}
return a
})
}
// String returns the reporting name of the underlying file prefixed with expand.
func (a busyboxBin) String() string {
return "expand-" + a.bin.(fmt.Stringer).String()
}
// Cure installs the underlying busybox [pkg.File] to bin/busybox.
func (a busyboxBin) Cure(t *pkg.TContext) (err error) {
var r io.ReadCloser
if r, err = t.Open(a.bin); err != nil {
return
}
defer func() {
closeErr := r.Close()
if err == nil {
err = closeErr
}
}()
binDir := t.GetWorkDir().Append("bin")
if err = os.MkdirAll(binDir.String(), 0700); err != nil {
return
}
var w *os.File
if w, err = os.OpenFile(
binDir.Append("busybox").String(),
os.O_WRONLY|os.O_CREATE|os.O_EXCL,
0500,
); err != nil {
return
}
defer func() {
closeErr := w.Close()
if err == nil {
err = closeErr
}
}()
_, err = io.Copy(w, r)
return
}
// newBusyboxBin returns a [pkg.Artifact] containing a busybox installation from
// the https://busybox.net/downloads/binaries/ binary release.
func (s *S) newBusyboxBin() pkg.Artifact {
var version, url, checksum string
switch s.arch {
case "amd64":
version = "1.35.0"
url = "https://busybox.net/downloads/binaries/" +
version + "-" + s.linuxArch() + "-linux-musl/busybox"
checksum = "L7OBIsPu9enNHn7FqpBT1kOg_mCLNmetSeNMA3i4Y60Z5jTgnlX3qX3zcQtLx5AB"
case "arm64":
version = "1.31.0"
url = "https://busybox.net/downloads/binaries/" +
version + "-defconfig-multiarch-musl/busybox-armv8l"
checksum = "npJjBO7iwhjW6Kx2aXeSxf8kXhVgTCDChOZTTsI8ZfFfa3tbsklxRiidZQdrVERg"
default:
panic("unsupported target " + s.arch)
}
return pkg.NewExec(
"busybox-bin-"+version, s.arch, nil, pkg.ExecTimeoutMax, false, false,
fhs.AbsRoot, []string{
"PATH=/system/bin",
},
AbsSystem.Append("bin", "busybox"),
[]string{"hush", "-c", "" +
"busybox mkdir -p /work/system/bin/ && " +
"busybox cp /system/bin/busybox /work/system/bin/ && " +
"busybox --install -s /work/system/bin/"},
pkg.Path(AbsSystem, true, busyboxBin{pkg.NewHTTPGet(
&http.Client{Transport: &http.Transport{
// busybox website is really slow to respond
TLSHandshakeTimeout: 2 * time.Minute,
}}, url,
mustDecode(checksum),
)}),
)
}
+104
View File
@@ -0,0 +1,104 @@
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
}
+1 -1
View File
@@ -8,7 +8,7 @@ import (
) )
func TestLLVMInputs(t *testing.T) { func TestLLVMInputs(t *testing.T) {
const wantInputCount = 473 const wantInputCount = 470
_, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm")) _, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm"))
var n int var n int
+4 -2
View File
@@ -292,11 +292,14 @@ package findutils {
anitya = 812; anitya = 812;
version# = "4.11.0"; version# = "4.11.0";
source = remoteFile { source = remoteTar {
url = "https://ftpmirror.gnu.org/gnu/findutils/findutils-"+version+".tar.xz"; url = "https://ftpmirror.gnu.org/gnu/findutils/findutils-"+version+".tar.xz";
compress = xz;
checksum = "X-qsv9aUoBL583q-4iZcBI3_7Ufd3fSIqFmNLXWdEpUihlRfMpGGyAUt8SAvDKae"; checksum = "X-qsv9aUoBL583q-4iZcBI3_7Ufd3fSIqFmNLXWdEpUihlRfMpGGyAUt8SAvDKae";
}; };
writable = true;
chmod = true;
early = ` early = `
echo '#!/bin/sh' > gnulib-tests/test-c32ispunct.sh echo '#!/bin/sh' > gnulib-tests/test-c32ispunct.sh
echo 'int main(){return 0;}' > gnulib-tests/test-fstatat.c echo 'int main(){return 0;}' > gnulib-tests/test-fstatat.c
@@ -307,7 +310,6 @@ echo 'int main(){return 0;}' > tests/xargs/test-sigusr.c
inputs = [ inputs = [
diffutils, diffutils,
xz,
sed, sed,
]; ];
} }
+13 -43
View File
@@ -26,8 +26,8 @@ const (
// kindEtc is the kind of [pkg.Artifact] of cureEtc. // kindEtc is the kind of [pkg.Artifact] of cureEtc.
kindEtc = iota + pkg.KindCustomOffset kindEtc = iota + pkg.KindCustomOffset
// kindBusyboxBin is the kind of [pkg.Artifact] of busyboxBin. // kindGentooOverlay is the kind of [pkg.Artifact] of gentooOverlay.
kindBusyboxBin kindGentooOverlay
) )
// mustDecode is like [pkg.MustDecode], but replaces the zero value and prints // mustDecode is like [pkg.MustDecode], but replaces the zero value and prints
@@ -97,15 +97,9 @@ func (s *S) earlyLDFLAGS(static bool) string {
} }
const ( const (
// _stageBusybox denotes a busybox installation from the busyboxBin
// binary distribution. This is defined as a [Stage] to make use of the
// toolchain abstractions to preprocess stageGentoo and is not a real,
// functioning toolchain. It does not contain any compilers.
_stageBusybox Stage = iota
// stageGentoo denotes the toolchain in a Gentoo stage3 tarball. Special // stageGentoo denotes the toolchain in a Gentoo stage3 tarball. Special
// care must be taken to compile correctly against this stage. // care must be taken to compile correctly against this stage.
stageGentoo stageGentoo Stage = iota
// stageIntermediateGentoo is like stageIntermediate, but compiled against // stageIntermediateGentoo is like stageIntermediate, but compiled against
// stageGentoo. // stageGentoo.
@@ -239,11 +233,6 @@ func (t Toolchain) New(
var support []pkg.Artifact var support []pkg.Artifact
switch t.stage { switch t.stage {
case _stageBusybox:
name += "-early"
support = slices.Concat([]pkg.Artifact{t.newBusyboxBin()}, extra)
env = fixupEnviron(env, nil, "/system/bin")
case stageGentoo, stageEarly: case stageGentoo, stageEarly:
name += "-boot" name += "-boot"
support = append(support, extra...) support = append(support, extra...)
@@ -251,22 +240,17 @@ func (t Toolchain) New(
if t.stage == stageEarly { if t.stage == stageEarly {
_, a := t.MustLoad(_stage0Dist) _, a := t.MustLoad(_stage0Dist)
support = append(support, a) support = append(support, a)
} else if t.gentooStage3 == nil {
panic(os.ErrInvalid)
} else { } else {
support = append(support, t.S.New(_stageBusybox).New("gentoo", 0, nil, nil, nil, ` support = append(support,
tar -C /work -xf /usr/src/stage3.tar.xz t.gentooStage3,
rm -rf /work/dev/ /work/proc/ gentooOverlay{t.gentooStage3},
ln -vs ../usr/bin /work/bin )
mkdir -vp /work/system/bin env = append(env,
(cd /work/system/bin && ln -vs \ "CC=clang",
../../bin/sh \ "CXX=clang++",
../../usr/lib/llvm/*/bin/* \ )
.)
`, pkg.Path(AbsUsrSrc.Append("stage3.tar.xz"), false,
pkg.NewHTTPGet(
nil, t.gentooStage3,
t.gentooStage3Checksum,
),
)))
} }
env = fixupEnviron(env, []string{ env = fixupEnviron(env, []string{
EnvTriple + "=" + t.triple(), EnvTriple + "=" + t.triple(),
@@ -516,20 +500,6 @@ func (t Toolchain) NewPackage(
sourceSuffix string sourceSuffix string
) )
if _, ok := source.(pkg.FileArtifact); ok {
if attr.Writable || attr.Chmod ||
wantsChmod || wantsWrite ||
len(attr.Patches) > 0 {
panic("source processing requested on a xz-compressed tarball")
}
sourceSuffix = ".tar.xz"
scriptEarly += `
tar -C /usr/src/ -xf '/usr/src/` + name + `.tar.xz'
mv '/usr/src/` + rn + `' '/usr/src/` + name + `'
`
}
dir, create := helper.wantsDir() dir, create := helper.wantsDir()
helperScriptEarly := helper.scriptEarly() helperScriptEarly := helper.scriptEarly()
if attr.EnterSource || if attr.EnterSource ||
+9 -6
View File
@@ -213,10 +213,8 @@ type S struct {
// Cached [pkg.Artifact]. // Cached [pkg.Artifact].
c [_stageEnd]sync.Map c [_stageEnd]sync.Map
// URL of a Gentoo stage3 tarball. // Unpacked Gentoo LLVM stage3.
gentooStage3 string gentooStage3 pkg.Artifact
// Expected checksum of gentooStage3.
gentooStage3Checksum pkg.Checksum
} }
// Clone returns a copy of s. // Clone returns a copy of s.
@@ -485,6 +483,7 @@ func (s *S) getFrame() azalea.Frame {
k("gzip"): pkg.Gzip + compressOffset, k("gzip"): pkg.Gzip + compressOffset,
k("bzip2"): pkg.Bzip2 + compressOffset, k("bzip2"): pkg.Bzip2 + compressOffset,
k("zstd"): pkg.Zstd + compressOffset, k("zstd"): pkg.Zstd + compressOffset,
k("xz"): pkg.XZ + compressOffset,
} }
s.frame.Val = map[unique.Handle[azalea.Ident]]any{ s.frame.Val = map[unique.Handle[azalea.Ident]]any{
@@ -803,6 +802,7 @@ func (s *S) getFrame() azalea.Frame {
k("gzip"): uint32(pkg.Gzip), k("gzip"): uint32(pkg.Gzip),
k("bzip2"): uint32(pkg.Bzip2), k("bzip2"): uint32(pkg.Bzip2),
k("zstd"): uint32(pkg.Zstd), k("zstd"): uint32(pkg.Zstd),
k("xz"): uint32(pkg.XZ),
}}, }},
// high-level helpers // high-level helpers
@@ -1372,12 +1372,15 @@ func (s *S) SetSource(fsys fs.FS) error {
// SetGentooStage3 sets the Gentoo stage3 tarball url and checksum. It panics // SetGentooStage3 sets the Gentoo stage3 tarball url and checksum. It panics
// if given zero values or if these values have already been set. // if given zero values or if these values have already been set.
func (s *S) SetGentooStage3(url string, checksum pkg.Checksum) { func (s *S) SetGentooStage3(url string, checksum pkg.Checksum) {
if s.gentooStage3 != "" { if s.gentooStage3 != nil {
panic(errors.New("attempting to set Gentoo stage3 url twice")) panic(errors.New("attempting to set Gentoo stage3 url twice"))
} }
if url == "" { if url == "" {
panic(errors.New("attempting to set Gentoo stage3 url to the zero value")) panic(errors.New("attempting to set Gentoo stage3 url to the zero value"))
} }
s.gentooStage3, s.gentooStage3Checksum = url, checksum s.gentooStage3 = pkg.NewTar(pkg.NewDecompress(
pkg.NewHTTPGet(nil, url, checksum),
pkg.XZ,
))
s.DropCaches(s.Arch(), s.Flags()) s.DropCaches(s.Arch(), s.Flags())
} }