From 9f753c3027b53b13ffd15ba7e85e4fd7622ae876 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 25 Mar 2019 18:25:01 -0700 Subject: [PATCH 01/14] Fix all the kubeadm config generation bugs I could find, add tests across versions --- .../bootstrapper/kubeadm/kubeadm_test.go | 489 +++++------------- .../bootstrapper/kubeadm/templates.go | 40 +- .../containerd-api-port__default.yaml | 39 ++ .../testdata/containerd-api-port__new.yaml | 43 ++ .../containerd-api-port__obsolete.yaml | 17 + .../testdata/containerd-api-port__old.yaml | 39 ++ .../testdata/containerd-api-port__recent.yaml | 39 ++ .../kubeadm/testdata/containerd__default.yaml | 39 ++ .../kubeadm/testdata/containerd__new.yaml | 43 ++ .../testdata/containerd__obsolete.yaml | 17 + .../kubeadm/testdata/containerd__old.yaml | 39 ++ .../kubeadm/testdata/containerd__recent.yaml | 39 ++ .../testdata/crio-options-gates__default.yaml | 49 ++ .../testdata/crio-options-gates__new.yaml | 56 ++ .../crio-options-gates__obsolete.yaml | 27 + .../testdata/crio-options-gates__old.yaml | 49 ++ .../testdata/crio-options-gates__recent.yaml | 49 ++ .../kubeadm/testdata/crio__default.yaml | 39 ++ .../kubeadm/testdata/crio__new.yaml | 43 ++ .../kubeadm/testdata/crio__obsolete.yaml | 17 + .../kubeadm/testdata/crio__old.yaml | 39 ++ .../kubeadm/testdata/crio__recent.yaml | 39 ++ .../kubeadm/testdata/default__default.yaml | 39 ++ .../kubeadm/testdata/default__new.yaml | 43 ++ .../kubeadm/testdata/default__obsolete.yaml | 16 + .../kubeadm/testdata/default__old.yaml | 39 ++ .../kubeadm/testdata/default__recent.yaml | 39 ++ .../testdata/image-repository__default.yaml | 40 ++ .../testdata/image-repository__new.yaml | 44 ++ .../testdata/image-repository__obsolete.yaml | 17 + .../testdata/image-repository__old.yaml | 40 ++ .../testdata/image-repository__recent.yaml | 40 ++ .../kubeadm/testdata/options__default.yaml | 44 ++ .../kubeadm/testdata/options__new.yaml | 50 ++ .../kubeadm/testdata/options__obsolete.yaml | 21 + .../kubeadm/testdata/options__old.yaml | 44 ++ .../kubeadm/testdata/options__recent.yaml | 44 ++ pkg/minikube/constants/constants.go | 6 + test/integration/start_stop_delete_test.go | 25 +- 39 files changed, 1490 insertions(+), 391 deletions(-) create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__recent.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/containerd__recent.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__recent.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/crio__recent.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/default__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/default__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/default__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/default__recent.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__recent.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/options__new.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/options__obsolete.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/options__old.yaml create mode 100644 pkg/minikube/bootstrapper/kubeadm/testdata/options__recent.yaml diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go index 7f780f9e8a..8017f44db7 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go @@ -17,37 +17,46 @@ limitations under the License. package kubeadm import ( - "strings" + "fmt" + "io/ioutil" "testing" - "github.com/google/go-cmp/cmp" + "github.com/pmezard/go-difflib/difflib" "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/cruntime" "k8s.io/minikube/pkg/util" ) +const ( + newMajor = "v1.14.0" + recentMajor = "v1.13.0" + oldMajor = "v1.12.0" + obsoleteMajor = "v1.10.0" +) + func TestGenerateKubeletConfig(t *testing.T) { tests := []struct { description string cfg config.KubernetesConfig - expectedCfg string + expected string shouldErr bool }{ { description: "docker runtime", cfg: config.KubernetesConfig{ NodeIP: "192.168.1.100", - KubernetesVersion: "v1.1.0", + KubernetesVersion: recentMajor, NodeName: "minikube", ContainerRuntime: "docker", }, - expectedCfg: ` + expected: ` [Unit] Wants=docker.socket [Service] ExecStart= -ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cadvisor-port=0 --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/manifests --require-kubeconfig=true +ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/manifests [Install] `, @@ -56,419 +65,161 @@ ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook description: "cri runtime", cfg: config.KubernetesConfig{ NodeIP: "192.168.1.100", - KubernetesVersion: "v1.1.0", + KubernetesVersion: constants.NewestKubernetesVersion, NodeName: "minikube", ContainerRuntime: "cri-o", }, - expectedCfg: ` + expected: ` [Unit] Wants=crio.service [Service] ExecStart= -ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cadvisor-port=0 --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock --hostname-override=minikube --image-service-endpoint=/var/run/crio/crio.sock --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/manifests --require-kubeconfig=true --runtime-request-timeout=15m +ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=/var/run/crio/crio.sock --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m [Install] `, }, { - description: "docker runtime with custom image repository", + description: "newest docker with custom image repository", cfg: config.KubernetesConfig{ NodeIP: "192.168.1.100", - KubernetesVersion: "v1.1.0", + KubernetesVersion: constants.DefaultKubernetesVersion, NodeName: "minikube", ContainerRuntime: "docker", ImageRepository: "docker-proxy-image.io/google_containers", }, - expectedCfg: ` + expected: ` [Unit] Wants=docker.socket [Service] ExecStart= -ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cadvisor-port=0 --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --pod-infra-container-image=docker-proxy-image.io/google_containers//pause-amd64:3.0 --pod-manifest-path=/etc/kubernetes/manifests --require-kubeconfig=true +ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --pod-infra-container-image=docker-proxy-image.io/google_containers/pause-amd64:3.1 --pod-manifest-path=/etc/kubernetes/manifests [Install] `, }, } - for _, test := range tests { - t.Run(test.description, func(t *testing.T) { - runtime, err := cruntime.New(cruntime.Config{Type: test.cfg.ContainerRuntime}) + for _, tc := range tests { + t.Run(tc.description, func(t *testing.T) { + runtime, err := cruntime.New(cruntime.Config{Type: tc.cfg.ContainerRuntime}) if err != nil { t.Fatalf("runtime: %v", err) } - actualCfg, err := NewKubeletConfig(test.cfg, runtime) - if err != nil && !test.shouldErr { + got, err := NewKubeletConfig(tc.cfg, runtime) + if err != nil && !tc.shouldErr { t.Errorf("got unexpected error generating config: %v", err) return } - if err == nil && test.shouldErr { - t.Errorf("expected error but got none, config: %s", actualCfg) + if err == nil && tc.shouldErr { + t.Errorf("expected error but got none, config: %s", got) return } - if diff := cmp.Diff(test.expectedCfg, actualCfg); diff != "" { - t.Errorf("actual config does not match expected. (-want +got)\n%s", diff) + + diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(tc.expected), + B: difflib.SplitLines(got), + FromFile: "Expected", + ToFile: "Got", + Context: 1, + }) + if err != nil { + t.Fatalf("diff error: %v", err) + } + if diff != "" { + t.Errorf("unexpected diff:\n%s", diff) } }) } } func TestGenerateConfig(t *testing.T) { - tests := []struct { - description string - cfg config.KubernetesConfig - expectedCfg string - shouldErr bool - }{ - { - description: "no extra args", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.100", - KubernetesVersion: "v1.10.0", - NodeName: "minikube", - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.100 - bindPort: 8443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: minikube -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" -`, + extraOpts := util.ExtraOptionSlice{ + util.ExtraOption{ + Component: Apiserver, + Key: "fail-no-swap", + Value: "true", }, - { - description: "extra args all components", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.101", - KubernetesVersion: "v1.10.0-alpha.0", - NodeName: "extra-args-minikube", - ExtraOptions: util.ExtraOptionSlice{ - util.ExtraOption{ - Component: Apiserver, - Key: "fail-no-swap", - Value: "true", - }, - util.ExtraOption{ - Component: ControllerManager, - Key: "kube-api-burst", - Value: "32", - }, - util.ExtraOption{ - Component: Scheduler, - Key: "scheduler-name", - Value: "mini-scheduler", - }, - }, - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.101 - bindPort: 8443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0-alpha.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: extra-args-minikube -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" - fail-no-swap: "true" -controllerManagerExtraArgs: - kube-api-burst: "32" -schedulerExtraArgs: - scheduler-name: "mini-scheduler" -`, + util.ExtraOption{ + Component: ControllerManager, + Key: "kube-api-burst", + Value: "32", }, - { - description: "extra args, v1.14.0", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.101", - KubernetesVersion: "v1.14.0-beta1", - NodeName: "extra-args-minikube-114", - ExtraOptions: util.ExtraOptionSlice{ - util.ExtraOption{ - Component: Apiserver, - Key: "fail-no-swap", - Value: "true", - }, - util.ExtraOption{ - Component: ControllerManager, - Key: "kube-api-burst", - Value: "32", - }, - }, - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1beta1 -kind: InitConfiguration -localAPIEndpoint: - advertiseAddress: 192.168.1.101 - bindPort: 8443 -bootstrapTokens: -- groups: - - system:bootstrappers:kubeadm:default-node-token - ttl: 24h0m0s - usages: - - signing - - authentication -nodeRegistration: - criSocket: /var/run/dockershim.sock - name: extra-args-minikube-114 - taints: [] ---- -apiVersion: kubeadm.k8s.io/v1beta1 -kind: ClusterConfiguration -apiServer: - extraArgs: - enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota"fail-no-swap: "true" -controllerManager: - extraArgs: - kube-api-burst: "32" -certificatesDir: /var/lib/minikube/certs/ -clusterName: kubernetes -controlPlaneEndpoint: localhost:8443 -dns: - type: CoreDNS -etcd: - local: - dataDir: /data/minikube -kubernetesVersion: v1.14.0-beta1 -networking: - dnsDomain: cluster.local - podSubnet: "" - serviceSubnet: 10.96.0.0/12 ---- -apiVersion: kubelet.config.k8s.io/v1beta1 -kind: KubeletConfiguration -imageGCHighThresholdPercent: 100 -evictionHard: - nodefs.available: "0%" - nodefs.inodesFree: "0%" - imagefs.available: "0%" -`, - }, { - description: "two extra args for one component", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.101", - KubernetesVersion: "v1.10.0-alpha.0", - NodeName: "extra-args-minikube", - ExtraOptions: util.ExtraOptionSlice{ - util.ExtraOption{ - Component: Apiserver, - Key: "fail-no-swap", - Value: "true", - }, - util.ExtraOption{ - Component: Apiserver, - Key: "kube-api-burst", - Value: "32", - }, - }, - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.101 - bindPort: 8443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0-alpha.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: extra-args-minikube -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" - fail-no-swap: "true" - kube-api-burst: "32" -`, - }, - { - description: "enable feature gates", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.101", - KubernetesVersion: "v1.10.0-alpha.0", - NodeName: "extra-args-minikube", - FeatureGates: "HugePages=true,OtherFeature=false", - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.101 - bindPort: 8443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0-alpha.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: extra-args-minikube -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" - feature-gates: "HugePages=true,OtherFeature=false" -controllerManagerExtraArgs: - feature-gates: "HugePages=true,OtherFeature=false" -kubeadmExtraArgs: - feature-gates: "HugePages=true,OtherFeature=false" -schedulerExtraArgs: - feature-gates: "HugePages=true,OtherFeature=false" -`, - }, - { - description: "enable feature gates and extra config", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.101", - KubernetesVersion: "v1.10.0-alpha.0", - NodeName: "extra-args-minikube", - FeatureGates: "HugePages=true,OtherFeature=false", - ExtraOptions: util.ExtraOptionSlice{ - util.ExtraOption{ - Component: Apiserver, - Key: "fail-no-swap", - Value: "true", - }, - }, - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.101 - bindPort: 8443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0-alpha.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: extra-args-minikube -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" - fail-no-swap: "true" - feature-gates: "HugePages=true,OtherFeature=false" -controllerManagerExtraArgs: - feature-gates: "HugePages=true,OtherFeature=false" -kubeadmExtraArgs: - feature-gates: "HugePages=true,OtherFeature=false" -schedulerExtraArgs: - feature-gates: "HugePages=true,OtherFeature=false" -`, - }, - { - // Unknown components should fail silently - description: "unknown component", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.101", - KubernetesVersion: "v1.8.0-alpha.0", - NodeName: "extra-args-minikube", - ExtraOptions: util.ExtraOptionSlice{ - util.ExtraOption{ - Component: "not-a-real-component", - Key: "killswitch", - Value: "true", - }, - }, - }, - shouldErr: true, - }, - { - description: "custom api server port", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.100", - NodePort: 18443, - KubernetesVersion: "v1.10.0", - NodeName: "minikube", - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.100 - bindPort: 18443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: minikube -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" -`, - }, - { - description: "custom image repository", - cfg: config.KubernetesConfig{ - NodeIP: "192.168.1.100", - KubernetesVersion: "v1.10.0", - NodeName: "minikube", - ImageRepository: "docker-proxy-image.io/google_containers", - }, - expectedCfg: `apiVersion: kubeadm.k8s.io/v1alpha1 -kind: MasterConfiguration -noTaintMaster: true -api: - advertiseAddress: 192.168.1.100 - bindPort: 8443 - controlPlaneEndpoint: localhost -kubernetesVersion: v1.10.0 -certificatesDir: /var/lib/minikube/certs/ -networking: - serviceSubnet: 10.96.0.0/12 -etcd: - dataDir: /data/minikube -nodeName: minikube -imageRepository: docker-proxy-image.io/google_containers -apiServerExtraArgs: - admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" -`, + util.ExtraOption{ + Component: Scheduler, + Key: "scheduler-name", + Value: "mini-scheduler", }, } - for _, test := range tests { - runtime, err := cruntime.New(cruntime.Config{Type: "docker"}) - if err != nil { - t.Fatalf("runtime: %v", err) + // Test version policy: Last 4 major releases (slightly looser than our general policy) + versions := map[string]string{ + "default": constants.DefaultKubernetesVersion, + "new": newMajor, + "recent": recentMajor, + "old": oldMajor, + "obsolete": obsoleteMajor, + } + + tests := []struct { + name string + runtime string + shouldErr bool + cfg config.KubernetesConfig + }{ + {"default", "docker", false, config.KubernetesConfig{}}, + {"containerd", "containerd", false, config.KubernetesConfig{}}, + {"crio", "crio", false, config.KubernetesConfig{}}, + {"options", "docker", false, config.KubernetesConfig{ExtraOptions: extraOpts}}, + {"crio-options-gates", "crio", false, config.KubernetesConfig{ExtraOptions: extraOpts, FeatureGates: "a=b"}}, + {"unknown-omponent", "docker", true, config.KubernetesConfig{ExtraOptions: util.ExtraOptionSlice{util.ExtraOption{Component: "not-a-real-component", Key: "killswitch", Value: "true"}}}}, + {"containerd-api-port", "containerd", false, config.KubernetesConfig{NodePort: 12345}}, + {"image-repository", "docker", false, config.KubernetesConfig{ImageRepository: "test/repo"}}, + } + for vname, version := range versions { + for _, tc := range tests { + runtime, err := cruntime.New(cruntime.Config{Type: tc.runtime}) + if err != nil { + t.Fatalf("runtime: %v", err) + } + tname := tc.name + "__" + vname + t.Run(tname, func(t *testing.T) { + cfg := tc.cfg + cfg.NodeIP = "1.1.1.1" + cfg.NodeName = "mk" + cfg.KubernetesVersion = version + + got, err := generateConfig(cfg, runtime) + if err != nil && !tc.shouldErr { + t.Fatalf("got unexpected error generating config: %v", err) + } + if err == nil && tc.shouldErr { + t.Fatalf("expected error but got none, config: %s", got) + } + if tc.shouldErr { + return + } + expected, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.yaml", tname)) + if err != nil { + t.Fatalf("unable to read testdata: %v", err) + } + diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(string(expected)), + B: difflib.SplitLines(got), + FromFile: "Expected", + ToFile: "Got", + Context: 1, + }) + if err != nil { + t.Fatalf("diff error: %v", err) + } + if diff != "" { + t.Errorf("unexpected diff:\n%s\n===== [RAW OUTPUT] =====\n%s", diff, got) + } + }) } - - t.Run(test.description, func(t *testing.T) { - gotCfg, err := generateConfig(test.cfg, runtime) - if err != nil && !test.shouldErr { - t.Errorf("got unexpected error generating config: %v", err) - return - } - if err == nil && test.shouldErr { - t.Errorf("expected error but got none, config: %s", gotCfg) - return - } - - // cmp.Diff doesn't present diffs of multi-line text well - gotSplit := strings.Split(gotCfg, "\n") - wantSplit := strings.Split(test.expectedCfg, "\n") - if diff := cmp.Diff(gotSplit, wantSplit); diff != "" { - t.Errorf("unexpected diff: (-want +got)\n%s\ngot: %s\n", diff, gotCfg) - } - }) } } diff --git a/pkg/minikube/bootstrapper/kubeadm/templates.go b/pkg/minikube/bootstrapper/kubeadm/templates.go index 7df240f120..e5a63efc44 100644 --- a/pkg/minikube/bootstrapper/kubeadm/templates.go +++ b/pkg/minikube/bootstrapper/kubeadm/templates.go @@ -56,12 +56,12 @@ apiEndpoint: advertiseAddress: {{.AdvertiseAddress}} bindPort: {{.APIServerPort}} bootstrapTokens: -- groups: - - system:bootstrappers:kubeadm:default-node-token - ttl: 24h0m0s - usages: - - signing - - authentication + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication nodeRegistration: criSocket: {{if .CRISocket}}{{.CRISocket}}{{else}}/var/run/dockershim.sock{{end}} name: {{.NodeName}} @@ -72,9 +72,10 @@ kind: ClusterConfiguration {{if .ImageRepository}}imageRepository: {{.ImageRepository}} {{end}}{{range .ExtraArgs}}{{.Component}}ExtraArgs:{{range $i, $val := printMapInOrder .Options ": " }} {{$val}}{{end}} -{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}} +{{end -}} +{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}} {{$i}}: {{$val}}{{end}} -{{end}} +{{end -}} certificatesDir: {{.CertDir}} clusterName: kubernetes controlPlaneEndpoint: localhost:{{.APIServerPort}} @@ -104,12 +105,12 @@ localAPIEndpoint: advertiseAddress: {{.AdvertiseAddress}} bindPort: {{.APIServerPort}} bootstrapTokens: -- groups: - - system:bootstrappers:kubeadm:default-node-token - ttl: 24h0m0s - usages: - - signing - - authentication + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication nodeRegistration: criSocket: {{if .CRISocket}}{{.CRISocket}}{{else}}/var/run/dockershim.sock{{end}} name: {{.NodeName}} @@ -117,13 +118,16 @@ nodeRegistration: --- apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -{{if .ImageRepository}}imageRepository: {{.ImageRepository}} +{{ if .ImageRepository}}imageRepository: {{.ImageRepository}} {{end}}{{range .ExtraArgs}}{{.Component}}: extraArgs: - {{range $i, $val := printMapInOrder .Options ": " }}{{$val}}{{end}} -{{end}}{{if .FeatureArgs}}featureGates: {{range $i, $val := .FeatureArgs}} - {{$i}}: {{$val}}{{end}} +{{- range $i, $val := printMapInOrder .Options ": " }} + {{$val}} +{{- end}} {{end -}} +{{if .FeatureArgs}}featureGates: +{{range $i, $val := .FeatureArgs}}{{$i}}: {{$val}} +{{end -}}{{end -}} certificatesDir: {{.CertDir}} clusterName: kubernetes controlPlaneEndpoint: localhost:{{.APIServerPort}} diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml new file mode 100644 index 0000000000..47e5c97cdc --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 12345 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:12345 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__new.yaml new file mode 100644 index 0000000000..cc96f136ac --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__new.yaml @@ -0,0 +1,43 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 12345 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:12345 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__obsolete.yaml new file mode 100644 index 0000000000..40c91637f3 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__obsolete.yaml @@ -0,0 +1,17 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 12345 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +criSocket: /run/containerd/containerd.sock +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__old.yaml new file mode 100644 index 0000000000..7d84e36369 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__old.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 12345 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:12345 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__recent.yaml new file mode 100644 index 0000000000..e776755631 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__recent.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 12345 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:12345 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml new file mode 100644 index 0000000000..8ffec02733 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__new.yaml new file mode 100644 index 0000000000..147a6ccbec --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__new.yaml @@ -0,0 +1,43 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__obsolete.yaml new file mode 100644 index 0000000000..b2d73f912b --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__obsolete.yaml @@ -0,0 +1,17 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 8443 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +criSocket: /run/containerd/containerd.sock +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__old.yaml new file mode 100644 index 0000000000..4e4b1e4830 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__old.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__recent.yaml new file mode 100644 index 0000000000..a852561fbe --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__recent.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /run/containerd/containerd.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml new file mode 100644 index 0000000000..e59290cbd3 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml @@ -0,0 +1,49 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" + feature-gates: "a=b" +controllerManagerExtraArgs: + feature-gates: "a=b" + kube-api-burst: "32" +kubeadmExtraArgs: + feature-gates: "a=b" +schedulerExtraArgs: + feature-gates: "a=b" + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__new.yaml new file mode 100644 index 0000000000..b593f313d3 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__new.yaml @@ -0,0 +1,56 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" + feature-gates: "a=b" +controllerManager: + extraArgs: + feature-gates: "a=b" + kube-api-burst: "32" +kubeadm: + extraArgs: + feature-gates: "a=b" +scheduler: + extraArgs: + feature-gates: "a=b" + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__obsolete.yaml new file mode 100644 index 0000000000..0635574f4c --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__obsolete.yaml @@ -0,0 +1,27 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 8443 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +criSocket: /var/run/crio/crio.sock +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" + feature-gates: "a=b" +controllerManagerExtraArgs: + feature-gates: "a=b" + kube-api-burst: "32" +kubeadmExtraArgs: + feature-gates: "a=b" +schedulerExtraArgs: + feature-gates: "a=b" + scheduler-name: "mini-scheduler" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__old.yaml new file mode 100644 index 0000000000..cf204e307a --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__old.yaml @@ -0,0 +1,49 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" + feature-gates: "a=b" +controllerManagerExtraArgs: + feature-gates: "a=b" + kube-api-burst: "32" +kubeadmExtraArgs: + feature-gates: "a=b" +schedulerExtraArgs: + feature-gates: "a=b" + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__recent.yaml new file mode 100644 index 0000000000..49e8c06a9f --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__recent.yaml @@ -0,0 +1,49 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" + feature-gates: "a=b" +controllerManagerExtraArgs: + feature-gates: "a=b" + kube-api-burst: "32" +kubeadmExtraArgs: + feature-gates: "a=b" +schedulerExtraArgs: + feature-gates: "a=b" + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml new file mode 100644 index 0000000000..9002456c7d --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__new.yaml new file mode 100644 index 0000000000..66dac1c8af --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__new.yaml @@ -0,0 +1,43 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__obsolete.yaml new file mode 100644 index 0000000000..f68df3416f --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__obsolete.yaml @@ -0,0 +1,17 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 8443 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +criSocket: /var/run/crio/crio.sock +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__old.yaml new file mode 100644 index 0000000000..033a7aefe2 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__old.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__recent.yaml new file mode 100644 index 0000000000..57b9f1b122 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__recent.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/crio/crio.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml new file mode 100644 index 0000000000..d1581fc1f9 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/default__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/default__new.yaml new file mode 100644 index 0000000000..d88c0efebf --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/default__new.yaml @@ -0,0 +1,43 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/default__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/default__obsolete.yaml new file mode 100644 index 0000000000..9f0ea00701 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/default__obsolete.yaml @@ -0,0 +1,16 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 8443 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/default__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/default__old.yaml new file mode 100644 index 0000000000..d9ba1066a5 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/default__old.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/default__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/default__recent.yaml new file mode 100644 index 0000000000..db611e2263 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/default__recent.yaml @@ -0,0 +1,39 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml new file mode 100644 index 0000000000..11b10ebfe3 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml @@ -0,0 +1,40 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +imageRepository: test/repo +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__new.yaml new file mode 100644 index 0000000000..bf53791b71 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__new.yaml @@ -0,0 +1,44 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +imageRepository: test/repo +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__obsolete.yaml new file mode 100644 index 0000000000..cebbc924ed --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__obsolete.yaml @@ -0,0 +1,17 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 8443 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +imageRepository: test/repo +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__old.yaml new file mode 100644 index 0000000000..bf00349785 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__old.yaml @@ -0,0 +1,40 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +imageRepository: test/repo +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__recent.yaml new file mode 100644 index 0000000000..037dd6add2 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__recent.yaml @@ -0,0 +1,40 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +imageRepository: test/repo +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml new file mode 100644 index 0000000000..2b53cec03a --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml @@ -0,0 +1,44 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" +controllerManagerExtraArgs: + kube-api-burst: "32" +schedulerExtraArgs: + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.4 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/options__new.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/options__new.yaml new file mode 100644 index 0000000000..a85a2447b2 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/options__new.yaml @@ -0,0 +1,50 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" +controllerManager: + extraArgs: + kube-api-burst: "32" +scheduler: + extraArgs: + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.14.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/options__obsolete.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/options__obsolete.yaml new file mode 100644 index 0000000000..97fcc2e56e --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/options__obsolete.yaml @@ -0,0 +1,21 @@ +apiVersion: kubeadm.k8s.io/v1alpha1 +kind: MasterConfiguration +noTaintMaster: true +api: + advertiseAddress: 1.1.1.1 + bindPort: 8443 + controlPlaneEndpoint: localhost +kubernetesVersion: v1.10.0 +certificatesDir: /var/lib/minikube/certs/ +networking: + serviceSubnet: 10.96.0.0/12 +etcd: + dataDir: /data/minikube +nodeName: mk +apiServerExtraArgs: + admission-control: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" +controllerManagerExtraArgs: + kube-api-burst: "32" +schedulerExtraArgs: + scheduler-name: "mini-scheduler" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/options__old.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/options__old.yaml new file mode 100644 index 0000000000..3e9052efa8 --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/options__old.yaml @@ -0,0 +1,44 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" +controllerManagerExtraArgs: + kube-api-burst: "32" +schedulerExtraArgs: + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/options__recent.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/options__recent.yaml new file mode 100644 index 0000000000..f1df66954d --- /dev/null +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/options__recent.yaml @@ -0,0 +1,44 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 1.1.1.1 + bindPort: 8443 +bootstrapTokens: + - groups: + - system:bootstrappers:kubeadm:default-node-token + ttl: 24h0m0s + usages: + - signing + - authentication +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: mk + taints: [] +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration +apiServerExtraArgs: + enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" +controllerManagerExtraArgs: + kube-api-burst: "32" +schedulerExtraArgs: + scheduler-name: "mini-scheduler" +certificatesDir: /var/lib/minikube/certs/ +clusterName: kubernetes +controlPlaneEndpoint: localhost:8443 +etcd: + local: + dataDir: /data/minikube +kubernetesVersion: v1.13.0 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +evictionHard: + nodefs.available: "0%" + nodefs.inodesFree: "0%" + imagefs.available: "0%" diff --git a/pkg/minikube/constants/constants.go b/pkg/minikube/constants/constants.go index 9025e0e4ef..c2ac821dab 100644 --- a/pkg/minikube/constants/constants.go +++ b/pkg/minikube/constants/constants.go @@ -156,6 +156,12 @@ var DefaultISOSHAURL = DefaultISOURL + SHASuffix // DefaultKubernetesVersion is the default kubernetes version var DefaultKubernetesVersion = "v1.13.4" +// NewestKubernetesVersion is the newest Kubernetes version to test against +var NewestKubernetesVersion = "v1.14.0" + +// OldestKubernetesVersion is the oldest Kubernetes version to test against +var OldestKubernetesVersion = "v1.10.13" + // ConfigFilePath is the path of the config directory var ConfigFilePath = MakeMiniPath("config") diff --git a/test/integration/start_stop_delete_test.go b/test/integration/start_stop_delete_test.go index d6d2ac0d0e..8616b4a810 100644 --- a/test/integration/start_stop_delete_test.go +++ b/test/integration/start_stop_delete_test.go @@ -19,12 +19,14 @@ limitations under the License. package integration import ( + "fmt" "net" "strings" "testing" "time" "github.com/docker/machine/libmachine/state" + "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/test/integration/util" ) @@ -33,10 +35,25 @@ func TestStartStop(t *testing.T) { name string args []string }{ - {"docker+cache", []string{"--container-runtime=docker", "--cache-images"}}, - {"docker+cache+ignore_verifications", []string{"--container-runtime=docker", "--cache-images", "--extra-config", "kubeadm.ignore-preflight-errors=SystemVerification"}}, - {"containerd+cache", []string{"--container-runtime=containerd", "--docker-opt containerd=/var/run/containerd/containerd.sock", "--cache-images"}}, - {"crio+cache", []string{"--container-runtime=crio", "--cache-images"}}, + {"docker+no-cache+oldest", []string{ + "--container-runtime=docker", + "--cache-images=false", + fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion), + }}, + {"docker+ignore_verifications+newest+gates", []string{ + "--container-runtime=docker", + "--extra-config", + "kubeadm.ignore-preflight-errors=SystemVerification", + "--feature-gates", + fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion), + }}, + {"containerd", []string{ + "--container-runtime=containerd", + "--docker-opt containerd=/var/run/containerd/containerd.sock", + }}, + {"crio", []string{ + "--container-runtime=crio", + }}, } for _, test := range tests { From 66cf896de4cf0549b21b1ef9a40fe06c7478c529 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 25 Mar 2019 18:29:22 -0700 Subject: [PATCH 02/14] Add difflib --- Gopkg.lock | 9 + vendor/github.com/pmezard/go-difflib/LICENSE | 27 + .../pmezard/go-difflib/difflib/difflib.go | 772 ++++++++++++++++++ 3 files changed, 808 insertions(+) create mode 100644 vendor/github.com/pmezard/go-difflib/LICENSE create mode 100644 vendor/github.com/pmezard/go-difflib/difflib/difflib.go diff --git a/Gopkg.lock b/Gopkg.lock index 5bc2516ee7..3e13432fd5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -505,6 +505,14 @@ pruneopts = "NUT" revision = "4d0e916071f68db74f8a73926335f809396d6b42" +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "NUT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + [[projects]] branch = "master" digest = "1:1b6f62a965e4b2e004184bf2d38ef2915af240befa4d44e5f0e83925bcf89727" @@ -1008,6 +1016,7 @@ "github.com/pkg/browser", "github.com/pkg/errors", "github.com/pkg/profile", + "github.com/pmezard/go-difflib/difflib", "github.com/r2d4/external-storage/lib/controller", "github.com/sirupsen/logrus", "github.com/spf13/cobra", diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/pmezard/go-difflib/LICENSE new file mode 100644 index 0000000000..c67dad612a --- /dev/null +++ b/vendor/github.com/pmezard/go-difflib/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013, Patrick Mezard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go new file mode 100644 index 0000000000..003e99fadb --- /dev/null +++ b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go @@ -0,0 +1,772 @@ +// Package difflib is a partial port of Python difflib module. +// +// It provides tools to compare sequences of strings and generate textual diffs. +// +// The following class and functions have been ported: +// +// - SequenceMatcher +// +// - unified_diff +// +// - context_diff +// +// Getting unified diffs was the main goal of the port. Keep in mind this code +// is mostly suitable to output text differences in a human friendly way, there +// are no guarantees generated diffs are consumable by patch(1). +package difflib + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strings" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func calculateRatio(matches, length int) float64 { + if length > 0 { + return 2.0 * float64(matches) / float64(length) + } + return 1.0 +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool) *SequenceMatcher { + + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s, _ := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s, _ := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s, _ := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// and for all (i',j',k') meeting those conditions, +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n)}) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s] = m.fullBCount[s] + 1 + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches += 1 + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return string(w.Bytes()), err +} + +// Convert range to the "ed" format. +func formatRangeContext(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + if length <= 1 { + return fmt.Sprintf("%d", beginning) + } + return fmt.Sprintf("%d,%d", beginning, beginning+length-1) +} + +type ContextDiff UnifiedDiff + +// Compare two sequences of lines; generate the delta as a context diff. +// +// Context diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by diff.Context +// which defaults to three. +// +// By default, the diff control lines (those with *** or ---) are +// created with a trailing newline. +// +// For inputs that do not have trailing newlines, set the diff.Eol +// argument to "" so that the output will be uniformly newline free. +// +// The context diff format normally has a header for filenames and +// modification times. Any or all of these may be specified using +// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. +// The modification times are normally expressed in the ISO 8601 format. +// If not specified, the strings default to blanks. +func WriteContextDiff(writer io.Writer, diff ContextDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + var diffErr error + wf := func(format string, args ...interface{}) { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + if diffErr == nil && err != nil { + diffErr = err + } + } + ws := func(s string) { + _, err := buf.WriteString(s) + if diffErr == nil && err != nil { + diffErr = err + } + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + prefix := map[byte]string{ + 'i': "+ ", + 'd': "- ", + 'r': "! ", + 'e': " ", + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + } + } + + first, last := g[0], g[len(g)-1] + ws("***************" + diff.Eol) + + range1 := formatRangeContext(first.I1, last.I2) + wf("*** %s ****%s", range1, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'd' { + for _, cc := range g { + if cc.Tag == 'i' { + continue + } + for _, line := range diff.A[cc.I1:cc.I2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + + range2 := formatRangeContext(first.J1, last.J2) + wf("--- %s ----%s", range2, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'i' { + for _, cc := range g { + if cc.Tag == 'd' { + continue + } + for _, line := range diff.B[cc.J1:cc.J2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + } + return diffErr +} + +// Like WriteContextDiff but returns the diff a string. +func GetContextDiffString(diff ContextDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteContextDiff(w, diff) + return string(w.Bytes()), err +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} From 294b26b5f18f98a78c75715202e5992cba0543fd Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 25 Mar 2019 18:56:32 -0700 Subject: [PATCH 03/14] Update default Kubernetes version to v1.14.0 --- pkg/minikube/constants/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/constants/constants.go b/pkg/minikube/constants/constants.go index 9025e0e4ef..06ee23b03d 100644 --- a/pkg/minikube/constants/constants.go +++ b/pkg/minikube/constants/constants.go @@ -154,7 +154,7 @@ var DefaultISOURL = fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.i var DefaultISOSHAURL = DefaultISOURL + SHASuffix // DefaultKubernetesVersion is the default kubernetes version -var DefaultKubernetesVersion = "v1.13.4" +var DefaultKubernetesVersion = "v1.14.0" // ConfigFilePath is the path of the config directory var ConfigFilePath = MakeMiniPath("config") From 1e8bd6f060c79ca5d84e5c8918c6e400a984b87a Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 25 Mar 2019 19:15:34 -0700 Subject: [PATCH 04/14] Bump Makefile VERSION to v1.0.0 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 110c0a6c09..da3aaf2fe3 100755 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ # limitations under the License. # Bump these on release - and please check ISO_VERSION for correctness. -VERSION_MAJOR ?= 0 -VERSION_MINOR ?= 35 +VERSION_MAJOR ?= 1 +VERSION_MINOR ?= 0 VERSION_BUILD ?= 0 # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0 From 9004134eb844ce5f2f6273b36186e16be3058b36 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 25 Mar 2019 21:02:44 -0700 Subject: [PATCH 05/14] Fix invalid feature-gates argument --- test/integration/start_stop_delete_test.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/integration/start_stop_delete_test.go b/test/integration/start_stop_delete_test.go index 8616b4a810..ec53219b6f 100644 --- a/test/integration/start_stop_delete_test.go +++ b/test/integration/start_stop_delete_test.go @@ -35,24 +35,23 @@ func TestStartStop(t *testing.T) { name string args []string }{ - {"docker+no-cache+oldest", []string{ - "--container-runtime=docker", + {"nocache_oldest", []string{ "--cache-images=false", fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion), }}, - {"docker+ignore_verifications+newest+gates", []string{ - "--container-runtime=docker", - "--extra-config", - "kubeadm.ignore-preflight-errors=SystemVerification", + {"feature_gates_newest", []string{ "--feature-gates", + "ServerSideApply=true", fmt.Sprintf("--kubernetes-version=%s", constants.NewestKubernetesVersion), }}, {"containerd", []string{ "--container-runtime=containerd", "--docker-opt containerd=/var/run/containerd/containerd.sock", }}, - {"crio", []string{ + {"crio_ignore_preflights", []string{ "--container-runtime=crio", + "--extra-config", + "kubeadm.ignore-preflight-errors=SystemVerification", }}, } From ec135dc4dabfa6ef88cce51ec25cc80ba4123587 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 10:43:03 -0700 Subject: [PATCH 06/14] Add addon-manager, dashboard, and storage-provisioner to minikube logs --- pkg/minikube/cruntime/docker.go | 4 ---- pkg/minikube/logs/logs.go | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index e8a0a9b39b..504ca255fc 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -24,9 +24,6 @@ import ( "github.com/golang/glog" ) -// KubernetesContainerPrefix is the prefix of each kubernetes container -const KubernetesContainerPrefix = "k8s_" - // Docker contains Docker runtime state type Docker struct { Socket string @@ -99,7 +96,6 @@ func (r *Docker) KubeletOptions() map[string]string { // ListContainers returns a list of containers func (r *Docker) ListContainers(filter string) ([]string, error) { - filter = KubernetesContainerPrefix + filter content, err := r.Runner.CombinedOutput(fmt.Sprintf(`docker ps -a --filter="name=%s" --format="{{.ID}}"`, filter)) if err != nil { return nil, err diff --git a/pkg/minikube/logs/logs.go b/pkg/minikube/logs/logs.go index 83e3f5c55f..3364a23f1c 100644 --- a/pkg/minikube/logs/logs.go +++ b/pkg/minikube/logs/logs.go @@ -41,6 +41,9 @@ var importantPods = []string{ "coredns", "kube-scheduler", "kube-proxy", + "kube-addon-manager", + "kubernetes-dashboard", + "storage-provisioner", } // lookbackwardsCount is how far back to look in a log for problems. This should be large enough to From 48e4808b72090b5bd76c37405aeac407899436d9 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 10:54:39 -0700 Subject: [PATCH 07/14] Remove special unrelated docker check --- pkg/minikube/cruntime/cruntime_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/minikube/cruntime/cruntime_test.go b/pkg/minikube/cruntime/cruntime_test.go index b7b5816b27..194c4a5b1c 100644 --- a/pkg/minikube/cruntime/cruntime_test.go +++ b/pkg/minikube/cruntime/cruntime_test.go @@ -445,9 +445,6 @@ func TestContainerFunctions(t *testing.T) { "fgh1": prefix + "coredns", "xyz2": prefix + "storage", } - if tc.runtime == "docker" { - runner.containers["zzz"] = "unrelated" - } cr, err := New(Config{Type: tc.runtime, Runner: runner}) if err != nil { t.Fatalf("New(%s): %v", tc.runtime, err) From c861ab7dc1eeced052e554760fc778cd32ecaf29 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 12:14:06 -0700 Subject: [PATCH 08/14] Switch mount ssh impl from native to CommandRunner --- cmd/minikube/cmd/mount.go | 15 +++++++++++++-- pkg/minikube/cluster/mount.go | 31 ++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/cmd/minikube/cmd/mount.go b/cmd/minikube/cmd/mount.go index 4260178135..677be7ee8b 100644 --- a/cmd/minikube/cmd/mount.go +++ b/cmd/minikube/cmd/mount.go @@ -98,6 +98,7 @@ var mountCmd = &cobra.Command{ } defer api.Close() host, err := api.Load(config.GetMachineName()) + if err != nil { exit.WithError("Error loading api", err) } @@ -163,22 +164,32 @@ var mountCmd = &cobra.Command{ go func() { console.OutStyle("fileserver", "Userspace file server: ") ufs.StartServer(net.JoinHostPort(ip.String(), strconv.Itoa(port)), debugVal, hostPath) + console.OutStyle("stopped", "Userspace file server is shutdown") wg.Done() }() } + // Use CommandRunner, as the native docker ssh service dies when Ctrl-C is received. + runner, err := machine.CommandRunner(host) + if err != nil { + exit.WithError("Failed to get command runner", err) + } + // Unmount if Ctrl-C or kill request is received. c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { for sig := range c { console.OutStyle("unmount", "Unmounting %s ...", vmPath) - cluster.Unmount(host, vmPath) + err := cluster.Unmount(runner, vmPath) + if err != nil { + console.ErrStyle("failure", "Failed unmount: %v", err) + } exit.WithCode(exit.Interrupted, "Exiting due to %s signal", sig) } }() - err = cluster.Mount(host, ip.String(), vmPath, cfg) + err = cluster.Mount(runner, ip.String(), vmPath, cfg) if err != nil { exit.WithError("mount failed", err) } diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 41181330b8..d10a2de6ac 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -23,6 +23,7 @@ import ( "strconv" "strings" + "github.com/golang/glog" "github.com/pkg/errors" ) @@ -48,7 +49,7 @@ type MountConfig struct { // hostRunner is the subset of host.Host used for mounting type hostRunner interface { - RunSSHCommand(cmd string) (string, error) + CombinedOutput(string) (string, error) } // Mount runs the mount command from the 9p client on the VM to the 9p server on the host @@ -58,7 +59,9 @@ func Mount(h hostRunner, source string, target string, c *MountConfig) error { } cmd := fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)) - out, err := h.RunSSHCommand(cmd) + glog.Infof("Will run: %s", cmd) + out, err := h.CombinedOutput(cmd) + glog.Infof("mount err=%s, out=%s", err, out) if err != nil { return errors.Wrap(err, out) } @@ -100,9 +103,31 @@ func mntCmd(source string, target string, c *MountConfig) string { return fmt.Sprintf("sudo mount -t %s -o %s %s %s", c.Type, strings.Join(opts, ","), source, target) } +// umountCmd returns a command for unmounting +func umountCmd(target string, force bool) string { + flag := "" + if force { + flag = "-f" + } + // grep because findmnt will also display the parent! + return fmt.Sprintf("findmnt -T %s | grep %s && sudo umount %s %s && echo unmounted || true", target, target, flag, target) +} + // Unmount unmounts a path func Unmount(h hostRunner, target string) error { - out, err := h.RunSSHCommand(fmt.Sprintf("findmnt -T %s && sudo umount %s || true", target, target)) + cmd := umountCmd(target, false) + glog.Infof("Will run: %s", cmd) + out, err := h.CombinedOutput(cmd) + if err == nil { + return nil + } + glog.Warningf("initial unmount error: %v, out: %s", err, out) + + // Try again, using force if needed. + cmd = umountCmd(target, true) + glog.Infof("Will run: %s", cmd) + out, err = h.CombinedOutput(cmd) + glog.Infof("unmount force err=%v, out=%s", err, out) if err != nil { return errors.Wrap(err, out) } From d4edae2d8c0166e3bf06861926339ae9aa874ac9 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 12:57:19 -0700 Subject: [PATCH 09/14] Fix tests than broke with the merge against master --- pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go index 518eaf521d..a43fe782c5 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm_test.go @@ -62,7 +62,7 @@ ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook `, }, { - description: "cri runtime", + description: "newest cri runtime", cfg: config.KubernetesConfig{ NodeIP: "192.168.1.100", KubernetesVersion: constants.NewestKubernetesVersion, @@ -81,7 +81,7 @@ ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook `, }, { - description: "newest docker with custom image repository", + description: "docker with custom image repository", cfg: config.KubernetesConfig{ NodeIP: "192.168.1.100", KubernetesVersion: constants.DefaultKubernetesVersion, @@ -95,7 +95,7 @@ Wants=docker.socket [Service] ExecStart= -ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cadvisor-port=0 --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --pod-infra-container-image=docker-proxy-image.io/google_containers/pause:3.0 --pod-manifest-path=/etc/kubernetes/manifests --require-kubeconfig=true +ExecStart=/usr/bin/kubelet --allow-privileged=true --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --pod-infra-container-image=docker-proxy-image.io/google_containers/pause:3.1 --pod-manifest-path=/etc/kubernetes/manifests [Install] `, From 9c3488a26f522cc933a20c734c35d7442578cf28 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 13:04:58 -0700 Subject: [PATCH 10/14] Make flag substitution cleaner, update tests --- pkg/minikube/cluster/mount.go | 20 ++++++++++---------- pkg/minikube/cluster/mount_test.go | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index d10a2de6ac..6104252d46 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -47,20 +47,20 @@ type MountConfig struct { Options map[string]string } -// hostRunner is the subset of host.Host used for mounting -type hostRunner interface { +// mountRunner is the subset of CommandRunner used for mounting +type mountRunner interface { CombinedOutput(string) (string, error) } // Mount runs the mount command from the 9p client on the VM to the 9p server on the host -func Mount(h hostRunner, source string, target string, c *MountConfig) error { - if err := Unmount(h, target); err != nil { +func Mount(r mountRunner, source string, target string, c *MountConfig) error { + if err := Unmount(r, target); err != nil { return errors.Wrap(err, "umount") } cmd := fmt.Sprintf("sudo mkdir -m %o -p %s && %s", c.Mode, target, mntCmd(source, target, c)) glog.Infof("Will run: %s", cmd) - out, err := h.CombinedOutput(cmd) + out, err := r.CombinedOutput(cmd) glog.Infof("mount err=%s, out=%s", err, out) if err != nil { return errors.Wrap(err, out) @@ -107,17 +107,17 @@ func mntCmd(source string, target string, c *MountConfig) string { func umountCmd(target string, force bool) string { flag := "" if force { - flag = "-f" + flag = "-f " } // grep because findmnt will also display the parent! - return fmt.Sprintf("findmnt -T %s | grep %s && sudo umount %s %s && echo unmounted || true", target, target, flag, target) + return fmt.Sprintf("findmnt -T %s | grep %s && sudo umount %s%s || true", target, target, flag, target) } // Unmount unmounts a path -func Unmount(h hostRunner, target string) error { +func Unmount(r mountRunner, target string) error { cmd := umountCmd(target, false) glog.Infof("Will run: %s", cmd) - out, err := h.CombinedOutput(cmd) + out, err := r.CombinedOutput(cmd) if err == nil { return nil } @@ -126,7 +126,7 @@ func Unmount(h hostRunner, target string) error { // Try again, using force if needed. cmd = umountCmd(target, true) glog.Infof("Will run: %s", cmd) - out, err = h.CombinedOutput(cmd) + out, err = r.CombinedOutput(cmd) glog.Infof("unmount force err=%v, out=%s", err, out) if err != nil { return errors.Wrap(err, out) diff --git a/pkg/minikube/cluster/mount_test.go b/pkg/minikube/cluster/mount_test.go index cd10d1d104..fa459cb591 100644 --- a/pkg/minikube/cluster/mount_test.go +++ b/pkg/minikube/cluster/mount_test.go @@ -23,19 +23,19 @@ import ( "github.com/google/go-cmp/cmp" ) -type mockMountHost struct { +type mockmountRunner struct { cmds []string T *testing.T } -func NewMockMountHost(t *testing.T) *mockMountHost { - return &mockMountHost{ +func NewMockmountRunner(t *testing.T) *mockmountRunner { + return &mockmountRunner{ T: t, cmds: []string{}, } } -func (m *mockMountHost) RunSSHCommand(cmd string) (string, error) { +func (m *mockmountRunner) CombinedOutput(cmd string) (string, error) { m.cmds = append(m.cmds, cmd) return "", nil } @@ -54,7 +54,7 @@ func TestMount(t *testing.T) { target: "target", cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700)}, want: []string{ - "findmnt -T target && sudo umount target || true", + "findmnt -T target | grep target && sudo umount target || true", "sudo mkdir -m 700 -p target && sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target", }, }, @@ -67,7 +67,7 @@ func TestMount(t *testing.T) { "cache": "fscache", }}, want: []string{ - "findmnt -T /target && sudo umount /target || true", + "findmnt -T /target | grep /target && sudo umount /target || true", "sudo mkdir -m 777 -p /target && sudo mount -t 9p -o cache=fscache,dfltgid=72,dfltuid=82,noextend,version=9p2000.u 10.0.0.1 /target", }, }, @@ -79,14 +79,14 @@ func TestMount(t *testing.T) { "version": "9p2000.L", }}, want: []string{ - "findmnt -T tgt && sudo umount tgt || true", + "findmnt -T tgt | grep tgt && sudo umount tgt || true", "sudo mkdir -m 700 -p tgt && sudo mount -t 9p -o dfltgid=0,dfltuid=0,version=9p2000.L src tgt", }, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - h := NewMockMountHost(t) + h := NewMockmountRunner(t) err := Mount(h, tc.source, tc.target, tc.cfg) if err != nil { t.Fatalf("Mount(%s, %s, %+v): %v", tc.source, tc.target, tc.cfg, err) @@ -99,13 +99,13 @@ func TestMount(t *testing.T) { } func TestUnmount(t *testing.T) { - h := NewMockMountHost(t) + h := NewMockmountRunner(t) err := Unmount(h, "/mnt") if err != nil { t.Fatalf("Unmount(/mnt): %v", err) } - want := []string{"findmnt -T /mnt && sudo umount /mnt || true"} + want := []string{"findmnt -T /mnt | grep /mnt && sudo umount /mnt || true"} if diff := cmp.Diff(h.cmds, want); diff != "" { t.Errorf("command diff (-want +got): %s", diff) } From 7233a2d50defae0a55fe47ce58bd7d507da0d108 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 14:27:50 -0700 Subject: [PATCH 11/14] Allow mount to work when the uid/gid of docker changes --- cmd/minikube/cmd/mount.go | 12 +++++----- pkg/minikube/cluster/mount.go | 35 ++++++++++++++++++++++++++---- pkg/minikube/cluster/mount_test.go | 12 +++++++++- test/integration/mount_test.go | 6 ++++- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/cmd/minikube/cmd/mount.go b/cmd/minikube/cmd/mount.go index 4260178135..81c6474e43 100644 --- a/cmd/minikube/cmd/mount.go +++ b/cmd/minikube/cmd/mount.go @@ -45,8 +45,8 @@ var mountIP string var mountVersion string var mountType string var isKill bool -var uid int -var gid int +var uid string +var gid string var mSize int var options []string var mode uint @@ -144,8 +144,8 @@ var mountCmd = &cobra.Command{ console.OutStyle("mounting", "Mounting host path %s into VM as %s ...", hostPath, vmPath) console.OutStyle("mount-options", "Mount options:") console.OutStyle("option", "Type: %s", cfg.Type) - console.OutStyle("option", "UID: %d", cfg.UID) - console.OutStyle("option", "GID: %d", cfg.GID) + console.OutStyle("option", "UID: %s", cfg.UID) + console.OutStyle("option", "GID: %s", cfg.GID) console.OutStyle("option", "Version: %s", cfg.Version) console.OutStyle("option", "MSize: %d", cfg.MSize) console.OutStyle("option", "Mode: %o (%s)", cfg.Mode, cfg.Mode) @@ -194,8 +194,8 @@ func init() { mountCmd.Flags().StringVar(&mountType, "type", nineP, "Specify the mount filesystem type (supported types: 9p)") mountCmd.Flags().StringVar(&mountVersion, "9p-version", constants.DefaultMountVersion, "Specify the 9p version that the mount should use") mountCmd.Flags().BoolVar(&isKill, "kill", false, "Kill the mount process spawned by minikube start") - mountCmd.Flags().IntVar(&uid, "uid", 1001, "Default user id used for the mount") - mountCmd.Flags().IntVar(&gid, "gid", 1001, "Default group id used for the mount") + mountCmd.Flags().StringVar(&uid, "uid", "docker", "Default user id used for the mount") + mountCmd.Flags().StringVar(&gid, "gid", "docker", "Default group id used for the mount") mountCmd.Flags().UintVar(&mode, "mode", 0755, "File permissions used for the mount") mountCmd.Flags().StringSliceVar(&options, "options", []string{}, "Additional mount options, such as cache=fscache") mountCmd.Flags().IntVar(&mSize, "msize", constants.DefaultMsize, "The number of bytes to use for 9p packet payload") diff --git a/pkg/minikube/cluster/mount.go b/pkg/minikube/cluster/mount.go index 41181330b8..95ad69a123 100644 --- a/pkg/minikube/cluster/mount.go +++ b/pkg/minikube/cluster/mount.go @@ -31,9 +31,9 @@ type MountConfig struct { // Type is the filesystem type (Typically 9p) Type string // UID is the User ID which this path will be mounted as - UID int + UID string // GID is the Group ID which this path will be mounted as - GID int + GID string // Version is the 9P protocol version. Valid options: 9p2000, 9p200.u, 9p2000.L Version string // MSize is the number of bytes to use for 9p packet payload @@ -65,11 +65,38 @@ func Mount(h hostRunner, source string, target string, c *MountConfig) error { return nil } +// returns either a raw UID number, or the subshell to resolve it. +func resolveUID(id string) string { + _, err := strconv.ParseInt(id, 10, 64) + if err == nil { + return id + } + // Preserve behavior where unset ID == 0 + if id == "" { + return "0" + } + return fmt.Sprintf(`$(id -u %s)`, id) +} + +// returns either a raw GID number, or the subshell to resolve it. +func resolveGID(id string) string { + _, err := strconv.ParseInt(id, 10, 64) + if err == nil { + return id + } + // Preserve behavior where unset ID == 0 + if id == "" { + return "0" + } + // Because `getent` isn't part of our ISO + return fmt.Sprintf(`$(grep ^%s: /etc/group | cut -d: -f3)`, id) +} + // mntCmd returns a mount command based on a config. func mntCmd(source string, target string, c *MountConfig) string { options := map[string]string{ - "dfltgid": strconv.Itoa(c.GID), - "dfltuid": strconv.Itoa(c.UID), + "dfltgid": resolveGID(c.GID), + "dfltuid": resolveUID(c.UID), } if c.Port != 0 { options["port"] = strconv.Itoa(c.Port) diff --git a/pkg/minikube/cluster/mount_test.go b/pkg/minikube/cluster/mount_test.go index cd10d1d104..1770e33c14 100644 --- a/pkg/minikube/cluster/mount_test.go +++ b/pkg/minikube/cluster/mount_test.go @@ -58,11 +58,21 @@ func TestMount(t *testing.T) { "sudo mkdir -m 700 -p target && sudo mount -t 9p -o dfltgid=0,dfltuid=0 src target", }, }, + { + name: "named uid", + source: "src", + target: "target", + cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0700), UID: "docker", GID: "docker"}, + want: []string{ + "findmnt -T target && sudo umount target || true", + "sudo mkdir -m 700 -p target && sudo mount -t 9p -o dfltgid=$(grep ^docker: /etc/group | cut -d: -f3),dfltuid=$(id -u docker) src target", + }, + }, { name: "everything", source: "10.0.0.1", target: "/target", - cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0777), UID: 82, GID: 72, Version: "9p2000.u", Options: map[string]string{ + cfg: &MountConfig{Type: "9p", Mode: os.FileMode(0777), UID: "82", GID: "72", Version: "9p2000.u", Options: map[string]string{ "noextend": "", "cache": "fscache", }}, diff --git a/test/integration/mount_test.go b/test/integration/mount_test.go index 08dd127a13..6e426a223f 100644 --- a/test/integration/mount_test.go +++ b/test/integration/mount_test.go @@ -56,6 +56,8 @@ func testMounting(t *testing.T) { } else { mountCmd = fmt.Sprintf("mount %s:/mount-9p", tempDir) } + + t.Logf("Starting mount: %s", mountCmd) cmd, _, _ := minikubeRunner.RunDaemon2(mountCmd) defer func() { err := cmd.Process.Kill() @@ -81,12 +83,14 @@ func testMounting(t *testing.T) { // Create the pods we need outside the main test loop. setupTest := func() error { + t.Logf("Deploying pod from: %s", podPath) if _, err := kubectlRunner.RunCommand([]string{"create", "-f", podPath}); err != nil { return err } return nil } defer func() { + t.Logf("Deleting pod from: %s", podPath) if out, err := kubectlRunner.RunCommand([]string{"delete", "-f", podPath}); err != nil { t.Logf("delete -f %s failed: %v\noutput: %s\n", podPath, err, out) } @@ -104,6 +108,7 @@ func testMounting(t *testing.T) { if err := pkgutil.WaitForPodsWithLabelRunning(client, "default", selector); err != nil { t.Fatalf("Error waiting for busybox mount pod to be up: %v", err) } + t.Logf("Pods appear to be running") mountTest := func() error { path := filepath.Join(tempDir, "frompod") @@ -161,5 +166,4 @@ func testMounting(t *testing.T) { if err := util.Retry(t, mountTest, 5*time.Second, 40); err != nil { t.Fatalf("mountTest failed with error: %v", err) } - } From 23eee62e102719ce3e29b22fc62edbcefb6b34fd Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 14:31:24 -0700 Subject: [PATCH 12/14] Revert Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1c19af654a..7f53075b48 100755 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ # limitations under the License. # Bump these on release - and please check ISO_VERSION for correctness. -VERSION_MAJOR ?= 1 -VERSION_MINOR ?= 0 +VERSION_MAJOR ?= 0 +VERSION_MINOR ?= 35 VERSION_BUILD ?= 0 # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0 From 53a246b71c1313297cffb0f9dc8d4de012a70d6d Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 14:42:02 -0700 Subject: [PATCH 13/14] Fix function name case --- pkg/minikube/cluster/mount_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/minikube/cluster/mount_test.go b/pkg/minikube/cluster/mount_test.go index fa459cb591..9402d28af0 100644 --- a/pkg/minikube/cluster/mount_test.go +++ b/pkg/minikube/cluster/mount_test.go @@ -23,19 +23,19 @@ import ( "github.com/google/go-cmp/cmp" ) -type mockmountRunner struct { +type mockMountRunner struct { cmds []string T *testing.T } -func NewMockmountRunner(t *testing.T) *mockmountRunner { - return &mockmountRunner{ +func newMockMountRunner(t *testing.T) *mockMountRunner { + return &mockMountRunner{ T: t, cmds: []string{}, } } -func (m *mockmountRunner) CombinedOutput(cmd string) (string, error) { +func (m *mockMountRunner) CombinedOutput(cmd string) (string, error) { m.cmds = append(m.cmds, cmd) return "", nil } @@ -86,7 +86,7 @@ func TestMount(t *testing.T) { } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - h := NewMockmountRunner(t) + h := newMockMountRunner(t) err := Mount(h, tc.source, tc.target, tc.cfg) if err != nil { t.Fatalf("Mount(%s, %s, %+v): %v", tc.source, tc.target, tc.cfg, err) @@ -99,7 +99,7 @@ func TestMount(t *testing.T) { } func TestUnmount(t *testing.T) { - h := NewMockmountRunner(t) + h := newMockMountRunner(t) err := Unmount(h, "/mnt") if err != nil { t.Fatalf("Unmount(/mnt): %v", err) From 7d36629d5b74c9ce8e7e899e0d4a44f9f895ed37 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Tue, 26 Mar 2019 17:09:30 -0700 Subject: [PATCH 14/14] Update testdata templates for v1.14 --- .../containerd-api-port__default.yaml | 16 +++++--- .../kubeadm/testdata/containerd__default.yaml | 16 +++++--- .../testdata/crio-options-gates__default.yaml | 39 +++++++++++-------- .../kubeadm/testdata/crio__default.yaml | 16 +++++--- .../kubeadm/testdata/default__default.yaml | 16 +++++--- .../testdata/image-repository__default.yaml | 16 +++++--- .../kubeadm/testdata/options__default.yaml | 28 +++++++------ 7 files changed, 90 insertions(+), 57 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml index 47e5c97cdc..cc96f136ac 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd-api-port__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 12345 bootstrapTokens: @@ -15,17 +15,20 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:12345 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -33,6 +36,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml index 8ffec02733..147a6ccbec 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/containerd__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 8443 bootstrapTokens: @@ -15,17 +15,20 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -33,6 +36,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml index e59290cbd3..b593f313d3 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio-options-gates__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 8443 bootstrapTokens: @@ -15,27 +15,33 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" - fail-no-swap: "true" - feature-gates: "a=b" -controllerManagerExtraArgs: - feature-gates: "a=b" - kube-api-burst: "32" -kubeadmExtraArgs: - feature-gates: "a=b" -schedulerExtraArgs: - feature-gates: "a=b" - scheduler-name: "mini-scheduler" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" + feature-gates: "a=b" +controllerManager: + extraArgs: + feature-gates: "a=b" + kube-api-burst: "32" +kubeadm: + extraArgs: + feature-gates: "a=b" +scheduler: + extraArgs: + feature-gates: "a=b" + scheduler-name: "mini-scheduler" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -43,6 +49,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml index 9002456c7d..66dac1c8af 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/crio__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 8443 bootstrapTokens: @@ -15,17 +15,20 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -33,6 +36,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml index d1581fc1f9..d88c0efebf 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/default__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 8443 bootstrapTokens: @@ -15,17 +15,20 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -33,6 +36,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml index 11b10ebfe3..bf53791b71 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/image-repository__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 8443 bootstrapTokens: @@ -15,18 +15,21 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration imageRepository: test/repo -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -34,6 +37,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%" diff --git a/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml b/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml index 2b53cec03a..a85a2447b2 100644 --- a/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml +++ b/pkg/minikube/bootstrapper/kubeadm/testdata/options__default.yaml @@ -1,6 +1,6 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration -apiEndpoint: +localAPIEndpoint: advertiseAddress: 1.1.1.1 bindPort: 8443 bootstrapTokens: @@ -15,22 +15,27 @@ nodeRegistration: name: mk taints: [] --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration -apiServerExtraArgs: - enable-admission-plugins: "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" - fail-no-swap: "true" -controllerManagerExtraArgs: - kube-api-burst: "32" -schedulerExtraArgs: - scheduler-name: "mini-scheduler" +apiServer: + extraArgs: + enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" + fail-no-swap: "true" +controllerManager: + extraArgs: + kube-api-burst: "32" +scheduler: + extraArgs: + scheduler-name: "mini-scheduler" certificatesDir: /var/lib/minikube/certs/ clusterName: kubernetes controlPlaneEndpoint: localhost:8443 +dns: + type: CoreDNS etcd: local: dataDir: /data/minikube -kubernetesVersion: v1.13.4 +kubernetesVersion: v1.14.0 networking: dnsDomain: cluster.local podSubnet: "" @@ -38,6 +43,7 @@ networking: --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration +imageGCHighThresholdPercent: 100 evictionHard: nodefs.available: "0%" nodefs.inodesFree: "0%"