-
-
Notifications
You must be signed in to change notification settings - Fork 517
/
util.go
112 lines (102 loc) · 3.63 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package cli
import (
"context"
"fmt"
"io"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/datawire/dlib/dcontext"
"github.com/telepresenceio/telepresence/rpc/v2/connector"
"github.com/telepresenceio/telepresence/rpc/v2/daemon"
"github.com/telepresenceio/telepresence/v2/pkg/client/cli/cliutil"
)
// quit sends the quit message to the daemon and waits for it to exit.
func quit(ctx context.Context) error {
// When the daemon shuts down, it will tell the connector to shut down.
if err := cliutil.QuitDaemon(ctx); err != nil {
return err
}
// But also do that ourselves; to ensure the connector is killed even if daemon isn't
// running. If the daemon already shut down the connector, then this is a no-op.
if err := cliutil.QuitConnector(ctx); err != nil {
return err
}
return nil
}
func kubeFlagMap() map[string]string {
kubeFlagMap := make(map[string]string)
kubeFlags.VisitAll(func(flag *pflag.Flag) {
if flag.Changed {
kubeFlagMap[flag.Name] = flag.Value.String()
}
})
return kubeFlagMap
}
// withConnector is like cliutil.WithConnector, but also
//
// - Ensures that the damon is running too
//
// - Cleans up after itself if !retain (If it launches the daemon or connector, then it will shut
// them down when it's done. If they were already running, it will leave them running.)
//
// - Makes the connector.Connect gRPC call to set up networking
func withConnector(cmd *cobra.Command, retain bool, f func(context.Context, connector.ConnectorClient, *connector.ConnectInfo) error) error {
return cliutil.WithDaemon(cmd.Context(), dnsIP, func(ctx context.Context, daemonClient daemon.DaemonClient) (err error) {
if cliutil.DidLaunchDaemon(ctx) {
defer func() {
if err != nil || !retain {
_ = cliutil.QuitDaemon(dcontext.WithoutCancel(ctx))
}
}()
}
return cliutil.WithConnector(ctx, func(ctx context.Context, connectorClient connector.ConnectorClient) (err error) {
if cliutil.DidLaunchConnector(ctx) && !cliutil.DidLaunchDaemon(ctx) {
// Don't shut down the connector if we're shutting down the daemon.
// The daemon will shut down the connector for us, and if we shut it
// down early the daemon will get upset.
defer func() {
if err != nil || !retain {
_ = cliutil.QuitConnector(dcontext.WithoutCancel(ctx))
}
}()
}
connInfo, err := setConnectInfo(ctx, cmd.OutOrStdout())
if err != nil {
return err
}
return f(ctx, connectorClient, connInfo)
})
})
}
func setConnectInfo(ctx context.Context, stdout io.Writer) (*connector.ConnectInfo, error) {
var resp *connector.ConnectInfo
err := cliutil.WithStartedConnector(ctx, func(ctx context.Context, connectorClient connector.ConnectorClient) error {
var err error
resp, err = connectorClient.Connect(ctx, &connector.ConnectRequest{
KubeFlags: kubeFlagMap(),
MappedNamespaces: mappedNamespaces,
})
if err != nil {
return err
}
var msg string
switch resp.Error {
case connector.ConnectInfo_UNSPECIFIED:
fmt.Fprintf(stdout, "Connected to context %s (%s)\n", resp.ClusterContext, resp.ClusterServer)
return nil
case connector.ConnectInfo_ALREADY_CONNECTED:
return nil
case connector.ConnectInfo_DISCONNECTED:
msg = "Not connected"
case connector.ConnectInfo_MUST_RESTART:
msg = "Cluster configuration changed, please quit telepresence and reconnect"
case connector.ConnectInfo_TRAFFIC_MANAGER_FAILED, connector.ConnectInfo_CLUSTER_FAILED, connector.ConnectInfo_DAEMON_FAILED:
msg = resp.ErrorText
}
return fmt.Errorf("connector.Connect: %s", msg) // Return err != nil to ensure disconnect
})
if err != nil {
return nil, err
}
return resp, nil
}