aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/rosa/mirror.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/internal/rosa/mirror.go b/internal/rosa/mirror.go
index d4dfba1e..80d4509c 100644
--- a/internal/rosa/mirror.go
+++ b/internal/rosa/mirror.go
@@ -14,6 +14,7 @@ import (
"path/filepath"
"strconv"
"strings"
+ "syscall"
"unique"
"hakurei.app/internal/pkg"
@@ -211,6 +212,114 @@ type Mirror struct {
msg message.Msg
}
+// Populate fills an empty root with a static mirror snapshot.
+func (m Mirror) Populate(root *os.Root) error {
+ if dents, err := fs.ReadDir(root.FS(), "."); err != nil {
+ return err
+ } else if len(dents) > 0 {
+ return syscall.ENOTEMPTY
+ }
+
+ for _, name := range []string{
+ dirArtifact,
+ dirOutcome,
+ dirStatus,
+ } {
+ if err := root.Mkdir(name, 0755); err != nil {
+ return err
+ }
+ }
+ var w *os.File
+
+ if dents, err := fs.ReadDir(m.fsys, "identifier"); err != nil {
+ return err
+ } else {
+ for _, dent := range dents {
+ name := dent.Name()
+ var buf [2 * len(pkg.Checksum{})]byte
+ if err = pkg.Decode(
+ (*pkg.Checksum)(buf[:len(pkg.Checksum{})]),
+ name,
+ ); err != nil {
+ return err
+ }
+
+ if w, err = root.OpenFile(
+ filepath.Join(dirArtifact, name),
+ syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL,
+ 0444,
+ ); err != nil {
+ return err
+ }
+ err = m.writeArtifact(&buf, w, nil)
+ if err = errors.Join(err, w.Close()); err != nil {
+ return err
+ }
+ }
+ }
+
+ if dents, err := fs.ReadDir(m.fsys, "checksum"); err != nil {
+ return err
+ } else {
+ for _, dent := range dents {
+ name := dent.Name()
+ var buf pkg.Checksum
+ if err = pkg.Decode(&buf, name); err != nil {
+ return err
+ }
+
+ var fsys fs.FS
+ fsys, err = fs.Sub(m.fsys, filepath.Join("checksum", name))
+ if err != nil {
+ return err
+ }
+
+ if w, err = root.OpenFile(
+ filepath.Join(dirOutcome, name),
+ syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL,
+ 0444,
+ ); err != nil {
+ return err
+ }
+
+ m.msg.Verbosef("exporting outcome %s", name)
+ err = pkg.Write(fsys, ".", w)
+ if err = errors.Join(err, w.Close()); err != nil {
+ return err
+ }
+ }
+ }
+
+ if dents, err := fs.ReadDir(m.fsys, "status"); err != nil {
+ return err
+ } else {
+ for _, dent := range dents {
+ name := dent.Name()
+ var buf [2 * len(pkg.Checksum{})]byte
+ if err = pkg.Decode(
+ (*pkg.Checksum)(buf[:len(pkg.Checksum{})]),
+ name,
+ ); err != nil {
+ return err
+ }
+
+ if w, err = root.OpenFile(
+ filepath.Join(dirStatus, name),
+ syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL,
+ 0444,
+ ); err != nil {
+ return err
+ }
+ err = m.writeStatus(&buf, w, nil)
+ if err = errors.Join(err, w.Close()); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
// NewMirror returns a populated [Mirror] for servicing mirror requests.
func NewMirror(
msg message.Msg,