From 349506569bc36d8efeb45b09abdfa08629c715cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=94=A6=E5=8D=97=E8=B7=AF=E4=B9=8B=E8=8A=B1?= Date: Sun, 18 Aug 2024 01:25:38 +0200 Subject: [PATCH] feat: allow publish and download kicbase image in github release --- go.mod | 3 +- hack/jenkins/release_build_and_upload.sh | 18 ++++++++++- pkg/minikube/download/download.go | 3 +- pkg/minikube/download/image.go | 33 ++++++++++++++++++++ pkg/minikube/node/cache.go | 39 ++++++++++++++++++++++-- 5 files changed, 90 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9a18c7eb1890..8dd7dae3d3b2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module k8s.io/minikube -go 1.22.0 +go 1.23.0 + toolchain go1.23.4 require ( diff --git a/hack/jenkins/release_build_and_upload.sh b/hack/jenkins/release_build_and_upload.sh index e0a18a439b15..2314e10860dd 100755 --- a/hack/jenkins/release_build_and_upload.sh +++ b/hack/jenkins/release_build_and_upload.sh @@ -39,7 +39,8 @@ grep -E "^VERSION_BUILD \\?=" Makefile | grep "${VERSION_BUILD}" # Force go packages to the Jekins home directory export GOPATH=$HOME/go - +# Make sure docker is installed and configured +./hack/jenkins/installers/check_install_docker.sh # Verify ISO exists echo "Verifying ISO exists ..." make verify-iso @@ -111,5 +112,20 @@ fi #echo "Updating Docker images ..." #make push-gvisor-addon-image push-storage-provisioner-manifest +echo "Generating tarballs for kicbase images" +# first get the correct tag of the kic base image +KIC_VERSION=$(grep -E "Version =" pkg/drivers/kic/types.go | cut -d \" -f 2 | cut -d "-" -f 1) +# then generate tarballs for all achitectures +for ARCH in "amd64" "arm64" "arm/v7" "ppc64le" "s390x" +do + SUFFIX=$(echo $ARCH | sed 's/\///g') + IMAGE_NAME=kicbase/stable:${KIC_VERSION} + TARBALL_NAME=out/kicbase-${KIC_VERSION}-${SUFFIX}.tar + docker pull ${IMAGE_NAME} --platform linux/${ARCH} + docker image save ${IMAGE_NAME} -o ${TARBALL_NAME} + openssl sha256 "${TARBALL_NAME}" | awk '{print $2}' > "${TARBALL_NAME}.sha256" + docker rmi -f ${IMAGE_NAME} +done + echo "Updating latest bucket for ${VERSION} release ..." gsutil cp -r "gs://${BUCKET}/releases/${TAGNAME}/*" "gs://${BUCKET}/releases/latest/" diff --git a/pkg/minikube/download/download.go b/pkg/minikube/download/download.go index a4404cbf458e..27289bfedce4 100644 --- a/pkg/minikube/download/download.go +++ b/pkg/minikube/download/download.go @@ -65,7 +65,7 @@ func CreateDstDownloadMock(_, dst string) error { } // download is a well-configured atomic download function -func download(src, dst string) error { +func download(src, dst string, options ...getter.ClientOption) error { var clientOptions []getter.ClientOption if out.IsTerminal(os.Stdout) && !detect.GithubActionRunner() { progress := getter.WithProgress(DefaultProgressBar) @@ -76,6 +76,7 @@ func download(src, dst string) error { } else { clientOptions = []getter.ClientOption{} } + clientOptions = append(clientOptions, options...) tmpDst := dst + ".download" client := &getter.Client{ Src: src, diff --git a/pkg/minikube/download/image.go b/pkg/minikube/download/image.go index 9f54470bf940..a87071ea6a3f 100644 --- a/pkg/minikube/download/image.go +++ b/pkg/minikube/download/image.go @@ -32,6 +32,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/daemon" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/tarball" + "github.com/hashicorp/go-getter" "github.com/pkg/errors" "k8s.io/klog/v2" "k8s.io/minikube/pkg/minikube/detect" @@ -39,6 +40,7 @@ import ( "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/out" "k8s.io/minikube/pkg/minikube/out/register" + "k8s.io/minikube/pkg/version" ) var ( @@ -224,6 +226,37 @@ func ImageToCache(img string) error { } } +// GHImageTarballToCache try to download the tarball of kicbase from github release. +// This is the last resort, in case of all docker registry is not available. +func GHImageTarballToCache(img, imgVersion string) (string, error) { + f := imagePathInCache(img) + fileLock := f + ".lock" + + kicbaseArch := runtime.GOARCH + if kicbaseArch == "arm" { + kicbaseArch = "armv7" + } + + releaser, err := lockDownload(fileLock) + if err != nil { + return "", err + } + if releaser != nil { + defer releaser.Release() + } + downloadURL := fmt.Sprintf("https://github.com/kubernetes/minikube/releases/download/%s/%s-%s-%s.tar", + version.GetVersion(), + img, imgVersion, kicbaseArch) + + // we don't want the tarball to be decompressed + // so we pass client options to suppress this behavior + if err := download(downloadURL, f, getter.WithDecompressors(map[string]getter.Decompressor{})); err != nil { + return "", err + } + return downloadURL, nil + +} + func parseImage(img string) (*name.Tag, name.Reference, error) { var ref name.Reference diff --git a/pkg/minikube/node/cache.go b/pkg/minikube/node/cache.go index 6feffc855763..d158c36b771e 100644 --- a/pkg/minikube/node/cache.go +++ b/pkg/minikube/node/cache.go @@ -133,12 +133,13 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down if finalImg != "" { cc.KicBaseImage = finalImg if image.Tag(finalImg) != image.Tag(baseImg) { - out.WarningT(fmt.Sprintf("minikube was unable to download %s, but successfully downloaded %s as a fallback image", image.Tag(baseImg), image.Tag(finalImg))) + out.WarningT(fmt.Sprintf("minikube was unable to download %s, but successfully downloaded %s as a fallback image", image.Tag(baseImg), finalImg)) } } }() + // first we try to download the kicbase image (and fall back images) from docker registry + var err error for _, img := range append([]string{baseImg}, kic.FallbackImages...) { - var err error if driver.IsDocker(cc.Driver) && download.ImageExistsInDaemon(img) && !downloadOnly { klog.Infof("%s exists in daemon, skipping load", img) @@ -167,7 +168,39 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down } klog.Infof("failed to download %s, will try fallback image if available: %v", img, err) } - return fmt.Errorf("failed to download kic base image or any fallback image") + // second if we failed to download any fallback image + // that means probably all registries are blocked by network issues + // we can try to download the image from minikube release page + + // if we reach here, that means the user cannot have access to any docker registry + // this means the user is very likely to have a network issue + // downloading from github via http is the last resort, and we should remind the user + // that he should at least get access to github + // print essential warnings + out.WarningT("minikube cannot pull kicbase image from any docker registry, and is trying to download kicbase tarball from github release page via HTTP.") + out.WarningT("It's very likely that you have an internet issue. Please ensure that you can access the internet at least via HTTP, directly or with proxy. Currently your proxy configure is:") + envs := []string{"HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy", "ALL_PROXY", "NO_PROXY"} + for _, env := range envs { + if v := os.Getenv(env); v != "" { + out.Infof("{{.env}}={{.value}}", out.V{"env": env, "value": v}) + } + } + out.Ln("") + + kicbaseVersion := strings.Split(kic.Version, "-")[0] + finalImg, err = download.GHImageTarballToCache("kicbase", kicbaseVersion) + if err != nil { + klog.Infof("failed to download %s", finalImg) + return fmt.Errorf("failed to download kic base image or any fallback image") + } + klog.Infof("successfully downloaded %s as fall back image", finalImg) + if !downloadOnly && driver.IsDocker(cc.Driver) { + if finalImg, err = download.CacheToDaemon("kicbase"); err == nil { + klog.Infof("successfully loaded and using kicbase from tarball on github") + } + } + return nil + }) }