m/c/metroctl: split cmd_install for future changes

Change-Id: I99119cc8f5e3728cf832427d1cad79f69fbd48bc
Reviewed-on: https://review.monogon.dev/c/monogon/+/2793
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/cli/metroctl/cmd_install_usb.go b/metropolis/cli/metroctl/cmd_install_usb.go
new file mode 100644
index 0000000..a9873b6
--- /dev/null
+++ b/metropolis/cli/metroctl/cmd_install_usb.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+	_ "embed"
+	"log"
+
+	"github.com/spf13/cobra"
+
+	"source.monogon.dev/metropolis/cli/metroctl/core"
+)
+
+var genusbCmd = &cobra.Command{
+	Use:     "genusb target",
+	Short:   "Generates a Metropolis installer disk or image.",
+	Example: "metroctl install --bundle=metropolis-v0.1.zip genusb /dev/sdx",
+	Args:    cobra.ExactArgs(1), // One positional argument: the target
+	Run:     doGenUSB,
+}
+
+func doGenUSB(cmd *cobra.Command, args []string) {
+	params := makeNodeParams()
+
+	installerPath, err := cmd.Flags().GetString("installer")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	installer := external("installer", "_main/metropolis/installer/kernel.efi", &installerPath)
+	bundle := external("bundle", "_main/metropolis/node/bundle.zip", bundlePath)
+
+	installerImageArgs := core.MakeInstallerImageArgs{
+		TargetPath: args[0],
+		Installer:  installer,
+		NodeParams: params,
+		Bundle:     bundle,
+	}
+
+	log.Printf("Generating installer image (this can take a while, see issues/92).")
+	if err := core.MakeInstallerImage(installerImageArgs); err != nil {
+		log.Fatalf("Failed to create installer: %v", err)
+	}
+}
+
+func init() {
+	genusbCmd.Flags().StringP("installer", "i", "", "Path to the Metropolis installer to use when installing")
+	installCmd.AddCommand(genusbCmd)
+}