-
Notifications
You must be signed in to change notification settings - Fork 290
/
switch.go
146 lines (133 loc) · 5.17 KB
/
switch.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package docker
import (
"context"
"io"
"sync"
"github.com/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"golang.org/x/sync/errgroup"
"github.com/tilt-dev/tilt/internal/container"
"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
"github.com/tilt-dev/tilt/pkg/model"
)
// A Cli implementation that lets us switch back and forth between a local
// Docker instance and one that lives in our K8s cluster.
type switchCli struct {
localCli LocalClient
clusterCli ClusterClient
orc model.Orchestrator
mu sync.Mutex
}
var _ Client = &switchCli{}
var _ CompositeClient = &switchCli{}
func ProvideSwitchCli(clusterCli ClusterClient, localCli LocalClient) CompositeClient {
return &switchCli{
localCli: localCli,
clusterCli: clusterCli,
orc: model.OrchestratorK8s,
}
}
var orcKey model.Orchestrator
// WithOrchestrator returns a Context with the current orchestrator set.
func WithOrchestrator(ctx context.Context, orc model.Orchestrator) context.Context {
return context.WithValue(ctx, orcKey, orc)
}
func (c *switchCli) client(ctx context.Context) Client {
c.mu.Lock()
defer c.mu.Unlock()
orc, ok := ctx.Value(orcKey).(model.Orchestrator)
if ok {
return c.ForOrchestrator(orc)
}
return c.ForOrchestrator(c.orc)
}
func (c *switchCli) SetOrchestrator(orc model.Orchestrator) {
c.mu.Lock()
defer c.mu.Unlock()
c.orc = orc
}
func (c *switchCli) ForOrchestrator(orc model.Orchestrator) Client {
if orc == model.OrchestratorK8s {
return c.clusterCli
}
return c.localCli
}
func (c *switchCli) CheckConnected() error {
return c.client(context.Background()).CheckConnected()
}
func (c *switchCli) Env() Env {
return c.client(context.Background()).Env()
}
func (c *switchCli) BuilderVersion(ctx context.Context) (types.BuilderVersion, error) {
return c.client(ctx).BuilderVersion(ctx)
}
func (c *switchCli) ServerVersion(ctx context.Context) (types.Version, error) {
return c.client(ctx).ServerVersion(ctx)
}
func (c *switchCli) ContainerLogs(ctx context.Context, containerID string, options types.ContainerLogsOptions) (io.ReadCloser, error) {
return c.client(ctx).ContainerLogs(ctx, containerID, options)
}
func (c *switchCli) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) {
return c.client(ctx).ContainerInspect(ctx, containerID)
}
func (c *switchCli) ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) {
return c.client(ctx).ContainerList(ctx, options)
}
func (c *switchCli) ContainerRestartNoWait(ctx context.Context, containerID string) error {
return c.client(ctx).ContainerRestartNoWait(ctx, containerID)
}
func (c *switchCli) Run(ctx context.Context, opts RunConfig) (RunResult, error) {
return c.client(ctx).Run(ctx, opts)
}
func (c *switchCli) ExecInContainer(ctx context.Context, cID container.ID, cmd model.Cmd, in io.Reader, out io.Writer) error {
return c.client(ctx).ExecInContainer(ctx, cID, cmd, in, out)
}
func (c *switchCli) ImagePull(ctx context.Context, ref reference.Named) (reference.Canonical, error) {
return c.client(ctx).ImagePull(ctx, ref)
}
func (c *switchCli) ImagePush(ctx context.Context, ref reference.NamedTagged) (io.ReadCloser, error) {
return c.client(ctx).ImagePush(ctx, ref)
}
func (c *switchCli) ImageBuild(ctx context.Context, g *errgroup.Group, buildContext io.Reader, options BuildOptions) (types.ImageBuildResponse, error) {
return c.client(ctx).ImageBuild(ctx, g, buildContext, options)
}
func (c *switchCli) ImageTag(ctx context.Context, source, target string) error {
return c.client(ctx).ImageTag(ctx, source, target)
}
func (c *switchCli) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
return c.client(ctx).ImageInspectWithRaw(ctx, imageID)
}
func (c *switchCli) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error) {
return c.client(ctx).ImageList(ctx, options)
}
func (c *switchCli) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
return c.client(ctx).ImageRemove(ctx, imageID, options)
}
func (c *switchCli) NewVersionError(apiRequired, feature string) error {
return c.client(context.Background()).NewVersionError(apiRequired, feature)
}
func (c *switchCli) BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {
return c.client(ctx).BuildCachePrune(ctx, opts)
}
func (c *switchCli) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) {
return c.client(ctx).ContainersPrune(ctx, pruneFilters)
}
// CompositeClient
func (c *switchCli) DefaultLocalClient() Client {
return c.localCli
}
func (c *switchCli) DefaultClusterClient() Client {
return c.clusterCli
}
func (c *switchCli) ClientFor(cluster v1alpha1.Cluster) Client {
conn := cluster.Spec.Connection
if conn.Kubernetes != nil {
// TODO: pick correct client in multiple cluster situation
return c.DefaultClusterClient()
}
return c.DefaultLocalClient()
}
func (c *switchCli) HasMultipleClients() bool {
return c.localCli.Env().DaemonHost() != c.clusterCli.Env().DaemonHost()
}