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/BUILD.bazel b/metropolis/cli/metroctl/BUILD.bazel
index 60c59b6..a84ae03 100644
--- a/metropolis/cli/metroctl/BUILD.bazel
+++ b/metropolis/cli/metroctl/BUILD.bazel
@@ -19,6 +19,7 @@
srcs = [
"cmd_certs.go",
"cmd_install.go",
+ "cmd_install_usb.go",
"cmd_k8s_configure.go",
"cmd_k8scredplugin.go",
"cmd_node.go",
diff --git a/metropolis/cli/metroctl/cmd_install.go b/metropolis/cli/metroctl/cmd_install.go
index 64cdb26..f729d34 100644
--- a/metropolis/cli/metroctl/cmd_install.go
+++ b/metropolis/cli/metroctl/cmd_install.go
@@ -5,7 +5,6 @@
"context"
"crypto/ed25519"
_ "embed"
- "io"
"log"
"os"
"strings"
@@ -27,55 +26,18 @@
Use: "install",
}
-var bundlePath = installCmd.PersistentFlags().StringP("bundle", "b", "", "Path to the Metropolis bundle to be installed")
-var installerPath = installCmd.PersistentFlags().StringP("installer", "i", "", "Path to the Metropolis installer to use when installing")
-
-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,
-}
-
// bootstrap is a flag controlling node parameters included in the installer
// image. If set, the installed node will bootstrap a new cluster. Otherwise,
// it will try to connect to the cluster which endpoints were provided with
// the --endpoints flag.
-var bootstrap bool
+var bootstrap = installCmd.PersistentFlags().Bool("bootstrap", false, "Create a bootstrap installer image.")
+var bootstrapTPMMode = installCmd.PersistentFlags().String("bootstrap-tpm-mode", "required", "TPM mode to set on cluster (required, best-effort, disabled)")
+var bootstrapStorageSecurityPolicy = installCmd.PersistentFlags().String("bootstrap-storage-security", "needs-encryption-and-authentication", "Storage security policy to set on cluster (permissive, needs-encryption, needs-encryption-and-authentication, needs-insecure)")
+var bundlePath = installCmd.PersistentFlags().StringP("bundle", "b", "", "Path to the Metropolis bundle to be installed")
-var bootstrapTPMMode string
-var bootstrapStorageSecurityPolicy string
-
-type externalFile struct {
- reader io.Reader
- size uint64
-}
-
-func external(name, datafilePath string, flag *string) fat32.SizedReader {
- if flag == nil || *flag == "" {
- rPath, err := runfiles.Rlocation(datafilePath)
- if err != nil {
- log.Fatalf("No %s specified", name)
- }
- df, err := os.ReadFile(rPath)
- if err != nil {
- log.Fatalf("Cant read file: %v", err)
- }
- return bytes.NewReader(df)
- }
-
- f, err := blkio.NewFileReader(*bundlePath)
- if err != nil {
- log.Fatalf("Failed to open specified %s: %v", name, err)
- }
-
- return f
-}
-
-func doGenUSB(cmd *cobra.Command, args []string) {
+func makeNodeParams() *api.NodeParameters {
var tpmMode cpb.ClusterConfiguration_TPMMode
- switch strings.ToLower(bootstrapTPMMode) {
+ switch strings.ToLower(*bootstrapTPMMode) {
case "required", "require":
tpmMode = cpb.ClusterConfiguration_TPM_MODE_REQUIRED
case "best-effort", "besteffort":
@@ -87,7 +49,7 @@
}
var bootstrapStorageSecurity cpb.ClusterConfiguration_StorageSecurityPolicy
- switch strings.ToLower(bootstrapStorageSecurityPolicy) {
+ switch strings.ToLower(*bootstrapStorageSecurityPolicy) {
case "permissive":
bootstrapStorageSecurity = cpb.ClusterConfiguration_STORAGE_SECURITY_POLICY_PERMISSIVE
case "needs-encryption":
@@ -101,17 +63,15 @@
log.Fatalf("Invalid --bootstrap-storage-security (must be one of: permissive, needs-encryption, needs-encryption-and-authentication, needs-insecure)")
}
- bundle := external("bundle", "metropolis/node/bundle.zip", bundlePath)
- installer := external("installer", "metropolis/installer/kernel.efi", installerPath)
ctx := clicontext.WithInterrupt(context.Background())
- // TODO(lorenz): Have a key management story for this
if err := os.MkdirAll(flags.configPath, 0700); err != nil && !os.IsExist(err) {
log.Fatalf("Failed to create config directory: %v", err)
}
var params *api.NodeParameters
- if bootstrap {
+ if *bootstrap {
+ // TODO(lorenz): Have a key management story for this
priv, err := core.GetOrMakeOwnerKey(flags.configPath)
if err != nil {
log.Fatalf("Failed to generate or get owner key: %v", err)
@@ -150,25 +110,30 @@
},
}
}
+ return params
+}
- installerImageArgs := core.MakeInstallerImageArgs{
- TargetPath: args[0],
- Installer: installer,
- NodeParams: params,
- Bundle: bundle,
+func external(name, datafilePath string, flag *string) fat32.SizedReader {
+ if flag == nil || *flag == "" {
+ rPath, err := runfiles.Rlocation(datafilePath)
+ if err != nil {
+ log.Fatalf("No %s specified", name)
+ }
+ df, err := os.ReadFile(rPath)
+ if err != nil {
+ log.Fatalf("Cant read file: %v", err)
+ }
+ return bytes.NewReader(df)
}
- 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)
+ f, err := blkio.NewFileReader(*bundlePath)
+ if err != nil {
+ log.Fatalf("Failed to open specified %s: %v", name, err)
}
+
+ return f
}
func init() {
rootCmd.AddCommand(installCmd)
-
- genusbCmd.Flags().BoolVar(&bootstrap, "bootstrap", false, "Create a bootstrap installer image.")
- genusbCmd.Flags().StringVar(&bootstrapTPMMode, "bootstrap-tpm-mode", "required", "TPM mode to set on cluster (required, best-effort, disabled)")
- genusbCmd.Flags().StringVar(&bootstrapStorageSecurityPolicy, "bootstrap-storage-security", "needs-encryption-and-authentication", "Storage security policy to set on cluster (permissive, needs-encryption, needs-encryption-and-authentication, needs-insecure)")
- installCmd.AddCommand(genusbCmd)
}
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)
+}