internal/rosa: populate mirror snapshot
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 2m52s
Test / ShareFS (push) Successful in 3m54s
Test / Hakurei (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 5m45s
Test / Hakurei (race detector) (push) Successful in 6m38s
Test / Flake checks (push) Successful in 1m10s
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 2m52s
Test / ShareFS (push) Successful in 3m54s
Test / Hakurei (push) Successful in 4m2s
Test / Sandbox (race detector) (push) Successful in 5m45s
Test / Hakurei (race detector) (push) Successful in 6m38s
Test / Flake checks (push) Successful in 1m10s
This produces the same structure served by the dynamic server. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -568,6 +568,47 @@ func main() {
|
||||
},
|
||||
)
|
||||
|
||||
c.NewCommand(
|
||||
"snapshot",
|
||||
"Populate an empty directory with a static mirror snapshot",
|
||||
func(args []string) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("snapshot requires 1 argument")
|
||||
}
|
||||
|
||||
var key ed25519.PrivateKey
|
||||
if p, err := os.ReadFile(filepath.Join(cm.base, "ed25519")); err != nil {
|
||||
return err
|
||||
} else if len(p) != ed25519.PrivateKeySize {
|
||||
return errors.New("invalid private key")
|
||||
} else {
|
||||
key = p
|
||||
}
|
||||
|
||||
var m rosa.Mirror
|
||||
if base, err := os.OpenRoot(cm.base); err != nil {
|
||||
return err
|
||||
} else {
|
||||
m = rosa.NewMirror(msg, base.FS(), key)
|
||||
}
|
||||
|
||||
retry:
|
||||
root, err := os.OpenRoot(args[0])
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(args[0], 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
goto retry
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
go func() { <-ctx.Done(); _ = root.Close() }()
|
||||
return m.Populate(root)
|
||||
},
|
||||
)
|
||||
|
||||
{
|
||||
var (
|
||||
flagGentoo string
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user