blob: 3a402e883597ba4fa95761253b41e6c91ee551e3 [file] [log] [blame]
Serge Bazanskicaa12082023-02-16 14:54:04 +01001package main
2
3import (
4 "context"
5 "flag"
6 "fmt"
7 "os"
Serge Bazanskicaa12082023-02-16 14:54:04 +01008
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +02009 "golang.org/x/crypto/ssh"
Tim Windelschmidt44cacd62023-06-12 23:54:45 +020010 "k8s.io/klog/v2"
Serge Bazanskicaa12082023-02-16 14:54:04 +010011
12 "source.monogon.dev/cloud/bmaas/bmdb"
Serge Bazanski77628312023-02-15 23:33:22 +010013 "source.monogon.dev/cloud/bmaas/bmdb/webug"
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020014 "source.monogon.dev/cloud/equinix/wrapngo"
Serge Bazanskicaa12082023-02-16 14:54:04 +010015 "source.monogon.dev/cloud/lib/component"
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020016 "source.monogon.dev/cloud/shepherd/manager"
Serge Bazanskicaa12082023-02-16 14:54:04 +010017 clicontext "source.monogon.dev/metropolis/cli/pkg/context"
18)
19
20type Config struct {
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020021 Component component.ComponentConfig
22 BMDB bmdb.BMDB
23 WebugConfig webug.Config
Serge Bazanskicaa12082023-02-16 14:54:04 +010024
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020025 SSHKey manager.SSHKey
Serge Bazanskicaa12082023-02-16 14:54:04 +010026 InitializerConfig manager.InitializerConfig
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020027 ProvisionerConfig manager.ProvisionerConfig
Serge Bazanskiae004682023-04-18 13:28:48 +020028 RecovererConfig manager.RecovererConfig
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020029
30 API wrapngo.Opts
31 Provider providerConfig
32 UpdaterConfig UpdaterConfig
Serge Bazanskicaa12082023-02-16 14:54:04 +010033}
34
35// TODO(q3k): factor this out to BMDB library?
36func runtimeInfo() string {
37 hostname, _ := os.Hostname()
38 if hostname == "" {
39 hostname = "UNKNOWN"
40 }
41 return fmt.Sprintf("host %s", hostname)
42}
43
44func (c *Config) RegisterFlags() {
45 c.Component.RegisterFlags("shepherd")
46 c.BMDB.ComponentName = "shepherd-equinix"
47 c.BMDB.RuntimeInfo = runtimeInfo()
48 c.BMDB.Database.RegisterFlags("bmdb")
Serge Bazanski77628312023-02-15 23:33:22 +010049 c.WebugConfig.RegisterFlags()
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020050
51 c.SSHKey.RegisterFlags()
52 c.InitializerConfig.RegisterFlags()
53 c.ProvisionerConfig.RegisterFlags()
54 c.RecovererConfig.RegisterFlags()
55
Serge Bazanskicaa12082023-02-16 14:54:04 +010056 c.API.RegisterFlags()
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020057 c.Provider.RegisterFlags()
58 c.UpdaterConfig.RegisterFlags()
Serge Bazanskicaa12082023-02-16 14:54:04 +010059}
60
61func main() {
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020062 var c Config
Serge Bazanskicaa12082023-02-16 14:54:04 +010063 c.RegisterFlags()
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020064
Serge Bazanskicaa12082023-02-16 14:54:04 +010065 flag.Parse()
Tim Windelschmidt44cacd62023-06-12 23:54:45 +020066 if flag.NArg() > 0 {
67 klog.Exitf("unexpected positional arguments: %v", flag.Args())
68 }
Serge Bazanskicaa12082023-02-16 14:54:04 +010069
Serge Bazanskic50f6942023-04-24 18:27:22 +020070 registry := c.Component.PrometheusRegistry()
71 c.BMDB.EnableMetrics(registry)
72
Serge Bazanskicaa12082023-02-16 14:54:04 +010073 ctx := clicontext.WithInterrupt(context.Background())
Serge Bazanskifbda89e2023-04-24 17:43:58 +020074 c.Component.StartPrometheus(ctx)
Serge Bazanskicaa12082023-02-16 14:54:04 +010075
76 if c.API.APIKey == "" || c.API.User == "" {
77 klog.Exitf("-equinix_api_username and -equinix_api_key must be set")
78 }
Serge Bazanskidea7cd02023-04-26 13:58:17 +020079 c.API.MetricsRegistry = registry
Serge Bazanskicaa12082023-02-16 14:54:04 +010080 api := wrapngo.New(&c.API)
81
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020082 provider, err := c.Provider.New(&c.SSHKey, api)
Serge Bazanskicaa12082023-02-16 14:54:04 +010083 if err != nil {
84 klog.Exitf("%v", err)
85 }
86
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020087 sshSigner, err := c.SSHKey.Signer()
Serge Bazanskicaa12082023-02-16 14:54:04 +010088 if err != nil {
89 klog.Exitf("%v", err)
90 }
91
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020092 sshClient := &manager.PlainSSHClient{
93 AuthMethod: ssh.PublicKeys(sshSigner),
94 // Equinix OS installations always use root.
95 Username: "root",
96 }
97
98 provisioner, err := manager.NewProvisioner(provider, c.ProvisionerConfig)
99 if err != nil {
100 klog.Exitf("%v", err)
101 }
102
103 initializer, err := manager.NewInitializer(provider, sshClient, c.InitializerConfig)
104 if err != nil {
105 klog.Exitf("%v", err)
106 }
107
108 recoverer, err := manager.NewRecoverer(provider, c.RecovererConfig)
Serge Bazanskiae004682023-04-18 13:28:48 +0200109 if err != nil {
110 klog.Exitf("%v", err)
111 }
112
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200113 updater, err := c.UpdaterConfig.New(api)
114 if err != nil {
115 klog.Exitf("%v", err)
116 }
117
Serge Bazanskicaa12082023-02-16 14:54:04 +0100118 conn, err := c.BMDB.Open(true)
119 if err != nil {
120 klog.Exitf("Failed to open BMDB connection: %v", err)
121 }
Serge Bazanski77628312023-02-15 23:33:22 +0100122
Serge Bazanskicaa12082023-02-16 14:54:04 +0100123 go func() {
124 err = provisioner.Run(ctx, conn)
125 if err != nil {
126 klog.Exit(err)
127 }
128 }()
129 go func() {
Serge Bazanski86a714d2023-04-17 15:54:21 +0200130 err = manager.RunControlLoop(ctx, conn, initializer)
Serge Bazanskicaa12082023-02-16 14:54:04 +0100131 if err != nil {
132 klog.Exit(err)
133 }
134 }()
Serge Bazanski77628312023-02-15 23:33:22 +0100135 go func() {
Serge Bazanskiae004682023-04-18 13:28:48 +0200136 err = manager.RunControlLoop(ctx, conn, recoverer)
137 if err != nil {
138 klog.Exit(err)
139 }
140 }()
141 go func() {
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200142 err = updater.Run(ctx, conn)
143 if err != nil {
144 klog.Exit(err)
145 }
146 }()
147 go func() {
Serge Bazanski77628312023-02-15 23:33:22 +0100148 if err := c.WebugConfig.Start(ctx, conn); err != nil && err != ctx.Err() {
149 klog.Exitf("Failed to start webug: %v", err)
150 }
151 }()
Serge Bazanskicaa12082023-02-16 14:54:04 +0100152
153 <-ctx.Done()
154}