package rosa import ( "fmt" "io" "net/http" "os" "time" "hakurei.app/container/fhs" "hakurei.app/internal/pkg" ) // busyboxBin is a busybox binary distribution installed under bin/busybox. type busyboxBin struct { // Underlying busybox binary. bin pkg.File } // 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) {} // Dependencies returns the underlying busybox [pkg.File]. func (a busyboxBin) Dependencies() []pkg.Artifact { return []pkg.Artifact{a.bin} } // 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 newBusyboxBin() pkg.Artifact { const ( version = "1.35.0" checksum = "L7OBIsPu9enNHn7FqpBT1kOg_mCLNmetSeNMA3i4Y60Z5jTgnlX3qX3zcQtLx5AB" ) return pkg.NewExec( "busybox-bin-"+version, nil, pkg.ExecTimeoutMax, 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, }}, "https://busybox.net/downloads/binaries/"+ version+"-"+linuxArch()+"-linux-musl/busybox", mustDecode(checksum), )}), ) }