github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/docker/context.go (about) 1 package docker 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 "sync" 8 9 "github.com/docker/docker/client" 10 11 "github.com/telepresenceio/telepresence/v2/pkg/proc" 12 ) 13 14 type clientKey struct{} 15 16 type clientHandle struct { 17 sync.Mutex 18 cli *client.Client 19 } 20 21 func (h *clientHandle) GetClient(ctx context.Context) (*client.Client, error) { 22 h.Lock() 23 defer h.Unlock() 24 if h.cli == nil { 25 cmd := proc.CommandContext(ctx, "docker", "context", "inspect", "--format", "{{.Endpoints.docker.Host}}") 26 stdout, err := proc.CaptureErr(cmd) 27 opts := []client.Opt{client.FromEnv, client.WithAPIVersionNegotiation()} 28 if err != nil { 29 return nil, fmt.Errorf("unable to retrieve docker context: %v", err) 30 } 31 if host := strings.TrimSpace(string(stdout)); host != "" { 32 opts = append(opts, client.WithHost(host)) 33 } 34 cli, err := client.NewClientWithOpts(opts...) 35 if err != nil { 36 return nil, err 37 } 38 h.cli = cli 39 } 40 return h.cli, nil 41 } 42 43 func EnableClient(ctx context.Context) context.Context { 44 if ctx.Value(clientKey{}) == nil { 45 ctx = context.WithValue(ctx, clientKey{}, &clientHandle{}) 46 } 47 return ctx 48 } 49 50 func GetClient(ctx context.Context) (*client.Client, error) { 51 if h, ok := ctx.Value(clientKey{}).(*clientHandle); ok { 52 return h.GetClient(ctx) 53 } 54 panic("docker client not initialized") 55 }