From 180b23f2c8368f7138873d20eee3980f26b4463d Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Tue, 21 Jan 2020 12:46:44 -0800 Subject: [PATCH 1/5] Save addons in subdirectories, separated by namespace This way we can pass the correct --namespace flag into 'kubectl apply' such that it works with '--prune' for kubectl >=v.17.0 --- pkg/addons/reconcile.go | 32 ++++++-- pkg/minikube/assets/addons.go | 140 +++++++++++++++++----------------- 2 files changed, 96 insertions(+), 76 deletions(-) diff --git a/pkg/addons/reconcile.go b/pkg/addons/reconcile.go index f774cb9393..e4096d71ff 100644 --- a/pkg/addons/reconcile.go +++ b/pkg/addons/reconcile.go @@ -17,6 +17,8 @@ limitations under the License. package addons import ( + "fmt" + "io/ioutil" "os" "os/exec" "path" @@ -24,10 +26,12 @@ import ( "github.com/blang/semver" "github.com/golang/glog" "github.com/pkg/errors" + "k8s.io/minikube/pkg/minikube/assets" "k8s.io/minikube/pkg/minikube/bootstrapper/bsutil" "k8s.io/minikube/pkg/minikube/command" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/vmpath" ) var ( @@ -58,18 +62,32 @@ var kubectlPruneWhitelist = []string{ // reconcile runs kubectl apply -f on the addons directory // to reconcile addons state in all running profiles func reconcile(cmd command.Runner, profile string) error { - c, err := kubectlCommand(profile) + // Walk through all subdirs in /etc/kubernetes/addons and reconcile addons + dirs, err := ioutil.ReadDir(vmpath.GuestAddonsDir) if err != nil { return err } - if _, err := cmd.RunCmd(c); err != nil { - glog.Warningf("reconciling addons failed: %v", err) - return err + + for _, d := range dirs { + if !d.IsDir() { + continue + } + namespace := d.Name() + glog.Infof("Reconciling addons in namespace %s", namespace) + c, err := kubectlCommand(profile, namespace) + if err != nil { + return err + } + if _, err := cmd.RunCmd(c); err != nil { + glog.Warningf("reconciling addons failed: %v", err) + return err + } } + return nil } -func kubectlCommand(profile string) (*exec.Cmd, error) { +func kubectlCommand(profile, namespace string) (*exec.Cmd, error) { v, err := k8sVersion(profile) if err != nil { return nil, err @@ -78,7 +96,7 @@ func kubectlCommand(profile string) (*exec.Cmd, error) { // prune will delete any existing objects with the label specified by "-l" which don't appear in /etc/kubernetes/addons // this is how we delete disabled addons - args := []string{"KUBECONFIG=/var/lib/minikube/kubeconfig", kubectlBinary, "apply", "-f", "/etc/kubernetes/addons", "-l", "kubernetes.io/cluster-service!=true,addonmanager.kubernetes.io/mode=Reconcile", "--prune=true"} + args := []string{"KUBECONFIG=/var/lib/minikube/kubeconfig", kubectlBinary, "apply", "-f", assets.TargetDirForAddon(namespace), "-l", "kubernetes.io/cluster-service!=true,addonmanager.kubernetes.io/mode=Reconcile", "--prune=true"} for _, k := range kubectlPruneWhitelist { args = append(args, []string{"--prune-whitelist", k}...) } @@ -89,7 +107,7 @@ func kubectlCommand(profile string) (*exec.Cmd, error) { return nil, errors.Wrap(err, "appending namespace flag") } if ok { - args = append(args, "--namespace=kube-system") + args = append(args, fmt.Sprintf("--namespace=%s", namespace)) } cmd := exec.Command("sudo", args...) diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index af5a01f13a..98b5d2ccc2 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -1,12 +1,9 @@ /* Copyright 2016 The Kubernetes Authors All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -40,7 +37,7 @@ type Addon struct { } // NewAddon creates a new Addon -func NewAddon(assets []*BinAsset, enabled bool, addonName string) *Addon { +func NewAddon(assets []*BinAsset, enabled bool, addonName, namespace string) *Addon { a := &Addon{ Assets: assets, enabled: enabled, @@ -71,235 +68,235 @@ var Addons = map[string]*Addon{ "addon-manager": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/addon-manager.yaml.tmpl", - vmpath.GuestManifestsDir, + TargetDirForAddon("kube-system"), "addon-manager.yaml.tmpl", "0640", true), - }, false, "addon-manager"), + }, false, "addon-manager", "kube-system"), "dashboard": NewAddon([]*BinAsset{ - MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrole.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrolebinding.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", vmpath.GuestAddonsDir, "dashboard-configmap.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml", vmpath.GuestAddonsDir, "dashboard-dp.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", vmpath.GuestAddonsDir, "dashboard-role.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-rolebinding.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-secret.yaml", vmpath.GuestAddonsDir, "dashboard-secret.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-svc.yaml", vmpath.GuestAddonsDir, "dashboard-svc.yaml", "0640", false), - }, false, "dashboard"), + MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-clusterrole.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-clusterrolebinding.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-configmap.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-dp.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-ns.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-role.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-rolebinding.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-sa.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-secret.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-secret.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-svc.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-svc.yaml", "0640", false), + }, false, "dashboard", "kubernetes-dashboard"), "default-storageclass": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/storageclass/storageclass.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "storageclass.yaml", "0640", false), - }, true, "default-storageclass"), + }, true, "default-storageclass", "kube-system"), "storage-provisioner": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/storage-provisioner/storage-provisioner.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "storage-provisioner.yaml", "0640", true), - }, true, "storage-provisioner"), + }, true, "storage-provisioner", "kube-system"), "storage-provisioner-gluster": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/storage-provisioner-gluster/storage-gluster-ns.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "storage-gluster-ns.yaml", "0640", false), MustBinAsset( "deploy/addons/storage-provisioner-gluster/glusterfs-daemonset.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "glusterfs-daemonset.yaml", "0640", false), MustBinAsset( "deploy/addons/storage-provisioner-gluster/heketi-deployment.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "heketi-deployment.yaml", "0640", false), MustBinAsset( "deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "storage-privisioner-glusterfile.yaml", "0640", false), - }, false, "storage-provisioner-gluster"), + }, false, "storage-provisioner-gluster", "kube-system"), "efk": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/efk/elasticsearch-rc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "elasticsearch-rc.yaml", "0640", true), MustBinAsset( "deploy/addons/efk/elasticsearch-svc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "elasticsearch-svc.yaml", "0640", false), MustBinAsset( "deploy/addons/efk/fluentd-es-rc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "fluentd-es-rc.yaml", "0640", true), MustBinAsset( "deploy/addons/efk/fluentd-es-configmap.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "fluentd-es-configmap.yaml", "0640", false), MustBinAsset( "deploy/addons/efk/kibana-rc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "kibana-rc.yaml", "0640", false), MustBinAsset( "deploy/addons/efk/kibana-svc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "kibana-svc.yaml", "0640", false), - }, false, "efk"), + }, false, "efk", "kube-system"), "ingress": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/ingress/ingress-configmap.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "ingress-configmap.yaml", "0640", false), MustBinAsset( "deploy/addons/ingress/ingress-rbac.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "ingress-rbac.yaml", "0640", false), MustBinAsset( "deploy/addons/ingress/ingress-dp.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "ingress-dp.yaml", "0640", true), - }, false, "ingress"), + }, false, "ingress", "kube-system"), "istio-provisioner": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/istio-provisioner/istio-operator.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("istio-operator"), "istio-operator.yaml", "0640", true), - }, false, "istio-provisioner"), + }, false, "istio-provisioner", "istio-operator"), "istio": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/istio/istio-default-profile.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("istio-operator"), "istio-default-profile.yaml", "0640", false), - }, false, "istio"), + }, false, "istio", "istio-operator"), "metrics-server": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/metrics-server/metrics-apiservice.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "metrics-apiservice.yaml", "0640", false), MustBinAsset( "deploy/addons/metrics-server/metrics-server-deployment.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "metrics-server-deployment.yaml", "0640", true), MustBinAsset( "deploy/addons/metrics-server/metrics-server-service.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "metrics-server-service.yaml", "0640", false), - }, false, "metrics-server"), + }, false, "metrics-server", "kube-system"), "registry": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/registry/registry-rc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "registry-rc.yaml", "0640", false), MustBinAsset( "deploy/addons/registry/registry-svc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "registry-svc.yaml", "0640", false), MustBinAsset( "deploy/addons/registry/registry-proxy.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "registry-proxy.yaml", "0640", false), - }, false, "registry"), + }, false, "registry", "kube-system"), "registry-creds": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/registry-creds/registry-creds-rc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "registry-creds-rc.yaml", "0640", false), - }, false, "registry-creds"), + }, false, "registry-creds", "kube-system"), "freshpod": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/freshpod/freshpod-rc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "freshpod-rc.yaml", "0640", true), - }, false, "freshpod"), + }, false, "freshpod", "kube-system"), "nvidia-driver-installer": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/gpu/nvidia-driver-installer.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "nvidia-driver-installer.yaml", "0640", true), - }, false, "nvidia-driver-installer"), + }, false, "nvidia-driver-installer", "kube-system"), "nvidia-gpu-device-plugin": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/gpu/nvidia-gpu-device-plugin.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "nvidia-gpu-device-plugin.yaml", "0640", true), - }, false, "nvidia-gpu-device-plugin"), + }, false, "nvidia-gpu-device-plugin", "kube-system"), "logviewer": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/logviewer/logviewer-dp-and-svc.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "logviewer-dp-and-svc.yaml", "0640", false), MustBinAsset( "deploy/addons/logviewer/logviewer-rbac.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "logviewer-rbac.yaml", "0640", false), - }, false, "logviewer"), + }, false, "logviewer", "kube-system"), "gvisor": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/gvisor/gvisor-pod.yaml.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "gvisor-pod.yaml", "0640", true), MustBinAsset( "deploy/addons/gvisor/gvisor-runtimeclass.yaml", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "gvisor-runtimeclass.yaml", "0640", false), @@ -309,35 +306,40 @@ var Addons = map[string]*Addon{ constants.GvisorConfigTomlTargetName, "0640", true), - }, false, "gvisor"), + }, false, "gvisor", "kube-system"), "helm-tiller": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/helm-tiller/helm-tiller-dp.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "helm-tiller-dp.yaml", "0640", true), MustBinAsset( "deploy/addons/helm-tiller/helm-tiller-rbac.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "helm-tiller-rbac.yaml", "0640", true), MustBinAsset( "deploy/addons/helm-tiller/helm-tiller-svc.tmpl", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "helm-tiller-svc.yaml", "0640", true), - }, false, "helm-tiller"), + }, false, "helm-tiller", "kube-system"), "ingress-dns": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/ingress-dns/ingress-dns-pod.yaml", - vmpath.GuestAddonsDir, + TargetDirForAddon("kube-system"), "ingress-dns-pod.yaml", "0640", false), - }, false, "ingress-dns"), + }, false, "ingress-dns", "kube-system"), +} + +// TargetDirForAddon appends the namespace as a directory to /etc/kubernetes/addons +func TargetDirForAddon(namespace string) string { + return filepath.Join(vmpath.GuestAddonsDir, namespace) } // AddMinikubeDirAssets adds all addons and files to the list From 7247a7dee614a563785c7cfcec602f6ddc21ba9c Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 22 Jan 2020 14:18:20 -0800 Subject: [PATCH 2/5] Switched to using kubectl apply and kubectl delete for addons kubectl apply with --prune wasn't working because it requires the --namespace flag to be passed in and we have multiple namespaces for addons. We tried to split up addons within /etc/kubernetes/addons by namespace, but this didn't work when disabling dashboard addon because there were no files left in the kubernetes-dashboard subdirectory. So, kubectl apply complained when trying to prune dashboard because no files were being passed in. So, I ended up removing all dependencies on prune and instead running `kubectl apply` when enabling an addon and running `kubectl delete` when disabling an addon. --- pkg/addons/addons.go | 28 ++-- pkg/addons/kubectl.go | 68 +++++++++ .../{reconcile_test.go => kubectl_test.go} | 0 pkg/addons/reconcile.go | 141 ------------------ pkg/minikube/assets/addons.go | 5 +- 5 files changed, 89 insertions(+), 153 deletions(-) create mode 100644 pkg/addons/kubectl.go rename pkg/addons/{reconcile_test.go => kubectl_test.go} (100%) delete mode 100644 pkg/addons/reconcile.go diff --git a/pkg/addons/addons.go b/pkg/addons/addons.go index 184d7952ff..1380c6bf29 100644 --- a/pkg/addons/addons.go +++ b/pkg/addons/addons.go @@ -19,6 +19,7 @@ package addons import ( "fmt" "os" + "path/filepath" "strconv" "github.com/pkg/errors" @@ -174,15 +175,10 @@ func isAddonAlreadySet(addon *assets.Addon, enable bool) (bool, error) { } func enableOrDisableAddonInternal(addon *assets.Addon, cmd command.Runner, data interface{}, enable bool, profile string) error { - var err error - - updateFile := cmd.Copy - if !enable { - updateFile = cmd.Remove - } - + files := []string{} for _, addon := range addon.Assets { var addonFile assets.CopyableFile + var err error if addon.IsTemplate() { addonFile, err = addon.Evaluate(data) if err != nil { @@ -192,11 +188,23 @@ func enableOrDisableAddonInternal(addon *assets.Addon, cmd command.Runner, data } else { addonFile = addon } - if err := updateFile(addonFile); err != nil { - return errors.Wrapf(err, "updating addon %s", addon.AssetName) + if enable { + if err := cmd.Copy(addonFile); err != nil { + return err + } + } else { + defer cmd.Remove(addonFile) } + files = append(files, filepath.Join(addonFile.GetTargetDir(), addonFile.GetTargetName())) } - return reconcile(cmd, profile) + command, err := kubectlCommand(profile, files, enable) + if err != nil { + return err + } + if result, err := cmd.RunCmd(command); err != nil { + return errors.Wrapf(err, "error enabling addon:\n%s", result.Output()) + } + return nil } // enableOrDisableStorageClasses enables or disables storage classes diff --git a/pkg/addons/kubectl.go b/pkg/addons/kubectl.go new file mode 100644 index 0000000000..5cc96383f8 --- /dev/null +++ b/pkg/addons/kubectl.go @@ -0,0 +1,68 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addons + +import ( + "os" + "os/exec" + "path" + + "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/constants" +) + +var ( + // For testing + k8sVersion = kubernetesVersion +) + +func kubectlCommand(profile string, files []string, enable bool) (*exec.Cmd, error) { + v, err := k8sVersion(profile) + if err != nil { + return nil, err + } + kubectlBinary := kubectlBinaryPath(v) + + kubectlAction := "apply" + if !enable { + kubectlAction = "delete" + } + + args := []string{"KUBECONFIG=/var/lib/minikube/kubeconfig", kubectlBinary, kubectlAction} + for _, f := range files { + args = append(args, []string{"-f", f}...) + } + + cmd := exec.Command("sudo", args...) + return cmd, nil +} + +func kubernetesVersion(profile string) (string, error) { + cc, err := config.Load(profile) + if err != nil && !os.IsNotExist(err) { + return "", err + } + version := constants.DefaultKubernetesVersion + if cc != nil { + version = cc.KubernetesConfig.KubernetesVersion + } + return version, nil +} + +func kubectlBinaryPath(version string) string { + return path.Join("/var/lib/minikube/binaries", version, "kubectl") +} diff --git a/pkg/addons/reconcile_test.go b/pkg/addons/kubectl_test.go similarity index 100% rename from pkg/addons/reconcile_test.go rename to pkg/addons/kubectl_test.go diff --git a/pkg/addons/reconcile.go b/pkg/addons/reconcile.go deleted file mode 100644 index e4096d71ff..0000000000 --- a/pkg/addons/reconcile.go +++ /dev/null @@ -1,141 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package addons - -import ( - "fmt" - "io/ioutil" - "os" - "os/exec" - "path" - - "github.com/blang/semver" - "github.com/golang/glog" - "github.com/pkg/errors" - "k8s.io/minikube/pkg/minikube/assets" - "k8s.io/minikube/pkg/minikube/bootstrapper/bsutil" - "k8s.io/minikube/pkg/minikube/command" - "k8s.io/minikube/pkg/minikube/config" - "k8s.io/minikube/pkg/minikube/constants" - "k8s.io/minikube/pkg/minikube/vmpath" -) - -var ( - // For testing - k8sVersion = kubernetesVersion -) - -// taken from https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/addon-manager/kube-addons.sh -var kubectlPruneWhitelist = []string{ - "core/v1/ConfigMap", - "core/v1/Endpoints", - "core/v1/Namespace", - "core/v1/PersistentVolumeClaim", - "core/v1/PersistentVolume", - "core/v1/Pod", - "core/v1/ReplicationController", - "core/v1/Secret", - "core/v1/Service", - "batch/v1/Job", - "batch/v1beta1/CronJob", - "apps/v1/DaemonSet", - "apps/v1/Deployment", - "apps/v1/ReplicaSet", - "apps/v1/StatefulSet", - "extensions/v1beta1/Ingress", -} - -// reconcile runs kubectl apply -f on the addons directory -// to reconcile addons state in all running profiles -func reconcile(cmd command.Runner, profile string) error { - // Walk through all subdirs in /etc/kubernetes/addons and reconcile addons - dirs, err := ioutil.ReadDir(vmpath.GuestAddonsDir) - if err != nil { - return err - } - - for _, d := range dirs { - if !d.IsDir() { - continue - } - namespace := d.Name() - glog.Infof("Reconciling addons in namespace %s", namespace) - c, err := kubectlCommand(profile, namespace) - if err != nil { - return err - } - if _, err := cmd.RunCmd(c); err != nil { - glog.Warningf("reconciling addons failed: %v", err) - return err - } - } - - return nil -} - -func kubectlCommand(profile, namespace string) (*exec.Cmd, error) { - v, err := k8sVersion(profile) - if err != nil { - return nil, err - } - kubectlBinary := kubectlBinaryPath(v) - - // prune will delete any existing objects with the label specified by "-l" which don't appear in /etc/kubernetes/addons - // this is how we delete disabled addons - args := []string{"KUBECONFIG=/var/lib/minikube/kubeconfig", kubectlBinary, "apply", "-f", assets.TargetDirForAddon(namespace), "-l", "kubernetes.io/cluster-service!=true,addonmanager.kubernetes.io/mode=Reconcile", "--prune=true"} - for _, k := range kubectlPruneWhitelist { - args = append(args, []string{"--prune-whitelist", k}...) - } - args = append(args, "--recursive") - - ok, err := shouldAppendNamespaceFlag(v) - if err != nil { - return nil, errors.Wrap(err, "appending namespace flag") - } - if ok { - args = append(args, fmt.Sprintf("--namespace=%s", namespace)) - } - - cmd := exec.Command("sudo", args...) - return cmd, nil -} - -func kubernetesVersion(profile string) (string, error) { - cc, err := config.Load(profile) - if err != nil && !os.IsNotExist(err) { - return "", err - } - version := constants.DefaultKubernetesVersion - if cc != nil { - version = cc.KubernetesConfig.KubernetesVersion - } - return version, nil -} - -// We need to append --namespace=kube-system for Kubernetes versions >=1.17 -// so that prune works as expected. See https://github.com/kubernetes/kubernetes/pull/83084/ -func shouldAppendNamespaceFlag(version string) (bool, error) { - v, err := bsutil.ParseKubernetesVersion(version) - if err != nil { - return false, err - } - return v.GTE(semver.MustParse("1.17.0")), nil -} - -func kubectlBinaryPath(version string) string { - return path.Join("/var/lib/minikube/binaries", version, "kubectl") -} diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 7be028bf8f..90eff0096a 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -66,11 +66,11 @@ func (a *Addon) IsEnabled() (bool, error) { // TODO: Make dynamically loadable: move this data to a .yaml file within each addon directory var Addons = map[string]*Addon{ "dashboard": NewAddon([]*BinAsset{ + MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-ns.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-clusterrole.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-clusterrolebinding.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-configmap.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-dp.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-ns.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-role.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-rolebinding.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-sa.yaml", "0640", false), @@ -331,7 +331,8 @@ var Addons = map[string]*Addon{ // TargetDirForAddon appends the namespace as a directory to /etc/kubernetes/addons func TargetDirForAddon(namespace string) string { - return filepath.Join(vmpath.GuestAddonsDir, namespace) + return vmpath.GuestAddonsDir + // return filepath.Join(vmpath.GuestAddonsDir, namespace) } // AddMinikubeDirAssets adds all addons and files to the list From 15a52098414b0f9f00324770727e3c7935ab786e Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 22 Jan 2020 14:23:32 -0800 Subject: [PATCH 3/5] Update unit tests --- pkg/addons/kubectl_test.go | 34 ++++----- pkg/minikube/assets/addons.go | 137 +++++++++++++++++----------------- 2 files changed, 81 insertions(+), 90 deletions(-) diff --git a/pkg/addons/kubectl_test.go b/pkg/addons/kubectl_test.go index d53e87e698..493ff35412 100644 --- a/pkg/addons/kubectl_test.go +++ b/pkg/addons/kubectl_test.go @@ -17,31 +17,27 @@ limitations under the License. package addons import ( - "fmt" "strings" "testing" ) func TestKubectlCommand(t *testing.T) { - expectedCommand := "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/%s/kubectl apply -f /etc/kubernetes/addons -l kubernetes.io/cluster-service!=true,addonmanager.kubernetes.io/mode=Reconcile --prune=true --prune-whitelist core/v1/ConfigMap --prune-whitelist core/v1/Endpoints --prune-whitelist core/v1/Namespace --prune-whitelist core/v1/PersistentVolumeClaim --prune-whitelist core/v1/PersistentVolume --prune-whitelist core/v1/Pod --prune-whitelist core/v1/ReplicationController --prune-whitelist core/v1/Secret --prune-whitelist core/v1/Service --prune-whitelist batch/v1/Job --prune-whitelist batch/v1beta1/CronJob --prune-whitelist apps/v1/DaemonSet --prune-whitelist apps/v1/Deployment --prune-whitelist apps/v1/ReplicaSet --prune-whitelist apps/v1/StatefulSet --prune-whitelist extensions/v1beta1/Ingress --recursive" - tests := []struct { description string - k8sVersion string + files []string + enable bool expected string }{ { - description: "k8s version < 1.17.0", - k8sVersion: "v1.16.0", - expected: expectedCommand, + description: "enable an addon", + files: []string{"a", "b"}, + enable: true, + expected: "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/v1.17.0/kubectl apply -f a -f b", }, { - description: "k8s version == 1.17.0", - k8sVersion: "v1.17.0", - expected: expectedCommand + " --namespace=kube-system", - }, { - description: "k8s version > 1.17.0", - k8sVersion: "v1.18.0", - expected: expectedCommand + " --namespace=kube-system", + description: "disable an addon", + files: []string{"a", "b"}, + enable: false, + expected: "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/v1.17.0/kubectl delete -f a -f b", }, } @@ -50,19 +46,17 @@ func TestKubectlCommand(t *testing.T) { originalK8sVersion := k8sVersion defer func() { k8sVersion = originalK8sVersion }() k8sVersion = func(_ string) (string, error) { - return test.k8sVersion, nil + return "v1.17.0", nil } - command, err := kubectlCommand("") + command, err := kubectlCommand("", test.files, test.enable) if err != nil { t.Fatalf("error getting kubectl command: %v", err) } actual := strings.Join(command.Args, " ") - expected := fmt.Sprintf(test.expected, test.k8sVersion) - - if actual != expected { - t.Fatalf("expected does not match actual\nExpected: %s\nActual: %s", expected, actual) + if actual != test.expected { + t.Fatalf("expected does not match actual\nExpected: %s\nActual: %s", test.expected, actual) } }) } diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 90eff0096a..1c8a0e0773 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -1,9 +1,12 @@ /* Copyright 2016 The Kubernetes Authors All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -37,7 +40,7 @@ type Addon struct { } // NewAddon creates a new Addon -func NewAddon(assets []*BinAsset, enabled bool, addonName, namespace string) *Addon { +func NewAddon(assets []*BinAsset, enabled bool, addonName string) *Addon { a := &Addon{ Assets: assets, enabled: enabled, @@ -66,229 +69,229 @@ func (a *Addon) IsEnabled() (bool, error) { // TODO: Make dynamically loadable: move this data to a .yaml file within each addon directory var Addons = map[string]*Addon{ "dashboard": NewAddon([]*BinAsset{ - MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-ns.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-clusterrole.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-clusterrolebinding.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-configmap.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-dp.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-role.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-rolebinding.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-sa.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-secret.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-secret.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-svc.yaml", TargetDirForAddon("kubernetes-dashboard"), "dashboard-svc.yaml", "0640", false), - }, false, "dashboard", "kubernetes-dashboard"), + MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrole.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrolebinding.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", vmpath.GuestAddonsDir, "dashboard-configmap.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml", vmpath.GuestAddonsDir, "dashboard-dp.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", vmpath.GuestAddonsDir, "dashboard-role.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-rolebinding.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-secret.yaml", vmpath.GuestAddonsDir, "dashboard-secret.yaml", "0640", false), + MustBinAsset("deploy/addons/dashboard/dashboard-svc.yaml", vmpath.GuestAddonsDir, "dashboard-svc.yaml", "0640", false), + }, false, "dashboard"), "default-storageclass": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/storageclass/storageclass.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "storageclass.yaml", "0640", false), - }, true, "default-storageclass", "kube-system"), + }, true, "default-storageclass"), "storage-provisioner": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/storage-provisioner/storage-provisioner.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "storage-provisioner.yaml", "0640", true), - }, true, "storage-provisioner", "kube-system"), + }, true, "storage-provisioner"), "storage-provisioner-gluster": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/storage-provisioner-gluster/storage-gluster-ns.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "storage-gluster-ns.yaml", "0640", false), MustBinAsset( "deploy/addons/storage-provisioner-gluster/glusterfs-daemonset.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "glusterfs-daemonset.yaml", "0640", false), MustBinAsset( "deploy/addons/storage-provisioner-gluster/heketi-deployment.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "heketi-deployment.yaml", "0640", false), MustBinAsset( "deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "storage-privisioner-glusterfile.yaml", "0640", false), - }, false, "storage-provisioner-gluster", "kube-system"), + }, false, "storage-provisioner-gluster"), "efk": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/efk/elasticsearch-rc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "elasticsearch-rc.yaml", "0640", true), MustBinAsset( "deploy/addons/efk/elasticsearch-svc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "elasticsearch-svc.yaml", "0640", false), MustBinAsset( "deploy/addons/efk/fluentd-es-rc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "fluentd-es-rc.yaml", "0640", true), MustBinAsset( "deploy/addons/efk/fluentd-es-configmap.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "fluentd-es-configmap.yaml", "0640", false), MustBinAsset( "deploy/addons/efk/kibana-rc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "kibana-rc.yaml", "0640", false), MustBinAsset( "deploy/addons/efk/kibana-svc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "kibana-svc.yaml", "0640", false), - }, false, "efk", "kube-system"), + }, false, "efk"), "ingress": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/ingress/ingress-configmap.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "ingress-configmap.yaml", "0640", false), MustBinAsset( "deploy/addons/ingress/ingress-rbac.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "ingress-rbac.yaml", "0640", false), MustBinAsset( "deploy/addons/ingress/ingress-dp.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "ingress-dp.yaml", "0640", true), - }, false, "ingress", "kube-system"), + }, false, "ingress"), "istio-provisioner": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/istio-provisioner/istio-operator.yaml.tmpl", - TargetDirForAddon("istio-operator"), + vmpath.GuestAddonsDir, "istio-operator.yaml", "0640", true), - }, false, "istio-provisioner", "istio-operator"), + }, false, "istio-provisioner"), "istio": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/istio/istio-default-profile.yaml.tmpl", - TargetDirForAddon("istio-operator"), + vmpath.GuestAddonsDir, "istio-default-profile.yaml", "0640", false), - }, false, "istio", "istio-operator"), + }, false, "istio"), "metrics-server": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/metrics-server/metrics-apiservice.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "metrics-apiservice.yaml", "0640", false), MustBinAsset( "deploy/addons/metrics-server/metrics-server-deployment.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "metrics-server-deployment.yaml", "0640", true), MustBinAsset( "deploy/addons/metrics-server/metrics-server-service.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "metrics-server-service.yaml", "0640", false), - }, false, "metrics-server", "kube-system"), + }, false, "metrics-server"), "registry": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/registry/registry-rc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "registry-rc.yaml", "0640", false), MustBinAsset( "deploy/addons/registry/registry-svc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "registry-svc.yaml", "0640", false), MustBinAsset( "deploy/addons/registry/registry-proxy.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "registry-proxy.yaml", "0640", false), - }, false, "registry", "kube-system"), + }, false, "registry"), "registry-creds": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/registry-creds/registry-creds-rc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "registry-creds-rc.yaml", "0640", false), - }, false, "registry-creds", "kube-system"), + }, false, "registry-creds"), "freshpod": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/freshpod/freshpod-rc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "freshpod-rc.yaml", "0640", true), - }, false, "freshpod", "kube-system"), + }, false, "freshpod"), "nvidia-driver-installer": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/gpu/nvidia-driver-installer.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "nvidia-driver-installer.yaml", "0640", true), - }, false, "nvidia-driver-installer", "kube-system"), + }, false, "nvidia-driver-installer"), "nvidia-gpu-device-plugin": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/gpu/nvidia-gpu-device-plugin.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "nvidia-gpu-device-plugin.yaml", "0640", true), - }, false, "nvidia-gpu-device-plugin", "kube-system"), + }, false, "nvidia-gpu-device-plugin"), "logviewer": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/logviewer/logviewer-dp-and-svc.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "logviewer-dp-and-svc.yaml", "0640", false), MustBinAsset( "deploy/addons/logviewer/logviewer-rbac.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "logviewer-rbac.yaml", "0640", false), - }, false, "logviewer", "kube-system"), + }, false, "logviewer"), "gvisor": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/gvisor/gvisor-pod.yaml.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "gvisor-pod.yaml", "0640", true), MustBinAsset( "deploy/addons/gvisor/gvisor-runtimeclass.yaml", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "gvisor-runtimeclass.yaml", "0640", false), @@ -298,41 +301,35 @@ var Addons = map[string]*Addon{ constants.GvisorConfigTomlTargetName, "0640", true), - }, false, "gvisor", "kube-system"), + }, false, "gvisor"), "helm-tiller": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/helm-tiller/helm-tiller-dp.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "helm-tiller-dp.yaml", "0640", true), MustBinAsset( "deploy/addons/helm-tiller/helm-tiller-rbac.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "helm-tiller-rbac.yaml", "0640", true), MustBinAsset( "deploy/addons/helm-tiller/helm-tiller-svc.tmpl", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "helm-tiller-svc.yaml", "0640", true), - }, false, "helm-tiller", "kube-system"), + }, false, "helm-tiller"), "ingress-dns": NewAddon([]*BinAsset{ MustBinAsset( "deploy/addons/ingress-dns/ingress-dns-pod.yaml", - TargetDirForAddon("kube-system"), + vmpath.GuestAddonsDir, "ingress-dns-pod.yaml", "0640", false), - }, false, "ingress-dns", "kube-system"), -} - -// TargetDirForAddon appends the namespace as a directory to /etc/kubernetes/addons -func TargetDirForAddon(namespace string) string { - return vmpath.GuestAddonsDir - // return filepath.Join(vmpath.GuestAddonsDir, namespace) + }, false, "ingress-dns"), } // AddMinikubeDirAssets adds all addons and files to the list From 8d8ea98378654cf388cc7c1a3f4891c4651b6b45 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 22 Jan 2020 15:11:33 -0800 Subject: [PATCH 4/5] check cmd.Remove error for linting --- pkg/addons/addons.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/addons/addons.go b/pkg/addons/addons.go index 1380c6bf29..0437793d04 100644 --- a/pkg/addons/addons.go +++ b/pkg/addons/addons.go @@ -22,6 +22,7 @@ import ( "path/filepath" "strconv" + "github.com/golang/glog" "github.com/pkg/errors" "github.com/spf13/viper" "k8s.io/minikube/pkg/minikube/assets" @@ -193,7 +194,11 @@ func enableOrDisableAddonInternal(addon *assets.Addon, cmd command.Runner, data return err } } else { - defer cmd.Remove(addonFile) + defer func() { + if err := cmd.Remove(addonFile); err != nil { + glog.Warningf("error removing %s; addon should still be disabled as expected", addonFile) + } + }() } files = append(files, filepath.Join(addonFile.GetTargetDir(), addonFile.GetTargetName())) } @@ -202,7 +207,7 @@ func enableOrDisableAddonInternal(addon *assets.Addon, cmd command.Runner, data return err } if result, err := cmd.RunCmd(command); err != nil { - return errors.Wrapf(err, "error enabling addon:\n%s", result.Output()) + return errors.Wrapf(err, "error updating addon:\n%s", result.Output()) } return nil } From 49b0cb1c9c2232dc58d1e27b853fa12755e2019c Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 22 Jan 2020 15:16:36 -0800 Subject: [PATCH 5/5] create dashboard ns first so that everything else can be created after --- pkg/minikube/assets/addons.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 1c8a0e0773..67fd6b33df 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -69,11 +69,12 @@ func (a *Addon) IsEnabled() (bool, error) { // TODO: Make dynamically loadable: move this data to a .yaml file within each addon directory var Addons = map[string]*Addon{ "dashboard": NewAddon([]*BinAsset{ + // We want to create the kubernetes-dashboard ns first so that every subsequent object can be created + MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrole.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrolebinding.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", vmpath.GuestAddonsDir, "dashboard-configmap.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml", vmpath.GuestAddonsDir, "dashboard-dp.yaml", "0640", false), - MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", vmpath.GuestAddonsDir, "dashboard-role.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-rolebinding.yaml", "0640", false), MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640", false),