diff --git a/Makefile b/Makefile index b39ffb9410..2c1c4adcb6 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ KUBERNETES_VERSION ?= $(shell egrep "DefaultKubernetesVersion =" pkg/minikube/co KIC_VERSION ?= $(shell egrep "Version =" pkg/drivers/kic/types.go | cut -d \" -f2) # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions -ISO_VERSION ?= v1.23.1 +ISO_VERSION ?= v1.23.1-1633115168-12081 # Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta DEB_VERSION ?= $(subst -,~,$(RAW_VERSION)) DEB_REVISION ?= 0 @@ -52,7 +52,8 @@ REGISTRY ?= gcr.io/k8s-minikube COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true) COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),"${COMMIT_NO}-dirty","${COMMIT_NO}") COMMIT_SHORT = $(shell git rev-parse --short HEAD 2> /dev/null || true) -HYPERKIT_BUILD_IMAGE ?= neilotoole/xcgo:go1.15 +# source code for image: https://github.com/spowelljr/xcgo +HYPERKIT_BUILD_IMAGE ?= gcr.io/k8s-minikube/xcgo:go1.17 # NOTE: "latest" as of 2021-02-06. kube-cross images aren't updated as often as Kubernetes # https://github.com/kubernetes/kubernetes/blob/master/build/build-image/cross/VERSION @@ -286,7 +287,7 @@ minikube_iso: deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/usr/b if [ ! -d $(BUILD_DIR)/buildroot ]; then \ mkdir -p $(BUILD_DIR); \ git clone --depth=1 --branch=$(BUILDROOT_BRANCH) https://github.com/buildroot/buildroot $(BUILD_DIR)/buildroot; \ - cp $(PWD)/deploy/iso/minikube-iso/go.hash $(BUILD_DIR)/buildroot/package/go/go.hash; \ + cp deploy/iso/minikube-iso/go.hash $(BUILD_DIR)/buildroot/package/go/go.hash; \ fi; $(MAKE) BR2_EXTERNAL=../../deploy/iso/minikube-iso minikube_defconfig -C $(BUILD_DIR)/buildroot $(BUILDROOT_OPTIONS) $(MAKE) -C $(BUILD_DIR)/buildroot $(BUILDROOT_OPTIONS) host-python diff --git a/cmd/auto-pause/auto-pause-hook/main.go b/cmd/auto-pause/auto-pause-hook/main.go index 57cd14d600..cd61ed47df 100644 --- a/cmd/auto-pause/auto-pause-hook/main.go +++ b/cmd/auto-pause/auto-pause-hook/main.go @@ -20,7 +20,7 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" + "io" "log" "net/http" "strconv" @@ -47,7 +47,7 @@ var targetIP *string func handler(w http.ResponseWriter, r *http.Request) { log.Println("Handling a request") - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { log.Printf("error: %v", err) return diff --git a/cmd/minikube/cmd/config/configure.go b/cmd/minikube/cmd/config/configure.go index 54b2d0df26..9dfa7a1630 100644 --- a/cmd/minikube/cmd/config/configure.go +++ b/cmd/minikube/cmd/config/configure.go @@ -17,8 +17,8 @@ limitations under the License. package config import ( - "io/ioutil" "net" + "os" "regexp" "github.com/spf13/cobra" @@ -84,7 +84,7 @@ var addonsConfigureCmd = &cobra.Command{ } // Read file from disk - dat, err := ioutil.ReadFile(gcrPath) + dat, err := os.ReadFile(gcrPath) if err != nil { out.FailureT("Error reading {{.path}}: {{.error}}", out.V{"path": gcrPath, "error": err}) diff --git a/cmd/minikube/cmd/config/set_test.go b/cmd/minikube/cmd/config/set_test.go index e54ebdc0e0..6795438ed3 100644 --- a/cmd/minikube/cmd/config/set_test.go +++ b/cmd/minikube/cmd/config/set_test.go @@ -17,7 +17,6 @@ limitations under the License. package config import ( - "io/ioutil" "os" "testing" @@ -67,7 +66,7 @@ func TestSetOK(t *testing.T) { func createTestConfig(t *testing.T) { t.Helper() - td, err := ioutil.TempDir("", "config") + td, err := os.MkdirTemp("", "config") if err != nil { t.Fatalf("tempdir: %v", err) } diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index 655b57ee79..74764207dd 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -19,7 +19,6 @@ package cmd import ( "context" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -518,13 +517,29 @@ func deleteMachineDirectories(cc *config.ClusterConfig) { // killMountProcess kills the mount process, if it is running func killMountProcess() error { - pidPath := filepath.Join(localpath.MiniPath(), constants.MountProcessFileName) + profile := viper.GetString("profile") + paths := []string{ + localpath.MiniPath(), // legacy mount-process path for backwards compatibility + localpath.Profile(profile), + } + + for _, path := range paths { + if err := killProcess(path); err != nil { + return err + } + } + + return nil +} + +func killProcess(path string) error { + pidPath := filepath.Join(path, constants.MountProcessFileName) if _, err := os.Stat(pidPath); os.IsNotExist(err) { return nil } klog.Infof("Found %s ...", pidPath) - out, err := ioutil.ReadFile(pidPath) + out, err := os.ReadFile(pidPath) if err != nil { return errors.Wrap(err, "ReadFile") } diff --git a/cmd/minikube/cmd/delete_test.go b/cmd/minikube/cmd/delete_test.go index 6422d04ac5..cdf0cb7495 100644 --- a/cmd/minikube/cmd/delete_test.go +++ b/cmd/minikube/cmd/delete_test.go @@ -18,7 +18,6 @@ package cmd import ( "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -53,7 +52,7 @@ func exclude(vals []string, exclude []string) []string { func fileNames(path string) ([]string, error) { result := []string{} - fis, err := ioutil.ReadDir(path) + fis, err := os.ReadDir(path) if err != nil { return result, err } @@ -64,7 +63,7 @@ func fileNames(path string) ([]string, error) { } func TestDeleteProfile(t *testing.T) { - td, err := ioutil.TempDir("", "single") + td, err := os.MkdirTemp("", "single") if err != nil { t.Fatalf("tempdir: %v", err) } @@ -170,7 +169,7 @@ func deleteContextTest() error { } func TestDeleteAllProfiles(t *testing.T) { - td, err := ioutil.TempDir("", "all") + td, err := os.MkdirTemp("", "all") if err != nil { t.Fatalf("tempdir: %v", err) } @@ -234,7 +233,7 @@ func TestDeleteAllProfiles(t *testing.T) { if err != nil { t.Errorf("profiles: %v", err) } - afterMachines, err := ioutil.ReadDir(filepath.Join(localpath.MiniPath(), "machines")) + afterMachines, err := os.ReadDir(filepath.Join(localpath.MiniPath(), "machines")) if err != nil { t.Errorf("machines: %v", err) } diff --git a/cmd/minikube/cmd/generate-docs_test.go b/cmd/minikube/cmd/generate-docs_test.go index 91ce515de6..daf0b19785 100644 --- a/cmd/minikube/cmd/generate-docs_test.go +++ b/cmd/minikube/cmd/generate-docs_test.go @@ -17,7 +17,6 @@ limitations under the License. package cmd import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -27,7 +26,7 @@ import ( ) func TestGenerateTestDocs(t *testing.T) { - tempdir, err := ioutil.TempDir("", "") + tempdir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("creating temp dir failed: %v", err) } @@ -38,7 +37,7 @@ func TestGenerateTestDocs(t *testing.T) { if err != nil { t.Fatalf("error generating test docs: %v", err) } - actualContents, err := ioutil.ReadFile(docPath) + actualContents, err := os.ReadFile(docPath) if err != nil { t.Fatalf("error reading generated file: %v", err) } diff --git a/cmd/minikube/cmd/image.go b/cmd/minikube/cmd/image.go index cea9f517d5..ec2a349e6f 100644 --- a/cmd/minikube/cmd/image.go +++ b/cmd/minikube/cmd/image.go @@ -18,7 +18,6 @@ package cmd import ( "io" - "io/ioutil" "net/url" "os" "path/filepath" @@ -58,7 +57,7 @@ var ( ) func saveFile(r io.Reader) (string, error) { - tmp, err := ioutil.TempFile("", "build.*.tar") + tmp, err := os.CreateTemp("", "build.*.tar") if err != nil { return "", err } @@ -184,7 +183,7 @@ var saveImageCmd = &cobra.Command{ output = args[1] if args[1] == "-" { - tmp, err := ioutil.TempFile("", "image.*.tar") + tmp, err := os.CreateTemp("", "image.*.tar") if err != nil { exit.Error(reason.GuestImageSave, "Failed to get temp", err) } diff --git a/cmd/minikube/cmd/logs.go b/cmd/minikube/cmd/logs.go index 9bf4348479..80b9d2c14b 100644 --- a/cmd/minikube/cmd/logs.go +++ b/cmd/minikube/cmd/logs.go @@ -100,9 +100,7 @@ var logsCmd = &cobra.Command{ err = logs.Output(cr, bs, *co.Config, co.CP.Runner, numberOfLines, logOutput) if err != nil { out.Ln("") - // Avoid exit.Error, since it outputs the issue URL out.WarningT("{{.error}}", out.V{"error": err}) - os.Exit(reason.ExSvcError) } }, } diff --git a/cmd/minikube/cmd/options.go b/cmd/minikube/cmd/options.go index 63211aefbb..8086931133 100644 --- a/cmd/minikube/cmd/options.go +++ b/cmd/minikube/cmd/options.go @@ -31,7 +31,7 @@ var optionsCmd = &cobra.Command{ Use: "options", Short: "Show a list of global command-line options (applies to all commands).", Long: "Show a list of global command-line options (applies to all commands).", - Hidden: true, + Hidden: false, Run: runOptions, } diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go index ba87db888e..fa7a7f7d18 100644 --- a/cmd/minikube/cmd/start_flags.go +++ b/cmd/minikube/cmd/start_flags.go @@ -617,7 +617,6 @@ func updateExistingConfigFromFlags(cmd *cobra.Command, existing *config.ClusterC out.WarningT("You cannot add or remove extra disks for an existing minikube cluster. Please first delete the cluster.") } - updateStringFromFlag(cmd, &cc.MinikubeISO, isoURL) updateBoolFromFlag(cmd, &cc.KeepContext, keepContext) updateBoolFromFlag(cmd, &cc.EmbedCerts, embedCerts) updateStringFromFlag(cmd, &cc.MinikubeISO, isoURL) diff --git a/cmd/minikube/cmd/stop.go b/cmd/minikube/cmd/stop.go index 1db7ab2038..fef1b5674c 100644 --- a/cmd/minikube/cmd/stop.go +++ b/cmd/minikube/cmd/stop.go @@ -119,9 +119,7 @@ func runStop(cmd *cobra.Command, args []string) { } register.Reg.SetStep(register.Done) - if stoppedNodes > 0 { - out.Step(style.Stopped, `{{.count}} nodes stopped.`, out.V{"count": stoppedNodes}) - } + out.Step(style.Stopped, `{{.count}} node{{if gt .count 1}}s{{end}} stopped.`, out.V{"count": stoppedNodes}) } func stopProfile(profile string) int { diff --git a/deploy/iso/minikube-iso/board/coreos/minikube/users b/deploy/iso/minikube-iso/board/coreos/minikube/users index cdff9ff1f9..e5ece397b9 100644 --- a/deploy/iso/minikube-iso/board/coreos/minikube/users +++ b/deploy/iso/minikube-iso/board/coreos/minikube/users @@ -1 +1 @@ -docker 1000 docker 1000 =tcuser /home/docker /bin/bash wheel,vboxsf,podman - +docker 1000 docker 1000 =tcuser /home/docker /bin/bash wheel,vboxsf,podman,buildkit - diff --git a/deploy/iso/minikube-iso/package/buildkit-bin/51-buildkit.preset b/deploy/iso/minikube-iso/package/buildkit-bin/51-buildkit.preset new file mode 100644 index 0000000000..37de892c71 --- /dev/null +++ b/deploy/iso/minikube-iso/package/buildkit-bin/51-buildkit.preset @@ -0,0 +1 @@ +disable buildkit.service diff --git a/deploy/iso/minikube-iso/package/buildkit-bin/buildkit-bin.mk b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit-bin.mk index cc479a30fd..6c54c2451f 100644 --- a/deploy/iso/minikube-iso/package/buildkit-bin/buildkit-bin.mk +++ b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit-bin.mk @@ -12,6 +12,10 @@ BUILDKIT_BIN_SOURCE = buildkit-$(BUILDKIT_BIN_VERSION).linux-amd64.tar.gz # https://github.com/opencontainers/runc.git BUILDKIT_RUNC_VERSION = 12644e614e25b05da6fd08a38ffa0cfe1903fdec +define BUILDKIT_BIN_USERS + - -1 buildkit -1 - - - - - +endef + define BUILDKIT_BIN_INSTALL_TARGET_CMDS $(INSTALL) -D -m 0755 \ $(@D)/buildctl \ @@ -25,6 +29,24 @@ define BUILDKIT_BIN_INSTALL_TARGET_CMDS $(INSTALL) -D -m 0755 \ $(@D)/buildkitd \ $(TARGET_DIR)/usr/sbin + $(INSTALL) -D -m 644 \ + $(BUILDKIT_BIN_PKGDIR)/buildkit.conf \ + $(TARGET_DIR)/usr/lib/tmpfiles.d/buildkit.conf + $(INSTALL) -D -m 644 \ + $(BUILDKIT_BIN_PKGDIR)/buildkitd.toml \ + $(TARGET_DIR)/etc/buildkit/buildkitd.toml +endef + +define BUILDKIT_BIN_INSTALL_INIT_SYSTEMD + $(INSTALL) -D -m 644 \ + $(BUILDKIT_BIN_PKGDIR)/buildkit.service \ + $(TARGET_DIR)/usr/lib/systemd/system/buildkit.service + $(INSTALL) -D -m 644 \ + $(BUILDKIT_BIN_PKGDIR)/buildkit.socket \ + $(TARGET_DIR)/usr/lib/systemd/system/buildkit.socket + $(INSTALL) -D -m 644 \ + $(BUILDKIT_BIN_PKGDIR)/51-buildkit.preset \ + $(TARGET_DIR)/usr/lib/systemd/system-preset/51-buildkit.preset endef $(eval $(generic-package)) diff --git a/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.conf b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.conf new file mode 100644 index 0000000000..006273ce91 --- /dev/null +++ b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.conf @@ -0,0 +1 @@ +d /run/buildkit 0770 root buildkit diff --git a/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.service b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.service new file mode 100644 index 0000000000..c1dad527ec --- /dev/null +++ b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.service @@ -0,0 +1,11 @@ +[Unit] +Description=BuildKit +Requires=buildkit.socket +After=buildkit.socket +Documentation=https://github.com/moby/buildkit + +[Service] +ExecStart=/usr/sbin/buildkitd --addr fd:// + +[Install] +WantedBy=multi-user.target diff --git a/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.socket b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.socket new file mode 100644 index 0000000000..776b237627 --- /dev/null +++ b/deploy/iso/minikube-iso/package/buildkit-bin/buildkit.socket @@ -0,0 +1,12 @@ +[Unit] +Description=BuildKit +Documentation=https://github.com/moby/buildkit + +[Socket] +ListenStream=%t/buildkit/buildkitd.sock +SocketMode=0660 +SocketUser=root +SocketGroup=buildkit + +[Install] +WantedBy=sockets.target diff --git a/deploy/iso/minikube-iso/package/buildkit-bin/buildkitd.toml b/deploy/iso/minikube-iso/package/buildkit-bin/buildkitd.toml new file mode 100644 index 0000000000..62158d44d7 --- /dev/null +++ b/deploy/iso/minikube-iso/package/buildkit-bin/buildkitd.toml @@ -0,0 +1,5 @@ +[worker.oci] + enabled = false +[worker.containerd] + enabled = true + namespace = "k8s.io" diff --git a/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash b/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash index 36451957fa..9db9e5e115 100644 --- a/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash +++ b/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash @@ -21,5 +21,5 @@ sha256 74a4e916acddc6cf47ab5752bdebb6732ce2c028505ef57b7edc21d2da9039b6 v1.18.4. sha256 fc8a8e61375e3ce30563eeb0fd6534c4f48fc20300a72e6ff51cc99cb2703516 v1.19.0.tar.gz sha256 6165c5b8212ea03be2a465403177318bfe25a54c3e8d66d720344643913a0223 v1.19.1.tar.gz sha256 76fd7543bc92d4364a11060f43a5131893a76c6e6e9d6de3a6bb6292c110b631 v1.20.0.tar.gz -sha256 1c01d4a76cdcfe3ac24147eb1d5f6ebd782bd98fb0ac0c19b79bd5a6560b1481 v1.20.2.tar.gz +sha256 36d9f4cf4966342e2d4099e44d8156c55c6a10745c67ce4f856aa9f6dcc2d9ba v1.20.2.tar.gz sha256 bc53ea8977e252bd9812974c33ff654ee22076598e901464468c5c105a5ef773 v1.22.0.tar.gz diff --git a/deploy/kicbase/Dockerfile b/deploy/kicbase/Dockerfile index f7092a32d7..8b91fe53d2 100644 --- a/deploy/kicbase/Dockerfile +++ b/deploy/kicbase/Dockerfile @@ -142,14 +142,21 @@ COPY deploy/kicbase/containerd-fuse-overlayfs.service /etc/systemd/system/contai # install buildkit RUN export ARCH=$(dpkg --print-architecture | sed 's/ppc64el/ppc64le/' | sed 's/armhf/arm-v7/') \ && echo "Installing buildkit ..." \ + && addgroup --system buildkit \ && export BUILDKIT_BASE_URL="https://github.com/moby/buildkit/releases/download/${BUILDKIT_VERSION}" \ && curl -sSL --retry 5 --output /tmp/buildkit.tgz "${BUILDKIT_BASE_URL}/buildkit-${BUILDKIT_VERSION}.linux-${ARCH}.tar.gz" \ && tar -C /usr/local -xzvf /tmp/buildkit.tgz \ && rm -rf /tmp/buildkit.tgz \ + && mkdir -p /usr/local/lib/systemd/system \ + && curl -L --retry 5 --output /usr/local/lib/systemd/system/buildkit.service "https://raw.githubusercontent.com/moby/buildkit/${BUILDKIT_VERSION}/examples/systemd/buildkit.service" \ + && curl -L --retry 5 --output /usr/local/lib/systemd/system/buildkit.socket "https://raw.githubusercontent.com/moby/buildkit/${BUILDKIT_VERSION}/examples/systemd/buildkit.socket" \ + && mkdir -p /etc/buildkit \ + && echo "[worker.oci]\n enabled = false\n[worker.containerd]\n enabled = true\n namespace = \"k8s.io\"" > /etc/buildkit/buildkitd.toml \ && chmod 755 /usr/local/bin/buildctl \ && chmod 755 /usr/local/bin/buildkit-runc \ && chmod 755 /usr/local/bin/buildkit-qemu-* \ - && chmod 755 /usr/local/bin/buildkitd + && chmod 755 /usr/local/bin/buildkitd \ + && systemctl enable buildkit.socket # Install cri-o/podman dependencies: RUN sh -c "echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list" && \ @@ -210,6 +217,7 @@ EXPOSE 22 RUN adduser --ingroup docker --disabled-password --gecos '' docker RUN adduser docker sudo RUN adduser docker podman +RUN adduser docker buildkit RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers USER docker RUN mkdir /home/docker/.ssh diff --git a/deploy/minikube/release_sanity_test.go b/deploy/minikube/release_sanity_test.go index 9b55312c36..09971ca446 100644 --- a/deploy/minikube/release_sanity_test.go +++ b/deploy/minikube/release_sanity_test.go @@ -20,7 +20,7 @@ import ( "crypto/sha256" "encoding/hex" "fmt" - "io/ioutil" + "io" "runtime" "testing" @@ -36,7 +36,7 @@ func getSHAFromURL(url string) (string, error) { return "", err } defer r.Body.Close() - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { return "", err } diff --git a/go.mod b/go.mod index ed120cd433..b84da6723a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module k8s.io/minikube go 1.17 require ( - cloud.google.com/go/storage v1.16.1 + cloud.google.com/go/storage v1.18.0 contrib.go.opencensus.io/exporter/stackdriver v0.12.1 github.com/Delta456/box-cli-maker/v2 v2.2.2 github.com/GoogleCloudPlatform/docker-credential-gcr v0.0.0-20210713212222-faed5e8b8ca2 @@ -19,7 +19,7 @@ require ( github.com/cloudevents/sdk-go/v2 v2.5.0 github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 // indirect - github.com/docker/docker v20.10.7+incompatible + github.com/docker/docker v20.10.9+incompatible github.com/docker/go-units v0.4.0 github.com/docker/machine v0.16.2 github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e @@ -29,7 +29,7 @@ require ( github.com/google/go-github/v36 v36.0.0 github.com/google/slowjam v1.0.0 github.com/google/uuid v1.3.0 - github.com/hashicorp/go-getter v1.5.8 + github.com/hashicorp/go-getter v1.5.9 github.com/hashicorp/go-retryablehttp v0.7.0 github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect @@ -66,7 +66,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6 // indirect github.com/samalba/dockerclient v0.0.0-20160414174713-91d7393ff859 // indirect - github.com/shirou/gopsutil/v3 v3.21.8 + github.com/shirou/gopsutil/v3 v3.21.9 github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.9.0 @@ -82,11 +82,11 @@ require ( golang.org/x/mod v0.5.1 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365 + golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 golang.org/x/text v0.3.7 gonum.org/v1/plot v0.10.0 - google.golang.org/api v0.57.0 + google.golang.org/api v0.58.0 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.22.2 @@ -99,7 +99,7 @@ require ( ) require ( - cloud.google.com/go v0.94.1 // indirect + cloud.google.com/go v0.97.0 // indirect cloud.google.com/go/container v0.1.0 // indirect cloud.google.com/go/monitoring v0.1.0 // indirect cloud.google.com/go/trace v0.1.0 // indirect @@ -139,7 +139,7 @@ require ( github.com/golang/snappy v0.0.3 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/google/gofuzz v1.1.0 // indirect - github.com/googleapis/gax-go/v2 v2.1.0 // indirect + github.com/googleapis/gax-go/v2 v2.1.1 // indirect github.com/googleapis/gnostic v0.4.1 // indirect github.com/gookit/color v1.4.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -194,7 +194,7 @@ require ( golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 // indirect + google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 // indirect google.golang.org/grpc v1.40.0 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 7588584070..f6a77723a3 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,9 @@ cloud.google.com/go v0.92.1/go.mod h1:cMc7asehN84LBi1JGTHo4n8wuaGuNAZ7lR7b1YNJBr cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.92.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1 h1:DwuSvDZ1pTYGbXo8yOJevCTr3BoBlE+OVkHAKiYQUXc= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -55,8 +56,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.16.1 h1:sMEIc4wxvoY3NXG7Rn9iP7jb/2buJgWR1vNXCR/UPfs= -cloud.google.com/go/storage v1.16.1/go.mod h1:LaNorbty3ehnU3rEjXSNV/NRgQA0O8Y+uh6bPe5UOk4= +cloud.google.com/go/storage v1.18.0 h1:HM5Hu/BqgmWbo7pT9KFYGUccwzA8ZWDICJww9m5t9UA= +cloud.google.com/go/storage v1.18.0/go.mod h1:h0NImijCz/2WHwLh03BvmWdrNe4I/pzUdvUHoxIUroU= cloud.google.com/go/trace v0.1.0 h1:nUGUK79FOkN0UGUXhBmVBkbu1PYsHe0YyFSPLOD9Npg= cloud.google.com/go/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= contrib.go.opencensus.io/exporter/stackdriver v0.12.1 h1:Dll2uFfOVI3fa8UzsHyP6z0M6fEc9ZTAMo+Y3z282Xg= @@ -366,8 +367,9 @@ github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc github.com/docker/docker v17.12.0-ce-rc1.0.20181225093023-5ddb1d410a8b+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20190115220918-5ec31380a5d3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.9+incompatible h1:JlsVnETOjM2RLQa0Cc1XCIspUdXW3Zenq9P54uXBm6k= +github.com/docker/docker v20.10.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -615,8 +617,9 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0 h1:6DWmvNpomjL1+3liNSZbVns3zsYzzCjm6pRBO1tLeso= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= @@ -649,8 +652,8 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.5.8 h1:qx5CZXxXz5YFpALPkbf/F1iZZoRE+f6T1i/AWw/Zkic= -github.com/hashicorp/go-getter v1.5.8/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= +github.com/hashicorp/go-getter v1.5.9 h1:b7ahZW50iQiUek/at3CvZhPK1/jiV6CtKcsJiR6E4R0= +github.com/hashicorp/go-getter v1.5.9/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= @@ -1052,8 +1055,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA= -github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= +github.com/shirou/gopsutil/v3 v3.21.9 h1:Vn4MUz2uXhqLSiCbGFRc0DILbMVLAY92DSkT8bsYrHg= +github.com/shirou/gopsutil/v3 v3.21.9/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -1491,8 +1494,9 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365 h1:6wSTsvPddg9gc/mVEEyk9oOAoxn+bT4Z9q1zx+4RwA4= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1634,8 +1638,9 @@ google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00 google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0 h1:4t9zuDlHLcIx0ZEhmXEeFVCRsiOgpgn2QOH9N0MNjPI= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0 h1:MDkAbYIB1JpSgCTOCYYoIec/coMlKK4oVbpnBLLcyT0= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1702,11 +1707,13 @@ google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKr google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210825212027-de86158e7fda/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 h1:3V2dxSZpz4zozWWUq36vUxXEKnSYitEH2LdsAx+RUmg= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 h1:5Tbluzus3QxoAJx4IefGt1W0HQZW4nuMrVk684jI74Q= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/hack/benchmark/time-to-k8s/public-chart/generate-chart.go b/hack/benchmark/time-to-k8s/public-chart/generate-chart.go index 95a8a65ab0..52fa557993 100644 --- a/hack/benchmark/time-to-k8s/public-chart/generate-chart.go +++ b/hack/benchmark/time-to-k8s/public-chart/generate-chart.go @@ -43,6 +43,7 @@ type benchmark struct { App float64 `json:"app"` DNSAns float64 `json:"dnsAns"` Total float64 `json:"total"` + CPU float64 `json:"cpu"` } // benchmarks contains a list of benchmarks, used for storing benchmark results to JSON @@ -70,8 +71,8 @@ func readInLatestBenchmark(latestBenchmarkPath string) benchmark { log.Fatal(err) } - var cmd, api, k8s, dnsSvc, app, dnsAns float64 - steps := []*float64{&cmd, &api, &k8s, &dnsSvc, &app, &dnsAns} + var cmd, api, k8s, dnsSvc, app, dnsAns, cpu float64 + steps := []*float64{&cmd, &api, &k8s, &dnsSvc, &app, &dnsAns, &cpu} count := 0 r := csv.NewReader(f) @@ -91,8 +92,13 @@ func readInLatestBenchmark(latestBenchmarkPath string) benchmark { values := []float64{} - // 8-13 contain the benchmark results + // 8-13 and 16 contain the benchmark results + var idx []int for i := 8; i <= 13; i++ { + idx = append(idx, i) + } + idx = append(idx, 16) + for _, i := range idx { v, err := strconv.ParseFloat(line[i], 64) if err != nil { log.Fatal(err) @@ -108,10 +114,14 @@ func readInLatestBenchmark(latestBenchmarkPath string) benchmark { var total float64 for _, step := range steps { *step /= float64(count) + // Don't add CPU time to the total time. + if step == &cpu { + continue + } total += *step } - return benchmark{time.Now(), cmd, api, k8s, dnsSvc, app, dnsAns, total} + return benchmark{time.Now(), cmd, api, k8s, dnsSvc, app, dnsAns, total, cpu} } // readInPastBenchmarks reads in the past benchmark results from a JSON file @@ -144,8 +154,8 @@ func updateRunsFile(h *benchmarks, pastRunsPath string) { // createChart creates a time series chart of the benchmarks func createChart(benchmarks []benchmark, chartOutputPath string) { n := len(benchmarks) - var cmdXYs, apiXYs, k8sXYs, dnsSvcXYs, appXYs, dnsAnsXYs, totalXYs plotter.XYs - xys := []*plotter.XYs{&cmdXYs, &apiXYs, &k8sXYs, &dnsSvcXYs, &appXYs, &dnsAnsXYs, &totalXYs} + var cmdXYs, apiXYs, k8sXYs, dnsSvcXYs, appXYs, dnsAnsXYs, totalXYs, cpuXYs plotter.XYs + xys := []*plotter.XYs{&cmdXYs, &apiXYs, &k8sXYs, &dnsSvcXYs, &appXYs, &dnsAnsXYs, &totalXYs, &cpuXYs} for _, xy := range xys { *xy = make(plotter.XYs, n) @@ -164,6 +174,7 @@ func createChart(benchmarks []benchmark, chartOutputPath string) { {&appXYs, b.App}, {&dnsAnsXYs, b.DNSAns}, {&totalXYs, b.Total}, + {&cpuXYs, b.CPU}, } for _, xyValue := range xyValues { xy := &(*xyValue.xys)[i] @@ -193,6 +204,7 @@ func createChart(benchmarks []benchmark, chartOutputPath string) { {appXYs, color.RGBA{R: 255, G: 255, A: 255}, "App Running"}, {dnsAnsXYs, color.RGBA{G: 255, B: 255, A: 255}, "DNS Answering"}, {totalXYs, color.RGBA{B: 255, R: 140, A: 255}, "Total"}, + {cpuXYs, color.RGBA{B: 57, R: 127, G: 85, A: 255}, "CPU"}, } for _, step := range steps { diff --git a/hack/benchmark/time-to-k8s/time-to-k8s-repo b/hack/benchmark/time-to-k8s/time-to-k8s-repo index f6f6b2db9e..6e6133456e 160000 --- a/hack/benchmark/time-to-k8s/time-to-k8s-repo +++ b/hack/benchmark/time-to-k8s/time-to-k8s-repo @@ -1 +1 @@ -Subproject commit f6f6b2db9e718f7c9af698b6247b232a7251522f +Subproject commit 6e6133456e56553c341fd1a8a465fd302d85123d diff --git a/hack/boilerplate/boilerplate.go b/hack/boilerplate/boilerplate.go index bb7e411bd4..e53a75a54b 100644 --- a/hack/boilerplate/boilerplate.go +++ b/hack/boilerplate/boilerplate.go @@ -20,7 +20,6 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" "log" "os" "path/filepath" @@ -75,7 +74,7 @@ func extensionToBoilerplate(dir string) (map[string][]byte, error) { files, _ := filepath.Glob(dir + "/*.txt") for _, filename := range files { extension := strings.ToLower(filepath.Ext(txtExtension.ReplaceAllString(filename, ""))) - data, err := ioutil.ReadFile(filename) + data, err := os.ReadFile(filename) if err != nil { return nil, err } @@ -97,7 +96,7 @@ func extensionToBoilerplate(dir string) (map[string][]byte, error) { // filePasses checks whether the processed file is valid. Returning false means that the file does not the proper boilerplate template. func filePasses(filename string, expectedBoilerplate []byte) (bool, error) { - data, err := ioutil.ReadFile(filename) + data, err := os.ReadFile(filename) if err != nil { return false, err } diff --git a/hack/jenkins/common.ps1 b/hack/jenkins/common.ps1 index 108a6f30b1..284533f3d4 100644 --- a/hack/jenkins/common.ps1 +++ b/hack/jenkins/common.ps1 @@ -12,18 +12,58 @@ # See the License for the specific language governing permissions and # limitations under the License. -mkdir -p out +# A utility to write commit statuses to github, since authenticating is complicated now +function Write-GithubStatus { + param ( + $JsonBody + ) + # Manually build basic authorization headers, ugh + $creds = "minikube-bot:$($env:access_token)" + $encoded = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($creds)) + $auth = "Basic $encoded" + $headers = @{ + Authorization = $auth + } + Invoke-WebRequest -Uri "https://api.github.com/repos/kubernetes/minikube/statuses/$env:COMMIT" -Headers $headers -Body $JsonBody -ContentType "application/json" -Method Post -usebasicparsing +} +$env:SHORT_COMMIT=$env:COMMIT.substring(0, 7) +$gcs_bucket="minikube-builds/logs/$env:MINIKUBE_LOCATION/$env:ROOT_JOB_ID" + +# Docker's kubectl breaks things, and comes earlier in the path than the regular kubectl. So download the expected kubectl and replace Docker's version. +(New-Object Net.WebClient).DownloadFile("https://dl.k8s.io/release/v1.20.0/bin/windows/amd64/kubectl.exe", "C:\Program Files\Docker\Docker\resources\bin\kubectl.exe") + +# Setup the cleanup and reboot cron +gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/windows_cleanup_and_reboot.ps1 C:\jenkins +gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/windows_cleanup_cron.ps1 out/ +./out/windows_cleanup_cron.ps1 + +# Make sure Docker is up and running +gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/setup_docker_desktop_windows.ps1 out/ +./out/setup_docker_desktop_windows.ps1 +If ($lastexitcode -gt 0) { + echo "Docker failed to start, exiting." + + $json = "{`"state`": `"failure`", `"description`": `"Jenkins: docker failed to start`", `"target_url`": `"https://storage.googleapis.com/$gcs_bucket/Hyper-V_Windows.txt`", `"context`": `"$env:JOB_NAME`"}" + + Write-GithubStatus -JsonBody $json + docker system prune --all --force + Exit $lastexitcode +} + +# Download gopogh and gotestsum (New-Object Net.WebClient).DownloadFile("https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh.exe", "C:\Go\bin\gopogh.exe") (New-Object Net.WebClient).DownloadFile("https://github.com/gotestyourself/gotestsum/releases/download/v1.6.4/gotestsum_1.6.4_windows_amd64.tar.gz", "$env:TEMP\gotestsum.tar.gz") tar --directory "C:\Go\bin\" -xzvf "$env:TEMP\gotestsum.tar.gz" "gotestsum.exe" +# Grab all the scripts we'll need for integration tests gsutil.cmd -m cp gs://minikube-builds/$env:MINIKUBE_LOCATION/minikube-windows-amd64.exe out/ gsutil.cmd -m cp gs://minikube-builds/$env:MINIKUBE_LOCATION/e2e-windows-amd64.exe out/ gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/testdata . gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/windows_integration_setup.ps1 out/ gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/windows_integration_teardown.ps1 out/ +# Make sure an old minikube instance isn't running ./out/minikube-windows-amd64.exe delete --all ./out/windows_integration_setup.ps1 @@ -62,19 +102,28 @@ If($env:status -eq "failure") { } echo $description -$env:SHORT_COMMIT=$env:COMMIT.substring(0, 7) -$gcs_bucket="minikube-builds/logs/$env:MINIKUBE_LOCATION/$env:ROOT_JOB_ID" #Upload logs to gcs -gsutil -qm cp testout.txt gs://$gcs_bucket/${env:JOB_NAME}out.txt -gsutil -qm cp testout.json gs://$gcs_bucket/${env:JOB_NAME}.json -gsutil -qm cp testout.html gs://$gcs_bucket/${env:JOB_NAME}.html -gsutil -qm cp testout_summary.json gs://$gcs_bucket/${env:JOB_NAME}_summary.json +If($env:EXTERNAL -eq "yes"){ + # If we're not already in GCP, we won't have credentials to upload to GCS + # Instad, move logs to a predictable spot Jenkins can find and upload itself + mkdir -p test_reports + cp testout.txt test_reports/out.txt + cp testout.json test_reports/out.json + cp testout.html test_reports/out.html + cp testout_summary.json test_reports/summary.txt +} Else { + gsutil -qm cp testout.txt gs://$gcs_bucket/${env:JOB_NAME}out.txt + gsutil -qm cp testout.json gs://$gcs_bucket/${env:JOB_NAME}.json + gsutil -qm cp testout.html gs://$gcs_bucket/${env:JOB_NAME}.html + gsutil -qm cp testout_summary.json gs://$gcs_bucket/${env:JOB_NAME}_summary.json +} $env:target_url="https://storage.googleapis.com/$gcs_bucket/$env:JOB_NAME.html" + # Update the PR with the new info -$json = "{`"state`": `"$env:status`", `"description`": `"Jenkins: $description`", `"target_url`": `"$env:target_url`", `"context`": `"${env:JOB_NAME}`"}" -Invoke-WebRequest -Uri "https://api.github.com/repos/kubernetes/minikube/statuses/$env:COMMIT`?access_token=$env:access_token" -Body $json -ContentType "application/json" -Method Post -usebasicparsing +$json = "{`"state`": `"$env:status`", `"description`": `"Jenkins: $description`", `"target_url`": `"$env:target_url`", `"context`": `"$env:JOB_NAME`"}" +Write-GithubStatus -JsonBody $json ./out/windows_integration_teardown.ps1 diff --git a/hack/jenkins/minikube_set_pending.sh b/hack/jenkins/minikube_set_pending.sh index d6ce0a350b..410715566e 100755 --- a/hack/jenkins/minikube_set_pending.sh +++ b/hack/jenkins/minikube_set_pending.sh @@ -28,7 +28,7 @@ set -eux -o pipefail jobs=( 'Hyperkit_macOS' - # 'Hyper-V_Windows' + 'Hyper-V_Windows' # 'VirtualBox_Linux' # 'VirtualBox_macOS' # 'VirtualBox_Windows' diff --git a/hack/jenkins/setup_docker_desktop_windows.ps1 b/hack/jenkins/setup_docker_desktop_windows.ps1 index fe71f046cf..8b40410a91 100644 --- a/hack/jenkins/setup_docker_desktop_windows.ps1 +++ b/hack/jenkins/setup_docker_desktop_windows.ps1 @@ -17,9 +17,9 @@ Get-Process "*Docker Desktop*" | Stop-Process $attempt = 1 while($attempt -le 10) { Write-Host "Attempt ", $attempt - Write-Host "Wait for 5 minutes" + Write-Host "Wait for 3 minutes" & "C:\Program Files\Docker\Docker\Docker Desktop.exe" - Start-Sleep 300 + Start-Sleep 180 $dockerInfo = docker info Write-Host "Docker Info ", $dockerInfo $serverVersion = $dockerInfo | Where-Object {$_ -Match "Server Version"} diff --git a/hack/jenkins/windows_cleanup_and_reboot_docker.ps1 b/hack/jenkins/windows_cleanup_and_reboot.ps1 similarity index 67% rename from hack/jenkins/windows_cleanup_and_reboot_docker.ps1 rename to hack/jenkins/windows_cleanup_and_reboot.ps1 index 48186ebce3..2ff742bc33 100644 --- a/hack/jenkins/windows_cleanup_and_reboot_docker.ps1 +++ b/hack/jenkins/windows_cleanup_and_reboot.ps1 @@ -17,4 +17,9 @@ if (Jenkins) { echo "doing it" docker system prune --all --force --volumes Get-Process "*Docker Desktop*" | Stop-Process +Get-VM | Where-Object {$_.Name -ne "DockerDesktopVM"} | Foreach { + Suspend-VM $_.Name + Stop-VM $_.Name -Force + Remove-VM $_.Name -Force +} shutdown /r diff --git a/hack/jenkins/windows_cleanup_and_reboot_hyperv.ps1 b/hack/jenkins/windows_cleanup_and_reboot_hyperv.ps1 deleted file mode 100644 index 0f8c5b2d03..0000000000 --- a/hack/jenkins/windows_cleanup_and_reboot_hyperv.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -function Jenkins { - Get-Process e2e-windows-amd64 2>$NULL - if ($?) { - return $TRUE - } - return $FALSE -} - -if (Jenkins) { - exit 0 -} -echo "waiting to see if any jobs are coming in..." -timeout 30 -if (Jenkins) { - exit 0 -} -echo "doing it" -taskkill /IM putty.exe -taskkill /F /IM java.exe -Get-VM | Where-Object {$_.Name -ne "DockerDesktopVM"} | Foreach { - C:\var\jenkins\workspace\Hyper-V_Windows_integration\out\minikube-windows-amd64.exe delete -p $_.Name - Suspend-VM $_.Name - Stop-VM $_.Name -Force - Remove-VM $_.Name -Force -} -Remove-Item -path C:\Users\admin\.minikube -recurse -force -shutdown /r \ No newline at end of file diff --git a/hack/jenkins/windows_cleanup_cron.ps1 b/hack/jenkins/windows_cleanup_cron.ps1 index 08648ea91e..7f7e62e53f 100644 --- a/hack/jenkins/windows_cleanup_cron.ps1 +++ b/hack/jenkins/windows_cleanup_cron.ps1 @@ -1 +1 @@ -Schtasks /create /tn cleanup_reboot /sc HOURLY /tr "Powershell gsutil -m cp gs://minikube-builds/master/windows_cleanup_and_reboot_docker.ps1 C:\Users\jenkins; C:\Users\jenkins\windows_cleanup_and_reboot_docker.ps1" +Schtasks /create /tn cleanup_reboot /sc MINUTE /mo 30 /tr "Powershell C:\jenkins\windows_cleanup_and_reboot.ps1" /f diff --git a/hack/jenkins/windows_integration_teardown.ps1 b/hack/jenkins/windows_integration_teardown.ps1 index db04b21adc..4ade0ba2b9 100644 --- a/hack/jenkins/windows_integration_teardown.ps1 +++ b/hack/jenkins/windows_integration_teardown.ps1 @@ -23,3 +23,4 @@ if ($driver -eq "docker") { } rm -r -Force $test_home +C:\jenkins\windows_cleanup_and_reboot.ps1 diff --git a/hack/jenkins/windows_integration_test_docker.ps1 b/hack/jenkins/windows_integration_test_docker.ps1 index 40729fb7d5..b06bdc13ff 100644 --- a/hack/jenkins/windows_integration_test_docker.ps1 +++ b/hack/jenkins/windows_integration_test_docker.ps1 @@ -14,29 +14,11 @@ mkdir -p out -# Docker's kubectl breaks things, and comes earlier in the path than the regular kubectl. So download the expected kubectl and replace Docker's version. -(New-Object Net.WebClient).DownloadFile("https://dl.k8s.io/release/v1.20.0/bin/windows/amd64/kubectl.exe", "C:\Program Files\Docker\Docker\resources\bin\kubectl.exe") - -gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/setup_docker_desktop_windows.ps1 out/ gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/common.ps1 out/ -$env:SHORT_COMMIT=$env:COMMIT.substring(0, 7) -$gcs_bucket="minikube-builds/logs/$env:MINIKUBE_LOCATION/$env:ROOT_JOB_ID" - -./out/setup_docker_desktop_windows.ps1 -If ($lastexitcode -gt 0) { - echo "Docker failed to start, exiting." - - $json = "{`"state`": `"failure`", `"description`": `"Jenkins: docker failed to start`", `"target_url`": `"https://storage.googleapis.com/$gcs_bucket/Docker_Windows.txt`", `"context`": `"Docker_Windows`"}" - - Invoke-WebRequest -Uri "https://api.github.com/repos/kubernetes/minikube/statuses/$env:COMMIT`?access_token=$env:access_token" -Body $json -ContentType "application/json" -Method Post -usebasicparsing - - docker system prune --all --force - Exit $lastexitcode -} - $driver="docker" $timeout="180m" $env:JOB_NAME="Docker_Windows" +$env:EXTERNAL="yes" . ./out/common.ps1 diff --git a/hack/jenkins/windows_integration_test_hyperv.ps1 b/hack/jenkins/windows_integration_test_hyperv.ps1 index 41520a9f8f..69b768f039 100644 --- a/hack/jenkins/windows_integration_test_hyperv.ps1 +++ b/hack/jenkins/windows_integration_test_hyperv.ps1 @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +mkdir -p out + gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/common.ps1 out/ $driver="hyperv" -$timeout="65m" +$timeout="180m" $env:JOB_NAME="Hyper-V_Windows" +$env:EXTERNAL="yes" . ./out/common.ps1 diff --git a/hack/kicbase_version/release_kicbase_version.go b/hack/kicbase_version/release_kicbase_version.go index c440502ca8..96c19848c5 100644 --- a/hack/kicbase_version/release_kicbase_version.go +++ b/hack/kicbase_version/release_kicbase_version.go @@ -46,7 +46,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "os" "os/exec" "regexp" @@ -218,7 +217,7 @@ func prepareImage(ctx context.Context, current, release string) (image string, e // getKICVersion returns current kic base image version and any error func getKICVersion() (string, error) { - blob, err := ioutil.ReadFile(kicFile) + blob, err := os.ReadFile(kicFile) if err != nil { return "", err } diff --git a/hack/metrics/minikube.go b/hack/metrics/minikube.go index 5b9d649205..f2fcbf98bb 100644 --- a/hack/metrics/minikube.go +++ b/hack/metrics/minikube.go @@ -19,7 +19,7 @@ package main import ( "context" "fmt" - "io/ioutil" + "io" "os" "os/exec" "runtime" @@ -56,12 +56,12 @@ func downloadMinikube(ctx context.Context, minikubePath string) error { } defer rc.Close() - data, err := ioutil.ReadAll(rc) + data, err := io.ReadAll(rc) if err != nil { - return errors.Wrap(err, "ioutil read all") + return errors.Wrap(err, "io read all") } log.Printf("downloading gs://%s/%s to %v", bucketName, binary(), minikubePath) - if err := ioutil.WriteFile(minikubePath, data, 0777); err != nil { + if err := os.WriteFile(minikubePath, data, 0777); err != nil { return errors.Wrap(err, "writing minikubePath") } if err := os.Chmod(minikubePath, 0700); err != nil { diff --git a/hack/update/filesystem.go b/hack/update/filesystem.go index d8cc6285f5..cc5e412514 100644 --- a/hack/update/filesystem.go +++ b/hack/update/filesystem.go @@ -19,7 +19,6 @@ package update import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" @@ -40,7 +39,7 @@ func fsUpdate(fsRoot string, schema map[string]Item, data interface{}) (changed return false, fmt.Errorf("unable to get file content: %w", err) } mode = info.Mode() - content, err = ioutil.ReadFile(path) + content, err = os.ReadFile(path) if err != nil { return false, fmt.Errorf("unable to read file content: %w", err) } @@ -54,7 +53,7 @@ func fsUpdate(fsRoot string, schema map[string]Item, data interface{}) (changed if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { return false, fmt.Errorf("unable to create directory: %w", err) } - if err := ioutil.WriteFile(path, item.Content, mode); err != nil { + if err := os.WriteFile(path, item.Content, mode); err != nil { return false, fmt.Errorf("unable to write file: %w", err) } changed = true @@ -65,7 +64,7 @@ func fsUpdate(fsRoot string, schema map[string]Item, data interface{}) (changed // Loadf returns the file content read as byte slice func Loadf(path string) []byte { - blob, err := ioutil.ReadFile(path) + blob, err := os.ReadFile(path) if err != nil { klog.Fatalf("Unable to load file %s: %v", path, err) return nil diff --git a/hack/update/golang_version/update_golang_version.go b/hack/update/golang_version/update_golang_version.go index d66f1c890d..255a5305ff 100644 --- a/hack/update/golang_version/update_golang_version.go +++ b/hack/update/golang_version/update_golang_version.go @@ -28,7 +28,7 @@ package main import ( "context" - "io/ioutil" + "io" "net/http" "strings" "time" @@ -157,7 +157,7 @@ func goVersions() (stable, stableMM, k8sVersion string, err error) { if err != nil { return "", "", "", err } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return "", "", "", err } diff --git a/hack/update/kicbase_version/update_kicbase_version.go b/hack/update/kicbase_version/update_kicbase_version.go index cf6cd49d41..6649de54b2 100644 --- a/hack/update/kicbase_version/update_kicbase_version.go +++ b/hack/update/kicbase_version/update_kicbase_version.go @@ -48,7 +48,7 @@ package main import ( "context" - "io/ioutil" + "os" "path/filepath" "regexp" "strings" @@ -121,7 +121,7 @@ func main() { // KICVersions returns current and stable KIC base image versions and any error occurred. func KICVersions() (current, stable string, err error) { - blob, err := ioutil.ReadFile(filepath.Join(update.FSRoot, kicFile)) + blob, err := os.ReadFile(filepath.Join(update.FSRoot, kicFile)) if err != nil { return "", "", err } diff --git a/pkg/addons/addons_gcpauth.go b/pkg/addons/addons_gcpauth.go index 2172ae19c4..e1b329cbc1 100644 --- a/pkg/addons/addons_gcpauth.go +++ b/pkg/addons/addons_gcpauth.go @@ -20,7 +20,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "os" "os/exec" "path" @@ -75,7 +74,7 @@ func enableAddonGCPAuth(cfg *config.ClusterConfig) error { if err != nil { if detect.IsCloudShell() { if c := os.Getenv("CLOUDSDK_CONFIG"); c != "" { - f, err := ioutil.ReadFile(path.Join(c, "application_default_credentials.json")) + f, err := os.ReadFile(path.Join(c, "application_default_credentials.json")) if err == nil { creds, _ = google.CredentialsFromJSON(ctx, f) } diff --git a/pkg/addons/addons_test.go b/pkg/addons/addons_test.go index a85051ee25..6101fbb3ea 100644 --- a/pkg/addons/addons_test.go +++ b/pkg/addons/addons_test.go @@ -17,7 +17,6 @@ limitations under the License. package addons import ( - "io/ioutil" "os" "path/filepath" "sync" @@ -31,7 +30,7 @@ import ( func createTestProfile(t *testing.T) string { t.Helper() - td, err := ioutil.TempDir("", "profile") + td, err := os.MkdirTemp("", "profile") if err != nil { t.Fatalf("tempdir: %v", err) } diff --git a/pkg/drivers/common.go b/pkg/drivers/common.go index a830cf897b..6fbed28035 100644 --- a/pkg/drivers/common.go +++ b/pkg/drivers/common.go @@ -19,7 +19,6 @@ package drivers import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" "syscall" @@ -136,7 +135,7 @@ func fixMachinePermissions(path string) error { if err := os.Chown(path, syscall.Getuid(), syscall.Getegid()); err != nil { return errors.Wrap(err, "chown dir") } - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return errors.Wrap(err, "read dir") } diff --git a/pkg/drivers/common_test.go b/pkg/drivers/common_test.go index 14cc631082..8104f72321 100644 --- a/pkg/drivers/common_test.go +++ b/pkg/drivers/common_test.go @@ -17,7 +17,6 @@ limitations under the License. package drivers import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -30,7 +29,7 @@ func Test_createDiskImage(t *testing.T) { defer tests.RemoveTempDir(tmpdir) sshPath := filepath.Join(tmpdir, "ssh") - if err := ioutil.WriteFile(sshPath, []byte("mysshkey"), 0644); err != nil { + if err := os.WriteFile(sshPath, []byte("mysshkey"), 0644); err != nil { t.Fatalf("writefile: %v", err) } diskPath := filepath.Join(tmpdir, "disk") diff --git a/pkg/drivers/hyperkit/driver.go b/pkg/drivers/hyperkit/driver.go index 3c908d6c75..e9e6566c29 100644 --- a/pkg/drivers/hyperkit/driver.go +++ b/pkg/drivers/hyperkit/driver.go @@ -22,7 +22,6 @@ package hyperkit import ( "encoding/json" "fmt" - "io/ioutil" "os" "os/user" "path" @@ -366,7 +365,7 @@ func (d *Driver) recoverFromUncleanShutdown() error { } log.Warnf("minikube might have been shutdown in an unclean way, the hyperkit pid file still exists: %s", pidFile) - bs, err := ioutil.ReadFile(pidFile) + bs, err := os.ReadFile(pidFile) if err != nil { return errors.Wrapf(err, "reading pidfile %s", pidFile) } diff --git a/pkg/drivers/hyperkit/iso_test.go b/pkg/drivers/hyperkit/iso_test.go index 9138cc020b..a55f8ffd46 100644 --- a/pkg/drivers/hyperkit/iso_test.go +++ b/pkg/drivers/hyperkit/iso_test.go @@ -17,13 +17,12 @@ limitations under the License. package hyperkit import ( - "io/ioutil" "os" "testing" ) func TestExtractFile(t *testing.T) { - testDir, err := ioutil.TempDir(os.TempDir(), "") + testDir, err := os.MkdirTemp(os.TempDir(), "") if nil != err { return } diff --git a/pkg/drivers/hyperkit/network_test.go b/pkg/drivers/hyperkit/network_test.go index 4c6b27ac1f..906680cab3 100644 --- a/pkg/drivers/hyperkit/network_test.go +++ b/pkg/drivers/hyperkit/network_test.go @@ -20,7 +20,7 @@ limitations under the License. package hyperkit import ( - "io/ioutil" + "os" "path/filepath" "testing" @@ -54,12 +54,12 @@ func Test_getIpAddressFromFile(t *testing.T) { defer tests.RemoveTempDir(tmpdir) dhcpFile := filepath.Join(tmpdir, "dhcp") - if err := ioutil.WriteFile(dhcpFile, validLeases, 0644); err != nil { + if err := os.WriteFile(dhcpFile, validLeases, 0644); err != nil { t.Fatalf("writefile: %v", err) } invalidFile := filepath.Join(tmpdir, "invalid") - if err := ioutil.WriteFile(invalidFile, []byte("foo"), 0644); err != nil { + if err := os.WriteFile(invalidFile, []byte("foo"), 0644); err != nil { t.Fatalf("writefile: %v", err) } diff --git a/pkg/drivers/kic/oci/network_create.go b/pkg/drivers/kic/oci/network_create.go index 494f90f56d..27dd083ef5 100644 --- a/pkg/drivers/kic/oci/network_create.go +++ b/pkg/drivers/kic/oci/network_create.go @@ -123,10 +123,8 @@ func tryCreateDockerNetwork(ociBin string, subnet *network.Parameters, mtu int, args = append(args, "-o") args = append(args, fmt.Sprintf("com.docker.network.driver.mtu=%d", mtu)) } - - args = append(args, fmt.Sprintf("--label=%s=%s", CreatedByLabelKey, "true")) } - args = append(args, name) + args = append(args, fmt.Sprintf("--label=%s=%s", CreatedByLabelKey, "true"), name) rr, err := runCmd(exec.Command(ociBin, args...)) if err != nil { @@ -220,7 +218,7 @@ func podmanNetworkInspect(name string) (netInfo, error) { rr, err := runCmd(cmd) if err != nil { logDockerNetworkInspect(Podman, name) - if strings.Contains(rr.Output(), "No such network") { + if strings.Contains(rr.Output(), "no such network") { return info, ErrNetworkNotFound } diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go index 6c116840c8..e397e7375c 100644 --- a/pkg/drivers/kic/types.go +++ b/pkg/drivers/kic/types.go @@ -24,13 +24,13 @@ import ( const ( // Version is the current version of kic - Version = "v0.0.27" + Version = "v0.0.27-1633027942-12081" // SHA of the kic base image - baseImageSHA = "89b4738ee74ba28684676e176752277f0db46f57d27f0e08c3feec89311e22de" + baseImageSHA = "4780f1897569d2bf77aafb3d133a08d42b4fe61127f06fcfc90c2c5d902d893c" // The name of the GCR kicbase repository - gcrRepo = "gcr.io/k8s-minikube/kicbase" + gcrRepo = "gcr.io/k8s-minikube/kicbase-builds" // The name of the Dockerhub kicbase repository - dockerhubRepo = "docker.io/kicbase/stable" + dockerhubRepo = "docker.io/kicbase/build" ) var ( diff --git a/pkg/drivers/kvm/gpu.go b/pkg/drivers/kvm/gpu.go index 534c0d94d4..3722c94e37 100644 --- a/pkg/drivers/kvm/gpu.go +++ b/pkg/drivers/kvm/gpu.go @@ -22,7 +22,6 @@ package kvm import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -106,7 +105,7 @@ func getDevicesXML() (string, error) { func getPassthroughableNVIDIADevices() ([]string, error) { // Make sure the host supports IOMMU - iommuGroups, err := ioutil.ReadDir(sysKernelIOMMUGroupsPath) + iommuGroups, err := os.ReadDir(sysKernelIOMMUGroupsPath) if err != nil { return []string{}, fmt.Errorf("error reading %q: %v", sysKernelIOMMUGroupsPath, err) } @@ -115,7 +114,7 @@ func getPassthroughableNVIDIADevices() ([]string, error) { } // Get list of PCI devices - devices, err := ioutil.ReadDir(sysFsPCIDevicesPath) + devices, err := os.ReadDir(sysFsPCIDevicesPath) if err != nil { return []string{}, fmt.Errorf("error reading %q: %v", sysFsPCIDevicesPath, err) } @@ -124,7 +123,7 @@ func getPassthroughableNVIDIADevices() ([]string, error) { found := false for _, device := range devices { vendorPath := filepath.Join(sysFsPCIDevicesPath, device.Name(), "vendor") - content, err := ioutil.ReadFile(vendorPath) + content, err := os.ReadFile(vendorPath) if err != nil { log.Infof("Error while reading %q: %v", vendorPath, err) continue @@ -173,7 +172,7 @@ func getPassthroughableNVIDIADevices() ([]string, error) { func isIsolated(device string) bool { // Find out the other devices in the same IOMMU group as one of our unbound device. iommuGroupPath := filepath.Join(sysFsPCIDevicesPath, device, "iommu_group", "devices") - otherDevices, err := ioutil.ReadDir(iommuGroupPath) + otherDevices, err := os.ReadDir(iommuGroupPath) if err != nil { log.Infof("Error reading %q: %v", iommuGroupPath, err) return false diff --git a/pkg/drivers/ssh/ssh.go b/pkg/drivers/ssh/ssh.go index aa613a75be..f032f9b313 100644 --- a/pkg/drivers/ssh/ssh.go +++ b/pkg/drivers/ssh/ssh.go @@ -18,7 +18,6 @@ package ssh import ( "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -110,7 +109,7 @@ func (d *Driver) PreCreateCheck() error { return fmt.Errorf("SSH key does not exist: %q", d.SSHKey) } - key, err := ioutil.ReadFile(d.SSHKey) + key, err := os.ReadFile(d.SSHKey) if err != nil { return err } diff --git a/pkg/generate/docs.go b/pkg/generate/docs.go index 6ba2170d7f..de18e7ae87 100644 --- a/pkg/generate/docs.go +++ b/pkg/generate/docs.go @@ -20,7 +20,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "path/filepath" "time" @@ -166,5 +165,5 @@ func saveDocForCommand(command *cobra.Command, contents []byte, path string) err if err := os.Remove(fp); err != nil { klog.Warningf("error removing %s", fp) } - return ioutil.WriteFile(fp, contents, 0o644) + return os.WriteFile(fp, contents, 0o644) } diff --git a/pkg/generate/errorcodes.go b/pkg/generate/errorcodes.go index c50d085e83..b6bff48e46 100644 --- a/pkg/generate/errorcodes.go +++ b/pkg/generate/errorcodes.go @@ -22,7 +22,7 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" + "os" "strings" "time" @@ -41,7 +41,7 @@ func ErrorCodes(docPath string, pathsToCheck []string) error { fset := token.NewFileSet() for _, pathToCheck := range pathsToCheck { - r, err := ioutil.ReadFile(pathToCheck) + r, err := os.ReadFile(pathToCheck) if err != nil { return errors.Wrap(err, fmt.Sprintf("error reading file %s", pathToCheck)) } @@ -122,5 +122,5 @@ func ErrorCodes(docPath string, pathsToCheck []string) error { } } - return ioutil.WriteFile(docPath, buf.Bytes(), 0o644) + return os.WriteFile(docPath, buf.Bytes(), 0o644) } diff --git a/pkg/generate/testdocs.go b/pkg/generate/testdocs.go index f496be95f1..0663040a20 100644 --- a/pkg/generate/testdocs.go +++ b/pkg/generate/testdocs.go @@ -22,9 +22,10 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" + "log" "os" "path/filepath" + "regexp" "strings" "time" @@ -33,7 +34,6 @@ import ( ) func TestDocs(docPath string, pathToCheck string) error { - counter := 0 buf := bytes.NewBuffer([]byte{}) date := time.Now().Format("2006-01-02") title := out.Fmt(title, out.V{"Command": "Integration Tests", "Description": "All minikube integration tests", "Date": date}) @@ -47,7 +47,7 @@ func TestDocs(docPath string, pathToCheck string) error { return nil } fset := token.NewFileSet() - r, e := ioutil.ReadFile(path) + r, e := os.ReadFile(path) if e != nil { return errors.Wrap(e, fmt.Sprintf("error reading file %s", path)) } @@ -62,35 +62,8 @@ func TestDocs(docPath string, pathToCheck string) error { if !shouldParse(fnName) { return true } - - if strings.HasPrefix(fnName, "valid") { - e := writeSubTest(fnName, buf) - if e != nil { - return false - } - } else { - e := writeTest(fnName, buf) - if e != nil { - return false - } - } - - counter++ - comments := fd.Doc - if comments == nil { - e := writeComment(fnName, "// NEEDS DOC\n", buf) - return e == nil - } - for _, comment := range comments.List { - if strings.Contains(comment.Text, "TODO") { - continue - } - e := writeComment(fnName, comment.Text, buf) - if e != nil { - return false - } - } - _, e := buf.WriteString("\n") + td := parseFuncDocs(file, fd) + _, e := buf.WriteString(td.toMarkdown()) if e != nil { return false } @@ -103,10 +76,104 @@ func TestDocs(docPath string, pathToCheck string) error { return err } - err = ioutil.WriteFile(docPath, buf.Bytes(), 0o644) + err = os.WriteFile(docPath, buf.Bytes(), 0o644) return err } +// TestDoc is the documentation for a test case +type TestDoc struct { + // name is the name of the test case + name string + // isSubTest is true if the test case is a top-level test case, false if it's a validation method + isSubTest bool + // description is parsed from the function comment + description string + // steps are parsed from comments starting with `docs: ` + steps []string + // specialCases are parsed from comments starting with `docs(special): ` + specialCases []string + // specialCases are parsed from comments starting with `docs(skip): ` + skips []string +} + +// toMarkdown converts the TestDoc into a string in Markdown format +func (d *TestDoc) toMarkdown() string { + b := &strings.Builder{} + if d.isSubTest { + b.WriteString("#### " + d.name + "\n") + } else { + b.WriteString("## " + d.name + "\n") + } + + b.WriteString(d.description + "\n") + if len(d.steps) > 0 { + b.WriteString("Steps:\n") + for _, s := range d.steps { + b.WriteString("- " + s + "\n") + } + b.WriteString("\n") + } + + if len(d.specialCases) > 0 { + b.WriteString("Special cases:\n") + for _, s := range d.specialCases { + b.WriteString("- " + s + "\n") + } + b.WriteString("\n") + } + + if len(d.skips) > 0 { + b.WriteString("Skips:\n") + for _, s := range d.skips { + b.WriteString("- " + s + "\n") + } + b.WriteString("\n") + } + return b.String() +} + +// docsRegex is the regex of the docs comment starting with either `docs: ` or `docs(...): ` +var docsRegex = regexp.MustCompile(`docs(?:\((.*?)\))?:\s*`) + +// parseFuncDocs parses the comments from a function starting with `docs` +func parseFuncDocs(file *ast.File, fd *ast.FuncDecl) TestDoc { + d := TestDoc{ + name: fd.Name.Name, + description: strings.TrimPrefix(fd.Doc.Text(), fd.Name.Name+" "), + isSubTest: strings.HasPrefix(fd.Name.Name, "valid"), + } + + for _, c := range file.Comments { + for _, ci := range c.List { + if ci.Pos() < fd.Pos() || ci.End() > fd.End() { + // only generate docs for comments that are within the function scope + continue + } + text := strings.TrimPrefix(ci.Text, "// ") + m := docsRegex.FindStringSubmatch(text) + if len(m) < 2 { + // comment doesn't start with `docs: ` or `docs(...): ` + continue + } + matched := m[0] + docsType := m[1] + + text = strings.TrimPrefix(text, matched) + switch docsType { + case "special": + d.specialCases = append(d.specialCases, text) + case "skip": + d.skips = append(d.skips, text) + case "": + d.steps = append(d.steps, text) + default: + log.Printf("docs type %s is not recognized", docsType) + } + } + } + return d +} + func shouldParse(name string) bool { if strings.HasPrefix(name, "Test") && !strings.HasPrefix(name, "TestMain") { return true @@ -118,21 +185,3 @@ func shouldParse(name string) bool { return false } - -func writeTest(testName string, w *bytes.Buffer) error { - _, err := w.WriteString("## " + testName + "\n") - return err -} - -func writeSubTest(testName string, w *bytes.Buffer) error { - _, err := w.WriteString("#### " + testName + "\n") - return err -} - -func writeComment(testName string, comment string, w *bytes.Buffer) error { - // Remove the leading // from the testdoc comments - comment = comment[3:] - comment = strings.TrimPrefix(comment, testName+" ") - _, err := w.WriteString(comment + "\n") - return err -} diff --git a/pkg/gvisor/enable.go b/pkg/gvisor/enable.go index d55dae38d4..51200c5d1a 100644 --- a/pkg/gvisor/enable.go +++ b/pkg/gvisor/enable.go @@ -19,7 +19,6 @@ package gvisor import ( "fmt" "io" - "io/ioutil" "log" "net/http" "os" @@ -179,7 +178,7 @@ func copyAssetToDest(targetName, dest string) error { // Now, copy the data from this asset to dest src := filepath.Join(vmpath.GuestGvisorDir, asset.GetTargetName()) log.Printf("%s asset path: %s", targetName, src) - contents, err := ioutil.ReadFile(src) + contents, err := os.ReadFile(src) if err != nil { return errors.Wrapf(err, "getting contents of %s", asset.GetSourcePath()) } diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 5afc4cb000..b6b6d11311 100755 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -467,7 +467,7 @@ var Addons = map[string]*Addon{ "helm-tiller-svc.yaml", "0640"), }, false, "helm-tiller", "", map[string]string{ - "Tiller": "helm/tiller:v2.16.12@sha256:6003775d503546087266eda39418d221f9afb5ccfe35f637c32a1161619a3f9c", + "Tiller": "helm/tiller:v2.17.0@sha256:4c43eb385032945cad047d2350e4945d913b90b3ab43ee61cecb32a495c6df0f", }, map[string]string{ // GCR is deprecated in helm // https://github.com/helm/helm/issues/10004#issuecomment-894478908 diff --git a/pkg/minikube/audit/logFile_test.go b/pkg/minikube/audit/logFile_test.go index 643c1513c1..617a43b8e0 100644 --- a/pkg/minikube/audit/logFile_test.go +++ b/pkg/minikube/audit/logFile_test.go @@ -18,7 +18,6 @@ package audit import ( "io" - "io/ioutil" "os" "path/filepath" "testing" @@ -39,7 +38,7 @@ func TestLogFile(t *testing.T) { }) t.Run("AppendToLog", func(t *testing.T) { - f, err := ioutil.TempFile("", "audit.json") + f, err := os.CreateTemp("", "audit.json") if err != nil { t.Fatalf("Error creating temporary file: %v", err) } diff --git a/pkg/minikube/audit/report_test.go b/pkg/minikube/audit/report_test.go index cb5cbfe0af..0e23a7acee 100644 --- a/pkg/minikube/audit/report_test.go +++ b/pkg/minikube/audit/report_test.go @@ -17,13 +17,12 @@ limitations under the License. package audit import ( - "io/ioutil" "os" "testing" ) func TestReport(t *testing.T) { - f, err := ioutil.TempFile("", "audit.json") + f, err := os.CreateTemp("", "audit.json") if err != nil { t.Fatalf("failed creating temporary file: %v", err) } diff --git a/pkg/minikube/bootstrapper/bsutil/kubeadm_test.go b/pkg/minikube/bootstrapper/bsutil/kubeadm_test.go index 469a6ec0f9..424b7155ad 100644 --- a/pkg/minikube/bootstrapper/bsutil/kubeadm_test.go +++ b/pkg/minikube/bootstrapper/bsutil/kubeadm_test.go @@ -18,7 +18,7 @@ package bsutil import ( "fmt" - "io/ioutil" + "os" "sort" "strings" "testing" @@ -83,7 +83,7 @@ func getExtraOptsPodCidr() []config.ExtraOption { // It will error if no testdata are available or in absence of testdata for newest and default minor k8s versions. func recentReleases(n int) ([]string, error) { path := "testdata" - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return nil, fmt.Errorf("unable to list testdata directory %s: %w", path, err) } @@ -177,7 +177,7 @@ func TestGenerateKubeadmYAMLDNS(t *testing.T) { if tc.shouldErr { return } - expected, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s/%s.yaml", version, tc.name)) + expected, err := os.ReadFile(fmt.Sprintf("testdata/%s/%s.yaml", version, tc.name)) if err != nil { t.Fatalf("unable to read testdata: %v", err) } @@ -270,7 +270,7 @@ func TestGenerateKubeadmYAML(t *testing.T) { if tc.shouldErr { return } - expected, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s/%s.yaml", version, tc.name)) + expected, err := os.ReadFile(fmt.Sprintf("testdata/%s/%s.yaml", version, tc.name)) if err != nil { t.Fatalf("unable to read testdata: %v", err) } diff --git a/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go b/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go index d66dd2ca6e..05d5e1d3b8 100644 --- a/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go +++ b/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go @@ -21,9 +21,10 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" + "io" "net" "net/http" + "os" "os/exec" "path" "strconv" @@ -237,7 +238,7 @@ func apiServerHealthz(hostname string, port int) (state.State, error) { func apiServerHealthzNow(hostname string, port int) (state.State, error) { url := fmt.Sprintf("https://%s/healthz", net.JoinHostPort(hostname, fmt.Sprint(port))) klog.Infof("Checking apiserver healthz at %s ...", url) - cert, err := ioutil.ReadFile(localpath.CACert()) + cert, err := os.ReadFile(localpath.CACert()) if err != nil { klog.Infof("ca certificate: %v", err) return state.Stopped, err @@ -257,7 +258,7 @@ func apiServerHealthzNow(hostname string, port int) (state.State, error) { } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { klog.Warningf("unable to read response body: %s", err) } diff --git a/pkg/minikube/bootstrapper/certs.go b/pkg/minikube/bootstrapper/certs.go index ff843bea5b..e86641ee04 100644 --- a/pkg/minikube/bootstrapper/certs.go +++ b/pkg/minikube/bootstrapper/certs.go @@ -21,7 +21,6 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -334,7 +333,7 @@ func generateProfileCerts(cfg config.ClusterConfig, n config.Node, ccs CACerts, // isValidPEMCertificate checks whether the input file is a valid PEM certificate (with at least one CERTIFICATE block) func isValidPEMCertificate(filePath string) (bool, error) { - fileBytes, err := ioutil.ReadFile(filePath) + fileBytes, err := os.ReadFile(filePath) if err != nil { return false, err } diff --git a/pkg/minikube/cni/cilium.go b/pkg/minikube/cni/cilium.go index 30035b6a4e..4b6932eb92 100644 --- a/pkg/minikube/cni/cilium.go +++ b/pkg/minikube/cni/cilium.go @@ -17,14 +17,18 @@ limitations under the License. package cni import ( + "bytes" "os/exec" + "text/template" "github.com/pkg/errors" + "k8s.io/klog/v2" "k8s.io/minikube/pkg/minikube/config" ) // From https://raw.githubusercontent.com/cilium/cilium/v1.9/install/kubernetes/quick-install.yaml -var ciliumTmpl = `--- +var ciliumTmpl = template.Must(template.New("name").Parse( + `--- # Source: cilium/templates/cilium-agent-serviceaccount.yaml apiVersion: v1 kind: ServiceAccount @@ -175,7 +179,7 @@ data: hubble-tls-key-file: /var/lib/cilium/tls/hubble/server.key hubble-tls-client-ca-files: /var/lib/cilium/tls/hubble/client-ca.crt ipam: "cluster-pool" - cluster-pool-ipv4-cidr: "10.0.0.0/8" + cluster-pool-ipv4-cidr: "{{.PodSubnet }}" cluster-pool-ipv4-mask-size: "24" disable-cnp-status-updates: "true" cgroup-root: "/run/cilium/cgroupv2" @@ -786,7 +790,8 @@ spec: - configMap: name: cilium-config name: cilium-config-path -` +`, +)) // Cilium is the Cilium CNI manager type Cilium struct { @@ -798,6 +803,35 @@ func (c Cilium) String() string { return "Cilium" } +// CIDR returns the default CIDR used by this CNI +func (c Cilium) CIDR() string { + return DefaultPodCIDR +} + +// GenerateKubeadmYAML generates the .yaml file +func GenerateCiliumYAML() ([]byte, error) { + + podCIDR := DefaultPodCIDR + + klog.Infof("Using pod CIDR: %s", podCIDR) + + opts := struct { + PodSubnet string + }{ + PodSubnet: podCIDR, + } + + b := bytes.Buffer{} + configTmpl := ciliumTmpl + + klog.Infof("cilium options: %+v", opts) + if err := configTmpl.Execute(&b, opts); err != nil { + return nil, err + } + klog.Infof("cilium config:\n%s\n", b.String()) + return b.Bytes(), nil +} + // Apply enables the CNI func (c Cilium) Apply(r Runner) error { // see https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy/ @@ -805,10 +839,10 @@ func (c Cilium) Apply(r Runner) error { return errors.Wrap(err, "bpf mount") } - return applyManifest(c.cc, r, manifestAsset([]byte(ciliumTmpl))) -} + ciliumCfg, err := GenerateCiliumYAML() + if err != nil { + return errors.Wrap(err, "generating cilium cfg") + } -// CIDR returns the default CIDR used by this CNI -func (c Cilium) CIDR() string { - return DefaultPodCIDR + return applyManifest(c.cc, r, manifestAsset(ciliumCfg)) } diff --git a/pkg/minikube/command/command_runner.go b/pkg/minikube/command/command_runner.go index 3abd0dbdfc..ca2766adde 100644 --- a/pkg/minikube/command/command_runner.go +++ b/pkg/minikube/command/command_runner.go @@ -189,7 +189,7 @@ func fileExists(r Runner, f assets.CopyableFile, dst string) (bool, error) { return srcModTime.Equal(dstModTime), nil } -// writeFile is like ioutil.WriteFile, but does not require reading file into memory +// writeFile is like os.WriteFile, but does not require reading file into memory func writeFile(dst string, f assets.CopyableFile, perms os.FileMode) error { w, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, perms) if err != nil { diff --git a/pkg/minikube/command/exec_runner.go b/pkg/minikube/command/exec_runner.go index 7d91519776..4ceae15292 100644 --- a/pkg/minikube/command/exec_runner.go +++ b/pkg/minikube/command/exec_runner.go @@ -20,7 +20,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "os/exec" "path" @@ -161,7 +160,7 @@ func (e *execRunner) Copy(f assets.CopyableFile) error { if e.sudo { // write to temp location ... - tmpfile, err := ioutil.TempFile("", "minikube") + tmpfile, err := os.CreateTemp("", "minikube") if err != nil { return errors.Wrapf(err, "error creating tempfile") } diff --git a/pkg/minikube/command/kic_runner.go b/pkg/minikube/command/kic_runner.go index 7156246ff2..b1a3dd2b5d 100644 --- a/pkg/minikube/command/kic_runner.go +++ b/pkg/minikube/command/kic_runner.go @@ -20,7 +20,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "os/exec" "path" @@ -192,7 +191,7 @@ func (k *kicRunner) Copy(f assets.CopyableFile) error { return errors.Wrap(err, "determining temp directory") } - tf, err := ioutil.TempFile(tmpFolder, "tmpf-memory-asset") + tf, err := os.CreateTemp(tmpFolder, "tmpf-memory-asset") if err != nil { return errors.Wrap(err, "creating temporary file") } diff --git a/pkg/minikube/config/config.go b/pkg/minikube/config/config.go index f5c76c6deb..aba63f0b97 100644 --- a/pkg/minikube/config/config.go +++ b/pkg/minikube/config/config.go @@ -20,7 +20,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "github.com/pkg/errors" @@ -211,7 +210,7 @@ func (c *simpleConfigLoader) LoadConfigFromFile(profileName string, miniHome ... return nil, errors.Wrap(err, "stat") } - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { if os.IsPermission(err) { return nil, &ErrPermissionDenied{err.Error()} @@ -231,7 +230,7 @@ func (c *simpleConfigLoader) WriteConfigToFile(profileName string, cc *ClusterCo if err != nil { return err } - return ioutil.WriteFile(path, contents, 0644) + return os.WriteFile(path, contents, 0644) } // MultiNode returns true if the cluster has multiple nodes or if the request is asking for multinode diff --git a/pkg/minikube/config/config_test.go b/pkg/minikube/config/config_test.go index 4b4a196950..374434dc35 100644 --- a/pkg/minikube/config/config_test.go +++ b/pkg/minikube/config/config_test.go @@ -19,7 +19,6 @@ package config import ( "bytes" "fmt" - "io/ioutil" "os" "reflect" "testing" @@ -144,7 +143,7 @@ func TestReadConfig(t *testing.T) { } func TestWriteConfig(t *testing.T) { - configFile, err := ioutil.TempFile("/tmp", "configTest") + configFile, err := os.CreateTemp("/tmp", "configTest") if err != nil { t.Fatalf("Error not expected but got %v", err) } diff --git a/pkg/minikube/config/profile.go b/pkg/minikube/config/profile.go index 167558f15f..155dd891b8 100644 --- a/pkg/minikube/config/profile.go +++ b/pkg/minikube/config/profile.go @@ -19,7 +19,6 @@ package config import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "regexp" @@ -155,13 +154,13 @@ func SaveProfile(name string, cfg *ClusterConfig, miniHome ...string) error { return lock.WriteFile(path, data, 0600) } - tf, err := ioutil.TempFile(filepath.Dir(path), "config.json.tmp") + tf, err := os.CreateTemp(filepath.Dir(path), "config.json.tmp") if err != nil { return err } defer os.Remove(tf.Name()) - if err = ioutil.WriteFile(tf.Name(), data, 0600); err != nil { + if err = os.WriteFile(tf.Name(), data, 0600); err != nil { return err } @@ -295,7 +294,7 @@ func profileDirs(miniHome ...string) (dirs []string, err error) { miniPath = miniHome[0] } pRootDir := filepath.Join(miniPath, "profiles") - items, err := ioutil.ReadDir(pRootDir) + items, err := os.ReadDir(pRootDir) for _, f := range items { if f.IsDir() { dirs = append(dirs, f.Name()) diff --git a/pkg/minikube/config/profile_test.go b/pkg/minikube/config/profile_test.go index 8c778bb393..4b79487228 100644 --- a/pkg/minikube/config/profile_test.go +++ b/pkg/minikube/config/profile_test.go @@ -17,7 +17,6 @@ limitations under the License. package config import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -302,12 +301,12 @@ func TestGetPrimaryControlPlane(t *testing.T) { originalFilePath := profileFilePath(tc.profile, miniDir) tempFilePath := filepath.Join(miniDir, "profiles", tc.profile, "config_temp.json") - d, err := ioutil.ReadFile(originalFilePath) + d, err := os.ReadFile(originalFilePath) if err != nil { t.Fatalf("Failed to read config file : %s", originalFilePath) } - err = ioutil.WriteFile(tempFilePath, d, 0644) + err = os.WriteFile(tempFilePath, d, 0644) if err != nil { t.Fatalf("Failed to write temporal config file : %s", tempFilePath) } diff --git a/pkg/minikube/cruntime/containerd.go b/pkg/minikube/cruntime/containerd.go index ca50cd9892..86b202d3e6 100644 --- a/pkg/minikube/cruntime/containerd.go +++ b/pkg/minikube/cruntime/containerd.go @@ -393,10 +393,6 @@ func downloadRemote(cr CommandRunner, src string) (string, error) { // BuildImage builds an image into this runtime func (r *Containerd) BuildImage(src string, file string, tag string, push bool, env []string, opts []string) error { - if err := r.initBuildkitDaemon(); err != nil { - return fmt.Errorf("failed to init buildkit daemon: %v", err) - } - // download url if not already present dir, err := downloadRemote(r.Runner, src) if err != nil { @@ -456,24 +452,6 @@ func (r *Containerd) PushImage(name string) error { } return nil } -func (r *Containerd) initBuildkitDaemon() error { - // if daemon is already running, do nothing - cmd := exec.Command("pgrep", "buildkitd") - if _, err := r.Runner.RunCmd(cmd); err == nil { - return nil - } - - // otherwise, start daemon - cmd = exec.Command("/bin/bash", "-c", "sudo -b buildkitd --oci-worker false --containerd-worker true --containerd-worker-namespace k8s.io &> /dev/null") - if _, err := r.Runner.RunCmd(cmd); err != nil { - return fmt.Errorf("failed to start buildkit daemon: %v", err) - } - - // give the daemon time to finish starting up or image build will fail - time.Sleep(1 * time.Second) - - return nil -} // CGroupDriver returns cgroup driver ("cgroupfs" or "systemd") func (r *Containerd) CGroupDriver() (string, error) { diff --git a/pkg/minikube/delete/delete.go b/pkg/minikube/delete/delete.go index 48ddd69593..cd6000496c 100644 --- a/pkg/minikube/delete/delete.go +++ b/pkg/minikube/delete/delete.go @@ -28,7 +28,7 @@ import ( "k8s.io/minikube/pkg/minikube/style" ) -// PossibleLeftOvers deletes KIC & non-KIC drivers left +// PossibleLeftOvers deletes KIC driver left overs func PossibleLeftOvers(ctx context.Context, cname string, driverName string) { bin := "" switch driverName { diff --git a/pkg/minikube/download/iso.go b/pkg/minikube/download/iso.go index 08f4042ba1..6370cf2e6d 100644 --- a/pkg/minikube/download/iso.go +++ b/pkg/minikube/download/iso.go @@ -40,7 +40,7 @@ const fileScheme = "file" // DefaultISOURLs returns a list of ISO URL's to consult by default, in priority order func DefaultISOURLs() []string { v := version.GetISOVersion() - isoBucket := "minikube/iso" + isoBucket := "minikube-builds/iso/12081" return []string{ fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.iso", isoBucket, v), fmt.Sprintf("https://github.com/kubernetes/minikube/releases/download/%s/minikube-%s.iso", v, v), diff --git a/pkg/minikube/download/preload.go b/pkg/minikube/download/preload.go index 2141bfd027..287e2b829e 100644 --- a/pkg/minikube/download/preload.go +++ b/pkg/minikube/download/preload.go @@ -21,7 +21,6 @@ import ( "crypto/md5" "encoding/hex" "fmt" - "io/ioutil" "net/http" "os" "path/filepath" @@ -188,7 +187,7 @@ func Preload(k8sVersion, containerRuntime, driverName string) error { if err != nil { klog.Warningf("No checksum for preloaded tarball for k8s version %s: %v", k8sVersion, err) realPath = targetPath - tmp, err := ioutil.TempFile(targetDir(), TarballName(k8sVersion, containerRuntime)+".*") + tmp, err := os.CreateTemp(targetDir(), TarballName(k8sVersion, containerRuntime)+".*") if err != nil { return errors.Wrap(err, "tempfile") } @@ -245,7 +244,7 @@ var getChecksum = func(k8sVersion, containerRuntime string) ([]byte, error) { // saveChecksumFile saves the checksum to a local file for later verification func saveChecksumFile(k8sVersion, containerRuntime string, checksum []byte) error { klog.Infof("saving checksum for %s ...", TarballName(k8sVersion, containerRuntime)) - return ioutil.WriteFile(PreloadChecksumPath(k8sVersion, containerRuntime), checksum, 0o644) + return os.WriteFile(PreloadChecksumPath(k8sVersion, containerRuntime), checksum, 0o644) } // verifyChecksum returns true if the checksum of the local binary matches @@ -253,13 +252,13 @@ func saveChecksumFile(k8sVersion, containerRuntime string, checksum []byte) erro func verifyChecksum(k8sVersion, containerRuntime, path string) error { klog.Infof("verifying checksumm of %s ...", path) // get md5 checksum of tarball path - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return errors.Wrap(err, "reading tarball") } checksum := md5.Sum(contents) - remoteChecksum, err := ioutil.ReadFile(PreloadChecksumPath(k8sVersion, containerRuntime)) + remoteChecksum, err := os.ReadFile(PreloadChecksumPath(k8sVersion, containerRuntime)) if err != nil { return errors.Wrap(err, "reading checksum file") } diff --git a/pkg/minikube/driver/driver_test.go b/pkg/minikube/driver/driver_test.go index 4691555b05..021f78c74c 100644 --- a/pkg/minikube/driver/driver_test.go +++ b/pkg/minikube/driver/driver_test.go @@ -18,7 +18,6 @@ package driver import ( "fmt" - "io/ioutil" "os" "testing" @@ -91,7 +90,7 @@ func TestFlagDefaults(t *testing.T) { t.Errorf("defaults mismatch (-want +got):\n%s", diff) } - tf, err := ioutil.TempFile("", "resolv.conf") + tf, err := os.CreateTemp("", "resolv.conf") if err != nil { t.Fatalf("tempfile: %v", err) } diff --git a/pkg/minikube/extract/extract.go b/pkg/minikube/extract/extract.go index 425d7f1516..d5b6013372 100644 --- a/pkg/minikube/extract/extract.go +++ b/pkg/minikube/extract/extract.go @@ -22,7 +22,6 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" "net/url" "os" "path/filepath" @@ -161,7 +160,7 @@ func shouldCheckFile(path string) bool { // inspectFile goes through the given file line by line looking for translatable strings func inspectFile(e *state) error { fset := token.NewFileSet() - r, err := ioutil.ReadFile(e.filename) + r, err := os.ReadFile(e.filename) if err != nil { return err } @@ -451,7 +450,7 @@ func writeStringsToFiles(e *state, output string) error { } fmt.Printf("Writing to %s", filepath.Base(path)) currentTranslations := make(map[string]interface{}) - f, err := ioutil.ReadFile(path) + f, err := os.ReadFile(path) if err != nil { return errors.Wrap(err, "reading translation file") } @@ -491,7 +490,7 @@ func writeStringsToFiles(e *state, output string) error { if err != nil { return errors.Wrap(err, "marshalling translations") } - err = ioutil.WriteFile(path, c, info.Mode()) + err = os.WriteFile(path, c, info.Mode()) if err != nil { return errors.Wrap(err, "writing translation file") } @@ -509,7 +508,7 @@ func writeStringsToFiles(e *state, output string) error { return errors.Wrap(err, "marshalling translations") } path := filepath.Join(output, "strings.txt") - err = ioutil.WriteFile(path, c, 0644) + err = os.WriteFile(path, c, 0644) if err != nil { return errors.Wrap(err, "writing translation file") } diff --git a/pkg/minikube/extract/extract_test.go b/pkg/minikube/extract/extract_test.go index 0d0e96c4c6..4217d4840b 100644 --- a/pkg/minikube/extract/extract_test.go +++ b/pkg/minikube/extract/extract_test.go @@ -19,7 +19,6 @@ package extract import ( "encoding/json" "errors" - "io/ioutil" "os" "path/filepath" "reflect" @@ -33,7 +32,7 @@ func TestExtract(t *testing.T) { // The function we care about functions := []string{"extract.PrintToScreen"} - tempdir, err := ioutil.TempDir("", "temptestdata") + tempdir, err := os.MkdirTemp("", "temptestdata") if err != nil { t.Fatalf("Creating temp dir: %v", err) } @@ -44,13 +43,13 @@ func TestExtract(t *testing.T) { } }() - src, err := ioutil.ReadFile("testdata/test.json") + src, err := os.ReadFile("testdata/test.json") if err != nil { t.Fatalf("Reading json file: %v", err) } tempfile := filepath.Join(tempdir, "tmpdata.json") - err = ioutil.WriteFile(tempfile, src, 0666) + err = os.WriteFile(tempfile, src, 0666) if err != nil { t.Fatalf("Writing temp json file: %v", err) } @@ -68,7 +67,7 @@ func TestExtract(t *testing.T) { t.Fatalf("Error translating strings: %v", err) } - f, err := ioutil.ReadFile(tempfile) + f, err := os.ReadFile(tempfile) if err != nil { t.Fatalf("Reading resulting json file: %v", err) } diff --git a/pkg/minikube/image/cache.go b/pkg/minikube/image/cache.go index 03bd1dcdc0..a6085c0565 100644 --- a/pkg/minikube/image/cache.go +++ b/pkg/minikube/image/cache.go @@ -17,7 +17,6 @@ limitations under the License. package image import ( - "io/ioutil" "os" "path/filepath" "time" @@ -160,7 +159,7 @@ func saveToTarFile(iname, rawDest string, overwrite bool) error { func writeImage(img v1.Image, dst string, ref name.Reference) error { klog.Infoln("opening: ", dst) - f, err := ioutil.TempFile(filepath.Dir(dst), filepath.Base(dst)+".*.tmp") + f, err := os.CreateTemp(filepath.Dir(dst), filepath.Base(dst)+".*.tmp") if err != nil { return err } diff --git a/pkg/minikube/image/image.go b/pkg/minikube/image/image.go index e376530d10..aea60c1a52 100644 --- a/pkg/minikube/image/image.go +++ b/pkg/minikube/image/image.go @@ -19,7 +19,6 @@ package image import ( "context" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -289,7 +288,7 @@ func cleanImageCacheDir() error { return nil } // If directory is empty, delete it - entries, err := ioutil.ReadDir(path) + entries, err := os.ReadDir(path) if err != nil { return err } diff --git a/pkg/minikube/kubeconfig/context_test.go b/pkg/minikube/kubeconfig/context_test.go index a7bcc4af30..77b1fca070 100644 --- a/pkg/minikube/kubeconfig/context_test.go +++ b/pkg/minikube/kubeconfig/context_test.go @@ -17,7 +17,6 @@ limitations under the License. package kubeconfig import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -50,7 +49,7 @@ func TestDeleteContext(t *testing.T) { } func TestSetCurrentContext(t *testing.T) { - f, err := ioutil.TempFile("/tmp", "kubeconfig") + f, err := os.CreateTemp("/tmp", "kubeconfig") if err != nil { t.Fatalf("Error not expected but got %v", err) } diff --git a/pkg/minikube/kubeconfig/kubeconfig.go b/pkg/minikube/kubeconfig/kubeconfig.go index 25317fce23..f5242471fc 100644 --- a/pkg/minikube/kubeconfig/kubeconfig.go +++ b/pkg/minikube/kubeconfig/kubeconfig.go @@ -18,7 +18,6 @@ package kubeconfig import ( "fmt" - "io/ioutil" "net/url" "os" "path" @@ -201,7 +200,7 @@ func readOrNew(configPath ...string) (*api.Config, error) { fPath = configPath[0] } - data, err := ioutil.ReadFile(fPath) + data, err := os.ReadFile(fPath) if os.IsNotExist(err) { return api.NewConfig(), nil } else if err != nil { diff --git a/pkg/minikube/kubeconfig/kubeconfig_test.go b/pkg/minikube/kubeconfig/kubeconfig_test.go index 7cc8c7390e..0ee7095dd3 100644 --- a/pkg/minikube/kubeconfig/kubeconfig_test.go +++ b/pkg/minikube/kubeconfig/kubeconfig_test.go @@ -17,7 +17,6 @@ limitations under the License. package kubeconfig import ( - "io/ioutil" "os" "path/filepath" "strconv" @@ -229,7 +228,7 @@ func TestUpdate(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("Error making temp directory %v", err) } @@ -242,7 +241,7 @@ func TestUpdate(t *testing.T) { test.cfg.SetPath(filepath.Join(tmpDir, "kubeconfig")) if len(test.existingCfg) != 0 { - if err := ioutil.WriteFile(test.cfg.filePath(), test.existingCfg, 0600); err != nil { + if err := os.WriteFile(test.cfg.filePath(), test.existingCfg, 0600); err != nil { t.Fatalf("WriteFile: %v", err) } } @@ -460,7 +459,7 @@ func TestEmptyConfig(t *testing.T) { } func TestNewConfig(t *testing.T) { - dir, err := ioutil.TempDir("", ".kube") + dir, err := os.MkdirTemp("", ".kube") if err != nil { t.Fatal(err) } @@ -537,7 +536,7 @@ func Test_Endpoint(t *testing.T) { // tempFile creates a temporary with the provided bytes as its contents. // The caller is responsible for deleting file after use. func tempFile(t *testing.T, data []byte) string { - tmp, err := ioutil.TempFile("", "kubeconfig") + tmp, err := os.CreateTemp("", "kubeconfig") if err != nil { t.Fatal(err) } diff --git a/pkg/minikube/kubeconfig/settings.go b/pkg/minikube/kubeconfig/settings.go index 2d206c390b..da4077e028 100644 --- a/pkg/minikube/kubeconfig/settings.go +++ b/pkg/minikube/kubeconfig/settings.go @@ -17,7 +17,7 @@ limitations under the License. package kubeconfig import ( - "io/ioutil" + "os" "path/filepath" "sync/atomic" @@ -83,7 +83,7 @@ func PopulateFromSettings(cfg *Settings, apiCfg *api.Config) error { cluster := api.NewCluster() cluster.Server = cfg.ClusterServerAddress if cfg.EmbedCerts { - cluster.CertificateAuthorityData, err = ioutil.ReadFile(cfg.CertificateAuthority) + cluster.CertificateAuthorityData, err = os.ReadFile(cfg.CertificateAuthority) if err != nil { return errors.Wrapf(err, "reading CertificateAuthority %s", cfg.CertificateAuthority) } @@ -100,11 +100,11 @@ func PopulateFromSettings(cfg *Settings, apiCfg *api.Config) error { userName := cfg.ClusterName user := api.NewAuthInfo() if cfg.EmbedCerts { - user.ClientCertificateData, err = ioutil.ReadFile(cfg.ClientCertificate) + user.ClientCertificateData, err = os.ReadFile(cfg.ClientCertificate) if err != nil { return errors.Wrapf(err, "reading ClientCertificate %s", cfg.ClientCertificate) } - user.ClientKeyData, err = ioutil.ReadFile(cfg.ClientKey) + user.ClientKeyData, err = os.ReadFile(cfg.ClientKey) if err != nil { return errors.Wrapf(err, "reading ClientKey %s", cfg.ClientKey) } diff --git a/pkg/minikube/localpath/localpath_test.go b/pkg/minikube/localpath/localpath_test.go index 07dead3b45..02da464d26 100644 --- a/pkg/minikube/localpath/localpath_test.go +++ b/pkg/minikube/localpath/localpath_test.go @@ -18,7 +18,6 @@ package localpath import ( "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -29,7 +28,7 @@ import ( ) func TestReplaceWinDriveLetterToVolumeName(t *testing.T) { - path, err := ioutil.TempDir("", "repwindl2vn") + path, err := os.MkdirTemp("", "repwindl2vn") if err != nil { t.Fatalf("Error make tmp directory: %v", err) } diff --git a/pkg/minikube/machine/cache_binaries_test.go b/pkg/minikube/machine/cache_binaries_test.go index 994a2a868f..8359fbf1fc 100644 --- a/pkg/minikube/machine/cache_binaries_test.go +++ b/pkg/minikube/machine/cache_binaries_test.go @@ -18,7 +18,6 @@ package machine import ( "fmt" - "io/ioutil" "os" "strings" "testing" @@ -89,7 +88,7 @@ func TestCacheBinariesForBootstrapper(t *testing.T) { oldMinikubeHome := os.Getenv("MINIKUBE_HOME") defer os.Setenv("MINIKUBE_HOME", oldMinikubeHome) - minikubeHome, err := ioutil.TempDir("/tmp", "") + minikubeHome, err := os.MkdirTemp("/tmp", "") if err != nil { t.Fatalf("error during creating tmp dir: %v", err) } @@ -148,7 +147,7 @@ func TestExcludedBinariesNotDownloaded(t *testing.T) { oldMinikubeHome := os.Getenv("MINIKUBE_HOME") defer os.Setenv("MINIKUBE_HOME", oldMinikubeHome) - minikubeHome, err := ioutil.TempDir("/tmp", "") + minikubeHome, err := os.MkdirTemp("/tmp", "") if err != nil { t.Fatalf("error during creating tmp dir: %v", err) } diff --git a/pkg/minikube/machine/info.go b/pkg/minikube/machine/info.go index 10b8035d50..e1a897d0c6 100644 --- a/pkg/minikube/machine/info.go +++ b/pkg/minikube/machine/info.go @@ -18,7 +18,7 @@ package machine import ( "errors" - "io/ioutil" + "os" "os/exec" "strconv" "strings" @@ -105,7 +105,7 @@ func RemoteHostInfo(r command.Runner) (*HostInfo, error, error, error) { // showLocalOsRelease shows systemd information about the current linux distribution, on the local host func showLocalOsRelease() { - osReleaseOut, err := ioutil.ReadFile("/etc/os-release") + osReleaseOut, err := os.ReadFile("/etc/os-release") if err != nil { klog.Errorf("ReadFile: %v", err) return diff --git a/pkg/minikube/machine/start_test.go b/pkg/minikube/machine/start_test.go index fa9c878e0c..7798ed01a2 100644 --- a/pkg/minikube/machine/start_test.go +++ b/pkg/minikube/machine/start_test.go @@ -18,7 +18,6 @@ package machine import ( "fmt" - "io/ioutil" "net" "os" "testing" @@ -67,7 +66,7 @@ func TestAddHostAliasInner(t *testing.T) { t.Error(err) } - buff, err := ioutil.ReadFile(tempFilePath) + buff, err := os.ReadFile(tempFilePath) if err != nil { t.Error(err) } @@ -81,7 +80,7 @@ func TestAddHostAliasInner(t *testing.T) { } func writeContentToTempFile(content string) (string, error) { - etcHosts, err := ioutil.TempFile("", "hosts") + etcHosts, err := os.CreateTemp("", "hosts") if err != nil { return "", err } diff --git a/pkg/minikube/node/config.go b/pkg/minikube/node/config.go index 5d3d926e73..81ebe1011b 100644 --- a/pkg/minikube/node/config.go +++ b/pkg/minikube/node/config.go @@ -65,7 +65,8 @@ func configureMounts(wg *sync.WaitGroup) { if klog.V(8).Enabled() { mountDebugVal = 1 } - mountCmd := exec.Command(path, "mount", fmt.Sprintf("--v=%d", mountDebugVal), viper.GetString(mountString)) + profile := viper.GetString("profile") + mountCmd := exec.Command(path, "mount", "-p", profile, fmt.Sprintf("--v=%d", mountDebugVal), viper.GetString(mountString)) mountCmd.Env = append(os.Environ(), constants.IsMinikubeChildProcess+"=true") if klog.V(8).Enabled() { mountCmd.Stdout = os.Stdout @@ -74,7 +75,7 @@ func configureMounts(wg *sync.WaitGroup) { if err := mountCmd.Start(); err != nil { exit.Error(reason.GuestMount, "Error starting mount", err) } - if err := lock.WriteFile(filepath.Join(localpath.MiniPath(), constants.MountProcessFileName), []byte(strconv.Itoa(mountCmd.Process.Pid)), 0o644); err != nil { + if err := lock.WriteFile(filepath.Join(localpath.Profile(profile), constants.MountProcessFileName), []byte(strconv.Itoa(mountCmd.Process.Pid)), 0o644); err != nil { exit.Error(reason.HostMountPid, "Error writing mount pid", err) } } diff --git a/pkg/minikube/notify/notify.go b/pkg/minikube/notify/notify.go index 4e1a77569d..4785838259 100644 --- a/pkg/minikube/notify/notify.go +++ b/pkg/minikube/notify/notify.go @@ -19,8 +19,8 @@ package notify import ( "encoding/json" "fmt" - "io/ioutil" "net/http" + "os" "runtime" "strings" "time" @@ -185,7 +185,7 @@ func writeTimeToFile(path string, inputTime time.Time) error { } func timeFromFileIfExists(path string) time.Time { - lastUpdateCheckTime, err := ioutil.ReadFile(path) + lastUpdateCheckTime, err := os.ReadFile(path) if err != nil { return time.Time{} } diff --git a/pkg/minikube/notify/notify_test.go b/pkg/minikube/notify/notify_test.go index 839e559a78..da078706d3 100644 --- a/pkg/minikube/notify/notify_test.go +++ b/pkg/minikube/notify/notify_test.go @@ -19,7 +19,6 @@ package notify import ( "encoding/json" "fmt" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -223,7 +222,7 @@ func TestMaybePrintUpdateText(t *testing.T) { viper.Set(config.WantBetaUpdateNotification, tt.wantBetaUpdateNotification) lastUpdateCheckFilePath = filepath.Join(tempDir, "last_update_check") - tmpfile, err := ioutil.TempFile("", "") + tmpfile, err := os.CreateTemp("", "") if err != nil { t.Fatalf("Cannot create temp file: %v", err) } diff --git a/pkg/minikube/out/out.go b/pkg/minikube/out/out.go index 01dd5318de..8c45898741 100644 --- a/pkg/minikube/out/out.go +++ b/pkg/minikube/out/out.go @@ -23,7 +23,6 @@ import ( "html" "html/template" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -382,7 +381,7 @@ func displayError(msg string, err error) { func latestLogFilePath() (string, error) { tmpdir := os.TempDir() - files, err := ioutil.ReadDir(tmpdir) + files, err := os.ReadDir(tmpdir) if err != nil { return "", fmt.Errorf("failed to get list of files in tempdir: %v", err) } @@ -392,11 +391,15 @@ func latestLogFilePath() (string, error) { if !strings.Contains(file.Name(), "minikube_") { continue } - if !lastModTime.IsZero() && lastModTime.After(file.ModTime()) { + fileInfo, err := file.Info() + if err != nil { + return "", fmt.Errorf("failed to get file info: %v", err) + } + if !lastModTime.IsZero() && lastModTime.After(fileInfo.ModTime()) { continue } lastModName = file.Name() - lastModTime = file.ModTime() + lastModTime = fileInfo.ModTime() } fullPath := filepath.Join(tmpdir, lastModName) diff --git a/pkg/minikube/registry/drvs/ssh/ssh.go b/pkg/minikube/registry/drvs/ssh/ssh.go index 8985143b61..8308cf9005 100644 --- a/pkg/minikube/registry/drvs/ssh/ssh.go +++ b/pkg/minikube/registry/drvs/ssh/ssh.go @@ -18,6 +18,9 @@ package ssh import ( "fmt" + "os" + "path/filepath" + "strings" "github.com/docker/machine/libmachine/drivers" "github.com/pkg/errors" @@ -63,7 +66,17 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { d.IPAddress = cc.SSHIPAddress d.SSHUser = cc.SSHUser - d.SSHKey = cc.SSHKey + + if strings.HasPrefix(cc.SSHKey, "~") { + dirname, err := os.UserHomeDir() + if err != nil { + return nil, errors.Errorf("Error determining path to ssh key: %v", err) + } + d.SSHKey = filepath.Join(dirname, cc.SSHKey[1:]) + } else { + d.SSHKey = cc.SSHKey + } + d.SSHPort = cc.SSHPort return d, nil diff --git a/pkg/minikube/schedule/daemonize_unix.go b/pkg/minikube/schedule/daemonize_unix.go index 7c38e80ddb..2544fdd651 100644 --- a/pkg/minikube/schedule/daemonize_unix.go +++ b/pkg/minikube/schedule/daemonize_unix.go @@ -21,7 +21,6 @@ package schedule import ( "fmt" - "io/ioutil" "os" "strconv" "time" @@ -51,7 +50,7 @@ func KillExisting(profiles []string) { func killPIDForProfile(profile string) error { file := localpath.PID(profile) - f, err := ioutil.ReadFile(file) + f, err := os.ReadFile(file) if os.IsNotExist(err) { return nil } @@ -91,7 +90,7 @@ func daemonize(profiles []string, duration time.Duration) error { func savePIDs(pid int, profiles []string) error { for _, p := range profiles { file := localpath.PID(p) - if err := ioutil.WriteFile(file, []byte(fmt.Sprintf("%v", pid)), 0600); err != nil { + if err := os.WriteFile(file, []byte(fmt.Sprintf("%v", pid)), 0600); err != nil { return err } } diff --git a/pkg/minikube/service/service_test.go b/pkg/minikube/service/service_test.go index fe2aade3b8..5f79facee1 100644 --- a/pkg/minikube/service/service_test.go +++ b/pkg/minikube/service/service_test.go @@ -20,7 +20,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "os" "reflect" "strings" @@ -612,7 +611,7 @@ users: t.Run(test.description, func(t *testing.T) { mockK8sConfigByte := []byte(test.config) mockK8sConfigPath := test.kubeconfigPath - err := ioutil.WriteFile(mockK8sConfigPath, mockK8sConfigByte, 0644) + err := os.WriteFile(mockK8sConfigPath, mockK8sConfigByte, 0644) defer os.Remove(mockK8sConfigPath) if err != nil { t.Fatalf("Unexpected error when writing to file %v. Error: %v", test.kubeconfigPath, err) diff --git a/pkg/minikube/storageclass/storageclass_test.go b/pkg/minikube/storageclass/storageclass_test.go index a3b76772e8..246b800e3c 100644 --- a/pkg/minikube/storageclass/storageclass_test.go +++ b/pkg/minikube/storageclass/storageclass_test.go @@ -19,7 +19,6 @@ package storageclass import ( "context" "fmt" - "io/ioutil" "os" "strings" "testing" @@ -229,7 +228,7 @@ func TestGetStoragev1(t *testing.T) { err: true, }, } - configFile, err := ioutil.TempFile("/tmp", "") + configFile, err := os.CreateTemp("/tmp", "") if err != nil { t.Fatalf(err.Error()) } @@ -255,7 +254,7 @@ func TestGetStoragev1(t *testing.T) { func setK8SConfig(config, kubeconfigPath string) error { mockK8sConfigByte := []byte(config) mockK8sConfigPath := kubeconfigPath - err := ioutil.WriteFile(mockK8sConfigPath, mockK8sConfigByte, 0644) + err := os.WriteFile(mockK8sConfigPath, mockK8sConfigByte, 0644) if err != nil { return fmt.Errorf("Unexpected error when writing to file %v. Error: %v", kubeconfigPath, err) } diff --git a/pkg/minikube/tests/dir_utils.go b/pkg/minikube/tests/dir_utils.go index 7cf9ba2f48..b80ed2d00e 100644 --- a/pkg/minikube/tests/dir_utils.go +++ b/pkg/minikube/tests/dir_utils.go @@ -18,7 +18,6 @@ package tests import ( "bytes" - "io/ioutil" "log" "os" "path/filepath" @@ -28,7 +27,7 @@ import ( // MakeTempDir creates the temp dir and returns the path func MakeTempDir() string { - tempDir, err := ioutil.TempDir("", "minipath") + tempDir, err := os.MkdirTemp("", "minipath") if err != nil { log.Fatal(err) } diff --git a/pkg/minikube/tunnel/registry.go b/pkg/minikube/tunnel/registry.go index c520357f6e..2bf3ec03be 100644 --- a/pkg/minikube/tunnel/registry.go +++ b/pkg/minikube/tunnel/registry.go @@ -19,7 +19,7 @@ package tunnel import ( "encoding/json" "fmt" - "io/ioutil" + "io" "os" "github.com/pkg/errors" @@ -186,7 +186,7 @@ func (r *persistentRegistry) List() ([]*ID, error) { } return []*ID{}, nil } - byteValue, _ := ioutil.ReadAll(f) + byteValue, _ := io.ReadAll(f) var tunnels []*ID if len(byteValue) == 0 { return tunnels, nil diff --git a/pkg/minikube/tunnel/registry_test.go b/pkg/minikube/tunnel/registry_test.go index 9240908ee2..89c66f822f 100644 --- a/pkg/minikube/tunnel/registry_test.go +++ b/pkg/minikube/tunnel/registry_test.go @@ -17,7 +17,6 @@ limitations under the License. package tunnel import ( - "io/ioutil" "os" "reflect" "testing" @@ -246,7 +245,7 @@ func TestTunnelTakeoverFromNonRunningProcess(t *testing.T) { func tmpFile(t *testing.T) string { t.Helper() - f, err := ioutil.TempFile(os.TempDir(), "reg_") + f, err := os.CreateTemp(os.TempDir(), "reg_") f.Close() if err != nil { t.Errorf("failed to create temp file %s", err) @@ -255,7 +254,7 @@ func tmpFile(t *testing.T) string { } func createTestRegistry(t *testing.T) (reg *persistentRegistry, cleanup func()) { - f, err := ioutil.TempFile(os.TempDir(), "reg_") + f, err := os.CreateTemp(os.TempDir(), "reg_") f.Close() if err != nil { t.Errorf("failed to create temp file %s", err) diff --git a/pkg/minikube/tunnel/route_darwin.go b/pkg/minikube/tunnel/route_darwin.go index 7583bf2ce7..65891de2df 100644 --- a/pkg/minikube/tunnel/route_darwin.go +++ b/pkg/minikube/tunnel/route_darwin.go @@ -18,7 +18,6 @@ package tunnel import ( "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -187,7 +186,7 @@ func writeResolverFile(route *Route) error { klog.Infof("preparing DNS forwarding config in %q:\n%s", resolverFile, content) // write resolver content into tf, then copy it to /etc/resolver/clusterDomain - tf, err := ioutil.TempFile("", "minikube-tunnel-resolver-") + tf, err := os.CreateTemp("", "minikube-tunnel-resolver-") if err != nil { return errors.Wrap(err, "tempfile") } diff --git a/pkg/minikube/tunnel/tunnel_test.go b/pkg/minikube/tunnel/tunnel_test.go index c017fd7aac..b3f72a2bc3 100644 --- a/pkg/minikube/tunnel/tunnel_test.go +++ b/pkg/minikube/tunnel/tunnel_test.go @@ -25,7 +25,6 @@ import ( "k8s.io/minikube/pkg/minikube/tests" "fmt" - "io/ioutil" "os" "reflect" "strings" @@ -485,7 +484,7 @@ func TestErrorCreatingTunnel(t *testing.T) { e: errors.New("error loading machine"), } - f, err := ioutil.TempFile(os.TempDir(), "reg_") + f, err := os.CreateTemp(os.TempDir(), "reg_") f.Close() if err != nil { t.Errorf("failed to create temp file %s", err) diff --git a/pkg/util/crypto.go b/pkg/util/crypto.go index 5222957390..96151cf470 100644 --- a/pkg/util/crypto.go +++ b/pkg/util/crypto.go @@ -23,7 +23,6 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" - "io/ioutil" "math/big" "net" "os" @@ -67,7 +66,7 @@ func GenerateCACert(certPath, keyPath string, name string) error { // GenerateSignedCert generates a signed certificate and key func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string, expiration time.Duration) error { klog.Infof("Generating cert %s with IP's: %s", certPath, ips) - signerCertBytes, err := ioutil.ReadFile(signerCertPath) + signerCertBytes, err := os.ReadFile(signerCertPath) if err != nil { return errors.Wrap(err, "Error reading file: signerCertPath") } @@ -79,7 +78,7 @@ func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS if err != nil { return errors.Wrap(err, "Error parsing certificate: decodedSignerCert.Bytes") } - signerKeyBytes, err := ioutil.ReadFile(signerKeyPath) + signerKeyBytes, err := os.ReadFile(signerKeyPath) if err != nil { return errors.Wrap(err, "Error reading file: signerKeyPath") } @@ -118,7 +117,7 @@ func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS } func loadOrGeneratePrivateKey(keyPath string) (*rsa.PrivateKey, error) { - keyBytes, err := ioutil.ReadFile(keyPath) + keyBytes, err := os.ReadFile(keyPath) if err == nil { decodedKey, _ := pem.Decode(keyBytes) if decodedKey != nil { diff --git a/pkg/util/crypto_test.go b/pkg/util/crypto_test.go index b6db864368..d8773778d3 100644 --- a/pkg/util/crypto_test.go +++ b/pkg/util/crypto_test.go @@ -19,7 +19,6 @@ package util import ( "crypto/x509" "encoding/pem" - "io/ioutil" "net" "os" "path/filepath" @@ -29,7 +28,7 @@ import ( ) func TestGenerateCACert(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") defer func() { // clean up tempdir err := os.RemoveAll(tmpDir) if err != nil { @@ -47,7 +46,7 @@ func TestGenerateCACert(t *testing.T) { } // Check the cert has the right shape. - certBytes, err := ioutil.ReadFile(certPath) + certBytes, err := os.ReadFile(certPath) if err != nil { t.Fatalf("Error reading cert data: %v", err) } @@ -62,7 +61,7 @@ func TestGenerateCACert(t *testing.T) { } func TestGenerateSignedCert(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") defer func() { // clean up tempdir err := os.RemoveAll(tmpDir) if err != nil { @@ -73,7 +72,7 @@ func TestGenerateSignedCert(t *testing.T) { t.Fatalf("Error generating tmpdir: %v", err) } - signerTmpDir, err := ioutil.TempDir("", "") + signerTmpDir, err := os.MkdirTemp("", "") defer func() { // clean up tempdir err := os.RemoveAll(signerTmpDir) if err != nil { @@ -149,7 +148,7 @@ func TestGenerateSignedCert(t *testing.T) { t.Errorf("GenerateSignedCert() should have returned error, but didn't") } if err == nil { - certBytes, err := ioutil.ReadFile(certPath) + certBytes, err := os.ReadFile(certPath) if err != nil { t.Errorf("Error reading cert data: %v", err) } diff --git a/pkg/util/lock/lock.go b/pkg/util/lock/lock.go index c1facc8c6f..84158a2289 100644 --- a/pkg/util/lock/lock.go +++ b/pkg/util/lock/lock.go @@ -19,7 +19,6 @@ package lock import ( "crypto/sha1" "fmt" - "io/ioutil" "os" "time" @@ -30,7 +29,7 @@ import ( "k8s.io/klog/v2" ) -// WriteFile decorates ioutil.WriteFile with a file lock and retry +// WriteFile decorates os.WriteFile with a file lock and retry func WriteFile(filename string, data []byte, perm os.FileMode) error { spec := PathMutexSpec(filename) klog.Infof("WriteFile acquiring %s: %+v", filename, spec) @@ -41,7 +40,7 @@ func WriteFile(filename string, data []byte, perm os.FileMode) error { defer releaser.Release() - return ioutil.WriteFile(filename, data, perm) + return os.WriteFile(filename, data, perm) } // PathMutexSpec returns a mutex spec for a path diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go index f0fc06cc6d..81ded7d025 100644 --- a/pkg/util/utils_test.go +++ b/pkg/util/utils_test.go @@ -17,7 +17,6 @@ limitations under the License. package util import ( - "io/ioutil" "os" "os/user" "runtime" @@ -81,7 +80,7 @@ func TestParseKubernetesVersion(t *testing.T) { } func TestChownR(t *testing.T) { - testDir, err := ioutil.TempDir(os.TempDir(), "") + testDir, err := os.MkdirTemp(os.TempDir(), "") if nil != err { return } @@ -134,7 +133,7 @@ func TestChownR(t *testing.T) { } func TestMaybeChownDirRecursiveToMinikubeUser(t *testing.T) { - testDir, err := ioutil.TempDir(os.TempDir(), "") + testDir, err := os.MkdirTemp(os.TempDir(), "") if nil != err { return } diff --git a/site/content/en/docs/commands/options.md b/site/content/en/docs/commands/options.md index 9536ffb349..ba0f2f43a8 100644 --- a/site/content/en/docs/commands/options.md +++ b/site/content/en/docs/commands/options.md @@ -5,7 +5,6 @@ description: > --- - ## minikube options Show a list of global command-line options (applies to all commands). @@ -14,27 +13,29 @@ Show a list of global command-line options (applies to all commands). Show a list of global command-line options (applies to all commands). -``` +```shell minikube options [flags] ``` -### Options - -``` - -h, --help help for options -``` - ### Options inherited from parent commands ``` + --add_dir_header If true, adds the file directory to the header of the log messages --alsologtostderr log to standard error as well as files - -b, --bootstrapper string The name of the cluster bootstrapper that will set up the kubernetes cluster. (default "kubeadm") + -b, --bootstrapper string The name of the cluster bootstrapper that will set up the Kubernetes cluster. (default "kubeadm") + -h, --help --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) --log_dir string If non-empty, write log files in this directory + --log_file string If non-empty, use this log file + --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) --logtostderr log to standard error instead of files + --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) -p, --profile string The name of the minikube VM being used. This can be set to allow having multiple instances of minikube independently. (default "minikube") + --skip_headers If true, avoid header prefixes in the log messages + --skip_log_headers If true, avoid headers when opening log files --stderrthreshold severity logs at or above this threshold go to stderr (default 2) - -v, --v Level log level for V logs + --user string Specifies the user executing the operation. Useful for auditing operations executed by 3rd party tools. Defaults to the operating system username. + -v, --v Level number for the log level verbosity --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging ``` diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md index bcccd4091e..fdf64a0c61 100644 --- a/site/content/en/docs/commands/start.md +++ b/site/content/en/docs/commands/start.md @@ -26,7 +26,7 @@ minikube start [flags] --apiserver-names strings A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine --apiserver-port int The apiserver listening port (default 8443) --auto-update-drivers If set, automatically updates drivers to the latest version. Defaults to true. (default true) - --base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase:v0.0.27@sha256:89b4738ee74ba28684676e176752277f0db46f57d27f0e08c3feec89311e22de") + --base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase-builds:v0.0.27-1633027942-12081@sha256:4780f1897569d2bf77aafb3d133a08d42b4fe61127f06fcfc90c2c5d902d893c") --cache-images If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none. (default true) --cert-expiration duration Duration until minikube certificate expiration, defaults to three years (26280h). (default 26280h0m0s) --cni string CNI plug-in to use. Valid options: auto, bridge, calico, cilium, flannel, kindnet, or path to a CNI manifest (default: auto) @@ -66,7 +66,7 @@ minikube start [flags] --insecure-registry strings Insecure Docker registries to pass to the Docker daemon. The default service CIDR range will automatically be added. --install-addons If set, install addons. Defaults to true. (default true) --interactive Allow user prompts for more information (default true) - --iso-url strings Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube/iso/minikube-v1.23.1.iso,https://github.com/kubernetes/minikube/releases/download/v1.23.1/minikube-v1.23.1.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.23.1.iso]) + --iso-url strings Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube-builds/iso/12081/minikube-v1.23.1-1633115168-12081.iso,https://github.com/kubernetes/minikube/releases/download/v1.23.1-1633115168-12081/minikube-v1.23.1-1633115168-12081.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.23.1-1633115168-12081.iso]) --keep-context This will keep the existing kubectl context and will create a minikube context. --kubernetes-version string The Kubernetes version that the minikube VM will use (ex: v1.2.3, 'stable' for v1.22.2, 'latest' for v1.22.3-rc.0). Defaults to 'stable'. --kvm-gpu Enable experimental NVIDIA GPU support in minikube diff --git a/site/content/en/docs/contrib/test_flakes.en.md b/site/content/en/docs/contrib/test_flakes.en.md index febd82bf33..6be126624c 100644 --- a/site/content/en/docs/contrib/test_flakes.en.md +++ b/site/content/en/docs/contrib/test_flakes.en.md @@ -20,3 +20,4 @@ description: > |MacOS|docker|docker|[Docker_macOS](https://storage.googleapis.com/minikube-flake-rate/flake_chart.html?env=Docker_macOS)| |MacOS|hyperkit|docker|[Hyperkit_macOS](https://storage.googleapis.com/minikube-flake-rate/flake_chart.html?env=Hyperkit_macOS)| |Windows|docker|docker|[Docker_Windows](https://storage.googleapis.com/minikube-flake-rate/flake_chart.html?env=Docker_Windows)| +|Windows|hyperv|docker|[Hyper-V_Windows](https://storage.googleapis.com/minikube-flake-rate/flake_chart.html?env=Hyper-V_Windows)| diff --git a/site/content/en/docs/contrib/tests.en.md b/site/content/en/docs/contrib/tests.en.md index b33a96a8ec..8fdaf64777 100644 --- a/site/content/en/docs/contrib/tests.en.md +++ b/site/content/en/docs/contrib/tests.en.md @@ -83,18 +83,63 @@ are functionality tests which can safely share a profile in parallel #### validateNodeLabels checks if minikube cluster is created with correct kubernetes's node label +Steps: +- Get the node labels from the cluster with `kubectl get nodes` +- check if the node labels matches with the expected Minikube labels: `minikube.k8s.io/*` + #### validateImageCommands runs tests on all the `minikube image` commands, ex. `minikube image load`, `minikube image list`, etc. +Steps: +- Make sure image listing works by `minikube image ls` +- Make sure image building works by `minikube image build` +- Make sure image loading from Docker daemon works by `minikube image load --daemon` +- Make sure image saving works by `minikube image load --daemon` +- Make sure image removal works by `minikube image rm` +- Make sure image loading from file works by `minikube image load` +- Make sure image saving to Docker daemon works by `minikube image load` + +Skips: +- Skips on `none` driver as image loading is not supported +- Skips on GitHub Actions and macOS as this test case requires a running docker daemon + #### validateDockerEnv check functionality of minikube after evaluating docker-env +Steps: +- Run `eval $(minikube docker-env)` to configure current environment to use minikube's Docker daemon +- Run `minikube status` to get the minikube status +- Make sure minikube components have status `Running` +- Make sure `docker-env` has status `in-use` +- Run eval `$(minikube -p profile docker-env)` and check if we are point to docker inside minikube +- Make sure `docker images` hits the minikube's Docker daemon by check if `gcr.io/k8s-minikube/storage-provisioner` is in the output of `docker images` + +Skips: +- Skips on `none` drive since `docker-env` is not supported +- Skips on non-docker container runtime + #### validatePodmanEnv check functionality of minikube after evaluating podman-env +Steps: +- Run `eval $(minikube podman-env)` to configure current environment to use minikube's Podman daemon, and `minikube status` to get the minikube status +- Make sure minikube components have status `Running` +- Make sure `podman-env` has status `in-use` +- Run `eval $(minikube docker-env)` again and `docker images` to list the docker images using the minikube's Docker daemon +- Make sure `docker images` hits the minikube's Podman daemon by check if `gcr.io/k8s-minikube/storage-provisioner` is in the output of `docker images` + +Skips: +- Skips on `none` drive since `podman-env` is not supported +- Skips on non-docker container runtime +- Skips on non-Linux platforms + #### validateStartWithProxy makes sure minikube start respects the HTTP_PROXY environment variable +Steps: +- Start a local HTTP proxy +- Start minikube with the environment variable `HTTP_PROXY` set to the local HTTP proxy + #### validateStartWithCustomCerts makes sure minikube start respects the HTTPS_PROXY environment variable and works with custom certs a proxy is started by calling the mitmdump binary in the background, then installing the certs generated by the binary @@ -104,85 +149,221 @@ only runs on Github Actions for amd64 linux, otherwise validateStartWithProxy ru #### validateAuditAfterStart makes sure the audit log contains the correct logging after minikube start +Steps: +- Read the audit log file and make sure it contains the current minikube profile name + #### validateSoftStart -validates that after minikube already started, a "minikube start" should not change the configs. +validates that after minikube already started, a `minikube start` should not change the configs. + +Steps: +- The test `validateStartWithProxy` should have start minikube, make sure the configured node port is `8441` +- Run `minikube start` again as a soft start +- Make sure the configured node port is not changed #### validateKubeContext asserts that kubectl is properly configured (race-condition prone!) +Steps: +- Run `kubectl config current-context` +- Make sure the current minikube profile name is in the output of the command + #### validateKubectlGetPods asserts that `kubectl get pod -A` returns non-zero content +Steps: +- Run `kubectl get po -A` to get all pods in the current minikube profile +- Make sure the output is not empty and contains `kube-system` components + #### validateMinikubeKubectl validates that the `minikube kubectl` command returns content +Steps: +- Run `minikube kubectl -- get pods` to get the pods in the current minikube profile +- Make sure the command doesn't raise any error + #### validateMinikubeKubectlDirectCall validates that calling minikube's kubectl +Steps: +- Run `kubectl get pods` by calling the minikube's `kubectl` binary file directly +- Make sure the command doesn't raise any error + #### validateExtraConfig verifies minikube with --extra-config works as expected +Steps: +- The tests before this already created a profile +- Soft-start minikube with different `--extra-config` command line option +- Load the profile's config +- Make sure the specified `--extra-config` is correctly returned + #### validateComponentHealth asserts that all Kubernetes components are healthy NOTE: It expects all components to be Ready, so it makes sense to run it close after only those tests that include '--wait=all' start flag +Steps: +- Run `kubectl get po po -l tier=control-plane -n kube-system -o=json` to get all the Kubernetes conponents +- For each component, make sure the pod status is `Running` + #### validateStatusCmd -makes sure minikube status outputs correctly +makes sure `minikube status` outputs correctly + +Steps: +- Run `minikube status` with custom format `host:{{.Host}},kublet:{{.Kubelet}},apiserver:{{.APIServer}},kubeconfig:{{.Kubeconfig}}` +- Make sure `host`, `kublete`, `apiserver` and `kubeconfig` statuses are shown in the output +- Run `minikube status` again as JSON output +- Make sure `host`, `kublete`, `apiserver` and `kubeconfig` statuses are set in the JSON output #### validateDashboardCmd asserts that the dashboard command works +Steps: +- Run `minikube dashboard --url` to start minikube dashboard and return the URL of it +- Send a GET request to the dashboard URL +- Make sure HTTP status OK is returned + #### validateDryRun asserts that the dry-run mode quickly exits with the right code +Steps: +- Run `minikube start --dry-run --memory 250MB` +- Since the 250MB memory is less than the required 2GB, minikube should exit with an exit code `ExInsufficientMemory` +- Run `minikube start --dry-run` +- Make sure the command doesn't raise any error + #### validateInternationalLanguage asserts that the language used can be changed with environment variables +Steps: +- Set environment variable `LC_ALL=fr` to enable minikube translation to French +- Start minikube with memory of 250MB which is too little: `minikube start --dry-run --memory 250MB` +- Make sure the dry-run output message is in French + #### validateCacheCmd tests functionality of cache command (cache add, delete, list) +Steps: +- Run `minikube cache add` and make sure we can add a remote image to the cache +- Run `minikube cache add` and make sure we can build and add a local image to the cache +- Run `minikube cache delete` and make sure we can delete an image from the cache +- Run `minikube cache list` and make sure we can list the images in the cache +- Run `minikube ssh sudo crictl images` and make sure we can list the images in the cache with `crictl` +- Delete an image from minikube node and run `minikube cache reload` to make sure the image is brought back correctly + #### validateConfigCmd asserts basic "config" command functionality +Steps: +- Run `minikube config set/get/unset` to make sure configuration is modified correctly + #### validateLogsCmd asserts basic "logs" command functionality +Steps: +- Run `minikube logs` and make sure the logs contains some keywords like `apiserver`, `Audit` and `Last Start` + #### validateLogsFileCmd asserts "logs --file" command functionality +Steps: +- Run `minikube logs --file logs.txt` to save the logs to a local file +- Make sure the logs are correctly written + #### validateProfileCmd asserts "profile" command functionality +Steps: +- Run `minikube profile lis` and make sure the command doesn't fail for the non-existent profile `lis` +- Run `minikube profile list --output json` to make sure the previous command doesn't create a new profile +- Run `minikube profile list` and make sure the profiles are correctly listed +- Run `minikube profile list -o JSON` and make sure the profiles are correctly listed as JSON output + #### validateServiceCmd asserts basic "service" command functionality +Steps: +- Create a new `k8s.gcr.io/echoserver` deployment +- Run `minikube service list` to make sure the newly created service is correctly listed in the output +- Run `minikube service` with `--https --url` to make sure the HTTPS endpoint URL of the service is printed +- Run `minikube service` with `--url --format={{.IP}}` to make sure the IP address of the service is printed +- Run `minikube service` with a regular `--url` to make sure the HTTP endpoint URL of the service is printed +- Make sure we can hit the endpoint URL with an HTTP GET request + #### validateAddonsCmd asserts basic "addon" command functionality +Steps: +- Run `minikube addons list` to list the addons in a tabular format +- Make sure `dashboard`, `ingress` and `ingress-dns` is listed as available addons +- Run `minikube addons list -o JSON` lists the addons in JSON format + #### validateSSHCmd asserts basic "ssh" command functionality +Steps: +- Run `minikube ssh echo hello` to make sure we can SSH into the minikube container and run an command +- Run `minikube ssh cat /etc/hostname` as well to make sure the command is run inside minikube + #### validateCpCmd asserts basic "cp" command functionality +Steps: +- Run `minikube cp ...` to copy a file to the minikube node +- Run `minikube ssh sudo cat ...` to print out the copied file within minikube +- make sure the file is correctly copied + +Skips: +- Skips `none` driver since `cp` is not supported + #### validateMySQL validates a minimalist MySQL deployment +Steps: +- Run `kubectl replace --force -f testdata/mysql/yaml` +- Wait for the `mysql` pod to be running +- Run `mysql -e show databases;` inside the MySQL pod to verify MySQL is up and running +- Retry with exponential backoff if failed, as `mysqld` first comes up without users configured. Scan for names in case of a reschedule. + +Skips: +- Skips for ARM64 architecture since it's not supported by MySQL + #### validateFileSync to check existence of the test file +Steps: +- Test files have been synced into minikube in the previous step `setupFileSync` +- Check the existence of the test file +- Make sure the file is correctly synced + +Skips: +- Skips on `none` driver since SSH is not supported + #### validateCertSync checks to make sure a custom cert has been copied into the minikube guest and installed correctly +Steps: +- Check both the installed & reference certs and make sure they are symlinked + #### validateNotActiveRuntimeDisabled -asserts that for a given runtime, the other runtimes disabled, for example for containerd runtime, docker and crio needs to be not running +asserts that for a given runtime, the other runtimes are disabled, for example for `containerd` runtime, `docker` and `crio` needs to be not running + +Steps: +- For each container runtime, run `minikube ssh sudo systemctl is-active ...` and make sure the other container runtimes are not running #### validateUpdateContextCmd asserts basic "update-context" command functionality +Steps: +- Run `minikube update-context` +- Make sure the context has been correctly updated by checking the command output + #### validateVersionCmd asserts `minikube version` command works fine for both --short and --components +Steps: +- Run `minikube version --short` and make sure the returned version is a valid semver +- Run `minikube version --components` and make sure the component versions are returned + #### validateMountCmd verifies the minikube mount command works properly @@ -243,6 +424,15 @@ verifies the docker driver and run with an existing network ## TestingKicBaseImage will return true if the integraiton test is running against a passed --base-image flag +## TestMountStart +tests using the mount command on start + +#### validateStartWithMount +starts a cluster with mount enabled + +#### validateMount +checks if the cluster has a folder mounted + ## TestMultiNode tests all multi node cluster functionality diff --git a/site/content/en/docs/handbook/registry.md b/site/content/en/docs/handbook/registry.md index 12995de882..a42d1595e5 100644 --- a/site/content/en/docs/handbook/registry.md +++ b/site/content/en/docs/handbook/registry.md @@ -83,13 +83,19 @@ The first step is to enable the registry addon: minikube addons enable registry ``` -When enabled, the registry addon exposes its port 5000 on the minikube's virtual machine. +When enabled, the registry addon exposes its port 80 on the minikube's virtual machine. You can confirm this by: +```shell +kubectl get service --namespace kube-system +> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +> kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 54m +> registry ClusterIP 10.98.34.133 80/TCP,443/TCP 37m +``` -In order to make docker accept pushing images to this registry, we have to redirect port 5000 on the docker virtual machine over to port 5000 on the minikube machine. Unfortunately, the docker vm cannot directly see the IP address of the minikube vm. To fix this, you will have to add one more level of redirection. +In order to make docker accept pushing images to this registry, we have to redirect port 5000 on the docker virtual machine over to port 80 on the minikube registry service. Unfortunately, the docker vm cannot directly see the IP address of the minikube vm. To fix this, you will have to add one more level of redirection. Use kubectl port-forward to map your local workstation to the minikube vm ```shell -kubectl port-forward --namespace kube-system 5000:5000 +kubectl port-forward --namespace kube-system service/registry 5000:80 ``` On your local machine you should now be able to reach the minikube registry by using `curl http://localhost:5000/v2/_catalog` diff --git a/site/content/en/docs/start/_index.md b/site/content/en/docs/start/_index.md index 69baefb7fc..f35f5398a4 100644 --- a/site/content/en/docs/start/_index.md +++ b/site/content/en/docs/start/_index.md @@ -16,7 +16,7 @@ All you need is Docker (or similarly compatible) container or a Virtual Machine * 2GB of free memory * 20GB of free disk space * Internet connection -* Container or virtual machine manager, such as: [Docker]({{}}), [Hyperkit]({{}}), [Hyper-V]({{}}), [KVM]({{}}), [Parallels]({{}}), [Podman]({{}}), [VirtualBox]({{}}), or [VMWare]({{}}) +* Container or virtual machine manager, such as: [Docker]({{}}), [Hyperkit]({{}}), [Hyper-V]({{}}), [KVM]({{}}), [Parallels]({{}}), [Podman]({{}}), [VirtualBox]({{}}), or [VMware]({{}})

1Installation

diff --git a/test/integration/aaa_download_only_test.go b/test/integration/aaa_download_only_test.go index fca29ccb17..d4c1f3d440 100644 --- a/test/integration/aaa_download_only_test.go +++ b/test/integration/aaa_download_only_test.go @@ -26,7 +26,6 @@ import ( "crypto/md5" "encoding/json" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -230,7 +229,7 @@ func TestDownloadOnlyKic(t *testing.T) { // Make sure the downloaded image tarball exists tarball := download.TarballPath(constants.DefaultKubernetesVersion, cRuntime) - contents, err := ioutil.ReadFile(tarball) + contents, err := os.ReadFile(tarball) if err != nil { t.Errorf("failed to read tarball file %q: %v", tarball, err) } @@ -240,7 +239,7 @@ func TestDownloadOnlyKic(t *testing.T) { } // Make sure it has the correct checksum checksum := md5.Sum(contents) - remoteChecksum, err := ioutil.ReadFile(download.PreloadChecksumPath(constants.DefaultKubernetesVersion, cRuntime)) + remoteChecksum, err := os.ReadFile(download.PreloadChecksumPath(constants.DefaultKubernetesVersion, cRuntime)) if err != nil { t.Errorf("failed to read checksum file %q : %v", download.PreloadChecksumPath(constants.DefaultKubernetesVersion, cRuntime), err) } diff --git a/test/integration/driver_install_or_update_test.go b/test/integration/driver_install_or_update_test.go index 24d1662348..b0cedaca33 100644 --- a/test/integration/driver_install_or_update_test.go +++ b/test/integration/driver_install_or_update_test.go @@ -18,7 +18,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -60,7 +59,7 @@ func TestKVMDriverInstallOrUpdate(t *testing.T) { defer os.Setenv("PATH", originalPath) for _, tc := range tests { - dir, err := ioutil.TempDir("", tc.name) + dir, err := os.MkdirTemp("", tc.name) if err != nil { t.Fatalf("Expected to create tempdir. test: %s, got: %v", tc.name, err) } @@ -129,7 +128,7 @@ func TestHyperKitDriverInstallOrUpdate(t *testing.T) { defer os.Setenv("PATH", originalPath) for _, tc := range tests { - dir, err := ioutil.TempDir("", tc.name) + dir, err := os.MkdirTemp("", tc.name) if err != nil { t.Fatalf("Expected to create tempdir. test: %s, got: %v", tc.name, err) } @@ -267,7 +266,7 @@ func driverVersion(path string) (string, error) { // prepareTempMinikubeDirWithHyperkitDriver creates a temp .minikube directory // with structure essential to testing of hyperkit driver updates func prepareTempMinikubeDirWithHyperkitDriver(name, driver string) (string, string, error) { - temp, err := ioutil.TempDir("", name) + temp, err := os.MkdirTemp("", name) if err != nil { return "", "", fmt.Errorf("failed to create tempdir: %v", err) } diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index 997095b199..daf81d7027 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -25,7 +25,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "os" @@ -209,10 +209,12 @@ func cleanupUnwantedImages(ctx context.Context, t *testing.T, profile string) { func validateNodeLabels(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) + // docs: Get the node labels from the cluster with `kubectl get nodes` rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "get", "nodes", "--output=go-template", "--template='{{range $k, $v := (index .items 0).metadata.labels}}{{$k}} {{end}}'")) if err != nil { t.Errorf("failed to 'kubectl get nodes' with args %q: %v", rr.Command(), err) } + // docs: check if the node labels matches with the expected Minikube labels: `minikube.k8s.io/*` expectedLabels := []string{"minikube.k8s.io/commit", "minikube.k8s.io/version", "minikube.k8s.io/updated_at", "minikube.k8s.io/name"} for _, el := range expectedLabels { if !strings.Contains(rr.Output(), el) { @@ -223,13 +225,16 @@ func validateNodeLabels(ctx context.Context, t *testing.T, profile string) { // validateImageCommands runs tests on all the `minikube image` commands, ex. `minikube image load`, `minikube image list`, etc. func validateImageCommands(ctx context.Context, t *testing.T, profile string) { + // docs(skip): Skips on `none` driver as image loading is not supported if NoneDriver() { t.Skip("image commands are not available on the none driver") } + // docs(skip): Skips on GitHub Actions and macOS as this test case requires a running docker daemon if GithubActionRunner() && runtime.GOOS == "darwin" { t.Skip("skipping on darwin github action runners, as this test requires a running docker daemon") } + // docs: Make sure image listing works by `minikube image ls` t.Run("ImageList", func(t *testing.T) { MaybeParallel(t) @@ -252,9 +257,14 @@ func validateImageCommands(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Make sure image building works by `minikube image build` t.Run("ImageBuild", func(t *testing.T) { MaybeParallel(t) + if _, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", "pgrep", "buildkitd")); err == nil { + t.Errorf("buildkitd process is running, should not be running until `minikube image build` is ran") + } + newImage := fmt.Sprintf("localhost/my-image:%s", profile) // try to build the new image with minikube @@ -296,6 +306,7 @@ func validateImageCommands(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Make sure image loading from Docker daemon works by `minikube image load --daemon` t.Run("ImageLoadDaemon", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "image", "load", "--daemon", taggedImage)) if err != nil { @@ -305,6 +316,7 @@ func validateImageCommands(ctx context.Context, t *testing.T, profile string) { checkImageExists(ctx, t, profile, taggedImage) }) + // docs: Make sure image saving works by `minikube image load --daemon` t.Run("ImageSaveToFile", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "image", "save", taggedImage, imagePath)) if err != nil { @@ -316,6 +328,7 @@ func validateImageCommands(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Make sure image removal works by `minikube image rm` t.Run("ImageRemove", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "image", "rm", taggedImage)) if err != nil { @@ -332,6 +345,7 @@ func validateImageCommands(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Make sure image loading from file works by `minikube image load` t.Run("ImageLoadFromFile", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "image", "load", imagePath)) if err != nil || rr.Stderr.String() != "" { @@ -341,6 +355,7 @@ func validateImageCommands(ctx context.Context, t *testing.T, profile string) { checkImageExists(ctx, t, profile, taggedImage) }) + // docs: Make sure image saving to Docker daemon works by `minikube image load` t.Run("ImageSaveDaemon", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, "docker", "rmi", taggedImage)) if err != nil { @@ -376,10 +391,12 @@ func listImages(ctx context.Context, t *testing.T, profile string) (*RunResult, // check functionality of minikube after evaluating docker-env func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { + // docs(skip): Skips on `none` drive since `docker-env` is not supported if NoneDriver() { t.Skipf("none driver does not support docker-env") } + // docs(skip): Skips on non-docker container runtime if cr := ContainerRuntime(); cr != "docker" { t.Skipf("only validate docker env with docker container runtime, currently testing %s", cr) } @@ -391,6 +408,7 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { formatArg string } + // docs: Run `eval $(minikube docker-env)` to configure current environment to use minikube's Docker daemon windowsTests := []ShellTest{ {"powershell", []string{"powershell.exe", "-NoProfile", "-NonInteractive"}, "%[1]s -p %[2]s docker-env | Invoke-Expression ; "}, } @@ -415,6 +433,7 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { formattedArg := fmt.Sprintf(tc.formatArg, Target(), profile) + // docs: Run `minikube status` to get the minikube status // we should be able to get minikube status with a shell which evaled docker-env command[len(command)-1] = formattedArg + Target() + " status -p " + profile c := exec.CommandContext(mctx, command[0], command[1:]...) @@ -426,9 +445,11 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { if err != nil { t.Fatalf("failed to do status after eval-ing docker-env. error: %v", err) } + // docs: Make sure minikube components have status `Running` if !strings.Contains(rr.Output(), "Running") { t.Fatalf("expected status output to include 'Running' after eval docker-env but got: *%s*", rr.Output()) } + // docs: Make sure `docker-env` has status `in-use` if !strings.Contains(rr.Output(), "in-use") { t.Fatalf("expected status output to include `in-use` after eval docker-env but got *%s*", rr.Output()) } @@ -436,7 +457,7 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { mctx, cancel = context.WithTimeout(ctx, Seconds(60)) defer cancel() - // do a eval $(minikube -p profile docker-env) and check if we are point to docker inside minikube + // docs: Run eval `$(minikube -p profile docker-env)` and check if we are point to docker inside minikube command[len(command)-1] = formattedArg + "docker images" c = exec.CommandContext(mctx, command[0], command[1:]...) rr, err = Run(t, c) @@ -449,6 +470,7 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { t.Fatalf("failed to run minikube docker-env. args %q : %v ", rr.Command(), err) } + // docs: Make sure `docker images` hits the minikube's Docker daemon by check if `gcr.io/k8s-minikube/storage-provisioner` is in the output of `docker images` expectedImgInside := "gcr.io/k8s-minikube/storage-provisioner" if !strings.Contains(rr.Output(), expectedImgInside) { t.Fatalf("expected 'docker images' to have %q inside minikube. but the output is: *%s*", expectedImgInside, rr.Output()) @@ -459,14 +481,17 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { // check functionality of minikube after evaluating podman-env func validatePodmanEnv(ctx context.Context, t *testing.T, profile string) { + // docs(skip): Skips on `none` drive since `podman-env` is not supported if NoneDriver() { t.Skipf("none driver does not support podman-env") } + // docs(skip): Skips on non-docker container runtime if cr := ContainerRuntime(); cr != "podman" { t.Skipf("only validate podman env with docker container runtime, currently testing %s", cr) } + // docs(skip): Skips on non-Linux platforms if runtime.GOOS != "linux" { t.Skipf("only validate podman env on linux, currently testing %s", runtime.GOOS) } @@ -476,6 +501,7 @@ func validatePodmanEnv(ctx context.Context, t *testing.T, profile string) { mctx, cancel := context.WithTimeout(ctx, Seconds(120)) defer cancel() + // docs: Run `eval $(minikube podman-env)` to configure current environment to use minikube's Podman daemon, and `minikube status` to get the minikube status c := exec.CommandContext(mctx, "/bin/bash", "-c", "eval $("+Target()+" -p "+profile+" podman-env) && "+Target()+" status -p "+profile) // we should be able to get minikube status with a bash which evaluated podman-env rr, err := Run(t, c) @@ -486,16 +512,18 @@ func validatePodmanEnv(ctx context.Context, t *testing.T, profile string) { if err != nil { t.Fatalf("failed to do status after eval-ing podman-env. error: %v", err) } + // docs: Make sure minikube components have status `Running` if !strings.Contains(rr.Output(), "Running") { t.Fatalf("expected status output to include 'Running' after eval podman-env but got: *%s*", rr.Output()) } + // docs: Make sure `podman-env` has status `in-use` if !strings.Contains(rr.Output(), "in-use") { t.Fatalf("expected status output to include `in-use` after eval podman-env but got *%s*", rr.Output()) } mctx, cancel = context.WithTimeout(ctx, Seconds(60)) defer cancel() - // do a eval $(minikube -p profile podman-env) and check if we are point to docker inside minikube + // docs: Run `eval $(minikube docker-env)` again and `docker images` to list the docker images using the minikube's Docker daemon c = exec.CommandContext(mctx, "/bin/bash", "-c", "eval $("+Target()+" -p "+profile+" podman-env) && docker images") rr, err = Run(t, c) @@ -506,6 +534,7 @@ func validatePodmanEnv(ctx context.Context, t *testing.T, profile string) { t.Fatalf("failed to run minikube podman-env. args %q : %v ", rr.Command(), err) } + // docs: Make sure `docker images` hits the minikube's Podman daemon by check if `gcr.io/k8s-minikube/storage-provisioner` is in the output of `docker images` expectedImgInside := "gcr.io/k8s-minikube/storage-provisioner" if !strings.Contains(rr.Output(), expectedImgInside) { t.Fatalf("expected 'docker images' to have %q inside minikube. but the output is: *%s*", expectedImgInside, rr.Output()) @@ -515,11 +544,13 @@ func validatePodmanEnv(ctx context.Context, t *testing.T, profile string) { // validateStartWithProxy makes sure minikube start respects the HTTP_PROXY environment variable func validateStartWithProxy(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) + // docs: Start a local HTTP proxy srv, err := startHTTPProxy(t) if err != nil { t.Fatalf("failed to set up the test proxy: %s", err) } + // docs: Start minikube with the environment variable `HTTP_PROXY` set to the local HTTP proxy startMinikubeWithProxy(ctx, t, profile, "HTTP_PROXY", srv.Addr) } @@ -539,6 +570,7 @@ func validateStartWithCustomCerts(ctx context.Context, t *testing.T, profile str // validateAuditAfterStart makes sure the audit log contains the correct logging after minikube start func validateAuditAfterStart(ctx context.Context, t *testing.T, profile string) { + // docs: Read the audit log file and make sure it contains the current minikube profile name got, err := auditContains(profile) if err != nil { t.Fatalf("failed to check audit log: %v", err) @@ -548,12 +580,12 @@ func validateAuditAfterStart(ctx context.Context, t *testing.T, profile string) } } -// validateSoftStart validates that after minikube already started, a "minikube start" should not change the configs. +// validateSoftStart validates that after minikube already started, a `minikube start` should not change the configs. func validateSoftStart(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) start := time.Now() - // the test before this had been start with --apiserver-port=8441 + // docs: The test `validateStartWithProxy` should have start minikube, make sure the configured node port is `8441` beforeCfg, err := config.LoadProfile(profile) if err != nil { t.Fatalf("error reading cluster config before soft start: %v", err) @@ -562,6 +594,7 @@ func validateSoftStart(ctx context.Context, t *testing.T, profile string) { t.Errorf("expected cluster config node port before soft start to be %d but got %d", apiPortTest, beforeCfg.Config.KubernetesConfig.NodePort) } + // docs: Run `minikube start` again as a soft start softStartArgs := []string{"start", "-p", profile, "--alsologtostderr", "-v=8"} c := exec.CommandContext(ctx, Target(), softStartArgs...) rr, err := Run(t, c) @@ -570,6 +603,7 @@ func validateSoftStart(ctx context.Context, t *testing.T, profile string) { } t.Logf("soft start took %s for %q cluster.", time.Since(start), profile) + // docs: Make sure the configured node port is not changed afterCfg, err := config.LoadProfile(profile) if err != nil { t.Errorf("error reading cluster config after soft start: %v", err) @@ -584,10 +618,12 @@ func validateSoftStart(ctx context.Context, t *testing.T, profile string) { func validateKubeContext(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) + // docs: Run `kubectl config current-context` rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "config", "current-context")) if err != nil { t.Errorf("failed to get current-context. args %q : %v", rr.Command(), err) } + // docs: Make sure the current minikube profile name is in the output of the command if !strings.Contains(rr.Stdout.String(), profile) { t.Errorf("expected current-context = %q, but got *%q*", profile, rr.Stdout.String()) } @@ -597,10 +633,12 @@ func validateKubeContext(ctx context.Context, t *testing.T, profile string) { func validateKubectlGetPods(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) + // docs: Run `kubectl get po -A` to get all pods in the current minikube profile rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "get", "po", "-A")) if err != nil { t.Errorf("failed to get kubectl pods: args %q : %v", rr.Command(), err) } + // docs: Make sure the output is not empty and contains `kube-system` components if rr.Stderr.String() != "" { t.Errorf("expected stderr to be empty but got *%q*: args %q", rr.Stderr, rr.Command()) } @@ -613,9 +651,11 @@ func validateKubectlGetPods(ctx context.Context, t *testing.T, profile string) { func validateMinikubeKubectl(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) + // docs: Run `minikube kubectl -- get pods` to get the pods in the current minikube profile // Must set the profile so that it knows what version of Kubernetes to use kubectlArgs := []string{"-p", profile, "kubectl", "--", "--context", profile, "get", "pods"} rr, err := Run(t, exec.CommandContext(ctx, Target(), kubectlArgs...)) + // docs: Make sure the command doesn't raise any error if err != nil { t.Fatalf("failed to get pods. args %q: %v", rr.Command(), err) } @@ -637,8 +677,10 @@ func validateMinikubeKubectlDirectCall(ctx context.Context, t *testing.T, profil } defer os.Remove(dstfn) // clean up + // docs: Run `kubectl get pods` by calling the minikube's `kubectl` binary file directly kubectlArgs := []string{"--context", profile, "get", "pods"} rr, err := Run(t, exec.CommandContext(ctx, dstfn, kubectlArgs...)) + // docs: Make sure the command doesn't raise any error if err != nil { t.Fatalf("failed to run kubectl directly. args %q: %v", rr.Command(), err) } @@ -649,7 +691,8 @@ func validateExtraConfig(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) start := time.Now() - // The tests before this already created a profile, starting minikube with different --extra-config cmdline option. + // docs: The tests before this already created a profile + // docs: Soft-start minikube with different `--extra-config` command line option startArgs := []string{"start", "-p", profile, "--extra-config=apiserver.enable-admission-plugins=NamespaceAutoProvision", "--wait=all"} c := exec.CommandContext(ctx, Target(), startArgs...) rr, err := Run(t, c) @@ -658,11 +701,13 @@ func validateExtraConfig(ctx context.Context, t *testing.T, profile string) { } t.Logf("restart took %s for %q cluster.", time.Since(start), profile) + // docs: Load the profile's config afterCfg, err := config.LoadProfile(profile) if err != nil { t.Errorf("error reading cluster config after soft start: %v", err) } + // docs: Make sure the specified `--extra-config` is correctly returned expectedExtraOptions := "apiserver.enable-admission-plugins=NamespaceAutoProvision" if !strings.Contains(afterCfg.Config.KubernetesConfig.ExtraOptions.String(), expectedExtraOptions) { @@ -703,6 +748,7 @@ func validateComponentHealth(ctx context.Context, t *testing.T, profile string) "kube-scheduler": false, } + // docs: Run `kubectl get po po -l tier=control-plane -n kube-system -o=json` to get all the Kubernetes conponents rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "get", "po", "-l", "tier=control-plane", "-n", "kube-system", "-o=json")) if err != nil { t.Fatalf("failed to get components. args %q: %v", rr.Command(), err) @@ -713,6 +759,7 @@ func validateComponentHealth(ctx context.Context, t *testing.T, profile string) t.Fatalf("failed to decode kubectl json output: args %q : %v", rr.Command(), err) } + // docs: For each component, make sure the pod status is `Running` for _, i := range cs.Items { for _, l := range i.Labels { if _, ok := found[l]; ok { // skip irrelevant (eg, repeating/redundant '"tier": "control-plane"') labels @@ -743,7 +790,7 @@ func validateComponentHealth(ctx context.Context, t *testing.T, profile string) } } -// validateStatusCmd makes sure minikube status outputs correctly +// validateStatusCmd makes sure `minikube status` outputs correctly func validateStatusCmd(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "status")) @@ -751,22 +798,24 @@ func validateStatusCmd(ctx context.Context, t *testing.T, profile string) { t.Errorf("failed to run minikube status. args %q : %v", rr.Command(), err) } - // Custom format + // docs: Run `minikube status` with custom format `host:{{.Host}},kublet:{{.Kubelet}},apiserver:{{.APIServer}},kubeconfig:{{.Kubeconfig}}` rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "status", "-f", "host:{{.Host}},kublet:{{.Kubelet}},apiserver:{{.APIServer}},kubeconfig:{{.Kubeconfig}}")) if err != nil { t.Errorf("failed to run minikube status with custom format: args %q: %v", rr.Command(), err) } + // docs: Make sure `host`, `kublete`, `apiserver` and `kubeconfig` statuses are shown in the output re := `host:([A-z]+),kublet:([A-z]+),apiserver:([A-z]+),kubeconfig:([A-z]+)` match, _ := regexp.MatchString(re, rr.Stdout.String()) if !match { t.Errorf("failed to match regex %q for minikube status with custom format. args %q. output: %s", re, rr.Command(), rr.Output()) } - // Json output + // docs: Run `minikube status` again as JSON output rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "status", "-o", "json")) if err != nil { t.Errorf("failed to run minikube status with json output. args %q : %v", rr.Command(), err) } + // docs: Make sure `host`, `kublete`, `apiserver` and `kubeconfig` statuses are set in the JSON output var jsonObject map[string]interface{} err = json.Unmarshal(rr.Stdout.Bytes(), &jsonObject) if err != nil { @@ -793,6 +842,7 @@ func validateDashboardCmd(ctx context.Context, t *testing.T, profile string) { mctx, cancel := context.WithTimeout(ctx, Seconds(300)) defer cancel() + // docs: Run `minikube dashboard --url` to start minikube dashboard and return the URL of it args := []string{"dashboard", "--url", "--port", "36195", "-p", profile, "--alsologtostderr", "-v=1"} ss, err := Start(t, exec.CommandContext(mctx, Target(), args...)) if err != nil { @@ -815,13 +865,15 @@ func validateDashboardCmd(ctx context.Context, t *testing.T, profile string) { t.Fatalf("failed to parse %q: %v", s, err) } + // docs: Send a GET request to the dashboard URL resp, err := retryablehttp.Get(u.String()) if err != nil { t.Fatalf("failed to http get %q: %v\nresponse: %+v", u.String(), err, resp) } + // docs: Make sure HTTP status OK is returned if resp.StatusCode != http.StatusOK { - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { t.Errorf("failed to read http response body from dashboard %q: %v", u.String(), err) } @@ -853,11 +905,13 @@ func validateDryRun(ctx context.Context, t *testing.T, profile string) { mctx, cancel := context.WithTimeout(ctx, Seconds(5)) defer cancel() + // docs: Run `minikube start --dry-run --memory 250MB` // Too little memory! startArgs := append([]string{"start", "-p", profile, "--dry-run", "--memory", "250MB", "--alsologtostderr"}, StartArgs()...) c := exec.CommandContext(mctx, Target(), startArgs...) rr, err := Run(t, c) + // docs: Since the 250MB memory is less than the required 2GB, minikube should exit with an exit code `ExInsufficientMemory` wantCode := reason.ExInsufficientMemory if rr.ExitCode != wantCode { if HyperVDriver() { @@ -869,9 +923,11 @@ func validateDryRun(ctx context.Context, t *testing.T, profile string) { dctx, cancel := context.WithTimeout(ctx, Seconds(5)) defer cancel() + // docs: Run `minikube start --dry-run` startArgs = append([]string{"start", "-p", profile, "--dry-run", "--alsologtostderr", "-v=1"}, StartArgs()...) c = exec.CommandContext(dctx, Target(), startArgs...) rr, err = Run(t, c) + // docs: Make sure the command doesn't raise any error if rr.ExitCode != 0 || err != nil { if HyperVDriver() { t.Skip("skipping this error on HyperV till this issue is solved https://github.com/kubernetes/minikube/issues/9785") @@ -891,8 +947,10 @@ func validateInternationalLanguage(ctx context.Context, t *testing.T, profile st // Too little memory! startArgs := append([]string{"start", "-p", profile, "--dry-run", "--memory", "250MB", "--alsologtostderr"}, StartArgs()...) c := exec.CommandContext(mctx, Target(), startArgs...) + // docs: Set environment variable `LC_ALL=fr` to enable minikube translation to French c.Env = append(os.Environ(), "LC_ALL=fr") + // docs: Start minikube with memory of 250MB which is too little: `minikube start --dry-run --memory 250MB` rr, err := Run(t, c) wantCode := reason.ExInsufficientMemory @@ -903,6 +961,7 @@ func validateInternationalLanguage(ctx context.Context, t *testing.T, profile st t.Errorf("dry-run(250MB) exit code = %d, wanted = %d: %v", rr.ExitCode, wantCode, err) } } + // docs: Make sure the dry-run output message is in French if !strings.Contains(rr.Stdout.String(), "Utilisation du pilote") { t.Errorf("dry-run output was expected to be in French. Expected \"Utilisation du pilote\", but not present in output:\n%s", rr.Stdout.String()) } @@ -917,6 +976,8 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } t.Run("cache", func(t *testing.T) { + + // docs: Run `minikube cache add` and make sure we can add a remote image to the cache t.Run("add_remote", func(t *testing.T) { for _, img := range []string{"k8s.gcr.io/pause:3.1", "k8s.gcr.io/pause:3.3", "k8s.gcr.io/pause:latest"} { rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "cache", "add", img)) @@ -926,6 +987,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube cache add` and make sure we can build and add a local image to the cache t.Run("add_local", func(t *testing.T) { if GithubActionRunner() && runtime.GOOS == "darwin" { t.Skipf("skipping this test because Docker can not run in macos on github action free version. https://github.community/t/is-it-possible-to-install-and-configure-docker-on-macos-runner/16981") @@ -936,13 +998,13 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { t.Skipf("docker is not installed, skipping local image test") } - dname, err := ioutil.TempDir("", profile) + dname, err := os.MkdirTemp("", profile) if err != nil { t.Fatalf("Cannot create temp dir: %v", err) } message := []byte("FROM scratch\nADD Dockerfile /x") - err = ioutil.WriteFile(filepath.Join(dname, "Dockerfile"), message, 0644) + err = os.WriteFile(filepath.Join(dname, "Dockerfile"), message, 0644) if err != nil { t.Fatalf("unable to write Dockerfile: %v", err) } @@ -972,6 +1034,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube cache delete` and make sure we can delete an image from the cache t.Run("delete_k8s.gcr.io/pause:3.3", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "cache", "delete", "k8s.gcr.io/pause:3.3")) if err != nil { @@ -979,6 +1042,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube cache list` and make sure we can list the images in the cache t.Run("list", func(t *testing.T) { rr, err := Run(t, exec.CommandContext(ctx, Target(), "cache", "list")) if err != nil { @@ -992,6 +1056,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube ssh sudo crictl images` and make sure we can list the images in the cache with `crictl` 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 { @@ -1003,6 +1068,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Delete an image from minikube node and run `minikube cache reload` to make sure the image is brought back correctly t.Run("cache_reload", func(t *testing.T) { // deleting image inside minikube node manually and expecting reload to bring it back img := "k8s.gcr.io/pause:latest" // deleting image inside minikube node manually @@ -1051,6 +1117,7 @@ func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { // validateConfigCmd asserts basic "config" command functionality func validateConfigCmd(ctx context.Context, t *testing.T, profile string) { + // docs: Run `minikube config set/get/unset` to make sure configuration is modified correctly tests := []struct { args []string wantOut string @@ -1102,6 +1169,7 @@ func checkSaneLogs(t *testing.T, logs string) { // validateLogsCmd asserts basic "logs" command functionality func validateLogsCmd(ctx context.Context, t *testing.T, profile string) { + // docs: Run `minikube logs` and make sure the logs contains some keywords like `apiserver`, `Audit` and `Last Start` rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "logs")) if err != nil { t.Errorf("%s failed: %v", rr.Command(), err) @@ -1112,12 +1180,13 @@ func validateLogsCmd(ctx context.Context, t *testing.T, profile string) { // validateLogsFileCmd asserts "logs --file" command functionality func validateLogsFileCmd(ctx context.Context, t *testing.T, profile string) { - dname, err := ioutil.TempDir("", profile) + dname, err := os.MkdirTemp("", profile) if err != nil { t.Fatalf("Cannot create temp dir: %v", err) } logFileName := filepath.Join(dname, "logs.txt") + // docs: Run `minikube logs --file logs.txt` to save the logs to a local file rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "logs", "--file", logFileName)) if err != nil { t.Errorf("%s failed: %v", rr.Command(), err) @@ -1126,11 +1195,12 @@ func validateLogsFileCmd(ctx context.Context, t *testing.T, profile string) { t.Errorf("expected empty minikube logs output, but got: \n***%s***\n", rr.Output()) } - logs, err := ioutil.ReadFile(logFileName) + logs, err := os.ReadFile(logFileName) if err != nil { t.Errorf("Failed to read logs output '%s': %v", logFileName, err) } + // docs: Make sure the logs are correctly written checkSaneLogs(t, string(logs)) } @@ -1139,10 +1209,12 @@ func validateProfileCmd(ctx context.Context, t *testing.T, profile string) { t.Run("profile_not_create", func(t *testing.T) { // Profile command should not create a nonexistent profile nonexistentProfile := "lis" + // docs: Run `minikube profile lis` and make sure the command doesn't fail for the non-existent profile `lis` rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", nonexistentProfile)) if err != nil { t.Errorf("%s failed: %v", rr.Command(), err) } + // docs: Run `minikube profile list --output json` to make sure the previous command doesn't create a new profile rr, err = Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "--output", "json")) if err != nil { t.Errorf("%s failed: %v", rr.Command(), err) @@ -1162,6 +1234,7 @@ func validateProfileCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube profile list` and make sure the profiles are correctly listed t.Run("profile_list", func(t *testing.T) { // helper function to run command then, return target profile line from table output. extractrofileListFunc := func(rr *RunResult) string { @@ -1208,6 +1281,7 @@ func validateProfileCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube profile list -o JSON` and make sure the profiles are correctly listed as JSON output t.Run("profile_json_output", func(t *testing.T) { // helper function to run command then, return target profile object from json output. extractProfileObjFunc := func(rr *RunResult) *config.Profile { @@ -1290,6 +1364,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { var rr *RunResult var err error + // docs: Create a new `k8s.gcr.io/echoserver` deployment // k8s.gcr.io/echoserver is not multi-arch if arm64Platform() { rr, err = Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "create", "deployment", "hello-node", "--image=k8s.gcr.io/echoserver-arm:1.8")) @@ -1309,6 +1384,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { t.Fatalf("failed waiting for hello-node pod: %v", err) } + // docs: Run `minikube service list` to make sure the newly created service is correctly listed in the output rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "service", "list")) if err != nil { t.Errorf("failed to do service list. args %q : %v", rr.Command(), err) @@ -1321,7 +1397,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { t.Skipf("test is broken for port-forwarded drivers: https://github.com/kubernetes/minikube/issues/7383") } - // Test --https --url mode + // docs: Run `minikube service` with `--https --url` to make sure the HTTPS endpoint URL of the service is printed rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "service", "--namespace=default", "--https", "--url", "hello-node")) if err != nil { t.Fatalf("failed to get service url. args %q : %v", rr.Command(), err) @@ -1341,7 +1417,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { t.Errorf("expected scheme for %s to be 'https' but got %q", endpoint, u.Scheme) } - // Test --format=IP + // docs: Run `minikube service` with `--url --format={{.IP}}` to make sure the IP address of the service is printed rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "service", "hello-node", "--url", "--format={{.IP}}")) if err != nil { t.Errorf("failed to get service url with custom format. args %q: %v", rr.Command(), err) @@ -1350,7 +1426,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { t.Errorf("expected 'service --format={{.IP}}' output to be -%q- but got *%q* . args %q.", u.Hostname(), rr.Stdout.String(), rr.Command()) } - // Test a regular URL + // docs: Run `minikube service` with a regular `--url` to make sure the HTTP endpoint URL of the service is printed rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "service", "hello-node", "--url")) if err != nil { t.Errorf("failed to get service url. args: %q: %v", rr.Command(), err) @@ -1370,6 +1446,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { t.Logf("Attempting to fetch %s ...", endpoint) + // docs: Make sure we can hit the endpoint URL with an HTTP GET request fetch := func() error { resp, err := http.Get(endpoint) if err != nil { @@ -1379,7 +1456,7 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { t.Logf("error reading body from %s: %v", endpoint, err) return err @@ -1401,18 +1478,19 @@ func validateServiceCmd(ctx context.Context, t *testing.T, profile string) { func validateAddonsCmd(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) - // Table output + // docs: Run `minikube addons list` to list the addons in a tabular format rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "list")) if err != nil { t.Errorf("failed to do addon list: args %q : %v", rr.Command(), err) } + // docs: Make sure `dashboard`, `ingress` and `ingress-dns` is listed as available addons for _, a := range []string{"dashboard", "ingress", "ingress-dns"} { if !strings.Contains(rr.Output(), a) { t.Errorf("expected 'addon list' output to include -%q- but got *%s*", a, rr.Output()) } } - // Json output + // docs: Run `minikube addons list -o JSON` lists the addons in JSON format rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "addons", "list", "-o", "json")) if err != nil { t.Errorf("failed to do addon list with json output. args %q: %v", rr.Command(), err) @@ -1435,6 +1513,7 @@ func validateSSHCmd(ctx context.Context, t *testing.T, profile string) { want := "hello" + // docs: Run `minikube ssh echo hello` to make sure we can SSH into the minikube container and run an command rr, err := Run(t, exec.CommandContext(mctx, Target(), "-p", profile, "ssh", "echo hello")) if mctx.Err() == context.DeadlineExceeded { t.Errorf("failed to run command by deadline. exceeded timeout : %s", rr.Command()) @@ -1447,7 +1526,7 @@ func validateSSHCmd(ctx context.Context, t *testing.T, profile string) { t.Errorf("expected minikube ssh command output to be -%q- but got *%q*. args %q", want, rr.Stdout.String(), rr.Command()) } - // testing hostname as well because testing something like "minikube ssh echo" could be confusing + // docs: Run `minikube ssh cat /etc/hostname` as well to make sure the command is run inside minikube // because it is not clear if echo was run inside minikube on the powershell // so better to test something inside minikube, that is meaningful per profile // in this case /etc/hostname is same as the profile name @@ -1468,32 +1547,40 @@ func validateSSHCmd(ctx context.Context, t *testing.T, profile string) { // validateCpCmd asserts basic "cp" command functionality func validateCpCmd(ctx context.Context, t *testing.T, profile string) { + // docs(skip): Skips `none` driver since `cp` is not supported if NoneDriver() { t.Skipf("skipping: cp is unsupported by none driver") } + // docs: Run `minikube cp ...` to copy a file to the minikube node + // docs: Run `minikube ssh sudo cat ...` to print out the copied file within minikube + // docs: make sure the file is correctly copied testCpCmd(ctx, t, profile, "") } // validateMySQL validates a minimalist MySQL deployment func validateMySQL(ctx context.Context, t *testing.T, profile string) { + // docs(skip): Skips for ARM64 architecture since it's not supported by MySQL if arm64Platform() { t.Skip("arm64 is not supported by mysql. Skip the test. See https://github.com/kubernetes/minikube/issues/10144") } defer PostMortemLogs(t, profile) + // docs: Run `kubectl replace --force -f testdata/mysql/yaml` rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "replace", "--force", "-f", filepath.Join(*testdataDir, "mysql.yaml"))) if err != nil { t.Fatalf("failed to kubectl replace mysql: args %q failed: %v", rr.Command(), err) } + // docs: Wait for the `mysql` pod to be running names, err := PodWait(ctx, t, profile, "default", "app=mysql", Minutes(10)) if err != nil { t.Fatalf("failed waiting for mysql pod: %v", err) } - // Retry, as mysqld first comes up without users configured. Scan for names in case of a reschedule. + // docs: Run `mysql -e show databases;` inside the MySQL pod to verify MySQL is up and running + // docs: Retry with exponential backoff if failed, as `mysqld` first comes up without users configured. Scan for names in case of a reschedule. mysql := func() error { rr, err = Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "exec", names[0], "--", "mysql", "-ppassword", "-e", "show databases;")) return err @@ -1610,12 +1697,15 @@ func setupFileSync(ctx context.Context, t *testing.T, profile string) { func validateFileSync(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) + // docs(skip): Skips on `none` driver since SSH is not supported if NoneDriver() { t.Skipf("skipping: ssh unsupported by none") } + // docs: Test files have been synced into minikube in the previous step `setupFileSync` vp := vmSyncTestPath() t.Logf("Checking for existence of %s within VM", vp) + // docs: Check the existence of the test file rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", fmt.Sprintf("sudo cat %s", vp))) if err != nil { t.Errorf("%s failed: %v", rr.Command(), err) @@ -1624,11 +1714,12 @@ func validateFileSync(ctx context.Context, t *testing.T, profile string) { t.Logf("file sync test content: %s", got) syncFile := filepath.Join(*testdataDir, "sync.test") - expected, err := ioutil.ReadFile(syncFile) + expected, err := os.ReadFile(syncFile) if err != nil { t.Errorf("failed to read test file 'testdata/sync.test' : %v", err) } + // docs: Make sure the file is correctly synced if diff := cmp.Diff(string(expected), got); diff != "" { t.Errorf("/etc/sync.test content mismatch (-want +got):\n%s", diff) } @@ -1643,12 +1734,12 @@ func validateCertSync(ctx context.Context, t *testing.T, profile string) { } testPem := filepath.Join(*testdataDir, "minikube_test.pem") - want, err := ioutil.ReadFile(testPem) + want, err := os.ReadFile(testPem) if err != nil { t.Errorf("test file not found: %v", err) } - // Check both the installed & reference certs (they should be symlinked) + // docs: Check both the installed & reference certs and make sure they are symlinked paths := []string{ path.Join("/etc/ssl/certs", testCert()), path.Join("/usr/share/ca-certificates", testCert()), @@ -1670,7 +1761,7 @@ func validateCertSync(ctx context.Context, t *testing.T, profile string) { } testPem2 := filepath.Join(*testdataDir, "minikube_test2.pem") - want, err = ioutil.ReadFile(testPem2) + want, err = os.ReadFile(testPem2) if err != nil { t.Errorf("test file not found: %v", err) } @@ -1697,7 +1788,7 @@ func validateCertSync(ctx context.Context, t *testing.T, profile string) { } } -// validateNotActiveRuntimeDisabled asserts that for a given runtime, the other runtimes disabled, for example for containerd runtime, docker and crio needs to be not running +// validateNotActiveRuntimeDisabled asserts that for a given runtime, the other runtimes are disabled, for example for `containerd` runtime, `docker` and `crio` needs to be not running func validateNotActiveRuntimeDisabled(ctx context.Context, t *testing.T, profile string) { if NoneDriver() { t.Skip("skipping on none driver, minikube does not control the runtime of user on the none driver.") @@ -1710,7 +1801,7 @@ func validateNotActiveRuntimeDisabled(ctx context.Context, t *testing.T, profile expectDisable := disableMap[ContainerRuntime()] for _, cr := range expectDisable { - // for example: minikube sudo systemctl is-active docker + // docs: For each container runtime, run `minikube ssh sudo systemctl is-active ...` and make sure the other container runtimes are not running rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", fmt.Sprintf("sudo systemctl is-active %s", cr))) got := rr.Stdout.String() if err != nil && !strings.Contains(got, "inactive") { @@ -1787,12 +1878,12 @@ users: t.Parallel() c := exec.CommandContext(ctx, Target(), "-p", profile, "update-context", "--alsologtostderr", "-v=2") if tc.kubeconfig != nil { - tf, err := ioutil.TempFile("", "kubeconfig") + tf, err := os.CreateTemp("", "kubeconfig") if err != nil { t.Fatal(err) } - if err := ioutil.WriteFile(tf.Name(), tc.kubeconfig, 0644); err != nil { + if err := os.WriteFile(tf.Name(), tc.kubeconfig, 0644); err != nil { t.Fatal(err) } t.Cleanup(func() { @@ -1802,11 +1893,13 @@ users: c.Env = append(os.Environ(), fmt.Sprintf("KUBECONFIG=%s", tf.Name())) } + // docs: Run `minikube update-context` rr, err := Run(t, c) if err != nil { t.Errorf("failed to run minikube update-context: args %q: %v", rr.Command(), err) } + // docs: Make sure the context has been correctly updated by checking the command output if !bytes.Contains(rr.Stdout.Bytes(), tc.want) { t.Errorf("update-context: got=%q, want=*%q*", rr.Stdout.Bytes(), tc.want) } @@ -1828,7 +1921,7 @@ func startProxyWithCustomCerts(ctx context.Context, t *testing.T) error { } }() - mitmDir, err := ioutil.TempDir("", "") + mitmDir, err := os.MkdirTemp("", "") if err != nil { return errors.Wrap(err, "create temp dir") } @@ -1938,6 +2031,7 @@ func startMinikubeWithProxy(ctx context.Context, t *testing.T, profile string, p // validateVersionCmd asserts `minikube version` command works fine for both --short and --components func validateVersionCmd(ctx context.Context, t *testing.T, profile string) { + // docs: Run `minikube version --short` and make sure the returned version is a valid semver t.Run("short", func(t *testing.T) { MaybeParallel(t) rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "version", "--short")) @@ -1951,6 +2045,7 @@ func validateVersionCmd(ctx context.Context, t *testing.T, profile string) { } }) + // docs: Run `minikube version --components` and make sure the component versions are returned t.Run("components", func(t *testing.T) { MaybeParallel(t) rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "version", "-o=json", "--components")) diff --git a/test/integration/functional_test_mount_test.go b/test/integration/functional_test_mount_test.go index 039df20417..05c7c0d8f3 100644 --- a/test/integration/functional_test_mount_test.go +++ b/test/integration/functional_test_mount_test.go @@ -24,7 +24,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "os" "os/exec" "path" @@ -60,7 +59,7 @@ func validateMountCmd(ctx context.Context, t *testing.T, profile string) { // no } t.Run("any-port", func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "mounttest") + tempDir, err := os.MkdirTemp("", "mounttest") defer func() { // clean up tempdir err := os.RemoveAll(tempDir) if err != nil { @@ -107,7 +106,7 @@ func validateMountCmd(ctx context.Context, t *testing.T, profile string) { // no wantFromTest := []byte(testMarker) for _, name := range []string{createdByTest, createdByTestRemovedByPod, testMarker} { p := filepath.Join(tempDir, name) - err := ioutil.WriteFile(p, wantFromTest, 0644) + err := os.WriteFile(p, wantFromTest, 0644) t.Logf("wrote %q to %s", wantFromTest, p) if err != nil { t.Errorf("WriteFile %s: %v", p, err) @@ -160,7 +159,7 @@ func validateMountCmd(ctx context.Context, t *testing.T, profile string) { // no // Read the file written by pod startup p := filepath.Join(tempDir, createdByPod) - got, err := ioutil.ReadFile(p) + got, err := os.ReadFile(p) if err != nil { t.Errorf("failed to read file created by pod %q: %v", p, err) } @@ -209,7 +208,7 @@ func validateMountCmd(ctx context.Context, t *testing.T, profile string) { // no } }) t.Run("specific-port", func(t *testing.T) { - tempDir, err := ioutil.TempDir("", "mounttest") + tempDir, err := os.MkdirTemp("", "mounttest") defer func() { // clean up tempdir err := os.RemoveAll(tempDir) if err != nil { diff --git a/test/integration/functional_test_tunnel_test.go b/test/integration/functional_test_tunnel_test.go index 4472408778..1f395731c3 100644 --- a/test/integration/functional_test_tunnel_test.go +++ b/test/integration/functional_test_tunnel_test.go @@ -22,7 +22,7 @@ package integration import ( "context" "fmt" - "io/ioutil" + "io" "net" "net/http" "os/exec" @@ -211,7 +211,7 @@ func validateAccessDirect(ctx context.Context, t *testing.T, profile string) { return &retry.RetriableError{Err: fmt.Errorf("no body")} } defer resp.Body.Close() - got, err = ioutil.ReadAll(resp.Body) + got, err = io.ReadAll(resp.Body) if err != nil { return &retry.RetriableError{Err: err} } @@ -342,7 +342,7 @@ func validateAccessDNS(ctx context.Context, t *testing.T, profile string) { return &retry.RetriableError{Err: fmt.Errorf("no body")} } defer resp.Body.Close() - got, err = ioutil.ReadAll(resp.Body) + got, err = io.ReadAll(resp.Body) if err != nil { return &retry.RetriableError{Err: err} } diff --git a/test/integration/helpers_test.go b/test/integration/helpers_test.go index 6680dcb32f..8fb3d858d6 100644 --- a/test/integration/helpers_test.go +++ b/test/integration/helpers_test.go @@ -29,7 +29,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -153,14 +152,14 @@ func (ss *StartSession) Stop(t *testing.T) { killProcessFamily(t, ss.cmd.Process.Pid) if t.Failed() { if ss.Stdout.Size() > 0 { - stdout, err := ioutil.ReadAll(ss.Stdout) + stdout, err := io.ReadAll(ss.Stdout) if err != nil { t.Logf("read stdout failed: %v", err) } t.Logf("(dbg) %s stdout:\n%s", ss.cmd.Args, stdout) } if ss.Stderr.Size() > 0 { - stderr, err := ioutil.ReadAll(ss.Stderr) + stderr, err := io.ReadAll(ss.Stderr) if err != nil { t.Logf("read stderr failed: %v", err) } @@ -554,7 +553,7 @@ func testCpCmd(ctx context.Context, t *testing.T, profile string, node string) { t.Errorf("failed to run an cp command. args %q : %v", rr.Command(), err) } - expected, err := ioutil.ReadFile(srcPath) + expected, err := os.ReadFile(srcPath) if err != nil { t.Errorf("failed to read test file 'testdata/cp-test.txt' : %v", err) } @@ -644,14 +643,18 @@ func CopyDir(src, dst string) error { // get the collection of directory entries under src. // for each entry build its corresponding path under dst. - entries, err := ioutil.ReadDir(src) + entries, err := os.ReadDir(src) if err != nil { return err } for _, entry := range entries { // skip symlinks - if entry.Mode()&os.ModeSymlink != 0 { + entryInfo, err := entry.Info() + if err != nil { + return err + } + if entryInfo.Mode()&os.ModeSymlink != 0 { continue } diff --git a/test/integration/mount_start_test.go b/test/integration/mount_start_test.go new file mode 100644 index 0000000000..104c3095c1 --- /dev/null +++ b/test/integration/mount_start_test.go @@ -0,0 +1,90 @@ +//go:build integration +// +build integration + +/* +Copyright 2021 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 integration + +import ( + "context" + "os/exec" + "testing" +) + +// TestMountStart tests using the mount command on start +func TestMountStart(t *testing.T) { + if NoneDriver() { + t.Skip("skipping: none driver does not support mount") + } + + MaybeParallel(t) + + type validateFunc func(context.Context, *testing.T, string) + profile1 := UniqueProfileName("mount-start-1") + profile2 := UniqueProfileName("mount-start-2") + ctx, cancel := context.WithTimeout(context.Background(), Minutes(15)) + defer Cleanup(t, profile1, cancel) + defer Cleanup(t, profile2, cancel) + + // Serial tests + t.Run("serial", func(t *testing.T) { + tests := []struct { + name string + validator validateFunc + profile string + }{ + {"StartWithMountFirst", validateStartWithMount, profile1}, + {"StartWithMountSecond", validateStartWithMount, profile2}, + {"VerifyMountFirst", validateMount, profile1}, + {"VerifyMountSecond", validateMount, profile2}, + {"DeleteFirst", validateDelete, profile1}, + {"VerifyMountPostDelete", validateMount, profile2}, + } + + for _, test := range tests { + if ctx.Err() == context.DeadlineExceeded { + t.Fatalf("Unable to run more tests (deadline exceeded)") + } + + t.Run(test.name, func(t *testing.T) { + test.validator(ctx, t, test.profile) + }) + } + }) +} + +// validateStartWithMount starts a cluster with mount enabled +func validateStartWithMount(ctx context.Context, t *testing.T, profile string) { + defer PostMortemLogs(t, profile) + + args := []string{"start", "-p", profile, "--memory=2048", "--mount"} + rr, err := Run(t, exec.CommandContext(ctx, Target(), args...)) + if err != nil { + t.Fatalf("failed to start minikube with args: %q : %v", rr.Command(), err) + } +} + +// validateMount checks if the cluster has a folder mounted +func validateMount(ctx context.Context, t *testing.T, profile string) { + defer PostMortemLogs(t, profile) + + args := []string{"-p", profile, "ssh", "ls", "/minikube-host"} + rr, err := Run(t, exec.CommandContext(ctx, Target(), args...)) + if err != nil { + t.Fatalf("mount failed: %q : %v", rr.Command(), err) + } +} diff --git a/test/integration/pause_test.go b/test/integration/pause_test.go index b125c7dc4e..3e62a2ebb0 100644 --- a/test/integration/pause_test.go +++ b/test/integration/pause_test.go @@ -173,6 +173,13 @@ func validateVerifyDeleted(ctx context.Context, t *testing.T, profile string) { t.Errorf("expected to see error and volume %q to not exist after deletion but got no error and this output: %s", rr.Command(), rr.Output()) } + rr, err = Run(t, exec.CommandContext(ctx, "sudo", bin, "network", "ls")) + if err != nil { + t.Errorf("failed to get list of networks: %v", err) + } + if strings.Contains(rr.Output(), profile) { + t.Errorf("expected network %q to not exist after deletion but contained: %s", profile, rr.Output()) + } } } diff --git a/test/integration/scheduled_stop_test.go b/test/integration/scheduled_stop_test.go index b44a477117..de5183cd00 100644 --- a/test/integration/scheduled_stop_test.go +++ b/test/integration/scheduled_stop_test.go @@ -22,7 +22,6 @@ package integration import ( "context" "fmt" - "io/ioutil" "os" "os/exec" "runtime" @@ -146,7 +145,7 @@ func checkPID(t *testing.T, profile string) string { var contents []byte getContents := func() error { var err error - contents, err = ioutil.ReadFile(file) + contents, err = os.ReadFile(file) return err } // first, make sure the PID file exists diff --git a/test/integration/skaffold_test.go b/test/integration/skaffold_test.go index 9a10f93c07..6d13af0a08 100644 --- a/test/integration/skaffold_test.go +++ b/test/integration/skaffold_test.go @@ -22,7 +22,6 @@ package integration import ( "context" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -122,7 +121,7 @@ func TestSkaffold(t *testing.T) { // installSkaffold installs the latest release of skaffold func installSkaffold() (f *os.File, err error) { - tf, err := ioutil.TempFile("", "skaffold.exe") + tf, err := os.CreateTemp("", "skaffold.exe") if err != nil { return tf, err } diff --git a/test/integration/testdata/multinodes/multinode-pod-dns-test.yaml b/test/integration/testdata/multinodes/multinode-pod-dns-test.yaml index f23beb0739..b0b5d1779f 100644 --- a/test/integration/testdata/multinodes/multinode-pod-dns-test.yaml +++ b/test/integration/testdata/multinodes/multinode-pod-dns-test.yaml @@ -18,7 +18,7 @@ spec: - name: busybox # flaky nslookup in busybox versions newer than 1.28: # https://github.com/docker-library/busybox/issues/48 - # note: gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 + # note: k8s.gcr.io/e2e-test-images/agnhost:2.32 # has similar issues (ie, resolves but returns exit code 1) image: busybox:1.28 command: diff --git a/test/integration/testdata/netcat-deployment-nomaster.yaml b/test/integration/testdata/netcat-deployment-nomaster.yaml index 7c16d83c43..6bc8f37f73 100644 --- a/test/integration/testdata/netcat-deployment-nomaster.yaml +++ b/test/integration/testdata/netcat-deployment-nomaster.yaml @@ -17,7 +17,7 @@ spec: containers: # dnsutils is easier to debug DNS issues with than the standard busybox image - name: dnsutils - image: gcr.io/kubernetes-e2e-test-images/dnsutils + image: k8s.gcr.io/e2e-test-images/agnhost:2.32 command: ["/bin/sh", "-c", "while true; do echo hello | nc -l -p 8080; done"] affinity: diff --git a/test/integration/testdata/netcat-deployment.yaml b/test/integration/testdata/netcat-deployment.yaml index 6b0d85a6c4..48930cb55d 100644 --- a/test/integration/testdata/netcat-deployment.yaml +++ b/test/integration/testdata/netcat-deployment.yaml @@ -17,7 +17,7 @@ spec: containers: # dnsutils is easier to debug DNS issues with than the standard busybox image - name: dnsutils - image: gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 + image: k8s.gcr.io/e2e-test-images/agnhost:2.32 command: ["/bin/sh", "-c", "while true; do echo hello | nc -l -p 8080; done"] --- diff --git a/test/integration/version_upgrade_test.go b/test/integration/version_upgrade_test.go index 928cadb643..e3812f537d 100644 --- a/test/integration/version_upgrade_test.go +++ b/test/integration/version_upgrade_test.go @@ -20,7 +20,6 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" "os" "os/exec" "runtime" @@ -37,7 +36,7 @@ import ( ) func installRelease(version string) (f *os.File, err error) { - tf, err := ioutil.TempFile("", fmt.Sprintf("minikube-%s.*.exe", version)) + tf, err := os.CreateTemp("", fmt.Sprintf("minikube-%s.*.exe", version)) if err != nil { return tf, err } @@ -117,7 +116,7 @@ func TestRunningBinaryUpgrade(t *testing.T) { } } // using a fresh kubeconfig for this test - legacyKubeConfig, err := ioutil.TempFile("", "legacy_kubeconfig") + legacyKubeConfig, err := os.CreateTemp("", "legacy_kubeconfig") if err != nil { t.Fatalf("failed to create temp file for legacy kubeconfig %v", err) } @@ -176,7 +175,7 @@ func TestStoppedBinaryUpgrade(t *testing.T) { } } // using a fresh kubeconfig for this test - legacyKubeConfig, err := ioutil.TempFile("", "legacy_kubeconfig") + legacyKubeConfig, err := os.CreateTemp("", "legacy_kubeconfig") if err != nil { t.Fatalf("failed to create temp file for legacy kubeconfig %v", err) } diff --git a/third_party/go-dockerclient/tar.go b/third_party/go-dockerclient/tar.go index bb6eee087f..cc5786fa11 100644 --- a/third_party/go-dockerclient/tar.go +++ b/third_party/go-dockerclient/tar.go @@ -7,7 +7,6 @@ package docker import ( "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -112,7 +111,7 @@ func validateContextDirectory(srcPath string, excludes []string) error { func parseDockerignore(root string) ([]string, error) { var excludes []string - ignore, err := ioutil.ReadFile(path.Join(root, ".dockerignore")) + ignore, err := os.ReadFile(path.Join(root, ".dockerignore")) if err != nil && !os.IsNotExist(err) { return excludes, fmt.Errorf("error reading .dockerignore: %w", err) } diff --git a/translations/de.json b/translations/de.json index 84f72afa84..17614c00ff 100644 --- a/translations/de.json +++ b/translations/de.json @@ -956,7 +956,7 @@ "{{ .name }}: Suggestion: {{ .suggestion}}": "", "{{ .name }}: {{ .rejection }}": "", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "", - "{{.count}} nodes stopped.": "", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "", diff --git a/translations/es.json b/translations/es.json index d4b17ff9c4..89b77535c3 100644 --- a/translations/es.json +++ b/translations/es.json @@ -962,7 +962,7 @@ "{{ .name }}: Suggestion: {{ .suggestion}}": "", "{{ .name }}: {{ .rejection }}": "", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "", - "{{.count}} nodes stopped.": "", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "", diff --git a/translations/fr.json b/translations/fr.json index ece72517ba..719cc2c991 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -71,7 +71,7 @@ "Bridge CNI is incompatible with multi-node clusters, use a different CNI": "Le pont CNI est incompatible avec les clusters multi-nœuds, utilisez un autre CNI", "Build a container image in minikube": "Construire une image de conteneur dans minikube", "Build a container image, using the container runtime.": "Construire une image de conteneur à l'aide de l'environnement d'exécution du conteneur.", - "Build image on all nodes.": "", + "Build image on all nodes.": "Construire une image sur tous les nœuds.", "CGroup allocation is not available in your environment, You might be running minikube in a nested container. Try running:\n\t\t\t\n\tminikube start --extra-config=kubelet.cgroups-per-qos=false --extra-config=kubelet.enforce-node-allocatable=\"\"\n\n\t\t\t\n\t\t\t": "L'allocation CGroup n'est pas disponible dans votre environnement, vous exécutez peut-être minikube dans un conteneur imbriqué. Essayez d'exécuter :\n\t\t\t\n\tminikube start --extra-config=kubelet.cgroups-per-qos=false --extra-config=kubelet.enforce-node-allocatable=\"\"\n\n\t\t\t\n\t\t\t", "CGroup allocation is not available in your environment. You might be running minikube in a nested container. Try running:\n\t\t\t\n\tminikube start --extra-config=kubelet.cgroups-per-qos=false --extra-config=kubelet.enforce-node-allocatable=\"\"\n\n\t\t\t\n\t\t\t": "L'allocation CGroup n'est pas disponible dans votre environnement, vous exécutez peut-être minikube dans un conteneur imbriqué. Essayez d'exécuter :\n\t\t\t\n\tminikube start --extra-config=kubelet.cgroups-per-qos=false --extra-config=kubelet.enforce-node-allocatable=\"\"\n\n\t\t\t\n\t\t\t", "CNI plug-in to use. Valid options: auto, bridge, calico, cilium, flannel, kindnet, or path to a CNI manifest (default: auto)": "Plug-in CNI à utiliser. Options valides : auto, bridge, calico, cilium, flannel, kindnet ou chemin vers un manifeste CNI (par défaut : auto)", @@ -266,7 +266,7 @@ "Failed to read temp": "Échec de la lecture du répertoire temporaire", "Failed to reload cached images": "Échec du rechargement des images mises en cache", "Failed to remove image": "Échec de la suppression de l'image", - "Failed to remove images for profile {{.pName}} {{.error}}": "", + "Failed to remove images for profile {{.pName}} {{.error}}": "Échec de la suppression des images pour le profil {{.pName}} {{.error}}", "Failed to save config {{.profile}}": "Échec de l'enregistrement de la configuration {{.profile}}", "Failed to save dir": "Échec de l'enregistrement du répertoire", "Failed to save image": "Échec de l'enregistrement de l'image", @@ -672,7 +672,7 @@ "The minimum required version for podman is \"{{.minVersion}}\". your version is \"{{.currentVersion}}\". minikube might not work. use at your own risk. To install latest version please see https://podman.io/getting-started/installation.html": "La version minimale requise pour podman est \"{{.minVersion}}\". votre version est \"{{.currentVersion}}\". minikube pourrait ne pas fonctionner. À utiliser à vos risques et périls. Pour installer la dernière version, veuillez consulter https://podman.io/getting-started/installation.html", "The name of the network plugin": "Nom du plug-in réseau.", "The named space to activate after start": "L'espace nommé à activer après le démarrage", - "The node to build on. Defaults to the primary control plane.": "", + "The node to build on. Defaults to the primary control plane.": "Le nœud sur lequel construire. La valeur par défaut est le plan de contrôle principal.", "The node to check status for. Defaults to control plane. Leave blank with default format for status on all nodes.": "Le nœud pour lequel vérifier l'état. La valeur par défaut est le plan de contrôle. Laissez vide avec le format par défaut pour l'état sur tous les nœuds.", "The node to get IP. Defaults to the primary control plane.": "Le nœud pour obtenir l'IP. La valeur par défaut est le plan de contrôle principal.", "The node to get logs from. Defaults to the primary control plane.": "Le nœud à partir duquel obtenir les journaux. La valeur par défaut est le plan de contrôle principal.", @@ -976,12 +976,13 @@ "{{ .name }}: {{ .rejection }}": "{{ .name }} : {{ .rejection }}", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "{{.Driver}} utilise actuellement le pilote de stockage {{.StorageDriver}}, envisagez de passer à overlay2 pour de meilleures performances", "{{.count}} nodes stopped.": "{{.count}} nœud(s) arrêté(s).", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "{{.count}} nœud{{if gt .count 1}}s{{end}} arrêté{{if gt .count 1}}s{{end}}.", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} est manquant, il va être recréé.", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "{{.driver_name}} n'a pas pu continuer car le service {{.driver_name}} n'est pas fonctionnel.", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "{{.driver_name}} dispose de moins de 2 processeurs disponibles, mais Kubernetes nécessite au moins 2 procésseurs pour fonctionner", "{{.driver_name}} has only {{.container_limit}}MB memory but you specified {{.specified_memory}}MB": "{{.driver_name}} ne dispose que de {{.container_limit}}Mo de mémoire, mais vous avez spécifié {{.specified_memory}}Mo", "{{.driver}} only has {{.size}}MiB available, less than the required {{.req}}MiB for Kubernetes": "{{.driver}} ne dispose que de {{.size}}Mio disponible, moins que les {{.req}}Mio requis pour Kubernetes", - "{{.err}}": "", + "{{.err}}": "{{.err}}", "{{.extra_option_component_name}}.{{.key}}={{.value}}": "{{.extra_option_component_name}}.{{.key}}={{.value}}", "{{.name}} doesn't have images.": "{{.name}} n'a pas d'images.", "{{.name}} has following images:": "{{.name}} a les images suivantes :", diff --git a/translations/ja.json b/translations/ja.json index 76d69183dc..35710fd831 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -597,53 +597,53 @@ "Suggestion: {{.advice}}": "提案: {{.advice}}", "Suggestion: {{.fix}}": "提案: {{.fix}}", "System only has {{.size}}MiB available, less than the required {{.req}}MiB for Kubernetes": "", - "Tag images": "", - "Tag to apply to the new image (optional)": "", - "Target directory {{.path}} must be an absolute path": "", - "Target {{.path}} can not be empty": "", - "Test docs have been saved at - {{.path}}": "", - "The \"{{.driver_name}}\" driver requires root privileges. Please run minikube using 'sudo minikube --vm-driver={{.driver_name}}": "「{{.driver_name}}」ドライバにはルート権限が必要です。「sudo minikube --vm-driver={{.driver_name}}」を使用して minikube を実行してください", - "The \"{{.driver_name}}\" driver should not be used with root privileges.": "", - "The \"{{.name}}\" cluster has been deleted.": "「{{.name}}」クラスタが削除されました", - "The \"{{.name}}\" cluster has been deleted.__1": "「{{.name}}」クラスタが削除されました", - "The 'none' driver is designed for experts who need to integrate with an existing VM": "", - "The 'none' driver provides limited isolation and may reduce system security and reliability.": "ドライバに「none」を指定すると、分離が制限され、システムのセキュリティと信頼性が低下する可能性があります", - "The '{{.addonName}}' addon is enabled": "", - "The '{{.driver}}' driver requires elevated permissions. The following commands will be executed:\\n\\n{{ .example }}\\n": "", - "The '{{.driver}}' provider was not found: {{.error}}": "", - "The '{{.name}} driver does not support multiple profiles: https://minikube.sigs.k8s.io/docs/reference/drivers/none/": "", - "The '{{.name}}' driver does not respect the --cpus flag": "", - "The '{{.name}}' driver does not respect the --memory flag": "", - "The --image-repository flag your provided contains Scheme: {{.scheme}}, which will be removed automatically": "", - "The --image-repository flag your provided ended with a trailing / that could cause conflict in kuberentes, removed automatically": "", - "The CIDR to be used for service cluster IPs.": "サービス クラスタ IP に使用される CIDR", - "The CIDR to be used for the minikube VM (virtualbox driver only)": "minikube VM に使用される CIDR(virtualbox ドライバのみ)", - "The KVM QEMU connection URI. (kvm2 driver only)": "KVM QEMU 接続 URI(kvm2 ドライバのみ)", - "The KVM default network name. (kvm2 driver only)": "", - "The KVM driver is unable to resurrect this old VM. Please run `minikube delete` to delete it and try again.": "", - "The KVM network name. (kvm2 driver only)": "KVM ネットワーク名(kvm2 ドライバのみ)", - "The VM driver crashed. Run 'minikube start --alsologtostderr -v=8' to see the VM driver error message": "", - "The VM driver exited with an error, and may be corrupt. Run 'minikube start' with --alsologtostderr -v=8 to see the error": "", - "The VM that minikube is configured for no longer exists. Run 'minikube delete'": "", - "The \\\"{{.name}}\\\" container runtime requires CNI": "", - "The ambassador addon has stopped working as of v1.23.0, for more details visit: https://github.com/datawire/ambassador-operator/issues/73": "", - "The apiserver listening port": "API サーバー リスニング ポート", + "Tag images": "イメージのタグ付与", + "Tag to apply to the new image (optional)": "新しいイメージに適用するタグ (任意)", + "Target directory {{.path}} must be an absolute path": "ターゲットディレクトリ {{.path}} は絶対パスでなければなりません。", + "Target {{.path}} can not be empty": "ターゲット {{.path}} は空にできません", + "Test docs have been saved at - {{.path}}": "テストドキュメントは {{.path}} に保存されました", + "The \"{{.driver_name}}\" driver requires root privileges. Please run minikube using 'sudo minikube --vm-driver={{.driver_name}}": "「{{.driver_name}}」ドライバーにはルート権限が必要です。'sudo minikube --vm-driver={{.driver_name}}' を使用して minikube を実行してください", + "The \"{{.driver_name}}\" driver should not be used with root privileges.": "「{{.driver_name}}」ドライバーは root 権限で使用すべきではありません。", + "The \"{{.name}}\" cluster has been deleted.": "「{{.name}}」クラスターが削除されました", + "The \"{{.name}}\" cluster has been deleted.__1": "「{{.name}}」クラスターが削除されました", + "The 'none' driver is designed for experts who need to integrate with an existing VM": "'none' ドライバーは既存 VM の統合が必要なエキスパートに向けて設計されています。", + "The 'none' driver provides limited isolation and may reduce system security and reliability.": "ドライバーに 'none' を指定すると、分離が制限され、システムのセキュリティーと信頼性が低下する可能性があります", + "The '{{.addonName}}' addon is enabled": "'{{.addonName}}' アドオンが有効です", + "The '{{.driver}}' driver requires elevated permissions. The following commands will be executed:\\n\\n{{ .example }}\\n": "'{{.driver}}' ドライバーは権限昇格が必要です。次のコマンドを実行してください:\\n\\n{{ .example }}\\n", + "The '{{.driver}}' provider was not found: {{.error}}": "'{{.driver}}' プロバイダーが見つかりません: {{.error}}", + "The '{{.name}} driver does not support multiple profiles: https://minikube.sigs.k8s.io/docs/reference/drivers/none/": "'{{.name}} ドライバーは複数のプロファイルをサポートしていません: https://minikube.sigs.k8s.io/docs/reference/drivers/none/", + "The '{{.name}}' driver does not respect the --cpus flag": "'{{.name}}' ドライバーは --cpus フラグを無視します", + "The '{{.name}}' driver does not respect the --memory flag": "'{{.name}}' ドライバーは --memory フラグを無視します", + "The --image-repository flag your provided contains Scheme: {{.scheme}}, which will be removed automatically": "指定された --image-repository フラグは {{.scheme}} スキームを含んでいますので、自動的に削除されます", + "The --image-repository flag your provided ended with a trailing / that could cause conflict in kuberentes, removed automatically": "指定された --image-repository フラグは kubernetes で競合の原因となりうる / が末尾に付いていますので、自動的に削除されます", + "The CIDR to be used for service cluster IPs.": "サービスクラスター IP に使用される CIDR。", + "The CIDR to be used for the minikube VM (virtualbox driver only)": "minikube VM に使用される CIDR (virtualbox ドライバーのみ)", + "The KVM QEMU connection URI. (kvm2 driver only)": "KVM QEMU 接続 URI (kvm2 ドライバーのみ)", + "The KVM default network name. (kvm2 driver only)": "KVM デフォルトネットワーク名 (kvm2 ドライバーのみ)", + "The KVM driver is unable to resurrect this old VM. Please run `minikube delete` to delete it and try again.": "KVM ドライバーはこの古い VM を復元できません。`minikube delete` で VM を削除して、再度試行してください。", + "The KVM network name. (kvm2 driver only)": "KVM ネットワーク名 (kvm2 ドライバーのみ)", + "The VM driver crashed. Run 'minikube start --alsologtostderr -v=8' to see the VM driver error message": "VM ドライバーがクラッシュしました。'minikube start --alsologtostderr -v=8' を実行して、VM ドライバーのエラーメッセージを参照してください", + "The VM driver exited with an error, and may be corrupt. Run 'minikube start' with --alsologtostderr -v=8 to see the error": "VM ドライバーがエラー停止したため、破損している可能性があります。'minikube start --alsologtostderr -v=8' を実行して、エラーを参照してください", + "The VM that minikube is configured for no longer exists. Run 'minikube delete'": "minikube が設定された VM はもう存在しません。'minikube delete' を実行してください", + "The \\\"{{.name}}\\\" container runtime requires CNI": "「{{.name}}」コンテナーランタイムは CNI が必要です", + "The ambassador addon has stopped working as of v1.23.0, for more details visit: https://github.com/datawire/ambassador-operator/issues/73": "v1.23.0 で ambassador アドオンは機能を停止しました。 詳細はこちらを参照してください: https://github.com/datawire/ambassador-operator/issues/73", + "The apiserver listening port": "API サーバーリスニングポート", "The apiserver name which is used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine": "Kubernetes 用に生成された証明書で使用される API サーバー名。マシンの外部から API サーバーを利用できるようにする場合に使用します", - "The argument to pass the minikube mount command on start": "起動時に minikube マウント コマンドを渡す引数", - "The argument to pass the minikube mount command on start.": "", - "The authoritative apiserver hostname for apiserver certificates and connectivity. This can be used if you want to make the apiserver available from outside the machine": "", - "The base image to use for docker/podman drivers. Intended for local development.": "", - "The certificate hostname provided appears to be invalid (may be a minikube bug, try 'minikube delete')": "", - "The cluster dns domain name used in the Kubernetes cluster": "", - "The cluster dns domain name used in the kubernetes cluster": "Kubernetes クラスタで使用されるクラスタ DNS ドメイン名", - "The cluster {{.cluster}} already exists which means the --nodes parameter will be ignored. Use \"minikube node add\" to add nodes to an existing cluster.": "", - "The container runtime to be used (docker, crio, containerd)": "使用されるコンテナ ランタイム(docker、crio、containerd)", - "The control plane for \"{{.name}}\" is paused!": "", - "The control plane node \"{{.name}}\" does not exist.": "", - "The control plane node is not running (state={{.state}})": "", - "The control plane node must be running for this command": "", + "The argument to pass the minikube mount command on start": "起動時に minikube マウントコマンドを渡す引数", + "The argument to pass the minikube mount command on start.": "起動時に minikube マウントコマンドを渡す引数。", + "The authoritative apiserver hostname for apiserver certificates and connectivity. This can be used if you want to make the apiserver available from outside the machine": "API サーバーの証明書と接続のための、権威 API サーバーホスト名。マシン外部から API サーバーに接続できるようにしたい場合に使用します。", + "The base image to use for docker/podman drivers. Intended for local development.": "Docker/Podman ドライバーで使用されるベースイメージ。ローカルデプロイ用です。", + "The certificate hostname provided appears to be invalid (may be a minikube bug, try 'minikube delete')": "提供された証明書ホスト名が無効のようです (minikube のバグかも知れません。'minikube delete' を試してください)", + "The cluster dns domain name used in the Kubernetes cluster": "Kubernetes クラスターで使用されるクラスター DNS ドメイン名", + "The cluster dns domain name used in the kubernetes cluster": "Kubernetes クラスターで使用されるクラスター DNS ドメイン名", + "The cluster {{.cluster}} already exists which means the --nodes parameter will be ignored. Use \"minikube node add\" to add nodes to an existing cluster.": "{{.cluster}} クラスターは既に存在するので、--nodes パラメーターは無視されます。「minikube node add」を使って、既存クラスターにノードを追加してください。", + "The container runtime to be used (docker, crio, containerd)": "使用されるコンテナーランタイム (docker、crio、containerd)", + "The control plane for \"{{.name}}\" is paused!": "「{{.name}}」用コントロールプレーンは一時停止中です!", + "The control plane node \"{{.name}}\" does not exist.": "「{{.name}}」コントロールプレーンノードが存在しません。", + "The control plane node is not running (state={{.state}})": "コントロールプレーンノードは実行中ではありません (state={{.state}})", + "The control plane node must be running for this command": "このコマンドではコントロールプレーンノードが実行中でなければなりません", "The cri socket path to be used": "使用される CRI ソケットパス", - "The cri socket path to be used.": "", + "The cri socket path to be used.": "使用される CRI ソケットパス。", "The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "", "The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "", "The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "ドライバ「{{.driver}}」は、{{.os}}/{{.arch}} ではサポートされていません", @@ -978,6 +978,7 @@ "{{.cluster}} IP has been updated to point at {{.ip}}": "{{.cluster}} の IP アドレスは {{.ip}} へと更新されました", "{{.cluster}} IP was already correctly configured for {{.ip}}": "{{.cluster}} の IP アドレスは {{.ip}} としてすでに正常に設定されています", "{{.count}} nodes stopped.": "{{.count}}台のノードが停止しました。", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "{{.driver_name}} 「 {{.cluster}} 」 {{.machine_type}} がありません。再生成します。", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "", diff --git a/translations/ko.json b/translations/ko.json index 192ddd1d06..fededccb14 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -972,6 +972,7 @@ "{{ .name }}: {{ .rejection }}": "", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "", "{{.count}} nodes stopped.": "{{.count}}개의 노드가 중지되었습니다.", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "", diff --git a/translations/pl.json b/translations/pl.json index 3c3f488c4e..dd30d67b82 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -975,7 +975,7 @@ "{{ .name }}: {{ .rejection }}": "", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "", "{{.addonName}} was successfully enabled": "{{.addonName}} został aktywowany pomyślnie", - "{{.count}} nodes stopped.": "", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "", diff --git a/translations/strings.txt b/translations/strings.txt index 1459f5f1f0..34a7d23095 100644 --- a/translations/strings.txt +++ b/translations/strings.txt @@ -900,7 +900,7 @@ "{{ .name }}: Suggestion: {{ .suggestion}}": "", "{{ .name }}: {{ .rejection }}": "", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "", - "{{.count}} nodes stopped.": "", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index 6a1aae7ad4..5c75da958c 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -1083,7 +1083,7 @@ "{{ .name }}: Suggestion: {{ .suggestion}}": "", "{{ .name }}: {{ .rejection }}": "", "{{.Driver}} is currently using the {{.StorageDriver}} storage driver, consider switching to overlay2 for better performance": "", - "{{.count}} nodes stopped.": "", + "{{.count}} node{{if gt .count 1}}s{{end}} stopped.": "", "{{.driver_name}} \"{{.cluster}}\" {{.machine_type}} is missing, will recreate.": "", "{{.driver_name}} couldn't proceed because {{.driver_name}} service is not healthy.": "", "{{.driver_name}} has less than 2 CPUs available, but Kubernetes requires at least 2 to be available": "",