| Tim Windelschmidt | 9f21f53 | 2024-05-07 15:14:20 +0200 | [diff] [blame] | 1 | package launch |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 2 | |
| 3 | import ( |
| Serge Bazanski | 7eeef0f | 2024-02-05 14:40:15 +0100 | [diff] [blame] | 4 | "context" |
| 5 | "crypto/x509" |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 6 | "fmt" |
| 7 | "net" |
| 8 | "os" |
| 9 | "path" |
| 10 | "sort" |
| 11 | |
| 12 | "github.com/kballard/go-shellquote" |
| 13 | |
| 14 | metroctl "source.monogon.dev/metropolis/cli/metroctl/core" |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 15 | ) |
| 16 | |
| Serge Bazanski | 7eeef0f | 2024-02-05 14:40:15 +0100 | [diff] [blame] | 17 | type acceptall struct{} |
| 18 | |
| 19 | func (a *acceptall) Ask(ctx context.Context, _ *metroctl.ConnectOptions, _ *x509.Certificate) (bool, error) { |
| 20 | return true, nil |
| 21 | } |
| 22 | |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 23 | // ConnectOptions returns metroctl.ConnectOptions that describe connectivity to |
| 24 | // the launched cluster. |
| 25 | func (c *Cluster) ConnectOptions() *metroctl.ConnectOptions { |
| 26 | // Use all metropolis nodes as endpoints. That's fine, metroctl's resolver will |
| 27 | // figure out what to actually use. |
| 28 | var endpoints []string |
| 29 | for _, n := range c.Nodes { |
| 30 | endpoints = append(endpoints, n.ManagementAddress) |
| 31 | } |
| 32 | sort.Strings(endpoints) |
| 33 | return &metroctl.ConnectOptions{ |
| 34 | ConfigPath: c.metroctlDir, |
| 35 | ProxyServer: net.JoinHostPort("127.0.0.1", fmt.Sprintf("%d", c.Ports[SOCKSPort])), |
| 36 | Endpoints: endpoints, |
| Serge Bazanski | 7eeef0f | 2024-02-05 14:40:15 +0100 | [diff] [blame] | 37 | TOFU: &acceptall{}, |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 38 | } |
| 39 | } |
| 40 | |
| 41 | // MetroctlFlags return stringified flags to pass to a metroctl binary to connect |
| 42 | // to the launched cluster. |
| 43 | func (c *Cluster) MetroctlFlags() string { |
| 44 | return shellquote.Join(c.ConnectOptions().ToFlags()...) |
| 45 | } |
| 46 | |
| 47 | // MakeMetroctlWrapper builds and returns the path to a shell script which calls |
| 48 | // metroctl (from //metropolis/cli/metroctl, which must be included as a data |
| 49 | // dependency of the built target) with all the required flags to connect to the |
| 50 | // launched cluster. |
| 51 | func (c *Cluster) MakeMetroctlWrapper() (string, error) { |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 52 | wpath := path.Join(c.metroctlDir, "metroctl.sh") |
| 53 | |
| 54 | // Don't create wrapper if it already exists. |
| 55 | if _, err := os.Stat(wpath); err == nil { |
| 56 | return wpath, nil |
| 57 | } |
| 58 | |
| Tim Windelschmidt | 82e6af7 | 2024-07-23 00:05:42 +0000 | [diff] [blame^] | 59 | wrapper := fmt.Sprintf("#!/usr/bin/env bash\nexec %s %s \"$@\"", xMetroctlPath, c.MetroctlFlags()) |
| Serge Bazanski | 1f8cad7 | 2023-03-20 16:58:10 +0100 | [diff] [blame] | 60 | if err := os.WriteFile(wpath, []byte(wrapper), 0555); err != nil { |
| 61 | return "", fmt.Errorf("could not write wrapper: %w", err) |
| 62 | } |
| 63 | return wpath, nil |
| 64 | } |