blob: cf43747f6348f956e5da17916e35352cc2f35d28 [file] [log] [blame]
Lorenz Brune6573102021-11-02 14:15:37 +01001package main
2
3import (
Serge Bazanski97783222021-12-14 16:04:26 +01004 "bytes"
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +02005 "context"
Lorenz Brune6573102021-11-02 14:15:37 +01006 "crypto/ed25519"
Lorenz Brun7a510192022-07-04 15:31:38 +00007 _ "embed"
Lorenz Brune6573102021-11-02 14:15:37 +01008 "log"
9 "os"
Tim Windelschmidtb765f242024-05-08 01:40:02 +020010 "os/signal"
Lorenz Brune6573102021-11-02 14:15:37 +010011
Tim Windelschmidt2a1d1b22024-02-06 07:07:42 +010012 "github.com/bazelbuild/rules_go/go/runfiles"
Lorenz Brune6573102021-11-02 14:15:37 +010013 "github.com/spf13/cobra"
14
Tim Windelschmidt2a1d1b22024-02-06 07:07:42 +010015 "source.monogon.dev/metropolis/proto/api"
16 cpb "source.monogon.dev/metropolis/proto/common"
17
Jan Schära9b060b2024-08-07 10:42:29 +020018 "source.monogon.dev/metropolis/cli/flagdefs"
Lorenz Brune6573102021-11-02 14:15:37 +010019 "source.monogon.dev/metropolis/cli/metroctl/core"
Tim Windelschmidt9f21f532024-05-07 15:14:20 +020020 "source.monogon.dev/osbase/blkio"
21 "source.monogon.dev/osbase/fat32"
Lorenz Brune6573102021-11-02 14:15:37 +010022)
23
24var installCmd = &cobra.Command{
Lorenz Brun7a510192022-07-04 15:31:38 +000025 Short: "Contains subcommands to install Metropolis via different media.",
Lorenz Brune6573102021-11-02 14:15:37 +010026 Use: "install",
27}
28
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020029// bootstrap is a flag controlling node parameters included in the installer
30// image. If set, the installed node will bootstrap a new cluster. Otherwise,
31// it will try to connect to the cluster which endpoints were provided with
32// the --endpoints flag.
Tim Windelschmidt7006caf2024-02-27 16:49:39 +010033var bootstrap = installCmd.PersistentFlags().Bool("bootstrap", false, "Create a bootstrap installer image.")
Jan Schära9b060b2024-08-07 10:42:29 +020034var bootstrapTPMMode = flagdefs.TPMModePflag(installCmd.PersistentFlags(), "bootstrap-tpm-mode", cpb.ClusterConfiguration_TPM_MODE_REQUIRED, "TPM mode to set on cluster")
35var bootstrapStorageSecurityPolicy = flagdefs.StorageSecurityPolicyPflag(installCmd.PersistentFlags(), "bootstrap-storage-security", cpb.ClusterConfiguration_STORAGE_SECURITY_POLICY_NEEDS_ENCRYPTION_AND_AUTHENTICATION, "Storage security policy to set on cluster")
Tim Windelschmidt7006caf2024-02-27 16:49:39 +010036var bundlePath = installCmd.PersistentFlags().StringP("bundle", "b", "", "Path to the Metropolis bundle to be installed")
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020037
Tim Windelschmidt7006caf2024-02-27 16:49:39 +010038func makeNodeParams() *api.NodeParameters {
Tim Windelschmidtb765f242024-05-08 01:40:02 +020039 ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020040
Mateusz Zalega8234c162022-07-08 17:05:50 +020041 if err := os.MkdirAll(flags.configPath, 0700); err != nil && !os.IsExist(err) {
Lorenz Brune6573102021-11-02 14:15:37 +010042 log.Fatalf("Failed to create config directory: %v", err)
43 }
Lorenz Brune6573102021-11-02 14:15:37 +010044
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020045 var params *api.NodeParameters
Tim Windelschmidt7006caf2024-02-27 16:49:39 +010046 if *bootstrap {
47 // TODO(lorenz): Have a key management story for this
Serge Bazanskicf23ebc2023-03-14 17:02:04 +010048 priv, err := core.GetOrMakeOwnerKey(flags.configPath)
49 if err != nil {
50 log.Fatalf("Failed to generate or get owner key: %v", err)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020051 }
Serge Bazanskicf23ebc2023-03-14 17:02:04 +010052 pub := priv.Public().(ed25519.PublicKey)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020053 params = &api.NodeParameters{
54 Cluster: &api.NodeParameters_ClusterBootstrap_{
55 ClusterBootstrap: &api.NodeParameters_ClusterBootstrap{
Serge Bazanskicf23ebc2023-03-14 17:02:04 +010056 OwnerPublicKey: pub,
Serge Bazanskibdc803b2023-03-27 10:55:09 +020057 InitialClusterConfiguration: &cpb.ClusterConfiguration{
Jan Schära9b060b2024-08-07 10:42:29 +020058 StorageSecurityPolicy: *bootstrapStorageSecurityPolicy,
59 TpmMode: *bootstrapTPMMode,
Serge Bazanskibdc803b2023-03-27 10:55:09 +020060 },
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020061 },
Lorenz Brune6573102021-11-02 14:15:37 +010062 },
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020063 }
64 } else {
Mateusz Zalegadb75e212022-08-04 17:31:34 +020065 cc := dialAuthenticated(ctx)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020066 mgmt := api.NewManagementClient(cc)
67 resT, err := mgmt.GetRegisterTicket(ctx, &api.GetRegisterTicketRequest{})
68 if err != nil {
69 log.Fatalf("While receiving register ticket: %v", err)
70 }
71 resI, err := mgmt.GetClusterInfo(ctx, &api.GetClusterInfoRequest{})
72 if err != nil {
73 log.Fatalf("While receiving cluster directory: %v", err)
74 }
75
76 params = &api.NodeParameters{
77 Cluster: &api.NodeParameters_ClusterRegister_{
78 ClusterRegister: &api.NodeParameters_ClusterRegister{
79 RegisterTicket: resT.Ticket,
80 ClusterDirectory: resI.ClusterDirectory,
81 CaCertificate: resI.CaCertificate,
82 },
83 },
84 }
Lorenz Brune6573102021-11-02 14:15:37 +010085 }
Tim Windelschmidt7006caf2024-02-27 16:49:39 +010086 return params
87}
Lorenz Brune6573102021-11-02 14:15:37 +010088
Tim Windelschmidt7006caf2024-02-27 16:49:39 +010089func external(name, datafilePath string, flag *string) fat32.SizedReader {
90 if flag == nil || *flag == "" {
91 rPath, err := runfiles.Rlocation(datafilePath)
92 if err != nil {
93 log.Fatalf("No %s specified", name)
94 }
95 df, err := os.ReadFile(rPath)
96 if err != nil {
97 log.Fatalf("Cant read file: %v", err)
98 }
99 return bytes.NewReader(df)
Lorenz Brune6573102021-11-02 14:15:37 +0100100 }
101
Tim Windelschmidt9ded9942024-04-08 21:30:17 +0200102 f, err := blkio.NewFileReader(*flag)
Tim Windelschmidt7006caf2024-02-27 16:49:39 +0100103 if err != nil {
104 log.Fatalf("Failed to open specified %s: %v", name, err)
Lorenz Brune6573102021-11-02 14:15:37 +0100105 }
Tim Windelschmidt7006caf2024-02-27 16:49:39 +0100106
107 return f
Lorenz Brune6573102021-11-02 14:15:37 +0100108}
109
110func init() {
111 rootCmd.AddCommand(installCmd)
Lorenz Brune6573102021-11-02 14:15:37 +0100112}