github.com/grahambrereton-form3/tilt@v0.10.18/internal/docker/env.go (about)

     1  package docker
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/docker/cli/opts"
     9  	"github.com/pkg/errors"
    10  
    11  	"github.com/windmilleng/tilt/internal/container"
    12  	"github.com/windmilleng/tilt/internal/k8s"
    13  	"github.com/windmilleng/tilt/internal/minikube"
    14  )
    15  
    16  // See notes on CreateClientOpts. These environment variables are standard docker env configs.
    17  type Env struct {
    18  	Host       string
    19  	APIVersion string
    20  	TLSVerify  string
    21  	CertPath   string
    22  
    23  	// Minikube's docker client has a bug where it can't use buildkit. See:
    24  	// https://github.com/kubernetes/minikube/issues/4143
    25  	IsMinikube bool
    26  }
    27  
    28  // Serializes this back to environment variables for os.Environ
    29  func (e Env) AsEnviron() []string {
    30  	vars := []string{}
    31  	if e.Host != "" {
    32  		vars = append(vars, fmt.Sprintf("DOCKER_HOST=%s", e.Host))
    33  	}
    34  	if e.APIVersion != "" {
    35  		vars = append(vars, fmt.Sprintf("DOCKER_API_VERSION=%s", e.APIVersion))
    36  	}
    37  	if e.CertPath != "" {
    38  		vars = append(vars, fmt.Sprintf("DOCKER_CERT_PATH=%s", e.CertPath))
    39  	}
    40  	if e.TLSVerify != "" {
    41  		vars = append(vars, fmt.Sprintf("DOCKER_TLS_VERIFY=%s", e.TLSVerify))
    42  	}
    43  	return vars
    44  }
    45  
    46  // Tell wire to create two docker envs: one for the local CLI and one for the in-cluster CLI.
    47  type ClusterEnv Env
    48  type LocalEnv Env
    49  
    50  func ProvideLocalEnv(ctx context.Context, cEnv ClusterEnv) (LocalEnv, error) {
    51  	result, err := overlayOSEnvVars(Env{})
    52  	if err != nil {
    53  		return LocalEnv{}, err
    54  	}
    55  
    56  	// The user may have already configured their local docker client
    57  	// to use Minikube's docker server. We check for that by comparing
    58  	// the hosts of the LocalEnv and ClusterEnv.
    59  	if cEnv.Host == result.Host {
    60  		result.IsMinikube = cEnv.IsMinikube
    61  	}
    62  
    63  	return LocalEnv(result), err
    64  }
    65  
    66  func ProvideClusterEnv(ctx context.Context, env k8s.Env, runtime container.Runtime, minikubeClient minikube.Client) (ClusterEnv, error) {
    67  	result := Env{}
    68  
    69  	if runtime == container.RuntimeDocker {
    70  		if env == k8s.EnvMinikube {
    71  			// If we're running Minikube with a docker runtime, talk to Minikube's docker socket.
    72  			envMap, err := minikubeClient.DockerEnv(ctx)
    73  			if err != nil {
    74  				return ClusterEnv{}, errors.Wrap(err, "ProvideDockerEnv")
    75  			}
    76  
    77  			host := envMap["DOCKER_HOST"]
    78  			if host != "" {
    79  				result.Host = host
    80  			}
    81  
    82  			apiVersion := envMap["DOCKER_API_VERSION"]
    83  			if apiVersion != "" {
    84  				result.APIVersion = apiVersion
    85  			}
    86  
    87  			certPath := envMap["DOCKER_CERT_PATH"]
    88  			if certPath != "" {
    89  				result.CertPath = certPath
    90  			}
    91  
    92  			tlsVerify := envMap["DOCKER_TLS_VERIFY"]
    93  			if tlsVerify != "" {
    94  				result.TLSVerify = tlsVerify
    95  			}
    96  
    97  			result.IsMinikube = true
    98  		} else if env == k8s.EnvMicroK8s {
    99  			// If we're running Microk8s with a docker runtime, talk to Microk8s's docker socket.
   100  			result.Host = microK8sDockerHost
   101  		}
   102  	}
   103  
   104  	resultEnv, err := overlayOSEnvVars(Env(result))
   105  	if err != nil {
   106  		return ClusterEnv{}, err
   107  	}
   108  	return ClusterEnv(resultEnv), nil
   109  }
   110  
   111  func overlayOSEnvVars(result Env) (Env, error) {
   112  	host := os.Getenv("DOCKER_HOST")
   113  	if host != "" {
   114  		host, err := opts.ParseHost(true, host)
   115  		if err != nil {
   116  			return Env{}, errors.Wrap(err, "ProvideDockerEnv")
   117  		}
   118  
   119  		// If the docker host is set from the env and different from the cluster host,
   120  		// ignore all the variables from minikube/microk8s
   121  		if host != result.Host {
   122  			result = Env{Host: host}
   123  		}
   124  	}
   125  
   126  	apiVersion := os.Getenv("DOCKER_API_VERSION")
   127  	if apiVersion != "" {
   128  		result.APIVersion = apiVersion
   129  	}
   130  
   131  	certPath := os.Getenv("DOCKER_CERT_PATH")
   132  	if certPath != "" {
   133  		result.CertPath = certPath
   134  	}
   135  
   136  	tlsVerify := os.Getenv("DOCKER_TLS_VERIFY")
   137  	if tlsVerify != "" {
   138  		result.TLSVerify = tlsVerify
   139  	}
   140  
   141  	return result, nil
   142  }