89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"metis/pkg/inventory"
|
|
"metis/pkg/plan"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
switch os.Args[1] {
|
|
case "plan":
|
|
planCmd(os.Args[2:])
|
|
case "burn":
|
|
burnCmd(os.Args[2:])
|
|
default:
|
|
usage()
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func usage() {
|
|
fmt.Fprintf(os.Stderr, "Usage: metis <plan|burn> [options]\n")
|
|
}
|
|
|
|
func loadInventory(path string) *inventory.Inventory {
|
|
inv, err := inventory.Load(path)
|
|
if err != nil {
|
|
log.Fatalf("load inventory: %v", err)
|
|
}
|
|
return inv
|
|
}
|
|
|
|
func planCmd(args []string) {
|
|
fs := flag.NewFlagSet("plan", flag.ExitOnError)
|
|
invPath := fs.String("inventory", "inventory.yaml", "inventory file")
|
|
node := fs.String("node", "", "target node")
|
|
device := fs.String("device", "/dev/sdX", "target block device")
|
|
cache := fs.String("cache", filepath.Join(os.TempDir(), "metis-cache"), "image cache dir")
|
|
fs.Parse(args)
|
|
if *node == "" {
|
|
log.Fatalf("--node is required")
|
|
}
|
|
inv := loadInventory(*invPath)
|
|
p, err := plan.Build(inv, *node, *device, *cache)
|
|
if err != nil {
|
|
log.Fatalf("build plan: %v", err)
|
|
}
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.SetIndent("", " ")
|
|
_ = enc.Encode(p)
|
|
}
|
|
|
|
func burnCmd(args []string) {
|
|
fs := flag.NewFlagSet("burn", flag.ExitOnError)
|
|
invPath := fs.String("inventory", "inventory.yaml", "inventory file")
|
|
node := fs.String("node", "", "target node")
|
|
device := fs.String("device", "", "target block device (e.g. /dev/sdX)")
|
|
cache := fs.String("cache", filepath.Join(os.TempDir(), "metis-cache"), "image cache dir")
|
|
confirm := fs.Bool("yes", false, "actually write to device")
|
|
fs.Parse(args)
|
|
if *node == "" || *device == "" {
|
|
log.Fatalf("--node and --device are required")
|
|
}
|
|
inv := loadInventory(*invPath)
|
|
p, err := plan.Build(inv, *node, *device, *cache)
|
|
if err != nil {
|
|
log.Fatalf("build plan: %v", err)
|
|
}
|
|
fmt.Printf("Plan for %s to %s:\n", p.Node, p.Device)
|
|
for _, a := range p.Actions {
|
|
fmt.Printf("- [%s] %s\n", a.Type, a.Detail)
|
|
}
|
|
if !*confirm {
|
|
fmt.Printf("\nDry run. Re-run with --yes to execute (not yet implemented).\n")
|
|
return
|
|
}
|
|
log.Fatalf("burn execution not yet implemented; follow plan commands manually")
|
|
}
|