1036 lines
44 KiB
Go
1036 lines
44 KiB
Go
/*
|
|
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 assets
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
semver "github.com/blang/semver/v4"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/viper"
|
|
"k8s.io/minikube/deploy/addons"
|
|
"k8s.io/minikube/pkg/minikube/config"
|
|
"k8s.io/minikube/pkg/minikube/out"
|
|
"k8s.io/minikube/pkg/minikube/vmpath"
|
|
"k8s.io/minikube/pkg/util"
|
|
"k8s.io/minikube/pkg/version"
|
|
)
|
|
|
|
// Addon is a named list of assets, that can be enabled
|
|
type Addon struct {
|
|
Assets []*BinAsset
|
|
enabled bool
|
|
addonName string
|
|
Maintainer string
|
|
VerifiedMaintainer string
|
|
Docs string
|
|
Images map[string]string
|
|
|
|
// Registries currently only shows the default registry of images
|
|
Registries map[string]string
|
|
}
|
|
|
|
// NetworkInfo contains control plane node IP address used for add on template
|
|
type NetworkInfo struct {
|
|
ControlPlaneNodeIP string
|
|
ControlPlaneNodePort int
|
|
}
|
|
|
|
// NewAddon creates a new Addon
|
|
func NewAddon(assets []*BinAsset, enabled bool, addonName, maintainer, verifiedMaintainer, docs string, images, registries map[string]string) *Addon {
|
|
return &Addon{
|
|
Assets: assets,
|
|
enabled: enabled,
|
|
addonName: addonName,
|
|
Maintainer: maintainer,
|
|
VerifiedMaintainer: verifiedMaintainer,
|
|
Docs: docs,
|
|
Images: images,
|
|
Registries: registries,
|
|
}
|
|
}
|
|
|
|
// Name gets the addon name
|
|
func (a *Addon) Name() string {
|
|
return a.addonName
|
|
}
|
|
|
|
// IsEnabled checks if an Addon is enabled for the given profile
|
|
func (a *Addon) IsEnabled(cc *config.ClusterConfig) bool {
|
|
status, ok := cc.Addons[a.Name()]
|
|
if ok {
|
|
return status
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// IsEnabledOrDefault checks if an Addon is enabled for the given profile. If not found in profile it returns the default state
|
|
func (a *Addon) IsEnabledOrDefault(cc *config.ClusterConfig) bool {
|
|
status, ok := cc.Addons[a.Name()]
|
|
if ok {
|
|
return status
|
|
}
|
|
|
|
// Return the default unconfigured state of the addon
|
|
return a.enabled
|
|
}
|
|
|
|
// EnableByDefault will enable the addon by default on cluster start
|
|
func (a *Addon) EnableByDefault() {
|
|
a.enabled = true
|
|
}
|
|
|
|
// Addons is the list of addons
|
|
// TODO: Make dynamically loadable: move this data to a .yaml file within each addon directory
|
|
var Addons = map[string]*Addon{
|
|
"auto-pause": NewAddon([]*BinAsset{
|
|
MustBinAsset(
|
|
addons.AutoPauseAssets,
|
|
"auto-pause/auto-pause.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"auto-pause.yaml",
|
|
"0640"),
|
|
MustBinAsset(
|
|
addons.AutoPauseAssets,
|
|
"auto-pause/auto-pause-hook.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"auto-pause-hook.yaml",
|
|
"0640"),
|
|
MustBinAsset(
|
|
addons.AutoPauseAssets,
|
|
"auto-pause/haproxy.cfg.tmpl",
|
|
vmpath.GuestPersistentDir,
|
|
"haproxy.cfg",
|
|
"0640"),
|
|
MustBinAsset(
|
|
addons.AutoPauseAssets,
|
|
"auto-pause/unpause.lua",
|
|
vmpath.GuestPersistentDir,
|
|
"unpause.lua",
|
|
"0640"),
|
|
MustBinAsset(
|
|
addons.AutoPauseAssets,
|
|
"auto-pause/auto-pause.service.tmpl",
|
|
"/etc/systemd/system/",
|
|
"auto-pause.service",
|
|
"0640"),
|
|
|
|
// GuestPersistentDir
|
|
}, false, "auto-pause", "minikube", "", "", map[string]string{
|
|
"AutoPauseHook": "k8s-minikube/auto-pause-hook:v0.0.5@sha256:d613ed2c891882b602b5aca668e92d4606a1b3832d96750ab25804de15929522",
|
|
}, map[string]string{
|
|
"AutoPauseHook": "gcr.io",
|
|
}),
|
|
"dashboard": NewAddon([]*BinAsset{
|
|
// We want to create the kubernetes-dashboard ns first so that every subsequent object can be created
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-clusterrole.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrole.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrolebinding.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-configmap.yaml", vmpath.GuestAddonsDir, "dashboard-configmap.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-dp.yaml.tmpl", vmpath.GuestAddonsDir, "dashboard-dp.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-role.yaml", vmpath.GuestAddonsDir, "dashboard-role.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-rolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-rolebinding.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-secret.yaml", vmpath.GuestAddonsDir, "dashboard-secret.yaml", "0640"),
|
|
MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-svc.yaml", vmpath.GuestAddonsDir, "dashboard-svc.yaml", "0640"),
|
|
}, false, "dashboard", "Kubernetes", "", "https://minikube.sigs.k8s.io/docs/handbook/dashboard/", map[string]string{
|
|
"Dashboard": "kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93",
|
|
"MetricsScraper": "kubernetesui/metrics-scraper:v1.0.8@sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c",
|
|
}, map[string]string{
|
|
"Dashboard": "docker.io",
|
|
"MetricsScraper": "docker.io",
|
|
}),
|
|
"default-storageclass": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.DefaultStorageClassAssets,
|
|
"storageclass/storageclass.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"storageclass.yaml",
|
|
"0640"),
|
|
}, true, "default-storageclass", "Kubernetes", "", "https://minikube.sigs.k8s.io/docs/handbook/persistent_volumes/", nil, nil),
|
|
"pod-security-policy": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.PodSecurityPolicyAssets,
|
|
"pod-security-policy/pod-security-policy.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"pod-security-policy.yaml",
|
|
"0640"),
|
|
}, false, "pod-security-policy", "3rd party (unknown)", "", "", nil, nil),
|
|
"storage-provisioner": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.StorageProvisionerAssets,
|
|
"storage-provisioner/storage-provisioner.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"storage-provisioner.yaml",
|
|
"0640"),
|
|
}, true, "storage-provisioner", "minikube", "", "", map[string]string{
|
|
"StorageProvisioner": fmt.Sprintf("k8s-minikube/storage-provisioner:%s", version.GetStorageProvisionerVersion()),
|
|
}, map[string]string{
|
|
"StorageProvisioner": "gcr.io",
|
|
}),
|
|
"storage-provisioner-gluster": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.StorageProvisionerGlusterAssets,
|
|
"storage-provisioner-gluster/storage-gluster-ns.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"storage-gluster-ns.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.StorageProvisionerGlusterAssets,
|
|
"storage-provisioner-gluster/glusterfs-daemonset.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"glusterfs-daemonset.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.StorageProvisionerGlusterAssets,
|
|
"storage-provisioner-gluster/heketi-deployment.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"heketi-deployment.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.StorageProvisionerGlusterAssets,
|
|
"storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"storage-provisioner-glusterfile.yaml",
|
|
"0640"),
|
|
}, false, "storage-provisioner-gluster", "3rd party (Gluster)", "", "", map[string]string{
|
|
"Heketi": "heketi/heketi:10@sha256:76d5a6a3b7cf083d1e99efa1c15abedbc5c8b73bef3ade299ce9a4c16c9660f8",
|
|
"GlusterfileProvisioner": "gluster/glusterfile-provisioner:latest@sha256:9961a35cb3f06701958e202324141c30024b195579e5eb1704599659ddea5223",
|
|
"GlusterfsServer": "gluster/gluster-centos:latest@sha256:8167034b9abf2d16581f3f4571507ce7d716fb58b927d7627ef72264f802e908",
|
|
}, map[string]string{
|
|
"Heketi": "docker.io",
|
|
"GlusterfsServer": "docker.io",
|
|
"GlusterfileProvisioner": "docker.io",
|
|
}),
|
|
"storage-provisioner-rancher": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.StorageProvisionerRancherAssets,
|
|
"storage-provisioner-rancher/storage-provisioner-rancher.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"storage-provisioner-rancher.yaml",
|
|
"0640"),
|
|
}, false, "storage-provisioner-rancher", "3rd party (Rancher)", "", "", map[string]string{
|
|
"LocalPathProvisioner": "rancher/local-path-provisioner:v0.0.22@sha256:e34c88ae0affb1cdefbb874140d6339d4a27ec4ee420ae8199cd839997b05246",
|
|
"Helper": "busybox:stable@sha256:3fbc632167424a6d997e74f52b878d7cc478225cffac6bc977eedfe51c7f4e79",
|
|
}, map[string]string{
|
|
"LocalPathProvisioner": "docker.io",
|
|
"Helper": "docker.io",
|
|
}),
|
|
"efk": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.EfkAssets,
|
|
"efk/elasticsearch-rc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"elasticsearch-rc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.EfkAssets,
|
|
"efk/elasticsearch-svc.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"elasticsearch-svc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.EfkAssets,
|
|
"efk/fluentd-es-rc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"fluentd-es-rc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.EfkAssets,
|
|
"efk/fluentd-es-configmap.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"fluentd-es-configmap.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.EfkAssets,
|
|
"efk/kibana-rc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"kibana-rc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.EfkAssets,
|
|
"efk/kibana-svc.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"kibana-svc.yaml",
|
|
"0640"),
|
|
}, false, "efk", "3rd party (Elastic)", "", "", map[string]string{
|
|
"Elasticsearch": "elasticsearch:v5.6.2@sha256:7e95b32a7a2aad0c0db5c881e4a1ce8b7e53236144ae9d9cfb5fbe5608af4ab2",
|
|
"FluentdElasticsearch": "fluentd-elasticsearch:v2.0.2@sha256:d0480bbf2d0de2344036fa3f7034cf7b4b98025a89c71d7f1f1845ac0e7d5a97",
|
|
"Alpine": "alpine:3.6@sha256:66790a2b79e1ea3e1dabac43990c54aca5d1ddf268d9a5a0285e4167c8b24475",
|
|
"Kibana": "kibana/kibana:5.6.2@sha256:cd948a9bda4622f1437afc4a3e78be6c8c25fc62f40aa0376f3d690f2436568f",
|
|
}, map[string]string{
|
|
"Elasticsearch": "registry.k8s.io",
|
|
"FluentdElasticsearch": "registry.k8s.io",
|
|
"Kibana": "docker.elastic.co",
|
|
"Alpine": "docker.io",
|
|
}),
|
|
"ingress": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.IngressAssets,
|
|
"ingress/ingress-deploy.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"ingress-deploy.yaml",
|
|
"0640"),
|
|
}, false, "ingress", "Kubernetes", "", "https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/", map[string]string{
|
|
// https://github.com/kubernetes/ingress-nginx/blob/3476232f5c38383dd157ddaff3b4c7cebd57284e/deploy/static/provider/kind/deploy.yaml#L445
|
|
"IngressController": "ingress-nginx/controller:v1.10.1@sha256:e24f39d3eed6bcc239a56f20098878845f62baa34b9f2be2fd2c38ce9fb0f29e",
|
|
// https://github.com/kubernetes/ingress-nginx/blob/3476232f5c38383dd157ddaff3b4c7cebd57284e/deploy/static/provider/kind/deploy.yaml#L552
|
|
"KubeWebhookCertgenCreate": "ingress-nginx/kube-webhook-certgen:v1.4.1@sha256:36d05b4077fb8e3d13663702fa337f124675ba8667cbd949c03a8e8ea6fa4366",
|
|
// https://github.com/kubernetes/ingress-nginx/blob/3476232f5c38383dd157ddaff3b4c7cebd57284e/deploy/static/provider/kind/deploy.yaml#L601
|
|
"KubeWebhookCertgenPatch": "ingress-nginx/kube-webhook-certgen:v1.4.1@sha256:36d05b4077fb8e3d13663702fa337f124675ba8667cbd949c03a8e8ea6fa4366",
|
|
}, map[string]string{
|
|
"IngressController": "registry.k8s.io",
|
|
"KubeWebhookCertgenCreate": "registry.k8s.io",
|
|
"KubeWebhookCertgenPatch": "registry.k8s.io",
|
|
}),
|
|
"istio-provisioner": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.IstioProvisionerAssets,
|
|
"istio-provisioner/istio-operator.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"istio-operator.yaml",
|
|
"0640"),
|
|
}, false, "istio-provisioner", "3rd party (Istio)", "", "https://istio.io/latest/docs/setup/platform-setup/minikube/", map[string]string{
|
|
"IstioOperator": "istio/operator:1.21.2@sha256:464738ecc5566c634dd22e3057fd58060a1d073d85647bebd16f535586006bcf",
|
|
}, map[string]string{
|
|
"IstioOperator": "docker.io",
|
|
}),
|
|
"istio": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.IstioAssets,
|
|
"istio/istio-default-profile.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"istio-default-profile.yaml",
|
|
"0640"),
|
|
}, false, "istio", "3rd party (Istio)", "", "https://istio.io/latest/docs/setup/platform-setup/minikube/", nil, nil),
|
|
"inspektor-gadget": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-namespace.yaml", vmpath.GuestAddonsDir, "ig-namespace.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-serviceaccount.yaml", vmpath.GuestAddonsDir, "ig-serviceaccount.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-role.yaml", vmpath.GuestAddonsDir, "ig-role.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-rolebinding.yaml", vmpath.GuestAddonsDir, "ig-rolebinding.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-clusterrole.yaml", vmpath.GuestAddonsDir, "ig-clusterrole.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "ig-clusterrolebinding.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-crd.yaml", vmpath.GuestAddonsDir, "ig-crd.yaml", "0640"),
|
|
MustBinAsset(addons.InspektorGadgetAssets, "inspektor-gadget/ig-daemonset.yaml.tmpl", vmpath.GuestAddonsDir, "ig-daemonset.yaml", "0640"),
|
|
}, false, "inspektor-gadget", "3rd party (inspektor-gadget.io)", "https://github.com/orgs/inspektor-gadget/people", "https://minikube.sigs.k8s.io/docs/handbook/addons/inspektor-gadget/",
|
|
map[string]string{
|
|
"InspektorGadget": "inspektor-gadget/inspektor-gadget:v0.27.0@sha256:abef4926f3e6f0aa50c968aa954f990a6b0178e04a955293a49d96810c43d0e1",
|
|
}, map[string]string{
|
|
"InspektorGadget": "ghcr.io",
|
|
}),
|
|
"kong": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.KongAssets,
|
|
"kong/kong-ingress-controller.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"kong-ingress-controller.yaml",
|
|
"0640"),
|
|
}, false, "kong", "3rd party (Kong HQ)", "@gAmUssA", "https://minikube.sigs.k8s.io/docs/handbook/addons/kong-ingress/", map[string]string{
|
|
"Kong": "kong:3.6.1@sha256:9829633b86325c387c9c1391dede996054fcc2435682579abed5188775333115",
|
|
"KongIngress": "kong/kubernetes-ingress-controller:2.12.0@sha256:ef450cd85f4237aa5acf3bfaebd064accdc6a445419bec20a5a68067c55c6809",
|
|
}, map[string]string{
|
|
"Kong": "docker.io",
|
|
"KongIngress": "docker.io",
|
|
}),
|
|
"kubevirt": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.KubevirtAssets,
|
|
"kubevirt/pod.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"pod.yaml",
|
|
"0640"),
|
|
}, false, "kubevirt", "3rd party (KubeVirt)", "", "https://minikube.sigs.k8s.io/docs/tutorials/kubevirt/", map[string]string{
|
|
"Kubectl": "bitnami/kubectl:1.30.0@sha256:b909f3a93813f25192bcb57f5c1e482d53ba01413db69c8143fca882e6e930e5",
|
|
}, map[string]string{
|
|
"Kubectl": "docker.io",
|
|
}),
|
|
"metrics-server": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.MetricsServerAssets,
|
|
"metrics-server/metrics-apiservice.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"metrics-apiservice.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.MetricsServerAssets,
|
|
"metrics-server/metrics-server-deployment.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"metrics-server-deployment.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.MetricsServerAssets,
|
|
"metrics-server/metrics-server-rbac.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"metrics-server-rbac.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.MetricsServerAssets,
|
|
"metrics-server/metrics-server-service.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"metrics-server-service.yaml",
|
|
"0640"),
|
|
}, false, "metrics-server", "Kubernetes", "", "", map[string]string{
|
|
"MetricsServer": "metrics-server/metrics-server:v0.7.1@sha256:db3800085a0957083930c3932b17580eec652cfb6156a05c0f79c7543e80d17a",
|
|
}, map[string]string{
|
|
"MetricsServer": "registry.k8s.io",
|
|
}),
|
|
"olm": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.OlmAssets,
|
|
"olm/crds.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"crds.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.OlmAssets,
|
|
"olm/olm.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"olm.yaml",
|
|
"0640"),
|
|
}, false, "olm", "3rd party (Operator Framework)", "", "", map[string]string{
|
|
"OLM": "operator-framework/olm@sha256:e74b2ac57963c7f3ba19122a8c31c9f2a0deb3c0c5cac9e5323ccffd0ca198ed",
|
|
// operator-framework/community-operators was deprecated: https://github.com/operator-framework/community-operators#repository-is-obsolete; switching to OperatorHub.io instead
|
|
"UpstreamCommunityOperators": "operatorhubio/catalog@sha256:e08a1cd21fe72dd1be92be738b4bf1515298206dac5479c17a4b3ed119e30bd4",
|
|
}, map[string]string{
|
|
"OLM": "quay.io",
|
|
"UpstreamCommunityOperators": "quay.io",
|
|
}),
|
|
"registry": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.RegistryAssets,
|
|
"registry/registry-rc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-rc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.RegistryAssets,
|
|
"registry/registry-svc.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-svc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.RegistryAssets,
|
|
"registry/registry-proxy.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-proxy.yaml",
|
|
"0640"),
|
|
}, false, "registry", "minikube", "", "", map[string]string{
|
|
"Registry": "registry:2.8.3@sha256:fb9c9aef62af3955f6014613456551c92e88a67dcf1fc51f5f91bcbd1832813f",
|
|
"KubeRegistryProxy": "k8s-minikube/kube-registry-proxy:0.0.6@sha256:b3fa0b2df8737fdb85ad5918a7e2652527463e357afff83a5e5bb966bcedc367",
|
|
}, map[string]string{
|
|
"KubeRegistryProxy": "gcr.io",
|
|
"Registry": "docker.io",
|
|
}),
|
|
"registry-creds": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.RegistryCredsAssets,
|
|
"registry-creds/registry-creds-rc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-creds-rc.yaml",
|
|
"0640"),
|
|
}, false, "registry-creds", "3rd party (UPMC Enterprises)", "", "https://minikube.sigs.k8s.io/docs/handbook/registry/", map[string]string{
|
|
"RegistryCreds": "upmcenterprises/registry-creds:1.10@sha256:93a633d4f2b76a1c66bf19c664dbddc56093a543de6d54320f19f585ccd7d605",
|
|
}, map[string]string{
|
|
"RegistryCreds": "docker.io",
|
|
}),
|
|
"registry-aliases": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.RegistryAliasesAssets,
|
|
"registry-aliases/registry-aliases-sa.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-aliases-sa.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.RegistryAliasesAssets,
|
|
"registry-aliases/registry-aliases-sa-crb.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-aliases-sa-crb.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.RegistryAliasesAssets,
|
|
"registry-aliases/registry-aliases-config.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"registry-aliases-config.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.RegistryAliasesAssets,
|
|
"registry-aliases/node-etc-hosts-update.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"node-etc-hosts-update.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.RegistryAliasesAssets,
|
|
"registry-aliases/patch-coredns-job.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"patch-coredns-job.yaml",
|
|
"0640"),
|
|
}, false, "registry-aliases", "3rd party (unknown)", "", "", map[string]string{
|
|
"CoreDNSPatcher": "rhdevelopers/core-dns-patcher@sha256:9220ff32f690c3d889a52afb59ca6fcbbdbd99e5370550cc6fd249adea8ed0a9",
|
|
"Alpine": "alpine:3.11@sha256:0bd0e9e03a022c3b0226667621da84fc9bf562a9056130424b5bfbd8bcb0397f",
|
|
"Pause": "google_containers/pause:3.1@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea",
|
|
}, map[string]string{
|
|
"CoreDNSPatcher": "quay.io",
|
|
"Pause": "gcr.io",
|
|
"Alpine": "docker.io",
|
|
}),
|
|
"freshpod": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.FreshpodAssets,
|
|
"freshpod/freshpod-rc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"freshpod-rc.yaml",
|
|
"0640"),
|
|
}, false, "freshpod", "Google", "", "https://github.com/GoogleCloudPlatform/freshpod", map[string]string{
|
|
"FreshPod": "google-samples/freshpod:v0.0.1@sha256:b9efde5b509da3fd2959519c4147b653d0c5cefe8a00314e2888e35ecbcb46f9",
|
|
}, map[string]string{
|
|
"FreshPod": "gcr.io",
|
|
}),
|
|
"nvidia-driver-installer": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.NvidiaDriverInstallerAssets,
|
|
"gpu/nvidia-driver-installer.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"nvidia-driver-installer.yaml",
|
|
"0640"),
|
|
}, false, "nvidia-driver-installer", "3rd party (Nvidia)", "", "https://minikube.sigs.k8s.io/docs/tutorials/nvidia_gpu/", map[string]string{
|
|
"NvidiaDriverInstaller": "minikube-nvidia-driver-installer:e2d9b43228decf5d6f7dce3f0a85d390f138fa01",
|
|
"Pause": "pause:2.0@sha256:9ce5316f9752b8347484ab0f6778573af15524124d52b93230b9a0dcc987e73e",
|
|
}, map[string]string{
|
|
"NvidiaDriverInstaller": "registry.k8s.io",
|
|
"Pause": "registry.k8s.io",
|
|
}),
|
|
"nvidia-gpu-device-plugin": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.NvidiaGpuDevicePluginAssets,
|
|
"gpu/nvidia-gpu-device-plugin.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"nvidia-gpu-device-plugin.yaml",
|
|
"0640"),
|
|
}, false, "nvidia-gpu-device-plugin", "3rd party (Nvidia)", "", "https://minikube.sigs.k8s.io/docs/tutorials/nvidia_gpu/", map[string]string{
|
|
"NvidiaDevicePlugin": "nvidia-gpu-device-plugin@sha256:4b036e8844920336fa48f36edeb7d4398f426d6a934ba022848deed2edbf09aa",
|
|
}, map[string]string{
|
|
"NvidiaDevicePlugin": "registry.k8s.io",
|
|
}),
|
|
"logviewer": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.LogviewerAssets,
|
|
"logviewer/logviewer-dp-and-svc.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"logviewer-dp-and-svc.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.LogviewerAssets,
|
|
"logviewer/logviewer-rbac.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"logviewer-rbac.yaml",
|
|
"0640"),
|
|
}, false, "logviewer", "3rd party (unknown)", "", "", map[string]string{
|
|
"LogViewer": "ivans3/minikube-log-viewer:latest@sha256:75854f45305cc47d17b04c6c588fa60777391761f951e3a34161ddf1f1b06405",
|
|
}, map[string]string{
|
|
"LogViewer": "docker.io",
|
|
}),
|
|
"gvisor": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.GvisorAssets,
|
|
"gvisor/gvisor-pod.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"gvisor-pod.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.GvisorAssets,
|
|
"gvisor/gvisor-runtimeclass.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"gvisor-runtimeclass.yaml",
|
|
"0640"),
|
|
}, false, "gvisor", "minikube", "", "https://github.com/kubernetes/minikube/blob/master/deploy/addons/gvisor/README.md", map[string]string{
|
|
"GvisorAddon": "k8s-minikube/gvisor-addon:v0.0.1@sha256:d29adbddc7a44dab4c675c0eaea398907fe1f33f5f723274b0d40195b3076cae",
|
|
}, map[string]string{
|
|
"GvisorAddon": "gcr.io",
|
|
}),
|
|
"helm-tiller": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.HelmTillerAssets,
|
|
"helm-tiller/helm-tiller-dp.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"helm-tiller-dp.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.HelmTillerAssets,
|
|
"helm-tiller/helm-tiller-rbac.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"helm-tiller-rbac.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.HelmTillerAssets,
|
|
"helm-tiller/helm-tiller-svc.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"helm-tiller-svc.yaml",
|
|
"0640"),
|
|
}, false, "helm-tiller", "3rd party (Helm)", "", "https://v2.helm.sh/docs/using_helm/", map[string]string{
|
|
"Tiller": "helm/tiller:v2.17.0@sha256:4c43eb385032945cad047d2350e4945d913b90b3ab43ee61cecb32a495c6df0f",
|
|
}, map[string]string{
|
|
// GCR is deprecated in helm
|
|
// https://github.com/helm/helm/issues/10004#issuecomment-894478908
|
|
"Tiller": "ghcr.io",
|
|
}),
|
|
"ingress-dns": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.IngressDNSAssets,
|
|
"ingress-dns/ingress-dns-pod.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"ingress-dns-pod.yaml",
|
|
"0640"),
|
|
}, false, "ingress-dns", "minikube", "", "https://minikube.sigs.k8s.io/docs/handbook/addons/ingress-dns/", map[string]string{
|
|
"IngressDNS": "k8s-minikube/minikube-ingress-dns:0.0.2@sha256:4abe27f9fc03fedab1d655e2020e6b165faf3bf6de1088ce6cf215a75b78f05f",
|
|
}, map[string]string{
|
|
"IngressDNS": "gcr.io",
|
|
}),
|
|
"metallb": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.MetallbAssets,
|
|
"metallb/metallb.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"metallb.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.MetallbAssets,
|
|
"metallb/metallb-config.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"metallb-config.yaml",
|
|
"0640"),
|
|
}, false, "metallb", "3rd party (MetalLB)", "", "", map[string]string{
|
|
"Speaker": "metallb/speaker:v0.9.6@sha256:7a400205b4986acd3d2ff32c29929682b8ff8d830837aff74f787c757176fa9f",
|
|
"Controller": "metallb/controller:v0.9.6@sha256:6932cf255dd7f06f550c7f106b9a206be95f847ab8cb77aafac7acd27def0b00",
|
|
}, map[string]string{
|
|
"Speaker": "quay.io",
|
|
"Controller": "quay.io",
|
|
}),
|
|
"ambassador": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.AmbassadorAssets,
|
|
"ambassador/ambassador-operator-crds.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"ambassador-operator-crds.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.AmbassadorAssets,
|
|
"ambassador/ambassador-operator.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"ambassador-operator.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.AmbassadorAssets,
|
|
"ambassador/ambassadorinstallation.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"ambassadorinstallation.yaml",
|
|
"0640"),
|
|
}, false, "ambassador", "3rd party (Ambassador)", "", "https://minikube.sigs.k8s.io/docs/tutorials/ambassador_ingress_controller/", map[string]string{
|
|
"AmbassadorOperator": "datawire/ambassador-operator:v1.2.3@sha256:492f33e0828a371aa23331d75c11c251b21499e31287f026269e3f6ec6da34ed",
|
|
}, map[string]string{
|
|
"AmbassadorOperator": "quay.io",
|
|
}),
|
|
"gcp-auth": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.GcpAuthAssets,
|
|
"gcp-auth/gcp-auth-ns.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"gcp-auth-ns.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.GcpAuthAssets,
|
|
"gcp-auth/gcp-auth-service.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"gcp-auth-service.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.GcpAuthAssets,
|
|
"gcp-auth/gcp-auth-webhook.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"gcp-auth-webhook.yaml",
|
|
"0640"),
|
|
}, false, "gcp-auth", "Google", "", "https://minikube.sigs.k8s.io/docs/handbook/addons/gcp-auth/", map[string]string{
|
|
"KubeWebhookCertgen": "ingress-nginx/kube-webhook-certgen:v1.4.1@sha256:36d05b4077fb8e3d13663702fa337f124675ba8667cbd949c03a8e8ea6fa4366",
|
|
"GCPAuthWebhook": "k8s-minikube/gcp-auth-webhook:v0.1.2@sha256:e6c5b3bc32072ea370d34c27836efd11b3519d25bd444c2a8efc339cff0e20fb",
|
|
}, map[string]string{
|
|
"GCPAuthWebhook": "gcr.io",
|
|
"KubeWebhookCertgen": "registry.k8s.io",
|
|
}),
|
|
"volumesnapshots": NewAddon([]*BinAsset{
|
|
// make sure the order of apply. `csi-hostpath-snapshotclass` must be the first position, because it depends on `snapshot.storage.k8s.io_volumesnapshotclasses`
|
|
// if user disable volumesnapshots addon and delete `csi-hostpath-snapshotclass` after `snapshot.storage.k8s.io_volumesnapshotclasses`, kubernetes will return the error
|
|
MustBinAsset(addons.VolumeSnapshotsAssets,
|
|
"volumesnapshots/csi-hostpath-snapshotclass.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"csi-hostpath-snapshotclass.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.VolumeSnapshotsAssets,
|
|
"volumesnapshots/snapshot.storage.k8s.io_volumesnapshotclasses.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"snapshot.storage.k8s.io_volumesnapshotclasses.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.VolumeSnapshotsAssets,
|
|
"volumesnapshots/snapshot.storage.k8s.io_volumesnapshotcontents.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"snapshot.storage.k8s.io_volumesnapshotcontents.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.VolumeSnapshotsAssets,
|
|
"volumesnapshots/snapshot.storage.k8s.io_volumesnapshots.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"snapshot.storage.k8s.io_volumesnapshots.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.VolumeSnapshotsAssets,
|
|
"volumesnapshots/rbac-volume-snapshot-controller.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-volume-snapshot-controller.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.VolumeSnapshotsAssets,
|
|
"volumesnapshots/volume-snapshot-controller-deployment.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"volume-snapshot-controller-deployment.yaml",
|
|
"0640"),
|
|
}, false, "volumesnapshots", "Kubernetes", "", "https://minikube.sigs.k8s.io/docs/tutorials/volume_snapshots_and_csi/", map[string]string{
|
|
"SnapshotController": "sig-storage/snapshot-controller:v6.1.0@sha256:823c75d0c45d1427f6d850070956d9ca657140a7bbf828381541d1d808475280",
|
|
}, map[string]string{
|
|
"SnapshotController": "registry.k8s.io",
|
|
}),
|
|
"csi-hostpath-driver": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/rbac/rbac-external-attacher.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-external-attacher.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/rbac/rbac-hostpath.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-hostpath.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/rbac/rbac-external-health-monitor-controller.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-external-health-monitor-controller.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/rbac/rbac-external-provisioner.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-external-provisioner.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/rbac/rbac-external-resizer.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-external-resizer.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/rbac/rbac-external-snapshotter.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"rbac-external-snapshotter.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/deploy/csi-hostpath-attacher.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"csi-hostpath-attacher.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/deploy/csi-hostpath-driverinfo.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"csi-hostpath-driverinfo.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/deploy/csi-hostpath-plugin.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"csi-hostpath-plugin.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/deploy/csi-hostpath-resizer.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"csi-hostpath-resizer.yaml",
|
|
"0640"),
|
|
MustBinAsset(addons.CsiHostpathDriverAssets,
|
|
"csi-hostpath-driver/deploy/csi-hostpath-storageclass.yaml",
|
|
vmpath.GuestAddonsDir,
|
|
"csi-hostpath-storageclass.yaml",
|
|
"0640"),
|
|
}, false, "csi-hostpath-driver", "Kubernetes", "", "https://minikube.sigs.k8s.io/docs/tutorials/volume_snapshots_and_csi/", map[string]string{
|
|
"Attacher": "sig-storage/csi-attacher:v4.0.0@sha256:9a685020911e2725ad019dbce6e4a5ab93d51e3d4557f115e64343345e05781b",
|
|
"HostMonitorController": "sig-storage/csi-external-health-monitor-controller:v0.7.0@sha256:80b9ba94aa2afe24553d69bd165a6a51552d1582d68618ec00d3b804a7d9193c",
|
|
"NodeDriverRegistrar": "sig-storage/csi-node-driver-registrar:v2.6.0@sha256:f1c25991bac2fbb7f5fcf91ed9438df31e30edee6bed5a780464238aa09ad24c",
|
|
"HostPathPlugin": "sig-storage/hostpathplugin:v1.9.0@sha256:92257881c1d6493cf18299a24af42330f891166560047902b8d431fb66b01af5",
|
|
"LivenessProbe": "sig-storage/livenessprobe:v2.8.0@sha256:cacee2b5c36dd59d4c7e8469c05c9e4ef53ecb2df9025fa8c10cdaf61bce62f0",
|
|
"Resizer": "sig-storage/csi-resizer:v1.6.0@sha256:425d8f1b769398127767b06ed97ce62578a3179bcb99809ce93a1649e025ffe7",
|
|
"Snapshotter": "sig-storage/csi-snapshotter:v6.1.0@sha256:291334908ddf71a4661fd7f6d9d97274de8a5378a2b6fdfeb2ce73414a34f82f",
|
|
"Provisioner": "sig-storage/csi-provisioner:v3.3.0@sha256:ee3b525d5b89db99da3b8eb521d9cd90cb6e9ef0fbb651e98bb37be78d36b5b8",
|
|
}, map[string]string{
|
|
"Attacher": "registry.k8s.io",
|
|
"HostMonitorController": "registry.k8s.io",
|
|
"NodeDriverRegistrar": "registry.k8s.io",
|
|
"HostPathPlugin": "registry.k8s.io",
|
|
"LivenessProbe": "registry.k8s.io",
|
|
"Resizer": "registry.k8s.io",
|
|
"Snapshotter": "registry.k8s.io",
|
|
"Provisioner": "registry.k8s.io",
|
|
}),
|
|
"portainer": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.PortainerAssets,
|
|
"portainer/portainer.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"portainer.yaml",
|
|
"0640"),
|
|
}, false, "portainer", "3rd party (Portainer.io)", "", "", map[string]string{
|
|
"Portainer": "portainer/portainer-ce:2.15.1@sha256:5466af30b8eaf3f75edd3c74703d1c9973f0963acd6ef164913ea6f195d640c2",
|
|
}, map[string]string{
|
|
"Portainer": "docker.io",
|
|
}),
|
|
"inaccel": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.InAccelAssets,
|
|
"inaccel/fpga-operator.yaml.tmpl",
|
|
vmpath.GuestAddonsDir,
|
|
"fpga-operator.yaml",
|
|
"0640"),
|
|
}, false, "inaccel", "3rd party (InAccel [info@inaccel.com])", "", "", map[string]string{
|
|
"Helm3": "alpine/helm:3.9.0@sha256:9f4bf4d24241f983910550b1fe8688571cd684046500abe58cef14308f9cb19e",
|
|
}, map[string]string{
|
|
"Helm3": "docker.io",
|
|
}),
|
|
"headlamp": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-namespace.yaml", vmpath.GuestAddonsDir, "headlamp-namespace.yaml", "0640"),
|
|
MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-service.yaml", vmpath.GuestAddonsDir, "headlamp-service.yaml", "0640"),
|
|
MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-deployment.yaml.tmpl", vmpath.GuestAddonsDir, "headlamp-deployment.yaml", "0640"),
|
|
MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-serviceaccount.yaml", vmpath.GuestAddonsDir, "headlamp-serviceaccount.yaml", "0640"),
|
|
MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "headlamp-clusterrolebinding.yaml", "0640"),
|
|
}, false, "headlamp", "3rd party (kinvolk.io)", "yolossn", "https://minikube.sigs.k8s.io/docs/handbook/addons/headlamp/",
|
|
map[string]string{
|
|
"Headlamp": "headlamp-k8s/headlamp:v0.23.1@sha256:dd9e2ad6ae6d23761372bc9cc0dbcb47aacd6a31986827b43ac207cecb25c39f",
|
|
},
|
|
map[string]string{
|
|
"Headlamp": "ghcr.io",
|
|
}),
|
|
"cloud-spanner": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.CloudSpanner, "cloud-spanner/deployment.yaml.tmpl", vmpath.GuestAddonsDir, "deployment.yaml", "0640"),
|
|
}, false, "cloud-spanner", "Google", "", "https://minikube.sigs.k8s.io/docs/handbook/addons/cloud-spanner/", map[string]string{
|
|
"CloudSpanner": "cloud-spanner-emulator/emulator:1.5.16@sha256:1680486ec721ba559ec0fe6f876c44cf784d77e6a82cf89874e9aff90de2ebd5",
|
|
}, map[string]string{
|
|
"CloudSpanner": "gcr.io",
|
|
}),
|
|
"kubeflow": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.Kubeflow, "kubeflow/kubeflow.yaml", vmpath.GuestAddonsDir, "kubeflow.yaml", "0640"),
|
|
}, false, "kubeflow", "3rd party", "", "", nil, nil,
|
|
),
|
|
"nvidia-device-plugin": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.NvidiaDevicePlugin, "nvidia-device-plugin/nvidia-device-plugin.yaml.tmpl", vmpath.GuestAddonsDir, "nvidia-device-plugin.yaml", "0640"),
|
|
}, false, "nvidia-device-plugin", "3rd party (NVIDIA)", "", "",
|
|
map[string]string{
|
|
"NvidiaDevicePlugin": "nvidia/k8s-device-plugin:v0.15.0@sha256:1aff0e9f0759758f87cb158d78241472af3a76cdc631f01ab395f997fa80f707",
|
|
}, map[string]string{
|
|
"NvidiaDevicePlugin": "nvcr.io",
|
|
}),
|
|
"yakd": NewAddon([]*BinAsset{
|
|
MustBinAsset(addons.YakdAssets, "yakd/yakd-ns.yaml", vmpath.GuestAddonsDir, "yakd-ns.yaml", "0640"),
|
|
MustBinAsset(addons.YakdAssets, "yakd/yakd-sa.yaml", vmpath.GuestAddonsDir, "yakd-sa.yaml", "0640"),
|
|
MustBinAsset(addons.YakdAssets, "yakd/yakd-crb.yaml", vmpath.GuestAddonsDir, "yakd-crb.yaml", "0640"),
|
|
MustBinAsset(addons.YakdAssets, "yakd/yakd-svc.yaml", vmpath.GuestAddonsDir, "yakd-svc.yaml", "0640"),
|
|
MustBinAsset(addons.YakdAssets, "yakd/yakd-dp.yaml.tmpl", vmpath.GuestAddonsDir, "yakd-dp.yaml", "0640"),
|
|
}, false, "yakd", "3rd party (marcnuri.com)", "manusa", "https://minikube.sigs.k8s.io/docs/handbook/addons/yakd/",
|
|
map[string]string{
|
|
"Yakd": "marcnuri/yakd:0.0.4@sha256:a3f540278e4c11373e15605311851dd9c64d208f4d63e727bccc0e39f9329310",
|
|
},
|
|
map[string]string{
|
|
"Yakd": "docker.io",
|
|
}),
|
|
}
|
|
|
|
// parseMapString creates a map based on `str` which is encoded as <key1>=<value1>,<key2>=<value2>,...
|
|
func parseMapString(str string) map[string]string {
|
|
mapResult := make(map[string]string)
|
|
if str == "" {
|
|
return mapResult
|
|
}
|
|
for _, pairText := range strings.Split(str, ",") {
|
|
vals := strings.Split(pairText, "=")
|
|
if len(vals) != 2 {
|
|
out.WarningT("Ignoring invalid pair entry {{.pair}}", out.V{"pair": pairText})
|
|
continue
|
|
}
|
|
mapResult[vals[0]] = vals[1]
|
|
}
|
|
return mapResult
|
|
}
|
|
|
|
// mergeMaps returns a map with the union of `source` and `override` where collisions take the value of `override`.
|
|
func mergeMaps(source, override map[string]string) map[string]string {
|
|
result := make(map[string]string)
|
|
for k, v := range source {
|
|
result[k] = v
|
|
}
|
|
for k, v := range override {
|
|
result[k] = v
|
|
}
|
|
return result
|
|
}
|
|
|
|
// filterKeySpace creates a map of the values in `target` where the keys are also in `keySpace`.
|
|
func filterKeySpace(keySpace, target map[string]string) map[string]string {
|
|
result := make(map[string]string)
|
|
for name := range keySpace {
|
|
if value, ok := target[name]; ok {
|
|
result[name] = value
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// overrideDefaults creates a copy of `def` where `override` replaces any of its values that `override` contains.
|
|
func overrideDefaults(def, override map[string]string) map[string]string {
|
|
return mergeMaps(def, filterKeySpace(def, override))
|
|
}
|
|
|
|
// SelectAndPersistImages selects which images to use based on addon default images, previously persisted images, and newly requested images - which are then persisted for future enables.
|
|
func SelectAndPersistImages(addon *Addon, cc *config.ClusterConfig) (images, customRegistries map[string]string, _ error) {
|
|
addonDefaultImages := addon.Images
|
|
if addonDefaultImages == nil {
|
|
addonDefaultImages = make(map[string]string)
|
|
}
|
|
|
|
// Use previously configured custom images.
|
|
images = overrideDefaults(addonDefaultImages, cc.CustomAddonImages)
|
|
if viper.IsSet(config.AddonImages) {
|
|
// Parse the AddonImages flag if present.
|
|
newImages := parseMapString(viper.GetString(config.AddonImages))
|
|
for name, image := range newImages {
|
|
if image == "" {
|
|
out.WarningT("Ignoring empty custom image {{.name}}", out.V{"name": name})
|
|
delete(newImages, name)
|
|
continue
|
|
}
|
|
if _, ok := addonDefaultImages[name]; !ok {
|
|
out.WarningT("Ignoring unknown custom image {{.name}}", out.V{"name": name})
|
|
delete(newImages, name)
|
|
}
|
|
}
|
|
// Use newly configured custom images.
|
|
images = overrideDefaults(images, newImages)
|
|
// Store custom addon images to be written.
|
|
cc.CustomAddonImages = mergeMaps(cc.CustomAddonImages, newImages)
|
|
}
|
|
|
|
// Use previously configured custom registries.
|
|
customRegistries = filterKeySpace(addonDefaultImages, cc.CustomAddonRegistries) // filter by images map because registry map may omit default registry.
|
|
if viper.IsSet(config.AddonRegistries) {
|
|
// Parse the AddonRegistries flag if present.
|
|
newRegistries := parseMapString(viper.GetString(config.AddonRegistries))
|
|
for name := range newRegistries {
|
|
if _, ok := addonDefaultImages[name]; !ok { // check images map because registry map may omitted default registry
|
|
out.WarningT("Ignoring unknown custom registry {{.name}}", out.V{"name": name})
|
|
delete(newRegistries, name)
|
|
}
|
|
}
|
|
// Use newly configured custom registries.
|
|
customRegistries = mergeMaps(customRegistries, newRegistries)
|
|
// Merge newly set registries into custom addon registries to be written.
|
|
cc.CustomAddonRegistries = mergeMaps(cc.CustomAddonRegistries, newRegistries)
|
|
}
|
|
|
|
// If images or registries were specified, save the config afterward.
|
|
if viper.IsSet(config.AddonImages) || viper.IsSet(config.AddonRegistries) {
|
|
// Since these values are only set when a user enables an addon, it is safe to refer to the profile name.
|
|
// Whether err is nil or not we still return here.
|
|
return images, customRegistries, config.Write(viper.GetString(config.ProfileName), cc)
|
|
}
|
|
return images, customRegistries, nil
|
|
}
|
|
|
|
// GenerateTemplateData generates template data for template assets
|
|
func GenerateTemplateData(addon *Addon, cc *config.ClusterConfig, netInfo NetworkInfo, images, customRegistries map[string]string, enable bool) interface{} {
|
|
cfg := cc.KubernetesConfig
|
|
a := runtime.GOARCH
|
|
// Some legacy docker images still need the -arch suffix
|
|
// for less common architectures blank suffix for amd64
|
|
ea := ""
|
|
if runtime.GOARCH != "amd64" {
|
|
ea = "-" + runtime.GOARCH
|
|
}
|
|
|
|
v, err := util.ParseKubernetesVersion(cfg.KubernetesVersion)
|
|
if err != nil {
|
|
return errors.Wrap(err, "parsing Kubernetes version")
|
|
}
|
|
|
|
opts := struct {
|
|
KubernetesVersion map[string]uint64
|
|
PreOneTwentyKubernetes bool
|
|
Arch string
|
|
ExoticArch string
|
|
ImageRepository string
|
|
LoadBalancerStartIP string
|
|
LoadBalancerEndIP string
|
|
CustomIngressCert string
|
|
IngressAPIVersion string
|
|
ContainerRuntime string
|
|
RegistryAliases string
|
|
Images map[string]string
|
|
Registries map[string]string
|
|
CustomRegistries map[string]string
|
|
NetworkInfo map[string]string
|
|
Environment map[string]string
|
|
LegacyPodSecurityPolicy bool
|
|
LegacyRuntimeClass bool
|
|
AutoPauseInterval time.Duration
|
|
}{
|
|
KubernetesVersion: make(map[string]uint64),
|
|
PreOneTwentyKubernetes: false,
|
|
Arch: a,
|
|
ExoticArch: ea,
|
|
ImageRepository: cfg.ImageRepository,
|
|
LoadBalancerStartIP: cfg.LoadBalancerStartIP,
|
|
LoadBalancerEndIP: cfg.LoadBalancerEndIP,
|
|
CustomIngressCert: cfg.CustomIngressCert,
|
|
RegistryAliases: cfg.RegistryAliases,
|
|
IngressAPIVersion: "v1", // api version for ingress (eg, "v1beta1"; defaults to "v1" for k8s 1.19+)
|
|
ContainerRuntime: cfg.ContainerRuntime,
|
|
Images: images,
|
|
Registries: addon.Registries,
|
|
CustomRegistries: customRegistries,
|
|
NetworkInfo: make(map[string]string),
|
|
Environment: map[string]string{
|
|
"MockGoogleToken": os.Getenv("MOCK_GOOGLE_TOKEN"),
|
|
},
|
|
LegacyPodSecurityPolicy: v.LT(semver.Version{Major: 1, Minor: 25}),
|
|
LegacyRuntimeClass: v.LT(semver.Version{Major: 1, Minor: 25}),
|
|
AutoPauseInterval: cc.AutoPauseInterval,
|
|
}
|
|
if opts.ImageRepository != "" && !strings.HasSuffix(opts.ImageRepository, "/") {
|
|
opts.ImageRepository += "/"
|
|
}
|
|
if opts.Registries == nil {
|
|
opts.Registries = make(map[string]string)
|
|
}
|
|
|
|
// maintain backwards compatibility with k8s < v1.19
|
|
// by using v1beta1 instead of v1 api version for ingress
|
|
if semver.MustParseRange("<1.19.0")(v) {
|
|
opts.IngressAPIVersion = "v1beta1"
|
|
}
|
|
if semver.MustParseRange("<1.20.0")(v) {
|
|
opts.PreOneTwentyKubernetes = true
|
|
}
|
|
|
|
// Network info for generating template
|
|
opts.NetworkInfo["ControlPlaneNodeIP"] = netInfo.ControlPlaneNodeIP
|
|
opts.NetworkInfo["ControlPlaneNodePort"] = fmt.Sprint(netInfo.ControlPlaneNodePort)
|
|
opts.NetworkInfo["DNSDomain"] = cfg.DNSDomain
|
|
|
|
// Append postfix "/" to registries
|
|
for k, v := range opts.Registries {
|
|
if v != "" && !strings.HasSuffix(v, "/") {
|
|
opts.Registries[k] = v + "/"
|
|
}
|
|
}
|
|
|
|
for k, v := range opts.CustomRegistries {
|
|
if v != "" && !strings.HasSuffix(v, "/") {
|
|
opts.CustomRegistries[k] = v + "/"
|
|
}
|
|
}
|
|
|
|
for name, image := range opts.Images {
|
|
if _, ok := opts.Registries[name]; !ok {
|
|
opts.Registries[name] = "" // Avoid nil access when rendering
|
|
}
|
|
|
|
// tl;dr If the user specified a custom image remove the default registry
|
|
// Without the line below, if you try to overwrite an image the default registry is still used in the templating
|
|
// Example - image name: MetricsScraper, default registry: docker.io, default image: kubernetesui/metrics-scraper
|
|
// Passed on addon enable: --images=MetricsScraper=registry.k8s.io/echoserver:1.4
|
|
// Without this line the resulting image would be docker.io/registry.k8s.io/echoserver:1.4
|
|
if _, ok := cc.CustomAddonImages[name]; ok {
|
|
opts.Registries[name] = ""
|
|
}
|
|
|
|
if enable {
|
|
if override, ok := opts.CustomRegistries[name]; ok {
|
|
out.Infof("Using image {{.registry}}{{.image}}", out.V{
|
|
"registry": override,
|
|
// removing the SHA from UI
|
|
// SHA example docker.io/my_image:v0.0.4@sha256:65e9e69022aa7b0eb1e390e1916e3bf67f75ae5c25987f9154ef3b0e8ab8528b
|
|
"image": strings.Split(image, "@")[0],
|
|
})
|
|
} else if opts.ImageRepository != "" {
|
|
out.Infof("Using image {{.registry}}{{.image}} (global image repository)", out.V{
|
|
"registry": opts.ImageRepository,
|
|
"image": image,
|
|
})
|
|
} else {
|
|
out.Infof("Using image {{.registry}}{{.image}}", out.V{
|
|
"registry": opts.Registries[name],
|
|
"image": strings.Split(image, "@")[0],
|
|
})
|
|
}
|
|
}
|
|
}
|
|
return opts
|
|
}
|