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 }