metis/cmd/metis/main.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")
}