diff --git a/pkg/drivers/kic/oci/network.go b/pkg/drivers/kic/oci/network.go index 4e28161d84..bfb602dcde 100644 --- a/pkg/drivers/kic/oci/network.go +++ b/pkg/drivers/kic/oci/network.go @@ -21,6 +21,7 @@ import ( "net" "os/exec" "runtime" + "strconv" "strings" "github.com/golang/glog" @@ -77,3 +78,82 @@ func dockerGatewayIP() (net.IP, error) { glog.Infof("got host ip for mount in container by inspect docker network: %s", ip.String()) return ip, nil } + +// HostPortBinding will return port mapping for a container using cli. +// example : HostPortBinding("docker", "minikube", "22") +// will return the docker assigned port: +// 32769, nil +// only supports TCP ports +func HostPortBinding(ociBinary string, ociID string, contPort int) (int, error) { + if err := PointToHostDockerDaemon(); err != nil { + return 0, errors.Wrap(err, "point host docker daemon") + } + var out []byte + var err error + if ociBinary == Podman { + //podman inspect -f "{{range .NetworkSettings.Ports}}{{if eq .ContainerPort "80"}}{{.HostPort}}{{end}}{{end}}" + cmd := exec.Command(ociBinary, "inspect", "-f", fmt.Sprintf("{{range .NetworkSettings.Ports}}{{if eq .ContainerPort %s}}{{.HostPort}}{{end}}{{end}}", fmt.Sprint(contPort)), ociID) + out, err = cmd.CombinedOutput() + if err != nil { + return 0, errors.Wrapf(err, "get host-bind port %d for %q, output %s", contPort, ociID, out) + } + } else { + cmd := exec.Command(ociBinary, "inspect", "-f", fmt.Sprintf("'{{(index (index .NetworkSettings.Ports \"%d/tcp\") 0).HostPort}}'", contPort), ociID) + out, err = cmd.CombinedOutput() + if err != nil { + return 0, errors.Wrapf(err, "get host-bind port %d for %q, output %s", contPort, ociID, out) + } + } + + o := strings.TrimSpace(string(out)) + o = strings.Trim(o, "'") + p, err := strconv.Atoi(o) + if err != nil { + return p, errors.Wrapf(err, "convert host-port %q to number", p) + } + return p, nil +} + +// ContainerIPs returns ipv4,ipv6, error of a container by their name +func ContainerIPs(ociBinary string, name string) (string, string, error) { + if ociBinary == Podman { + return podmanConttainerIP(name) + } + return dockerContainerIP(name) +} + +// podmanConttainerIP returns ipv4, ipv6 of container or error +func podmanConttainerIP(name string) (string, string, error) { + cmd := exec.Command(Podman, "inspect", + "-f", "{{.NetworkSettings.IPAddress}}", + name) + out, err := cmd.CombinedOutput() + if err != nil { + return "", "", errors.Wrapf(err, "podman inspect ip %s", name) + } + output := strings.TrimSpace(string(out)) + if err == nil && output == "" { // podman returns empty for 127.0.0.1 + return DefaultBindIPV4, "", nil + } + return output, "", nil +} + +// dockerContainerIP returns ipv4, ipv6 of container or error +func dockerContainerIP(name string) (string, string, error) { + if err := PointToHostDockerDaemon(); err != nil { + return "", "", errors.Wrap(err, "point host docker daemon") + } + // retrieve the IP address of the node using docker inspect + lines, err := inspect(Docker, name, "{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}") + if err != nil { + return "", "", errors.Wrap(err, "inspecting NetworkSettings.Networks") + } + if len(lines) != 1 { + return "", "", errors.Errorf("IPs output should only be one line, got %d lines", len(lines)) + } + ips := strings.Split(lines[0], ",") + if len(ips) != 2 { + return "", "", errors.Errorf("container addresses should have 2 values, got %d values: %+v", len(ips), ips) + } + return ips[0], ips[1], nil +} diff --git a/pkg/drivers/kic/oci/oci.go b/pkg/drivers/kic/oci/oci.go index df2b77b88c..c461b47000 100644 --- a/pkg/drivers/kic/oci/oci.go +++ b/pkg/drivers/kic/oci/oci.go @@ -20,7 +20,6 @@ import ( "context" "os" "path/filepath" - "strconv" "time" "bufio" @@ -210,85 +209,6 @@ func Copy(ociBinary string, ociID string, targetDir string, fName string) error return nil } -// HostPortBinding will return port mapping for a container using cli. -// example : HostPortBinding("docker", "minikube", "22") -// will return the docker assigned port: -// 32769, nil -// only supports TCP ports -func HostPortBinding(ociBinary string, ociID string, contPort int) (int, error) { - if err := PointToHostDockerDaemon(); err != nil { - return 0, errors.Wrap(err, "point host docker daemon") - } - var out []byte - var err error - if ociBinary == Podman { - //podman inspect -f "{{range .NetworkSettings.Ports}}{{if eq .ContainerPort "80"}}{{.HostPort}}{{end}}{{end}}" - cmd := exec.Command(ociBinary, "inspect", "-f", fmt.Sprintf("{{range .NetworkSettings.Ports}}{{if eq .ContainerPort %s}}{{.HostPort}}{{end}}{{end}}", fmt.Sprint(contPort)), ociID) - out, err = cmd.CombinedOutput() - if err != nil { - return 0, errors.Wrapf(err, "get host-bind port %d for %q, output %s", contPort, ociID, out) - } - } else { - cmd := exec.Command(ociBinary, "inspect", "-f", fmt.Sprintf("'{{(index (index .NetworkSettings.Ports \"%d/tcp\") 0).HostPort}}'", contPort), ociID) - out, err = cmd.CombinedOutput() - if err != nil { - return 0, errors.Wrapf(err, "get host-bind port %d for %q, output %s", contPort, ociID, out) - } - } - - o := strings.TrimSpace(string(out)) - o = strings.Trim(o, "'") - p, err := strconv.Atoi(o) - if err != nil { - return p, errors.Wrapf(err, "convert host-port %q to number", p) - } - return p, nil -} - -// ContainerIPs returns ipv4,ipv6, error of a container by their name -func ContainerIPs(ociBinary string, name string) (string, string, error) { - if ociBinary == Podman { - return podmanConttainerIP(name) - } - return dockerContainerIP(name) -} - -// podmanConttainerIP returns ipv4, ipv6 of container or error -func podmanConttainerIP(name string) (string, string, error) { - cmd := exec.Command(Podman, "inspect", - "-f", "{{.NetworkSettings.IPAddress}}", - name) - out, err := cmd.CombinedOutput() - if err != nil { - return "", "", errors.Wrapf(err, "podman inspect ip %s", name) - } - output := strings.TrimSpace(string(out)) - if err == nil && output == "" { // podman returns empty for 127.0.0.1 - return DefaultBindIPV4, "", nil - } - return output, "", nil -} - -// dockerContainerIP returns ipv4, ipv6 of container or error -func dockerContainerIP(name string) (string, string, error) { - if err := PointToHostDockerDaemon(); err != nil { - return "", "", errors.Wrap(err, "point host docker daemon") - } - // retrieve the IP address of the node using docker inspect - lines, err := inspect(Docker, name, "{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}") - if err != nil { - return "", "", errors.Wrap(err, "inspecting NetworkSettings.Networks") - } - if len(lines) != 1 { - return "", "", errors.Errorf("IPs output should only be one line, got %d lines", len(lines)) - } - ips := strings.Split(lines[0], ",") - if len(ips) != 2 { - return "", "", errors.Errorf("container addresses should have 2 values, got %d values: %+v", len(ips), ips) - } - return ips[0], ips[1], nil -} - // ContainerID returns id of a container name func ContainerID(ociBinary string, nameOrID string) (string, error) { if err := PointToHostDockerDaemon(); err != nil { diff --git a/pkg/minikube/machine/fix.go b/pkg/minikube/machine/fix.go index 0e5b009179..3e84eb8791 100644 --- a/pkg/minikube/machine/fix.go +++ b/pkg/minikube/machine/fix.go @@ -69,7 +69,10 @@ func fixHost(api libmachine.API, mc config.ClusterConfig) (*host.Host, error) { if err != nil { return h, errors.Wrap(err, "Error loading existing host. Please try running [minikube delete], then run [minikube start] again.") } - warnToReEvalEnv(mc.Driver, mc.Name) + + // check if need to re-run docker-env + maybeWarnAboutEvalEnv(mc.Driver, mc.Name) + s, err := h.Driver.GetState() if err != nil || s == state.Stopped || s == state.None { // If virtual machine does not exist due to user interrupt cancel(i.e. Ctrl + C), recreate virtual machine @@ -147,18 +150,24 @@ func fixHost(api libmachine.API, mc config.ClusterConfig) (*host.Host, error) { return h, ensureSyncedGuestClock(h, mc.Driver) } -// warnToReEvalEnv wil warn user if they need to re-eval their docker-env, podman-env +// maybeWarnAboutEvalEnv wil warn user if they need to re-eval their docker-env, podman-env // because docker changes the allocated bind ports after restart https://github.com/kubernetes/minikube/issues/6824 -func warnToReEvalEnv(drver string, name string) { +func maybeWarnAboutEvalEnv(drver string, name string) { if !driver.IsKIC(drver) { return } p := os.Getenv(constants.MinikubeActiveDockerdEnv) - if p != "" { - out.T(out.WarningType, "dockerd port changed since restart. minikube's docker-env need to be updated.") - out.T(out.WarningType, `Please run the following command: - 'minikube -p {{.profile_name}} docker-env'`, out.V{"profile_name": name}) + if p == "" { + return } + out.T(out.Notice, "Noticed that you are using minikube docker-env:") + out.T(out.WarningType, `After minikube restart the dockerd ports might have changed. To ensure docker-env works properly. +Please re-eval the docker-env command: + + 'minikube -p {{.profile_name}} docker-env' + + `, out.V{"profile_name": name}) + } // ensureGuestClockSync ensures that the guest system clock is relatively in-sync