diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-01-21 05:28:41 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-01-21 05:28:41 +0900 |
| commit | 8e59ff98b5aa1637ed4f47d283b9d7844d0a1b06 (patch) | |
| tree | 4d6f961754cb2f1c86a59735aa5c20ab0871dab2 /internal/rosa/etc.go | |
| parent | f06d7fd387d5b3b3e03f1795e5e3538067462419 (diff) | |
internal/rosa: include iana-etc
This is used by some programs and will likely end up in the Rosa OS system image anyway.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/rosa/etc.go')
| -rw-r--r-- | internal/rosa/etc.go | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/internal/rosa/etc.go b/internal/rosa/etc.go index 9126bdd2..25947c23 100644 --- a/internal/rosa/etc.go +++ b/internal/rosa/etc.go @@ -1,7 +1,10 @@ package rosa import ( + "errors" + "io" "os" + "syscall" "hakurei.app/internal/pkg" ) @@ -9,10 +12,13 @@ import ( // cureEtc contains deterministic elements of /etc, made available as part of // [Toolchain]. This silences test suites expecting certain standard files to be // available in /etc. -type cureEtc struct{} +type cureEtc struct { + // Optional via newIANAEtc. + iana pkg.Artifact +} // Cure writes hardcoded configuration to files under etc. -func (cureEtc) Cure(t *pkg.TContext) (err error) { +func (a cureEtc) Cure(t *pkg.FContext) (err error) { etc := t.GetWorkDir().Append("etc") if err = os.MkdirAll(etc.String(), 0700); err != nil { return @@ -36,6 +42,44 @@ nobody:x:65534: return } } + + if a.iana != nil { + iana, _ := t.GetArtifact(a.iana) + + buf := make([]byte, syscall.Getpagesize()<<3) + for _, name := range []string{ + "protocols", + "services", + } { + var dst, src *os.File + if dst, err = os.OpenFile( + etc.Append(name).String(), + syscall.O_CREAT|syscall.O_EXCL|syscall.O_WRONLY, + 0400, + ); err != nil { + return + } + + if src, err = os.Open( + iana.Append(name).String(), + ); err != nil { + _ = dst.Close() + return + } + + _, err = io.CopyBuffer(dst, src, buf) + closeErrs := [...]error{ + dst.Close(), + src.Close(), + } + if err != nil { + return + } else if err = errors.Join(closeErrs[:]...); err != nil { + return + } + } + } + return os.Chmod(etc.String(), 0500) } @@ -45,8 +89,27 @@ func (cureEtc) Kind() pkg.Kind { return kindEtc } // Params is a noop. func (cureEtc) Params(*pkg.IContext) {} -// Dependencies returns a nil slice. -func (cureEtc) Dependencies() []pkg.Artifact { return nil } +// Dependencies returns a slice containing the backing iana-etc release. +func (a cureEtc) Dependencies() []pkg.Artifact { + if a.iana != nil { + return []pkg.Artifact{a.iana} + } + return nil +} // String returns a hardcoded reporting name. func (cureEtc) String() string { return "cure-etc" } + +// newIANAEtc returns an unpacked iana-etc release. +func newIANAEtc() pkg.Artifact { + const ( + version = "20251215" + checksum = "kvKz0gW_rGG5QaNK9ZWmWu1IEgYAdmhj_wR7DYrh3axDfIql_clGRHmelP7525NJ" + ) + return pkg.NewHTTPGetTar( + nil, "https://github.com/Mic92/iana-etc/releases/download/"+ + version+"/iana-etc-"+version+".tar.gz", + mustDecode(checksum), + pkg.TarGzip, + ) +} |
