2026-03-31 14:52:50 -03:00
|
|
|
package plan
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"path/filepath"
|
2026-03-31 19:00:48 -03:00
|
|
|
"strings"
|
2026-03-31 14:52:50 -03:00
|
|
|
|
|
|
|
|
"metis/pkg/image"
|
|
|
|
|
"metis/pkg/inventory"
|
|
|
|
|
"metis/pkg/writer"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// BuildImageFile materializes a fully injected raw image for a node.
|
|
|
|
|
func BuildImageFile(ctx context.Context, inv *inventory.Inventory, nodeName, cacheDir, output string) error {
|
|
|
|
|
p, err := Build(inv, nodeName, output, cacheDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("build plan: %w", err)
|
|
|
|
|
}
|
|
|
|
|
_, class, err := inv.FindNode(nodeName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("load node class: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 19:00:48 -03:00
|
|
|
cacheImage := filepath.Join(cacheDir, cacheName(p.Image))
|
|
|
|
|
cacheImage, err = image.DownloadAndVerify(p.Image, cacheImage, class.Checksum)
|
|
|
|
|
if err != nil {
|
2026-03-31 14:52:50 -03:00
|
|
|
return fmt.Errorf("download image: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if err := writer.WriteImage(ctx, cacheImage, output); err != nil {
|
|
|
|
|
return fmt.Errorf("copy base image: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
files, err := Files(inv, nodeName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("resolve files: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if err := image.InjectRootFS(output, files); err != nil {
|
|
|
|
|
return fmt.Errorf("inject rootfs: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-03-31 19:00:48 -03:00
|
|
|
|
|
|
|
|
func cacheName(source string) string {
|
|
|
|
|
base := filepath.Base(source)
|
|
|
|
|
return strings.TrimSuffix(base, ".xz")
|
|
|
|
|
}
|