diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 39af4a9eeef6..0d0e2be6a105 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -290,6 +290,125 @@ jobs: if [ "$numPass" -lt 36 ];then echo "*** Failed to pass at least 36 ! ***";exit 2;fi if [ "$numPass" -eq 0 ];then echo "*** Passed! ***";exit 0;fi + functional_docker_rootless_containerd_ubuntu: + permissions: + contents: none + needs: [build_minikube] + env: + TIME_ELAPSED: time + JOB_NAME: "functional_docker_rootless_containerd_ubuntu" + GOPOGH_RESULT: "" + SHELL: "/bin/bash" # To prevent https://github.com/kubernetes/minikube/issues/6643 + DEBIAN_FRONTEND: noninteractive + # ubuntu-22.04 is needed for cgroup v2 + runs-on: ubuntu-22.04 + steps: + - name: Install kubectl + shell: bash + run: | + curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" + sudo install kubectl /usr/local/bin/kubectl + kubectl version --client=true + # https://rootlesscontaine.rs/getting-started/common/cgroup2/ + - name: Set up cgroup v2 delegation + run: | + sudo mkdir -p /etc/systemd/system/user@.service.d + cat <&1 | tee ./report/testout.txt + END_TIME=$(date -u +%s) + TIME_ELAPSED=$(($END_TIME-$START_TIME)) + min=$((${TIME_ELAPSED}/60)) + sec=$((${TIME_ELAPSED}%60)) + TIME_ELAPSED="${min} min $sec seconds " + echo "TIME_ELAPSED=${TIME_ELAPSED}" >> $GITHUB_ENV + - name: Generate HTML Report + shell: bash + run: | + cd minikube_binaries + export PATH=${PATH}:`go env GOPATH`/bin + go tool test2json -t < ./report/testout.txt > ./report/testout.json || true + STAT=$(gopogh -in ./report/testout.json -out_html ./report/testout.html -out_summary ./report/testout_summary.json -name "${JOB_NAME} ${GITHUB_REF}" -repo "${GITHUB_REPOSITORY}" -details "${GITHUB_SHA}") || true + echo status: ${STAT} + FailNum=$(echo $STAT | jq '.NumberOfFail') + TestsNum=$(echo $STAT | jq '.NumberOfTests') + GOPOGH_RESULT="${JOB_NAME} : completed with ${FailNum} / ${TestsNum} failures in ${TIME_ELAPSED}" + echo "GOPOGH_RESULT=${GOPOGH_RESULT}" >> $GITHUB_ENV + echo 'STAT<> $GITHUB_ENV + echo "${STAT}" >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb + with: + name: functional_docker_rootless_containerd_ubuntu + path: minikube_binaries/report + - name: The End Result functional_docker_rootless_containerd_ubuntu + shell: bash + run: | + echo ${GOPOGH_RESULT} + numFail=$(echo $STAT | jq '.NumberOfFail') + numPass=$(echo $STAT | jq '.NumberOfPass') + echo "*******************${numPass} Passes :) *******************" + echo $STAT | jq '.PassedTests' || true + echo "*******************************************************" + echo "---------------- ${numFail} Failures :( ----------------------------" + echo $STAT | jq '.FailedTests' || true + echo "-------------------------------------------------------" + if [ "$numFail" -gt 0 ];then echo "*** $numFail Failed ***";exit 2;fi + if [ "$numPass" -eq 0 ];then echo "*** 0 Passed! ***";exit 2;fi + if [ "$numPass" -lt 36 ];then echo "*** Failed to pass at least 36 ! ***";exit 2;fi + if [ "$numPass" -eq 0 ];then echo "*** Passed! ***";exit 0;fi + functional_podman_ubuntu: permissions: contents: none @@ -611,6 +730,7 @@ jobs: [ functional_docker_ubuntu, functional_docker_containerd_ubuntu, + functional_docker_rootless_containerd_ubuntu, functional_podman_ubuntu, functional_virtualbox_macos, functional_baremetal_ubuntu20_04, @@ -627,6 +747,7 @@ jobs: ls -lah cp -r ./functional_docker_ubuntu ./all_reports/ cp -r ./functional_docker_containerd_ubuntu ./all_reports/ + cp -r ./functional_docker_rootless_containerd_ubuntu ./all_reports/ cp -r ./functional_podman_ubuntu ./all_reports/ cp -r ./functional_virtualbox_macos ./all_reports/ cp -r ./functional_baremetal_ubuntu20_04 ./all_reports/ diff --git a/cmd/minikube/main.go b/cmd/minikube/main.go index 09dbe85f93d8..940ca1abe0dd 100644 --- a/cmd/minikube/main.go +++ b/cmd/minikube/main.go @@ -20,6 +20,7 @@ import ( "bytes" "crypto/sha1" "encoding/hex" + "errors" "flag" "fmt" "log" @@ -51,6 +52,10 @@ import ( "k8s.io/minikube/pkg/minikube/machine" "k8s.io/minikube/pkg/minikube/out" _ "k8s.io/minikube/pkg/provision" + + dconfig "github.com/docker/cli/cli/config" + ddocker "github.com/docker/cli/cli/context/docker" + dstore "github.com/docker/cli/cli/context/store" ) const minikubeEnableProfile = "MINIKUBE_ENABLE_PROFILING" @@ -68,6 +73,8 @@ func main() { bridgeLogMessages() defer klog.Flush() + propagateDockerContextToEnv() + // Don't parse flags when running as kubectl _, callingCmd := filepath.Split(os.Args[0]) callingCmd = strings.TrimSuffix(callingCmd, ".exe") @@ -247,3 +254,54 @@ func setLastStartFlags() { klog.Warningf("Unable to set default flag value for log_file: %v", err) } } + +// propagateDockerContextToEnv propagates the current context in ~/.docker/config.json to $DOCKER_HOST, +// so that google/go-containerregistry can pick it up. +func propagateDockerContextToEnv() { + if os.Getenv("DOCKER_HOST") != "" { + // Already explicitly set + return + } + currentContext := os.Getenv("DOCKER_CONTEXT") + if currentContext == "" { + dockerConfigDir := dconfig.Dir() + if _, err := os.Stat(dockerConfigDir); err != nil { + if !errors.Is(err, os.ErrNotExist) { + klog.Warning(err) + } + return + } + cf, err := dconfig.Load(dockerConfigDir) + if err != nil { + klog.Warningf("Unable to load the current Docker config from %q", dockerConfigDir) + return + } + currentContext = cf.CurrentContext + } + if currentContext == "" { + return + } + storeConfig := dstore.NewConfig( + func() interface{} { return &ddocker.EndpointMeta{} }, + dstore.EndpointTypeGetter(ddocker.DockerEndpoint, func() interface{} { return &ddocker.EndpointMeta{} }), + ) + st := dstore.New(dconfig.ContextStoreDir(), storeConfig) + md, err := st.GetMetadata(currentContext) + if err != nil { + klog.Warningf("Unable to resolve the current Docker CLI context %q: %v", currentContext, err) + return + } + dockerEP, ok := md.Endpoints[ddocker.DockerEndpoint] + if !ok { + // No warning (the context is not for Docker) + return + } + dockerEPMeta, ok := dockerEP.(ddocker.EndpointMeta) + if !ok { + klog.Warningf("expected docker.EndpointMeta, got %T", dockerEP) + return + } + if dockerEPMeta.Host != "" { + os.Setenv("DOCKER_HOST", dockerEPMeta.Host) + } +} diff --git a/go.mod b/go.mod index 551bfc838b41..cebb9f54356d 100644 --- a/go.mod +++ b/go.mod @@ -96,6 +96,7 @@ require ( require ( github.com/Xuanwo/go-locale v1.1.0 github.com/blang/semver v3.5.1+incompatible + github.com/docker/cli v20.10.20+incompatible github.com/docker/go-connections v0.4.0 github.com/google/go-github/v43 v43.0.0 github.com/opencontainers/runc v1.1.4 @@ -128,13 +129,13 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/cli v20.10.20+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fvbommel/sortorder v1.0.1 // indirect github.com/go-fonts/liberation v0.2.0 // indirect github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 // indirect github.com/go-logr/logr v1.2.3 // indirect diff --git a/go.sum b/go.sum index b48c3e6ab39b..6e9af3cb9f17 100644 --- a/go.sum +++ b/go.sum @@ -411,6 +411,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= +github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= diff --git a/pkg/minikube/image/cache.go b/pkg/minikube/image/cache.go index bf9d72d8eb98..13ed49a0f935 100644 --- a/pkg/minikube/image/cache.go +++ b/pkg/minikube/image/cache.go @@ -131,6 +131,7 @@ func saveToTarFile(iname, rawDest string, overwrite bool) error { img, cname, err := retrieveImage(ref, iname) if err != nil { + klog.V(2).ErrorS(err, "an error while retrieving the image") return errCacheImageDoesntExist } if img == nil { diff --git a/test/integration/functional_test_mount_test.go b/test/integration/functional_test_mount_test.go index 3a20c15e44f4..b09491d42061 100644 --- a/test/integration/functional_test_mount_test.go +++ b/test/integration/functional_test_mount_test.go @@ -52,6 +52,9 @@ func validateMountCmd(ctx context.Context, t *testing.T, profile string) { // no if HyperVDriver() { t.Skip("skipping: mount broken on hyperv: https://github.com/kubernetes/minikube/issues/5029") } + if RootlessDriver() { + t.Skip("skipping: rootless driver does not support mount (because 9p is not mountable inside UserNS)") + } if runtime.GOOS == "windows" { t.Skip("skipping: mount broken on windows: https://github.com/kubernetes/minikube/issues/8303") diff --git a/test/integration/main_test.go b/test/integration/main_test.go index 2fe79de38615..3a8e9c7b74bd 100644 --- a/test/integration/main_test.go +++ b/test/integration/main_test.go @@ -149,6 +149,11 @@ func PodmanDriver() bool { return strings.Contains(*startArgs, "--driver=podman") || strings.Contains(*startArgs, "--vm-driver=podman") } +// Rootless returns whether or not this test is using the rootless KIC driver +func RootlessDriver() bool { + return strings.Contains(*startArgs, "--rootless") +} + // KicDriver returns whether or not this test is using the docker or podman driver func KicDriver() bool { return DockerDriver() || PodmanDriver() @@ -171,9 +176,9 @@ func arm64Platform() bool { } // NeedsPortForward returns access to endpoints with this driver needs port forwarding -// (Docker on non-Linux platforms requires ports to be forwarded to 127.0.0.1) +// (Docker on non-Linux platforms and rootless KIC requires ports to be forwarded to 127.0.0.1) func NeedsPortForward() bool { - return KicDriver() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") || detect.IsMicrosoftWSL() + return KicDriver() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") || detect.IsMicrosoftWSL() || RootlessDriver() } // CanCleanup returns if cleanup is allowed