blob: 0fb28e12587340f1b7054c4c249a72dab09ba68f [file] [log] [blame]
Serge Bazanskicaa12082023-02-16 14:54:04 +01001package main
2
3import (
4 "context"
Tim Windelschmidtd5f851b2024-04-23 14:59:37 +02005 "errors"
Serge Bazanskicaa12082023-02-16 14:54:04 +01006 "flag"
7 "fmt"
8 "os"
Tim Windelschmidtb765f242024-05-08 01:40:02 +02009 "os/signal"
Serge Bazanskicaa12082023-02-16 14:54:04 +010010
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020011 "golang.org/x/crypto/ssh"
Tim Windelschmidt44cacd62023-06-12 23:54:45 +020012 "k8s.io/klog/v2"
Serge Bazanskicaa12082023-02-16 14:54:04 +010013
14 "source.monogon.dev/cloud/bmaas/bmdb"
Serge Bazanski77628312023-02-15 23:33:22 +010015 "source.monogon.dev/cloud/bmaas/bmdb/webug"
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020016 "source.monogon.dev/cloud/equinix/wrapngo"
Serge Bazanskicaa12082023-02-16 14:54:04 +010017 "source.monogon.dev/cloud/lib/component"
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020018 "source.monogon.dev/cloud/shepherd/manager"
Tim Windelschmidt5f5f3302024-02-22 23:50:24 +010019 ssh2 "source.monogon.dev/go/net/ssh"
Serge Bazanskicaa12082023-02-16 14:54:04 +010020)
21
22type Config struct {
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020023 Component component.ComponentConfig
24 BMDB bmdb.BMDB
25 WebugConfig webug.Config
Serge Bazanskicaa12082023-02-16 14:54:04 +010026
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020027 SSHKey manager.SSHKey
Serge Bazanskicaa12082023-02-16 14:54:04 +010028 InitializerConfig manager.InitializerConfig
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020029 ProvisionerConfig manager.ProvisionerConfig
Serge Bazanskiae004682023-04-18 13:28:48 +020030 RecovererConfig manager.RecovererConfig
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020031
32 API wrapngo.Opts
33 Provider providerConfig
34 UpdaterConfig UpdaterConfig
Serge Bazanskicaa12082023-02-16 14:54:04 +010035}
36
37// TODO(q3k): factor this out to BMDB library?
38func runtimeInfo() string {
39 hostname, _ := os.Hostname()
40 if hostname == "" {
41 hostname = "UNKNOWN"
42 }
43 return fmt.Sprintf("host %s", hostname)
44}
45
46func (c *Config) RegisterFlags() {
47 c.Component.RegisterFlags("shepherd")
48 c.BMDB.ComponentName = "shepherd-equinix"
49 c.BMDB.RuntimeInfo = runtimeInfo()
50 c.BMDB.Database.RegisterFlags("bmdb")
Serge Bazanski77628312023-02-15 23:33:22 +010051 c.WebugConfig.RegisterFlags()
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020052
53 c.SSHKey.RegisterFlags()
54 c.InitializerConfig.RegisterFlags()
55 c.ProvisionerConfig.RegisterFlags()
56 c.RecovererConfig.RegisterFlags()
57
Serge Bazanskicaa12082023-02-16 14:54:04 +010058 c.API.RegisterFlags()
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020059 c.Provider.RegisterFlags()
60 c.UpdaterConfig.RegisterFlags()
Serge Bazanskicaa12082023-02-16 14:54:04 +010061}
62
63func main() {
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020064 var c Config
Serge Bazanskicaa12082023-02-16 14:54:04 +010065 c.RegisterFlags()
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020066
Serge Bazanskicaa12082023-02-16 14:54:04 +010067 flag.Parse()
Tim Windelschmidt44cacd62023-06-12 23:54:45 +020068 if flag.NArg() > 0 {
69 klog.Exitf("unexpected positional arguments: %v", flag.Args())
70 }
Serge Bazanskicaa12082023-02-16 14:54:04 +010071
Serge Bazanskic50f6942023-04-24 18:27:22 +020072 registry := c.Component.PrometheusRegistry()
73 c.BMDB.EnableMetrics(registry)
74
Tim Windelschmidtb765f242024-05-08 01:40:02 +020075 ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
Serge Bazanskifbda89e2023-04-24 17:43:58 +020076 c.Component.StartPrometheus(ctx)
Serge Bazanskicaa12082023-02-16 14:54:04 +010077
78 if c.API.APIKey == "" || c.API.User == "" {
79 klog.Exitf("-equinix_api_username and -equinix_api_key must be set")
80 }
Serge Bazanskidea7cd02023-04-26 13:58:17 +020081 c.API.MetricsRegistry = registry
Serge Bazanskicaa12082023-02-16 14:54:04 +010082 api := wrapngo.New(&c.API)
83
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020084 provider, err := c.Provider.New(&c.SSHKey, api)
Serge Bazanskicaa12082023-02-16 14:54:04 +010085 if err != nil {
86 klog.Exitf("%v", err)
87 }
88
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020089 sshSigner, err := c.SSHKey.Signer()
Serge Bazanskicaa12082023-02-16 14:54:04 +010090 if err != nil {
91 klog.Exitf("%v", err)
92 }
93
Tim Windelschmidt5f5f3302024-02-22 23:50:24 +010094 sshClient := &ssh2.DirectClient{
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +020095 AuthMethod: ssh.PublicKeys(sshSigner),
96 // Equinix OS installations always use root.
97 Username: "root",
98 }
99
100 provisioner, err := manager.NewProvisioner(provider, c.ProvisionerConfig)
101 if err != nil {
102 klog.Exitf("%v", err)
103 }
104
105 initializer, err := manager.NewInitializer(provider, sshClient, c.InitializerConfig)
106 if err != nil {
107 klog.Exitf("%v", err)
108 }
109
110 recoverer, err := manager.NewRecoverer(provider, c.RecovererConfig)
Serge Bazanskiae004682023-04-18 13:28:48 +0200111 if err != nil {
112 klog.Exitf("%v", err)
113 }
114
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200115 updater, err := c.UpdaterConfig.New(api)
116 if err != nil {
117 klog.Exitf("%v", err)
118 }
119
Serge Bazanskicaa12082023-02-16 14:54:04 +0100120 conn, err := c.BMDB.Open(true)
121 if err != nil {
122 klog.Exitf("Failed to open BMDB connection: %v", err)
123 }
Serge Bazanski77628312023-02-15 23:33:22 +0100124
Serge Bazanskicaa12082023-02-16 14:54:04 +0100125 go func() {
126 err = provisioner.Run(ctx, conn)
127 if err != nil {
128 klog.Exit(err)
129 }
130 }()
131 go func() {
Serge Bazanski86a714d2023-04-17 15:54:21 +0200132 err = manager.RunControlLoop(ctx, conn, initializer)
Serge Bazanskicaa12082023-02-16 14:54:04 +0100133 if err != nil {
134 klog.Exit(err)
135 }
136 }()
Serge Bazanski77628312023-02-15 23:33:22 +0100137 go func() {
Serge Bazanskiae004682023-04-18 13:28:48 +0200138 err = manager.RunControlLoop(ctx, conn, recoverer)
139 if err != nil {
140 klog.Exit(err)
141 }
142 }()
143 go func() {
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200144 err = updater.Run(ctx, conn)
145 if err != nil {
146 klog.Exit(err)
147 }
148 }()
149 go func() {
Tim Windelschmidtd5f851b2024-04-23 14:59:37 +0200150 if err := c.WebugConfig.Start(ctx, conn); err != nil && !errors.Is(err, ctx.Err()) {
Serge Bazanski77628312023-02-15 23:33:22 +0100151 klog.Exitf("Failed to start webug: %v", err)
152 }
153 }()
Serge Bazanskicaa12082023-02-16 14:54:04 +0100154
155 <-ctx.Done()
156}