diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2ec7b9b32c3a..3c52acbada7b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -142,3 +142,37 @@ jobs: with: name: none_on_ubuntu_latest_report path: report + podman_ubuntu_18_04: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install podman + run: | + . /etc/os-release + sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list" + wget -q https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/xUbuntu_${VERSION_ID}/Release.key -O- | sudo apt-key add - + sudo apt-key add - < Release.key || true + sudo apt-get update -qq + sudo apt-get -qq -y install podman + - name: build binaries + run : | + make minikube-linux-amd64 + make e2e-linux-amd64 + - name: install gopogh + run: | + cd /tmp + GO111MODULE="on" go get github.com/medyagh/gopogh@v0.0.17 || true + cd - + - name: run integration test + run: | + mkdir -p /tmp/testhome + MINIKUBE_HOME=/tmp/testhome sudo -E ./out/e2e-linux-amd64 -minikube-start-args=--vm-driver=podman -expected-default-driver= -test.timeout=70m -test.v -binary=out/minikube-linux-amd64 2>&1 | tee ./report/testout.txt + - name: generate gopogh report + run: | + export PATH=${PATH}:`go env GOPATH`/bin + go tool test2json -t < ./report/testout.txt > ./report/testout.json || true + gopogh -in ./report/testout.json -out ./report/testout.html -name "docker ubuntu" -repo github.com/kubernetes/minikube/ || true + - uses: actions/upload-artifact@v1 + with: + name: podman_on_ubuntu_latest_report + path: report diff --git a/cmd/minikube/cmd/docker-env.go b/cmd/minikube/cmd/docker-env.go index ccea698d3e3f..91f797cad24c 100644 --- a/cmd/minikube/cmd/docker-env.go +++ b/cmd/minikube/cmd/docker-env.go @@ -32,7 +32,6 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - "k8s.io/minikube/pkg/drivers/kic" "k8s.io/minikube/pkg/drivers/kic/oci" "k8s.io/minikube/pkg/minikube/cluster" "k8s.io/minikube/pkg/minikube/config" @@ -269,7 +268,7 @@ func dockerEnvVars(ec DockerEnvConfig) (map[string]string, error) { if err != nil { return nil, errors.Wrapf(err, "get hostbind port for %d", constants.DockerDaemonPort) } - env[constants.DockerCertPathEnv] = dockerURL(kic.DefaultBindIPV4, port) + env[constants.DockerCertPathEnv] = dockerURL(oci.DefaultBindIPV4, port) } return env, nil } diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 13612ab01bf9..1e949d280174 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -747,11 +747,11 @@ func validateUser(drvName string) { useForce := viper.GetBool(force) - if driver.BareMetal(drvName) && u.Uid != "0" && !useForce { + if driver.NeedsRoot(drvName) && u.Uid != "0" && !useForce { exit.WithCodeT(exit.Permissions, `The "{{.driver_name}}" driver requires root privileges. Please run minikube using 'sudo minikube --vm-driver={{.driver_name}}'.`, out.V{"driver_name": drvName}) } - if driver.BareMetal(drvName) || u.Uid != "0" { + if driver.NeedsRoot(drvName) || u.Uid != "0" { return } @@ -815,16 +815,18 @@ func validateFlags(cmd *cobra.Command, drvName string) { validateDiskSize() validateMemorySize() - if driver.BareMetal(drvName) { - if viper.GetString(config.MachineProfile) != constants.DefaultMachineName { - exit.WithCodeT(exit.Config, "The 'none' driver does not support multiple profiles: https://minikube.sigs.k8s.io/docs/reference/drivers/none/") - } - + if !driver.HasResourceLimits(drvName) { // both podman and none need root and they both cant specify resources if cmd.Flags().Changed(cpus) { - out.WarningT("The 'none' driver does not respect the --cpus flag") + out.WarningT("The '{{.name}}' driver does not respect the --cpus flag", out.V{"name": drvName}) } if cmd.Flags().Changed(memory) { - out.WarningT("The 'none' driver does not respect the --memory flag") + out.WarningT("The '{{.name}}' driver does not respect the --memory flag", out.V{"name": drvName}) + } + } + + if driver.BareMetal(drvName) { + if viper.GetString(config.MachineProfile) != constants.DefaultMachineName { + exit.WithCodeT(exit.Config, "The '{{.name}} driver does not support multiple profiles: https://minikube.sigs.k8s.io/docs/reference/drivers/none/", out.V{"name": drvName}) } runtime := viper.GetString(containerRuntime) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index fce0f103a22d..4a3431e39881 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -27,8 +27,13 @@ readonly TEST_ROOT="${HOME}/minikube-integration" readonly TEST_HOME="${TEST_ROOT}/${OS_ARCH}-${VM_DRIVER}-${MINIKUBE_LOCATION}-$$-${COMMIT}" export GOPATH="$HOME/go" +export KUBECONFIG="${TEST_HOME}/kubeconfig" export PATH=$PATH:"/usr/local/bin/:/usr/local/go/bin/:$GOPATH/bin" +# installing golang so we could do go get for gopogh +sudo ./installers/check_install_golang.sh "1.13.4" "/usr/local" || true + + echo ">> Starting at $(date)" echo "" echo "arch: ${OS_ARCH}" @@ -42,6 +47,7 @@ echo "uptime: $(uptime)" # Setting KUBECONFIG prevents the version ceck from erroring out due to permission issues echo "kubectl: $(env KUBECONFIG=${TEST_HOME} kubectl version --client --short=true)" echo "docker: $(docker version --format '{{ .Client.Version }}')" +echo "podman: $(sudo podman version --format '{{.Version}}' || true)" echo "go: $(go version || true)" @@ -235,7 +241,6 @@ cleanup_stale_routes || true mkdir -p "${TEST_HOME}" export MINIKUBE_HOME="${TEST_HOME}/.minikube" -export KUBECONFIG="${TEST_HOME}/kubeconfig" # Build the gvisor image so that we can integration test changes to pkg/gvisor @@ -319,7 +324,7 @@ touch "${JSON_OUT}" echo ">> Running go test2json" go tool test2json -t < "${TEST_OUT}" > "${JSON_OUT}" || true echo ">> Installing gopogh" -cd /tmp +cd $(mktemp -d) GO111MODULE="on" go get -u github.com/medyagh/gopogh@v0.0.17 || true cd - echo ">> Running gopogh" @@ -347,7 +352,7 @@ fi echo ">> Cleaning up after ourselves ..." ${SUDO_PREFIX}${MINIKUBE_BIN} tunnel --cleanup || true -${SUDO_PREFIX}${MINIKUBE_BIN} delete --all >/dev/null 2>/dev/null || true +${SUDO_PREFIX}${MINIKUBE_BIN} delete --all --purge >/dev/null 2>/dev/null || true cleanup_stale_routes || true ${SUDO_PREFIX} rm -Rf "${MINIKUBE_HOME}" || true diff --git a/hack/jenkins/linux_integration_tests_docker.sh b/hack/jenkins/linux_integration_tests_docker.sh index 6adcccb4b9be..fb912d239102 100755 --- a/hack/jenkins/linux_integration_tests_docker.sh +++ b/hack/jenkins/linux_integration_tests_docker.sh @@ -32,4 +32,7 @@ JOB_NAME="Docker_Linux" mkdir -p cron && gsutil -qm rsync "gs://minikube-builds/${MINIKUBE_LOCATION}/cron" cron || echo "FAILED TO GET CRON FILES" sudo install cron/cleanup_and_reboot_Linux.sh /etc/cron.hourly/cleanup_and_reboot || echo "FAILED TO INSTALL CLEANUP" +# removing possible left over docker containers from previous runs +docker rm -f -v $(docker ps -aq) >/dev/null 2>&1 || true + source ./common.sh diff --git a/hack/jenkins/linux_integration_tests_none.sh b/hack/jenkins/linux_integration_tests_none.sh index b3a05d474499..7c52bb180057 100755 --- a/hack/jenkins/linux_integration_tests_none.sh +++ b/hack/jenkins/linux_integration_tests_none.sh @@ -44,8 +44,8 @@ docker rm -f $(docker ps -aq) >/dev/null 2>&1 || true sudo rm -rf /data/* # Cleanup old Kubernetes configs sudo rm -rf /etc/kubernetes/* -# Cleanup old minikube files -sudo rm -rf /var/lib/minikube/* +sudo rm -rf /var/lib/minikube/* + # Stop any leftover kubelets systemctl is-active --quiet kubelet \ && echo "stopping kubelet" \ diff --git a/hack/jenkins/linux_integration_tests_podman.sh b/hack/jenkins/linux_integration_tests_podman.sh new file mode 100755 index 000000000000..1dfbdb445600 --- /dev/null +++ b/hack/jenkins/linux_integration_tests_podman.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Copyright 2019 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# This script runs the integration tests on a Linux machine for the KVM Driver + +# The script expects the following env variables: +# MINIKUBE_LOCATION: GIT_COMMIT from upstream build. +# COMMIT: Actual commit ID from upstream build +# EXTRA_BUILD_ARGS (optional): Extra args to be passed into the minikube integrations tests +# access_token: The Github API access token. Injected by the Jenkins credential provider. + +set -e + +OS_ARCH="linux-amd64" +VM_DRIVER="podman" +JOB_NAME="Podman_Linux" + +mkdir -p cron && gsutil -qm rsync "gs://minikube-builds/${MINIKUBE_LOCATION}/cron" cron || echo "FAILED TO GET CRON FILES" +sudo install cron/cleanup_and_reboot_Linux.sh /etc/cron.hourly/cleanup_and_reboot || echo "FAILED TO INSTALL CLEANUP" +SUDO_PREFIX="sudo -E " + +EXTRA_ARGS="--container-runtime=containerd" + +# remove possible left over podman containers +sudo podman rm -f -v $(sudo podman ps -aq) || true + +source ./common.sh diff --git a/hack/jenkins/minikube_set_pending.sh b/hack/jenkins/minikube_set_pending.sh index ffffc5e72c75..4d7a2bedef4b 100755 --- a/hack/jenkins/minikube_set_pending.sh +++ b/hack/jenkins/minikube_set_pending.sh @@ -41,6 +41,7 @@ jobs=( 'KVM_Linux' 'none_Linux' 'Docker_Linux' + 'Podman_Linux' ) # retry_github_status provides reliable github status updates diff --git a/pkg/addons/kubectl.go b/pkg/addons/kubectl.go index 1e3fbe2a978e..97abf8023d61 100644 --- a/pkg/addons/kubectl.go +++ b/pkg/addons/kubectl.go @@ -17,11 +17,13 @@ limitations under the License. package addons import ( + "fmt" "os/exec" "path" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/vmpath" ) var ( @@ -41,7 +43,7 @@ func kubectlCommand(profile string, files []string, enable bool) (*exec.Cmd, err kubectlAction = "delete" } - args := []string{"KUBECONFIG=/var/lib/minikube/kubeconfig", kubectlBinary, kubectlAction} + args := []string{fmt.Sprintf("KUBECONFIG=%s", path.Join(vmpath.GuestPersistentDir, "kubeconfig")), kubectlBinary, kubectlAction} for _, f := range files { args = append(args, []string{"-f", f}...) } @@ -63,5 +65,5 @@ func kubernetesVersion(profile string) (string, error) { } func kubectlBinaryPath(version string) string { - return path.Join("/var/lib/minikube/binaries", version, "kubectl") + return path.Join(vmpath.GuestPersistentDir, "binaries", version, "kubectl") } diff --git a/pkg/drivers/kic/kic.go b/pkg/drivers/kic/kic.go index 13d7de7fb6cd..bb76fbd5ef2c 100644 --- a/pkg/drivers/kic/kic.go +++ b/pkg/drivers/kic/kic.go @@ -36,7 +36,7 @@ import ( "k8s.io/minikube/pkg/minikube/constants" ) -// Driver represents a kic driver https://minikube.sigs.k8s.io/docs/reference/drivers/kic/ +// Driver represents a kic driver https://minikube.sigs.k8s.io/docs/reference/drivers/docker type Driver struct { *drivers.BaseDriver *pkgdrivers.CommonDriver @@ -76,15 +76,15 @@ func (d *Driver) Create() error { // control plane specific options params.PortMappings = append(params.PortMappings, oci.PortMapping{ - ListenAddress: DefaultBindIPV4, + ListenAddress: oci.DefaultBindIPV4, ContainerPort: constants.APIServerPort, }, oci.PortMapping{ - ListenAddress: DefaultBindIPV4, + ListenAddress: oci.DefaultBindIPV4, ContainerPort: constants.SSHPort, }, oci.PortMapping{ - ListenAddress: DefaultBindIPV4, + ListenAddress: oci.DefaultBindIPV4, ContainerPort: constants.DockerDaemonPort, }, ) @@ -138,12 +138,12 @@ func (d *Driver) GetIP() (string, error) { // GetExternalIP returns an IP which is accissble from outside func (d *Driver) GetExternalIP() (string, error) { - return DefaultBindIPV4, nil + return oci.DefaultBindIPV4, nil } // GetSSHHostname returns hostname for use with ssh func (d *Driver) GetSSHHostname() (string, error) { - return DefaultBindIPV4, nil + return oci.DefaultBindIPV4, nil } // GetSSHPort returns port for use with ssh @@ -186,7 +186,7 @@ func (d *Driver) GetState() (state.State, error) { cmd := exec.Command(d.NodeConfig.OCIBinary, "inspect", "-f", "{{.State.Status}}", d.MachineName) out, err := cmd.CombinedOutput() - o := strings.Trim(string(out), "\n") + o := strings.TrimSpace(string(out)) if err != nil { return state.Error, errors.Wrapf(err, "get container %s status", d.MachineName) } @@ -222,7 +222,7 @@ func (d *Driver) Remove() error { } cmd := exec.Command(d.NodeConfig.OCIBinary, "rm", "-f", "-v", d.MachineName) o, err := cmd.CombinedOutput() - out := strings.Trim(string(o), "\n") + out := strings.TrimSpace(string(o)) if err != nil { if strings.Contains(out, "is already in progress") { log.Warnf("Docker engine is stuck. please restart docker daemon on your computer.", d.MachineName) diff --git a/pkg/drivers/kic/oci/oci.go b/pkg/drivers/kic/oci/oci.go index 9f8ddd6048f8..13b9c7f50d55 100644 --- a/pkg/drivers/kic/oci/oci.go +++ b/pkg/drivers/kic/oci/oci.go @@ -18,6 +18,7 @@ package oci import ( "os" + "path/filepath" "strconv" "bufio" @@ -26,6 +27,7 @@ import ( "github.com/golang/glog" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/localpath" "fmt" "os/exec" @@ -39,8 +41,6 @@ func CreateContainerNode(p CreateParams) error { } runArgs := []string{ - fmt.Sprintf("--cpus=%s", p.CPUs), - fmt.Sprintf("--memory=%s", p.Memory), "-d", // run the container detached "-t", // allocate a tty for entrypoint logs // running containers in a container requires privileged @@ -53,7 +53,6 @@ func CreateContainerNode(p CreateParams) error { "--tmpfs", "/tmp", // various things depend on working /tmp "--tmpfs", "/run", // systemd wants a writable /run // logs,pods be stroed on filesystem vs inside container, - "--volume", "/var", // some k8s things want /lib/modules "-v", "/lib/modules:/lib/modules:ro", "--hostname", p.Name, // make hostname match container name @@ -64,6 +63,23 @@ func CreateContainerNode(p CreateParams) error { "--label", fmt.Sprintf("%s=%s", nodeRoleKey, p.Role), } + // volume path in minikube home folder to mount to /var + hostVarVolPath := filepath.Join(localpath.MiniPath(), "machines", p.Name, "var") + if err := os.MkdirAll(hostVarVolPath, 0711); err != nil { + return errors.Wrapf(err, "create var dir %s", hostVarVolPath) + } + + if p.OCIBinary == Podman { // enable execing in /var + // podman mounts var/lib with no-exec by default https://github.com/containers/libpod/issues/5103 + runArgs = append(runArgs, "--volume", fmt.Sprintf("%s:/var:exec", hostVarVolPath)) + } + if p.OCIBinary == Docker { + runArgs = append(runArgs, "--volume", fmt.Sprintf("%s:/var", hostVarVolPath)) + // setting resource limit in privileged mode is only supported by docker + // podman error: "Error: invalid configuration, cannot set resources with rootless containers not using cgroups v2 unified mode" + runArgs = append(runArgs, fmt.Sprintf("--cpus=%s", p.CPUs), fmt.Sprintf("--memory=%s", p.Memory)) + } + for key, val := range p.Envs { runArgs = append(runArgs, "-e", fmt.Sprintf("%s=%s", key, val)) } @@ -113,6 +129,10 @@ func createContainer(ociBinary string, image string, opts ...createOpt) ([]strin } // construct the actual docker run argv args := []string{"run"} + // to run nested container from privileged container in podman https://bugzilla.redhat.com/show_bug.cgi?id=1687713 + if ociBinary == Podman { + args = append(args, "--cgroup-manager", "cgroupfs") + } args = append(args, runArgs...) args = append(args, image) args = append(args, o.ContainerArgs...) @@ -159,12 +179,24 @@ func HostPortBinding(ociBinary string, ociID string, contPort int) (int, error) if err := PointToHostDockerDaemon(); err != nil { return 0, errors.Wrap(err, "point host docker-daemon") } - 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, "getting host-bind port %d for container ID %q, output %s", contPort, ociID, out) + 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.Trim(string(out), "\n") + + o := strings.TrimSpace(string(out)) o = strings.Trim(o, "'") p, err := strconv.Atoi(o) if err != nil { @@ -175,11 +207,35 @@ func HostPortBinding(ociBinary string, ociID string, contPort int) (int, error) // 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(ociBinary, name, "{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}") + lines, err := inspect(Docker, name, "{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}") if err != nil { return "", "", errors.Wrap(err, "inspecting NetworkSettings.Networks") } @@ -191,7 +247,6 @@ func ContainerIPs(ociBinary string, name string) (string, string, error) { 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 diff --git a/pkg/drivers/kic/oci/types.go b/pkg/drivers/kic/oci/types.go index 786cf3980ba9..70ffbe5dbbe7 100644 --- a/pkg/drivers/kic/oci/types.go +++ b/pkg/drivers/kic/oci/types.go @@ -17,8 +17,10 @@ limitations under the License. package oci const ( - Docker = "docker" - Podman = "podman" + // DefaultBindIPV4 is The default IP the container will listen on. + DefaultBindIPV4 = "127.0.0.1" + Docker = "docker" + Podman = "podman" // ClusterLabelKey is applied to each node docker container for identification ClusterLabelKey = "io.x-k8s.kic.cluster" // NodeRoleKey is used to identify if it is control plane or worker diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go index 317ee956f0a1..f3082952a523 100644 --- a/pkg/drivers/kic/types.go +++ b/pkg/drivers/kic/types.go @@ -23,8 +23,7 @@ const ( DefaultNetwork = "bridge" // DefaultPodCIDR is The CIDR to be used for pods inside the node. DefaultPodCIDR = "10.244.0.0/16" - // DefaultBindIPV4 is The default IP the container will bind to. - DefaultBindIPV4 = "127.0.0.1" + // BaseImage is the base image is used to spin up kic containers. it uses same base-image as kind. BaseImage = "gcr.io/k8s-minikube/kicbase:v0.0.5@sha256:3ddd8461dfb5c3e452ccc44d87750b87a574ec23fc425da67dccc1f0c57d428a" // OverlayImage is the cni plugin used for overlay image, created by kind. diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index ed5738a03e1a..bb4bde2a3865 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/clientcmd/api" "k8s.io/client-go/tools/clientcmd/api/latest" - "k8s.io/minikube/pkg/drivers/kic" + "k8s.io/minikube/pkg/drivers/kic/oci" "k8s.io/minikube/pkg/minikube/assets" "k8s.io/minikube/pkg/minikube/command" "k8s.io/minikube/pkg/minikube/config" @@ -169,7 +169,7 @@ func generateCerts(k8s config.KubernetesConfig, n config.Node) error { apiServerIPs := append( k8s.APIServerIPs, - []net.IP{net.ParseIP(n.IP), serviceIP, net.ParseIP(kic.DefaultBindIPV4), net.ParseIP("10.0.0.1")}...) + []net.IP{net.ParseIP(n.IP), serviceIP, net.ParseIP(oci.DefaultBindIPV4), net.ParseIP("10.0.0.1")}...) apiServerNames := append(k8s.APIServerNames, k8s.APIServerName) apiServerAlternateNames := append( apiServerNames, diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 452287951b31..a083b02617cf 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -210,9 +210,9 @@ func (k *Bootstrapper) StartCluster(cfg config.MachineConfig) error { return errors.Wrapf(err, "init failed. output: %q", rr.Output()) } - if driver.IsKIC(cfg.VMDriver) { + if cfg.VMDriver == driver.Docker { if err := k.applyKicOverlay(cfg); err != nil { - return errors.Wrap(err, "applying kic overlay network") + return errors.Wrap(err, "apply kic overlay") } } @@ -276,7 +276,7 @@ func (k *Bootstrapper) WaitForCluster(cfg config.MachineConfig, timeout time.Dur ip := cp.IP port := cp.Port if driver.IsKIC(cfg.VMDriver) { - ip = kic.DefaultBindIPV4 + ip = oci.DefaultBindIPV4 port, err = oci.HostPortBinding(cfg.VMDriver, cfg.Name, port) if err != nil { return errors.Wrapf(err, "get host-bind port %d for container %s", port, cfg.Name) @@ -344,7 +344,7 @@ func (k *Bootstrapper) restartCluster(cfg config.MachineConfig) error { ip := n.IP port := n.Port if driver.IsKIC(cfg.VMDriver) { - ip = kic.DefaultBindIPV4 + ip = oci.DefaultBindIPV4 port, err = oci.HostPortBinding(cfg.VMDriver, cfg.Name, port) if err != nil { return errors.Wrapf(err, "get host-bind port %d for container %s", port, cfg.Name) @@ -471,7 +471,7 @@ func (k *Bootstrapper) UpdateCluster(cfg config.MachineConfig) error { // applyKicOverlay applies the CNI plugin needed to make kic work func (k *Bootstrapper) applyKicOverlay(cfg config.MachineConfig) error { cmd := exec.Command("sudo", - path.Join("/var/lib/minikube/binaries", cfg.KubernetesConfig.KubernetesVersion, "kubectl"), "create", "--kubeconfig=/var/lib/minikube/kubeconfig", + path.Join(vmpath.GuestPersistentDir, "binaries", cfg.KubernetesConfig.KubernetesVersion, "kubectl"), "create", fmt.Sprintf("--kubeconfig=%s", path.Join(vmpath.GuestPersistentDir, "kubeconfig")), "-f", "-") b := bytes.Buffer{} if err := kicCNIConfig.Execute(&b, struct{ ImageName string }{ImageName: kic.OverlayImage}); err != nil { diff --git a/pkg/minikube/cluster/ip.go b/pkg/minikube/cluster/ip.go index 8ea0cb5b1011..e1d8e97db2f8 100644 --- a/pkg/minikube/cluster/ip.go +++ b/pkg/minikube/cluster/ip.go @@ -25,7 +25,7 @@ import ( "github.com/docker/machine/libmachine" "github.com/docker/machine/libmachine/host" "github.com/pkg/errors" - "k8s.io/minikube/pkg/drivers/kic" + "k8s.io/minikube/pkg/drivers/kic/oci" "k8s.io/minikube/pkg/minikube/driver" ) @@ -84,7 +84,7 @@ func GetHostDriverIP(api libmachine.API, machineName string) (net.IP, error) { return nil, errors.Wrap(err, "getting IP") } if driver.IsKIC(host.DriverName) { - ipStr = kic.DefaultBindIPV4 + ipStr = oci.DefaultBindIPV4 } ip := net.ParseIP(ipStr) if ip == nil { diff --git a/pkg/minikube/cluster/start.go b/pkg/minikube/cluster/start.go index 6742e030f9ee..c7669e99661b 100644 --- a/pkg/minikube/cluster/start.go +++ b/pkg/minikube/cluster/start.go @@ -198,7 +198,7 @@ func commandRunner(h *host.Host) (command.Runner, error) { } if driver.IsKIC(d) { glog.Infof("Returning KICRunner for %q driver", d) - return command.NewKICRunner(h.Name, "docker"), nil + return command.NewKICRunner(h.Name, d), nil } glog.Infof("Creating SSH client and returning SSHRunner for %q driver", d) diff --git a/pkg/minikube/command/kic_runner.go b/pkg/minikube/command/kic_runner.go index 3fe57bb17d08..2d00a15251c4 100644 --- a/pkg/minikube/command/kic_runner.go +++ b/pkg/minikube/command/kic_runner.go @@ -30,6 +30,7 @@ import ( "github.com/golang/glog" "github.com/pkg/errors" "golang.org/x/crypto/ssh/terminal" + "k8s.io/minikube/pkg/drivers/kic/oci" "k8s.io/minikube/pkg/minikube/assets" ) @@ -126,7 +127,7 @@ func (k *kicRunner) RunCmd(cmd *exec.Cmd) (*RunResult, error) { // Copy copies a file and its permissions func (k *kicRunner) Copy(f assets.CopyableFile) error { - assetName := f.GetAssetName() + src := f.GetAssetName() if _, err := os.Stat(f.GetAssetName()); os.IsNotExist(err) { fc := make([]byte, f.GetLength()) // Read asset file into a []byte if _, err := f.Read(fc); err != nil { @@ -147,25 +148,37 @@ func (k *kicRunner) Copy(f assets.CopyableFile) error { if err := tmpFile.Close(); err != nil { return errors.Wrap(err, "close temporary file") } - assetName = tmpFile.Name() + src = tmpFile.Name() } - // based of format of "docker cp containerName:destination" - destination := fmt.Sprintf("%s:%s/%s", k.nameOrID, f.GetTargetDir(), f.GetTargetName()) - perms, err := strconv.ParseInt(f.GetPermissions(), 8, 0) if err != nil { - return errors.Wrapf(err, "error converting permissions %s to integer", f.GetPermissions()) + return errors.Wrapf(err, "converting permissions %s to integer", f.GetPermissions()) } // Rely on cp -a to propagate permissions - if err := os.Chmod(assetName, os.FileMode(perms)); err != nil { + if err := os.Chmod(src, os.FileMode(perms)); err != nil { return errors.Wrapf(err, "chmod") } - if out, err := exec.Command(k.ociBin, "cp", "-a", assetName, destination).CombinedOutput(); err != nil { - return errors.Wrapf(err, "error copying %s into node, output: %s", f.GetAssetName(), string(out)) + dest := fmt.Sprintf("%s:%s", k.nameOrID, path.Join(f.GetTargetDir(), f.GetTargetName())) + if k.ociBin == oci.Podman { + return copyToPodman(src, dest) } + return copyToDocker(src, dest) +} +// Podman cp command doesn't match docker and doesn't have -a +func copyToPodman(src string, dest string) error { + if out, err := exec.Command(oci.Podman, "cp", src, dest).CombinedOutput(); err != nil { + return errors.Wrapf(err, "podman copy %s into %s, output: %s", src, dest, string(out)) + } + return nil +} + +func copyToDocker(src string, dest string) error { + if out, err := exec.Command(oci.Docker, "cp", "-a", src, dest).CombinedOutput(); err != nil { + return errors.Wrapf(err, "docker copy %s into %s, output: %s", src, dest, string(out)) + } return nil } diff --git a/pkg/minikube/constants/constants.go b/pkg/minikube/constants/constants.go index 355c9319a06d..5fab19f81686 100644 --- a/pkg/minikube/constants/constants.go +++ b/pkg/minikube/constants/constants.go @@ -27,92 +27,81 @@ import ( ) const ( + // DefaultKubernetesVersion is the default kubernetes version + DefaultKubernetesVersion = "v1.17.2" + // NewestKubernetesVersion is the newest Kubernetes version to test against + NewestKubernetesVersion = "v1.17.2" + // OldestKubernetesVersion is the oldest Kubernetes version to test against + OldestKubernetesVersion = "v1.11.10" + // DefaultMachineName is the default name for the VM + DefaultMachineName = "minikube" + // DefaultNodeName is the default name for the kubeadm node within the VM + DefaultNodeName = "minikube" + // DockerDaemonPort is the port Docker daemon listening inside a minikube node (vm or container). DockerDaemonPort = 2376 - // SSHPort is the SSH serviceport on the node vm and container - SSHPort = 22 // APIServerPort is the default API server port APIServerPort = 8443 + // SSHPort is the SSH serviceport on the node vm and container + SSHPort = 22 + // APIServerName is the default API server name APIServerName = "minikubeCA" // ClusterDNSDomain is the default DNS domain ClusterDNSDomain = "cluster.local" // DefaultServiceCIDR is The CIDR to be used for service cluster IPs DefaultServiceCIDR = "10.96.0.0/12" - // DockerTLSVerifyEnv is used for docker daemon settings - DockerTLSVerifyEnv = "DOCKER_TLS_VERIFY" + // DockerHostEnv is used for docker daemon settings DockerHostEnv = "DOCKER_HOST" // DockerCertPathEnv is used for docker daemon settings DockerCertPathEnv = "DOCKER_CERT_PATH" + // DockerTLSVerifyEnv is used for docker daemon settings + DockerTLSVerifyEnv = "DOCKER_TLS_VERIFY" // MinikubeActiveDockerdEnv holds the docker daemon which user's shell is pointing at // value would be profile or empty if pointing to the user's host daemon. - // DockerDaemonEnvs has list of environment variables to control docker daemon shell is using - MinikubeActiveDockerdEnv = "MINIKUBE_ACTIVE_DOCKERD" // PodmanVarlinkBridgeEnv is used for podman settings PodmanVarlinkBridgeEnv = "PODMAN_VARLINK_BRIDGE" ) -var DockerDaemonEnvs = [3]string{DockerHostEnv, DockerTLSVerifyEnv, DockerCertPathEnv} - -// DefaultMinipath is the default Minikube path (under the home directory) -var DefaultMinipath = filepath.Join(homedir.HomeDir(), ".minikube") - -// KubeconfigPath is the path to the Kubernetes client config -var KubeconfigPath = clientcmd.RecommendedHomeFile - -// KubeconfigEnvVar is the env var to check for the Kubernetes client config -var KubeconfigEnvVar = clientcmd.RecommendedConfigPathEnvVar - -// DefaultMachineName is the default name for the VM -const DefaultMachineName = "minikube" - -// DefaultNodeName is the default name for the kubeadm node within the VM -const DefaultNodeName = "minikube" - -// MountProcessFileName is the filename of the mount process -var MountProcessFileName = ".mount-process" - -const ( - // SHASuffix is the suffix of a SHA-256 checksum file - SHASuffix = ".sha256" -) - -// DefaultISOURL is the default location of the minikube.iso file -var DefaultISOURL = fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.iso", minikubeVersion.GetISOPath(), minikubeVersion.GetISOVersion()) - -// DefaultISOSHAURL is the default location of the minikube.iso.sha256 file -var DefaultISOSHAURL = DefaultISOURL + SHASuffix - -// DefaultKubernetesVersion is the default kubernetes version -var DefaultKubernetesVersion = "v1.17.2" - -// NewestKubernetesVersion is the newest Kubernetes version to test against -var NewestKubernetesVersion = "v1.17.2" - -// OldestKubernetesVersion is the oldest Kubernetes version to test against -var OldestKubernetesVersion = "v1.11.10" - -const ( +var ( // IsMinikubeChildProcess is the name of "is minikube child process" variable IsMinikubeChildProcess = "IS_MINIKUBE_CHILD_PROCESS" -) - -// ImageRepositories contains all known image repositories -var ImageRepositories = map[string][]string{ - "global": {""}, - "cn": {"registry.cn-hangzhou.aliyuncs.com/google_containers"}, -} - -// KubernetesReleaseBinaries are Kubernetes release binaries required for -// kubeadm (kubelet, kubeadm) and the addon manager (kubectl) -var KubernetesReleaseBinaries = []string{"kubelet", "kubeadm", "kubectl"} - -// ImageCacheDir is the path to the image cache directory -var ImageCacheDir = localpath.MakeMiniPath("cache", "images") - -const ( // GvisorConfigTomlTargetName is the go-bindata target name for the gvisor config.toml GvisorConfigTomlTargetName = "gvisor-config.toml" + // MountProcessFileName is the filename of the mount process + MountProcessFileName = ".mount-process" + // SHASuffix is the suffix of a SHA-256 checksum file + +) + +var ( + SHASuffix = ".sha256" + // DefaultISOURL is the default location of the minikube.iso file + DefaultISOURL = fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.iso", minikubeVersion.GetISOPath(), minikubeVersion.GetISOVersion()) + // DefaultISOSHAURL is the default location of the minikube.iso.sha256 file + DefaultISOSHAURL = DefaultISOURL + SHASuffix + + // DockerDaemonEnvs is list of docker-daemon related environment variables. + DockerDaemonEnvs = [3]string{DockerHostEnv, DockerTLSVerifyEnv, DockerCertPathEnv} + + // DefaultMinipath is the default Minikube path (under the home directory) + DefaultMinipath = filepath.Join(homedir.HomeDir(), ".minikube") + // KubeconfigEnvVar is the env var to check for the Kubernetes client config + + KubeconfigEnvVar = clientcmd.RecommendedConfigPathEnvVar + // KubeconfigPath is the path to the Kubernetes client config + KubeconfigPath = clientcmd.RecommendedHomeFile + // ImageRepositories contains all known image repositories + + ImageRepositories = map[string][]string{ + "global": {""}, + "cn": {"registry.cn-hangzhou.aliyuncs.com/google_containers"}, + } + // KubernetesReleaseBinaries are Kubernetes release binaries required for + // kubeadm (kubelet, kubeadm) and the addon manager (kubectl) + KubernetesReleaseBinaries = []string{"kubelet", "kubeadm", "kubectl"} + // ImageCacheDir is the path to the image cache directory + ImageCacheDir = localpath.MakeMiniPath("cache", "images") ) diff --git a/pkg/minikube/driver/driver.go b/pkg/minikube/driver/driver.go index c00e7adb31e5..9791b0ab8b5d 100644 --- a/pkg/minikube/driver/driver.go +++ b/pkg/minikube/driver/driver.go @@ -28,6 +28,8 @@ import ( ) const ( + // Podman is Kubernetes in container using podman driver + Podman = "podman" // Docker is Kubernetes in container using docker driver Docker = "docker" // Mock driver @@ -85,7 +87,7 @@ func Supported(name string) bool { // IsKIC checks if the driver is a kubernetes in continer func IsKIC(name string) bool { - return name == Docker + return name == Docker || name == Podman } // IsMock checks if the driver is a mock @@ -106,6 +108,16 @@ func BareMetal(name string) bool { return name == None || name == Mock } +// NeedsRoot returns true if driver needs to run with root privileges +func NeedsRoot(name string) bool { + return name == None || name == Podman +} + +// HasResourceLimits returns true if driver can set resource limits such as memory size or CPU count. +func HasResourceLimits(name string) bool { + return name == None || name == Podman +} + // FlagHints are hints for what default options should be used for this driver type FlagHints struct { ExtraOptions []string diff --git a/pkg/minikube/driver/driver_darwin.go b/pkg/minikube/driver/driver_darwin.go index 4310aab74202..f951177677c2 100644 --- a/pkg/minikube/driver/driver_darwin.go +++ b/pkg/minikube/driver/driver_darwin.go @@ -26,6 +26,7 @@ var supportedDrivers = []string{ HyperKit, VMware, Docker, + Podman, } func VBoxManagePath() string { diff --git a/pkg/minikube/driver/driver_linux.go b/pkg/minikube/driver/driver_linux.go index 7eb79539bf05..dea2a80e18a8 100644 --- a/pkg/minikube/driver/driver_linux.go +++ b/pkg/minikube/driver/driver_linux.go @@ -29,6 +29,7 @@ var supportedDrivers = []string{ VMware, None, Docker, + Podman, } // VBoxManagePath returns the path to the VBoxManage command diff --git a/pkg/minikube/machine/client.go b/pkg/minikube/machine/client.go index ba79fe4745ef..0121c923582c 100644 --- a/pkg/minikube/machine/client.go +++ b/pkg/minikube/machine/client.go @@ -154,8 +154,9 @@ func CommandRunner(h *host.Host) (command.Runner, error) { if driver.BareMetal(h.Driver.DriverName()) { return command.NewExecRunner(), nil } - if h.Driver.DriverName() == driver.Docker { - return command.NewKICRunner(h.Name, "docker"), nil + + if driver.IsKIC(h.Driver.DriverName()) { + return command.NewKICRunner(h.Name, h.Driver.DriverName()), nil } client, err := sshutil.NewSSHClient(h.Driver) if err != nil { diff --git a/pkg/minikube/registry/drvs/docker/docker.go b/pkg/minikube/registry/drvs/docker/docker.go index d74947db0ca9..38cc95acb794 100644 --- a/pkg/minikube/registry/drvs/docker/docker.go +++ b/pkg/minikube/registry/drvs/docker/docker.go @@ -56,17 +56,18 @@ func configure(mc config.MachineConfig) (interface{}, error) { } func status() registry.State { - _, err := exec.LookPath("docker") + _, err := exec.LookPath(oci.Docker) if err != nil { - return registry.State{Error: err, Installed: false, Healthy: false, Fix: "Docker is required.", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/kic/"} + return registry.State{Error: err, Installed: false, Healthy: false, Fix: "Docker is required.", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/docker/"} } - // Allow no more than 2 seconds for querying state - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + + // Allow no more than 3 seconds for docker info + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() - err = exec.CommandContext(ctx, "docker", "info").Run() + err = exec.CommandContext(ctx, oci.Docker, "info").Run() if err != nil { - return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Docker is not running. Try: restarting docker desktop."} + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Docker is not running or is responding too slow. Try: restarting docker desktop."} } return registry.State{Installed: true, Healthy: true} diff --git a/pkg/minikube/registry/drvs/init.go b/pkg/minikube/registry/drvs/init.go index e585c4b5d522..bca12775c3ff 100644 --- a/pkg/minikube/registry/drvs/init.go +++ b/pkg/minikube/registry/drvs/init.go @@ -24,6 +24,7 @@ import ( _ "k8s.io/minikube/pkg/minikube/registry/drvs/kvm2" _ "k8s.io/minikube/pkg/minikube/registry/drvs/none" _ "k8s.io/minikube/pkg/minikube/registry/drvs/parallels" + _ "k8s.io/minikube/pkg/minikube/registry/drvs/podman" _ "k8s.io/minikube/pkg/minikube/registry/drvs/virtualbox" _ "k8s.io/minikube/pkg/minikube/registry/drvs/vmware" _ "k8s.io/minikube/pkg/minikube/registry/drvs/vmwarefusion" diff --git a/pkg/minikube/registry/drvs/podman/podman.go b/pkg/minikube/registry/drvs/podman/podman.go new file mode 100644 index 000000000000..a8e19dbbc01d --- /dev/null +++ b/pkg/minikube/registry/drvs/podman/podman.go @@ -0,0 +1,98 @@ +/* +Copyright 2020 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package podman + +import ( + "context" + "fmt" + "os/exec" + "strings" + "time" + + "github.com/blang/semver" + "github.com/docker/machine/libmachine/drivers" + "github.com/golang/glog" + "k8s.io/minikube/pkg/drivers/kic" + "k8s.io/minikube/pkg/drivers/kic/oci" + "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/driver" + "k8s.io/minikube/pkg/minikube/localpath" + "k8s.io/minikube/pkg/minikube/registry" +) + +// minReqPodmanVer is required the mininum version of podman to be installed for podman driver. +var minReqPodmanVer = semver.Version{Major: 1, Minor: 7, Patch: 0} + +func init() { + if err := registry.Register(registry.DriverDef{ + Name: driver.Podman, + Config: configure, + Init: func() drivers.Driver { return kic.NewDriver(kic.Config{OCIBinary: oci.Podman}) }, + Status: status, + Priority: registry.Experimental, + }); err != nil { + panic(fmt.Sprintf("register failed: %v", err)) + } +} + +func configure(mc config.MachineConfig) (interface{}, error) { + return kic.NewDriver(kic.Config{ + MachineName: mc.Name, + StorePath: localpath.MiniPath(), + ImageDigest: strings.Split(kic.BaseImage, "@")[0], // for podman does not support docker images references with both a tag and digest. + CPU: mc.CPUs, + Memory: mc.Memory, + OCIBinary: oci.Podman, + APIServerPort: mc.Nodes[0].Port, + }), nil +} + +func status() registry.State { + _, err := exec.LookPath(oci.Podman) + if err != nil { + return registry.State{Error: err, Installed: false, Healthy: false, Fix: "Podman is required.", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/podman/"} + } + + // Allow no more than 2 seconds for version command + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + cmd := exec.CommandContext(ctx, oci.Podman, "version", "-f", "{{.Version}}") + o, err := cmd.CombinedOutput() + output := string(o) + if err != nil { + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Cant verify mininim required version for podman . See podman website for installation guide.", Doc: "https://podman.io/getting-started/installation.html"} + } + + v, err := semver.Make(output) + if err != nil { + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Cant verify mininim required version for podman . See podman website for installation guide.", Doc: "https://podman.io/getting-started/installation.html"} + } + + if v.LT(minReqPodmanVer) { + glog.Warningf("Warning ! mininim required version for podman is %s. your version is %q. minikube might not work. use at your own risk. To install latest version please see https://podman.io/getting-started/installation.html ", minReqPodmanVer.String(), v.String()) + } + // Allow no more than 3 seconds for querying state + ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + err = exec.CommandContext(ctx, oci.Podman, "info").Run() + if err != nil { + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Podman is not running or taking too long to respond. Try: restarting podman."} + } + + return registry.State{Installed: true, Healthy: true} +} diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index df85356bb5e3..4a1a1b1cd36a 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -341,7 +341,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } } }) - t.Run("delete busybox:1.28.4-glibc", func(t *testing.T) { + t.Run("delete_busybox:1.28.4-glibc", func(t *testing.T) { _, err := Run(t, exec.CommandContext(ctx, Target(), "cache", "delete", "busybox:1.28.4-glibc")) if err != nil { t.Errorf("failed to delete image busybox:1.28.4-glibc from cache: %v", err) @@ -361,7 +361,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } }) - t.Run("verify cache inside node", func(t *testing.T) { + t.Run("verify_cache_inside_node", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", "sudo", "crictl", "images")) if err != nil { t.Errorf("failed to get images by %q ssh %v", rr.Command(), err) @@ -372,7 +372,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { }) - t.Run("cache reload", func(t *testing.T) { // deleting image inside minikube node manually and expecting reload to bring it back + t.Run("cache_reload", func(t *testing.T) { // deleting image inside minikube node manually and expecting reload to bring it back img := "busybox:latest" // deleting image inside minikube node manually rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", "sudo", "docker", "rmi", img)) // for some reason crictl rmi doesn't work diff --git a/test/integration/guest_env_test.go b/test/integration/guest_env_test.go index 29bf60ab5fce..8f57ac0ab6f5 100644 --- a/test/integration/guest_env_test.go +++ b/test/integration/guest_env_test.go @@ -24,6 +24,8 @@ import ( "os/exec" "testing" "time" + + "k8s.io/minikube/pkg/minikube/vmpath" ) func TestGuestEnvironment(t *testing.T) { @@ -59,7 +61,7 @@ func TestGuestEnvironment(t *testing.T) { "/var/lib/docker", "/var/lib/cni", "/var/lib/kubelet", - "/var/lib/minikube", + vmpath.GuestPersistentDir, "/var/lib/toolbox", "/var/lib/boot2docker", } {