60 lines
1.8 KiB
Go
60 lines
1.8 KiB
Go
package plan
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"metis/pkg/inventory"
|
|
)
|
|
|
|
// Action describes a step in the burn process.
|
|
type Action struct {
|
|
Type string `json:"type"`
|
|
Detail string `json:"detail"`
|
|
Command string `json:"command,omitempty"`
|
|
}
|
|
|
|
// Plan describes the overall burn for a node.
|
|
type Plan struct {
|
|
Node string `json:"node"`
|
|
Device string `json:"device"`
|
|
Image string `json:"image"`
|
|
Class string `json:"class"`
|
|
Actions []Action `json:"actions"`
|
|
}
|
|
|
|
// Build constructs a plan without executing it.
|
|
func Build(inv *inventory.Inventory, nodeName, device, cacheDir string) (*Plan, error) {
|
|
node, class, err := inv.FindNode(nodeName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if device == "" {
|
|
device = "/dev/sdX" // placeholder
|
|
}
|
|
cacheImage := filepath.Join(cacheDir, filepath.Base(class.Image))
|
|
actions := []Action{
|
|
{Type: "fetch", Detail: fmt.Sprintf("Download %s to %s", class.Image, cacheImage)},
|
|
}
|
|
if class.Checksum != "" {
|
|
actions = append(actions, Action{Type: "verify", Detail: fmt.Sprintf("Verify checksum %s", class.Checksum)})
|
|
}
|
|
actions = append(actions, Action{Type: "write", Detail: fmt.Sprintf("Write image to %s", device), Command: fmt.Sprintf("dd if=%s of=%s bs=4M status=progress conv=fsync", cacheImage, device)})
|
|
actions = append(actions, Action{Type: "inject", Detail: "Inject hostname/network/k3s config into boot or rootfs"})
|
|
actions = append(actions, Action{Type: "finalize", Detail: fmt.Sprintf("Ready to insert SD for %s", node.Hostname)})
|
|
|
|
return &Plan{
|
|
Node: nodeName,
|
|
Device: device,
|
|
Image: class.Image,
|
|
Class: class.Name,
|
|
Actions: actions,
|
|
}, nil
|
|
}
|
|
|
|
// NextRunStale returns true if the last success was older than the given duration.
|
|
func NextRunStale(lastSuccess time.Time, maxAge time.Duration) bool {
|
|
return time.Since(lastSuccess) > maxAge
|
|
}
|