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  }