Merge branch 'master' into shorter-prefixes
commit
f642f1abbc
|
@ -28,6 +28,16 @@ _testmain.go
|
|||
/out
|
||||
/_gopath
|
||||
|
||||
|
||||
#.yaml files specific to deploy's .template extensions
|
||||
deploy/addons/addon-manager.yaml
|
||||
deploy/addons/dashboard/dashboard-dp.yaml
|
||||
deploy/addons/heapster/heapster-rc.yaml
|
||||
deploy/addons/heapster/influx-grafana-rc.yaml
|
||||
deploy/addons/ingress/ingress-dp.yaml
|
||||
deploy/addons/metrics-server/metrics-server-deployment.yaml
|
||||
deploy/addons/storage-provisioner/storage-provisioner.yaml
|
||||
|
||||
#iso version file
|
||||
deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/etc/VERSION
|
||||
|
||||
|
@ -38,4 +48,4 @@ deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/etc/VERSION
|
|||
|
||||
/.idea
|
||||
|
||||
/.vscode
|
||||
/.vscode
|
||||
|
|
71
CHANGELOG.md
71
CHANGELOG.md
|
@ -1,5 +1,76 @@
|
|||
# Minikube Release Notes
|
||||
|
||||
## Version 1.0.1 - 2019-04-29
|
||||
|
||||
* update-context is confusing with profiles [#4049](https://github.com/kubernetes/minikube/pull/4049)
|
||||
* BugFix: ExecRunner.Copy now parses permissions strings as octal [#4139](https://github.com/kubernetes/minikube/pull/4139)
|
||||
* Add user-friendly error messages for VBOX_THIRD_PARTY & HYPERV_NO_VSWITCH [#4152](https://github.com/kubernetes/minikube/pull/4152)
|
||||
* Don't enable kubelet at boot, for consistency with other components [#4110](https://github.com/kubernetes/minikube/pull/4110)
|
||||
* Assert that docker has started rather than explicitly restarting it [#4116](https://github.com/kubernetes/minikube/pull/4116)
|
||||
* fix tunnel integration tests for driver None [#4105](https://github.com/kubernetes/minikube/pull/4105)
|
||||
* Download ISO image before Docker images, as it's required first [#4141](https://github.com/kubernetes/minikube/pull/4141)
|
||||
* Reroute logs printed directly to stdout [#4115](https://github.com/kubernetes/minikube/pull/4115)
|
||||
* Update default Kubernetes version to 1.14.1 [#4133](https://github.com/kubernetes/minikube/pull/4133)
|
||||
* Systemd returns error on inactive, so allow that [#4095](https://github.com/kubernetes/minikube/pull/4095)
|
||||
* Add known issue: VirtualBox won't boot a 64bits VM when Hyper-V is activated [#4112](https://github.com/kubernetes/minikube/pull/4112)
|
||||
* Upgrade Docker, from 18.06.2-ce to 18.06.3-ce [#4022](https://github.com/kubernetes/minikube/pull/4022)
|
||||
* Use Reference, allow caching images with both Tag and Digest [#3899](https://github.com/kubernetes/minikube/pull/3899)
|
||||
* Added REGISTRY_STORAGE_DELETE_ENABLED environment variable for Registry addon [#4080](https://github.com/kubernetes/minikube/pull/4080)
|
||||
* Add --download-only option to start command [#3737](https://github.com/kubernetes/minikube/pull/3737)
|
||||
* Escape ‘%’ in console.OutStyle arguments [#4026](https://github.com/kubernetes/minikube/pull/4026)
|
||||
* Add port name to service struct used in minikube service [#4011](https://github.com/kubernetes/minikube/pull/4011)
|
||||
* Update Hyper-V daemons [#4030](https://github.com/kubernetes/minikube/pull/4030)
|
||||
* Avoid surfacing "error: no objects passed to apply" non-error from addon-manager [#4076](https://github.com/kubernetes/minikube/pull/4076)
|
||||
* Don't cache images when --vmdriver=none [#4059](https://github.com/kubernetes/minikube/pull/4059)
|
||||
* Enable CONFIG_NF_CONNTRACK_ZONES [#3755](https://github.com/kubernetes/minikube/pull/3755)
|
||||
* Fixed status checking with non-default apiserver-port. [#4058](https://github.com/kubernetes/minikube/pull/4058)
|
||||
* Escape systemd special chars in docker-env [#3997](https://github.com/kubernetes/minikube/pull/3997)
|
||||
* Add conformance test script [#4040](https://github.com/kubernetes/minikube/pull/4040)
|
||||
* ```#compdef``` must be the first line [#4015](https://github.com/kubernetes/minikube/pull/4015)
|
||||
|
||||
Huge thank you for this release towards our contributors:
|
||||
- Abdulla Bin Mustaqeem
|
||||
- Anders F Björklund
|
||||
- Andy Daniels
|
||||
- Arnaud Jardiné
|
||||
- Artiom Diomin
|
||||
- Balint Pato
|
||||
- Benn Linger
|
||||
- Calin Don
|
||||
- Cristian Măgherușan-Stanciu @magheru_san
|
||||
- Dmitry Budaev
|
||||
- Don McCasland
|
||||
- Douglas Thrift
|
||||
- Elijah Oyekunle
|
||||
- Filip Havlíček
|
||||
- flyingcircle
|
||||
- Guang Ya Liu
|
||||
- Himanshu Pandey
|
||||
- Igor Akkerman
|
||||
- Ihor Dvoretskyi
|
||||
- Jan Janik
|
||||
- Jat
|
||||
- jay vyas
|
||||
- Joel Smith
|
||||
- Joji Mekkatt
|
||||
- karmab
|
||||
- Marcos Diez
|
||||
- Marco Vito Moscaritolo
|
||||
- Martynas Pumputis
|
||||
- Mas
|
||||
- Miel Donkers
|
||||
- morvencao
|
||||
- Oleg Atamanenko
|
||||
- RA489
|
||||
- Sharif Elgamal
|
||||
- Steven Davidovitz
|
||||
- Thomas Strömberg
|
||||
- Tom Reznik
|
||||
- u5surf
|
||||
- Yaroslav Skopets
|
||||
- Yoan Blanc
|
||||
- Zhongcheng Lao
|
||||
|
||||
## Version 1.0.0 - 2019-03-27
|
||||
|
||||
* Update default Kubernetes version to v1.14.0 [#3967](https://github.com/kubernetes/minikube/pull/3967)
|
||||
|
|
|
@ -695,8 +695,7 @@
|
|||
revision = "95c6576299259db960f6c5b9b69ea52422860fce"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:11d290de3457882172ce8d9ffe930999cfb62929b58e486e1ff1b6adcf3c52bc"
|
||||
digest = "1:2780cbd603ca1ee6f33330fb3a590ebaea0e95b99c7759f4d17e2337cca9352a"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
|
@ -717,6 +716,7 @@
|
|||
"language",
|
||||
"message",
|
||||
"message/catalog",
|
||||
"number",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
|
@ -725,7 +725,7 @@
|
|||
"unicode/rangetable",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "e6919f6577db79269a6443b9dc46d18f2238fb5d"
|
||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d37b0ef2944431fe9e8ef35c6fffc8990d9e2ca300588df94a6890f3649ae365"
|
||||
|
@ -1035,6 +1035,7 @@
|
|||
"golang.org/x/sys/windows/registry",
|
||||
"golang.org/x/text/language",
|
||||
"golang.org/x/text/message",
|
||||
"golang.org/x/text/number",
|
||||
"k8s.io/api/apps/v1",
|
||||
"k8s.io/api/core/v1",
|
||||
"k8s.io/api/rbac/v1beta1",
|
||||
|
@ -1046,6 +1047,7 @@
|
|||
"k8s.io/apimachinery/pkg/runtime",
|
||||
"k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"k8s.io/apimachinery/pkg/types",
|
||||
"k8s.io/apimachinery/pkg/util/intstr",
|
||||
"k8s.io/apimachinery/pkg/util/net",
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"k8s.io/apimachinery/pkg/util/uuid",
|
||||
|
|
|
@ -117,4 +117,4 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "golang.org/x/text"
|
||||
branch = "master"
|
||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||
|
|
|
@ -5,3 +5,4 @@ Balint Pato <balintp@google.com> (@balopat)
|
|||
Priya Wadhwa <priyawadhwa@google.com> (@priyawadhwa)
|
||||
Thomas Stromberg <tstromberg@google.com> (@tstromberg)
|
||||
Anders F Björklund <anders.f.bjorklund@gmail.com> (@afbjorklund)
|
||||
Sharif Elgamal <selgamal@google.com (@sharifelgamal)
|
||||
|
|
51
Makefile
51
Makefile
|
@ -15,9 +15,9 @@
|
|||
# Bump these on release - and please check ISO_VERSION for correctness.
|
||||
VERSION_MAJOR ?= 1
|
||||
VERSION_MINOR ?= 0
|
||||
VERSION_BUILD ?= 0
|
||||
VERSION_BUILD ?= 1
|
||||
# Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions
|
||||
ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0
|
||||
ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).1
|
||||
|
||||
VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD)
|
||||
DEB_VERSION ?= $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD)
|
||||
|
@ -99,6 +99,25 @@ endif
|
|||
ifeq ($(GOOS),windows)
|
||||
IS_EXE = ".exe"
|
||||
endif
|
||||
|
||||
ifeq ($(GOARCH),amd64)
|
||||
ARCHTAG ?= -amd64
|
||||
ARCHTAG_NONE ?=
|
||||
else
|
||||
ARCHTAG ?= -$(GOARCH)
|
||||
ARCHTAG_NONE ?= -$(GOARCH)
|
||||
endif
|
||||
|
||||
.PHONY: makedeploys
|
||||
makedeploys:
|
||||
sed "s|\-ARCHTAG_NONE|$(ARCHTAG_NONE)|g" deploy/addons/addon-manager.template > deploy/addons/addon-manager.yaml
|
||||
sed "s|\-ARCHTAG|$(ARCHTAG)|g" deploy/addons/dashboard/dashboard-dp.template > deploy/addons/dashboard/dashboard-dp.yaml
|
||||
sed "s|\-ARCHTAG|$(ARCHTAG)|g" deploy/addons/heapster/heapster-rc.template > deploy/addons/heapster/heapster-rc.yaml
|
||||
sed "s|\-ARCHTAG|$(ARCHTAG)|g" deploy/addons/heapster/influx-grafana-rc.template > deploy/addons/heapster/influx-grafana-rc.yaml
|
||||
sed "s|\-ARCHTAG_NONE|$(ARCHTAG_NONE)|g" deploy/addons/ingress/ingress-dp.template > deploy/addons/ingress/ingress-dp.yaml
|
||||
sed "s|\-ARCHTAG|$(ARCHTAG)|g" deploy/addons/metrics-server/metrics-server-deployment.template > deploy/addons/metrics-server/metrics-server-deployment.yaml
|
||||
sed "s|\-ARCHTAG_NONE|$(ARCHTAG_NONE)|g" deploy/addons/storage-provisioner/storage-provisioner.template > deploy/addons/storage-provisioner/storage-provisioner.yaml
|
||||
|
||||
out/minikube$(IS_EXE): out/minikube-$(GOOS)-$(GOARCH)$(IS_EXE)
|
||||
cp $< $@
|
||||
|
||||
|
@ -109,7 +128,9 @@ out/minikube.d: pkg/minikube/assets/assets.go
|
|||
$(MAKEDEPEND) out/minikube-$(GOOS)-$(GOARCH) $(ORG) $^ $(MINIKUBEFILES) > $@
|
||||
|
||||
-include out/minikube.d
|
||||
out/minikube-%: pkg/minikube/assets/assets.go
|
||||
|
||||
PHONY: out/minikube-%
|
||||
out/minikube-%:makedeploys pkg/minikube/assets/assets.go
|
||||
ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y)
|
||||
$(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@)
|
||||
else
|
||||
|
@ -127,9 +148,9 @@ endif
|
|||
GOOS="$(firstword $(subst -, ,$*))" GOARCH="$(lastword $(subst -, ,$*))" go build -tags "$(MINIKUBE_BUILD_TAGS)" -ldflags="$(MINIKUBE_LDFLAGS)" -a -o $@ k8s.io/minikube/cmd/minikube
|
||||
endif
|
||||
|
||||
.PHONY: e2e-%-amd64
|
||||
e2e-%-amd64: out/minikube-%-amd64
|
||||
GOOS=$* GOARCH=amd64 go test -c k8s.io/minikube/test/integration --tags="$(MINIKUBE_INTEGRATION_BUILD_TAGS)" -o out/$@
|
||||
.PHONY: e2e-%-$(GOARCH)
|
||||
e2e-%-$(GOARCH): out/minikube-%-$(GOARCH)
|
||||
GOOS=$* GOARCH=$(GOARCH) go test -c k8s.io/minikube/test/integration --tags="$(MINIKUBE_INTEGRATION_BUILD_TAGS)" -o out/$@
|
||||
|
||||
e2e-windows-amd64.exe: e2e-windows-amd64
|
||||
mv $(BUILD_DIR)/e2e-windows-amd64 $(BUILD_DIR)/e2e-windows-amd64.exe
|
||||
|
@ -192,8 +213,8 @@ integration: out/minikube
|
|||
go test -v -test.timeout=60m $(REPOPATH)/test/integration --tags="$(MINIKUBE_INTEGRATION_BUILD_TAGS)" $(TEST_ARGS)
|
||||
|
||||
.PHONY: integration-none-driver
|
||||
integration-none-driver: e2e-linux-amd64 out/minikube-linux-amd64
|
||||
sudo -E out/e2e-linux-amd64 -testdata-dir "test/integration/testdata" -minikube-start-args="--vm-driver=none" -test.v -test.timeout=60m -binary=out/minikube-linux-amd64 $(TEST_ARGS)
|
||||
integration-none-driver: e2e-linux-$(GOARCH) out/minikube-linux-$(GOARCH)
|
||||
sudo -E out/e2e-linux-$(GOARCH) -testdata-dir "test/integration/testdata" -minikube-start-args="--vm-driver=none" -test.v -test.timeout=60m -binary=out/minikube-linux-amd64 $(TEST_ARGS)
|
||||
|
||||
.PHONY: integration-versioned
|
||||
integration-versioned: out/minikube
|
||||
|
@ -212,14 +233,14 @@ pkg/minikube/assets/assets.go: $(shell find deploy/addons -type f)
|
|||
PATH="$(PATH):$(GOPATH)/bin" go-bindata -nomemcopy -o pkg/minikube/assets/assets.go -pkg assets deploy/addons/...
|
||||
|
||||
.PHONY: cross
|
||||
cross: out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe
|
||||
cross: out/minikube-linux-$(GOARCH) out/minikube-darwin-amd64 out/minikube-windows-amd64.exe
|
||||
|
||||
.PHONY: e2e-cross
|
||||
e2e-cross: e2e-linux-amd64 e2e-darwin-amd64 e2e-windows-amd64.exe
|
||||
|
||||
.PHONY: checksum
|
||||
checksum:
|
||||
for f in out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/minikube.iso \
|
||||
for f in out/minikube-linux-$(GOARCH) out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/minikube.iso \
|
||||
out/docker-machine-driver-kvm2 out/docker-machine-driver-hyperkit; do \
|
||||
if [ -f "$${f}" ]; then \
|
||||
openssl sha256 "$${f}" | awk '{print $$2}' > "$${f}.sha256" ; \
|
||||
|
@ -337,11 +358,19 @@ out/storage-provisioner:
|
|||
|
||||
.PHONY: storage-provisioner-image
|
||||
storage-provisioner-image: out/storage-provisioner
|
||||
docker build -t $(REGISTRY)/storage-provisioner:$(STORAGE_PROVISIONER_TAG) -f deploy/storage-provisioner/Dockerfile .
|
||||
ifeq ($(GOARCH),amd64)
|
||||
docker build -t $(REGISTRY)/storage-provisioner:$(STORAGE_PROVISIONER_TAG) -f deploy/storage-provisioner/Dockerfile .
|
||||
else
|
||||
docker build -t $(REGISTRY)/storage-provisioner-$(GOARCH):$(STORAGE_PROVISIONER_TAG) -f deploy/storage-provisioner/Dockerfile-$(GOARCH) .
|
||||
endif
|
||||
|
||||
.PHONY: push-storage-provisioner-image
|
||||
push-storage-provisioner-image: storage-provisioner-image
|
||||
ifeq ($(GOARCH),amd64)
|
||||
gcloud docker -- push $(REGISTRY)/storage-provisioner:$(STORAGE_PROVISIONER_TAG)
|
||||
else
|
||||
gcloud docker -- push $(REGISTRY)/storage-provisioner-$(GOARCH):$(STORAGE_PROVISIONER_TAG)
|
||||
endif
|
||||
|
||||
.PHONY: out/gvisor-addon
|
||||
out/gvisor-addon:
|
||||
|
|
4
OWNERS
4
OWNERS
|
@ -4,13 +4,13 @@ reviewers:
|
|||
- dlorenc
|
||||
- balopat
|
||||
- tstromberg
|
||||
- priyawadhwa
|
||||
- afbjorklund
|
||||
- sharifelgamal
|
||||
approvers:
|
||||
- dlorenc
|
||||
- luxas
|
||||
- jimmidyson
|
||||
- balopat
|
||||
- tstromberg
|
||||
- priyawadhwa
|
||||
- afbjorklund
|
||||
- sharifelgamal
|
||||
|
|
|
@ -17,13 +17,12 @@ minikube implements a local Kubernetes cluster on macOS, Linux, and Windows.
|
|||
|
||||
![screenshot](/images/start.jpg)
|
||||
|
||||
Our [project goals](https://github.com/kubernetes/minikube/blob/master/docs/contributors/principles.md) are to enable fast local development and to support all Kubernetes features that fit. We hope you enjoy it!
|
||||
minikube's [primary goals](https://github.com/kubernetes/minikube/blob/master/docs/contributors/principles.md) are to be the best tool for local Kubernetes application development and to support all Kubernetes features that fit. We hope you enjoy it!
|
||||
|
||||
## News
|
||||
|
||||
* 2019-04-29 - v1.0.1 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v1.0.1)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-101---2019-04-29)]
|
||||
* 2019-03-27 - v1.0.0 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v1.0.0)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-1000---2019-03-27)]
|
||||
* 2019-03-06 - v0.35.0 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v0.35.0)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0350---2019-03-06)]
|
||||
* 2019-02-16 - v0.34.1 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v0.34.1)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0341---2019-02-16)]
|
||||
|
||||
## Features
|
||||
|
||||
|
@ -106,6 +105,10 @@ Start a cluster by running:
|
|||
|
||||
`minikube start`
|
||||
|
||||
Access Kubernetes Dashboard within Minikube:
|
||||
|
||||
`minikube dashboard`
|
||||
|
||||
Once started, you can interact with your cluster using `kubectl`, just like any other Kubernetes cluster. For instance, starting a server:
|
||||
|
||||
`kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.4 --port=8080`
|
||||
|
|
|
@ -170,17 +170,23 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
if err != nil && !os.IsNotExist(err) {
|
||||
exit.WithCode(exit.Data, "Unable to load config: %v", err)
|
||||
}
|
||||
k8sVersion := validateKubernetesVersions(oldConfig)
|
||||
k8sVersion, isUpgrade := validateKubernetesVersions(oldConfig)
|
||||
config, err := generateConfig(cmd, k8sVersion)
|
||||
if err != nil {
|
||||
exit.WithError("Failed to generate config", err)
|
||||
}
|
||||
|
||||
if viper.GetString(vmDriver) == constants.DriverNone {
|
||||
// Optimization: images will be persistently loaded into the host's container runtime, so no need to duplicate work.
|
||||
// For non-"none", the ISO is required to boot, so block until it is downloaded
|
||||
if viper.GetString(vmDriver) != constants.DriverNone {
|
||||
if err := cluster.CacheISO(config.MachineConfig); err != nil {
|
||||
exit.WithError("Failed to cache ISO", err)
|
||||
}
|
||||
} else {
|
||||
// With "none", images are persistently stored in Docker, so internal caching isn't necessary.
|
||||
viper.Set(cacheImages, false)
|
||||
}
|
||||
|
||||
// Now that the ISO is downloaded, pull images in the background while the VM boots.
|
||||
var cacheGroup errgroup.Group
|
||||
beginCacheImages(&cacheGroup, k8sVersion)
|
||||
|
||||
|
@ -195,10 +201,8 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
exit.WithError("Failed to get machine client", err)
|
||||
}
|
||||
|
||||
// If --download-only, complete the remaining downloads and exit.
|
||||
if viper.GetBool(downloadOnly) {
|
||||
if err := cluster.CacheISO(config.MachineConfig); err != nil {
|
||||
exit.WithError("Failed to cache ISO", err)
|
||||
}
|
||||
if err := doCacheBinaries(k8sVersion); err != nil {
|
||||
exit.WithError("Failed to cache binaries", err)
|
||||
}
|
||||
|
@ -232,7 +236,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
|
||||
// The kube config must be update must come before bootstrapping, otherwise health checks may use a stale IP
|
||||
kubeconfig := updateKubeConfig(host, &config)
|
||||
bootstrapCluster(bs, cr, runner, config.KubernetesConfig, preexisting)
|
||||
bootstrapCluster(bs, cr, runner, config.KubernetesConfig, preexisting, isUpgrade)
|
||||
|
||||
apiserverPort := config.KubernetesConfig.NodePort
|
||||
validateCluster(bs, cr, runner, ip, apiserverPort)
|
||||
|
@ -455,8 +459,9 @@ func validateNetwork(h *host.Host) string {
|
|||
}
|
||||
|
||||
// validateKubernetesVersions ensures that the requested version is reasonable
|
||||
func validateKubernetesVersions(old *cfg.Config) string {
|
||||
func validateKubernetesVersions(old *cfg.Config) (string, bool) {
|
||||
nv := viper.GetString(kubernetesVersion)
|
||||
isUpgrade := false
|
||||
if nv == "" {
|
||||
nv = constants.DefaultKubernetesVersion
|
||||
}
|
||||
|
@ -466,7 +471,7 @@ func validateKubernetesVersions(old *cfg.Config) string {
|
|||
}
|
||||
|
||||
if old == nil || old.KubernetesConfig.KubernetesVersion == "" {
|
||||
return nv
|
||||
return nv, isUpgrade
|
||||
}
|
||||
|
||||
ovs, err := semver.Make(strings.TrimPrefix(old.KubernetesConfig.KubernetesVersion, version.VersionPrefix))
|
||||
|
@ -477,12 +482,13 @@ func validateKubernetesVersions(old *cfg.Config) string {
|
|||
if nvs.LT(ovs) {
|
||||
nv = version.VersionPrefix + ovs.String()
|
||||
console.ErrStyle("conflict", "Kubernetes downgrade is not supported, will continue to use %v", nv)
|
||||
return nv
|
||||
return nv, isUpgrade
|
||||
}
|
||||
if nvs.GT(ovs) {
|
||||
console.OutStyle("thumbs-up", "minikube will upgrade the local cluster from Kubernetes %s to %s", ovs, nvs)
|
||||
isUpgrade = true
|
||||
}
|
||||
return nv
|
||||
return nv, isUpgrade
|
||||
}
|
||||
|
||||
// prepareHostEnvironment adds any requested files into the VM before Kubernetes is started
|
||||
|
@ -560,14 +566,17 @@ func configureRuntimes(h *host.Host, runner bootstrapper.CommandRunner) cruntime
|
|||
}
|
||||
|
||||
// bootstrapCluster starts Kubernetes using the chosen bootstrapper
|
||||
func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bootstrapper.CommandRunner, kc cfg.KubernetesConfig, preexisting bool) {
|
||||
console.OutStyle("pulling", "Pulling images required by Kubernetes %s ...", kc.KubernetesVersion)
|
||||
if err := bs.PullImages(kc); err != nil {
|
||||
console.OutStyle("failure", "Unable to pull images, which may be OK: %v", err)
|
||||
}
|
||||
func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bootstrapper.CommandRunner, kc cfg.KubernetesConfig, preexisting bool, isUpgrade bool) {
|
||||
// hum. bootstrapper.Bootstrapper should probably have a Name function.
|
||||
bsName := viper.GetString(cmdcfg.Bootstrapper)
|
||||
|
||||
if isUpgrade || !preexisting {
|
||||
console.OutStyle("pulling", "Pulling images required by Kubernetes %s ...", kc.KubernetesVersion)
|
||||
if err := bs.PullImages(kc); err != nil {
|
||||
console.OutStyle("failure", "Unable to pull images, which may be OK: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if preexisting {
|
||||
console.OutStyle("restarting", "Relaunching Kubernetes %s using %s ... ", kc.KubernetesVersion, bsName)
|
||||
if err := bs.RestartCluster(kc); err != nil {
|
||||
|
|
|
@ -49,9 +49,9 @@ var updateContextCmd = &cobra.Command{
|
|||
exit.WithError("update config", err)
|
||||
}
|
||||
if updated {
|
||||
console.OutStyle("celebrate", "IP has been updated to point at %s", ip)
|
||||
console.OutStyle("celebrate", "%s IP has been updated to point at %s", machineName, ip)
|
||||
} else {
|
||||
console.OutStyle("meh", "IP was already correctly configured for %s", ip)
|
||||
console.OutStyle("meh", "%s IP was already correctly configured for %s", machineName, ip)
|
||||
}
|
||||
|
||||
},
|
||||
|
|
|
@ -25,7 +25,7 @@ spec:
|
|||
hostNetwork: true
|
||||
containers:
|
||||
- name: kube-addon-manager
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/kube-addon-manager:v9.0
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/kube-addon-manager-ARCHTAG_NONE:v9.0
|
||||
env:
|
||||
- name: KUBECONFIG
|
||||
value: /var/lib/minikube/kubeconfig
|
|
@ -37,7 +37,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: kubernetes-dashboard
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/kubernetes-dashboard-amd64:v1.10.1
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/kubernetes-dashboard-ARCHTAG:v1.10.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 9090
|
|
@ -37,7 +37,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: heapster
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/heapster-amd64:v1.5.3
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/heapster-ARCHTAG:v1.5.3
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /heapster
|
|
@ -34,7 +34,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: influxdb
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/heapster-influxdb-amd64:v1.3.3
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/heapster-influxdb-ARCHTAG:v1.3.3
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
|
@ -45,7 +45,7 @@ spec:
|
|||
- mountPath: /data
|
||||
name: influxdb-storage
|
||||
- name: grafana
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/heapster-grafana-amd64:v4.4.3
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/heapster-grafana-ARCHTAG:v4.4.3
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: INFLUXDB_SERVICE_URL
|
|
@ -39,7 +39,7 @@ spec:
|
|||
# Any image is permissible as long as:
|
||||
# 1. It serves a 404 page at /
|
||||
# 2. It serves 200 on a /healthz endpoint
|
||||
image: {{default "gcr.io/google_containers" .ImageRepository}}/defaultbackend:1.4
|
||||
image: {{default "gcr.io/google_containers" .ImageRepository}}/defaultbackend-ARCHTAG_NONE:1.4
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
|
@ -87,7 +87,7 @@ spec:
|
|||
serviceAccountName: nginx-ingress
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.23.0
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller-ARCHTAG_NONE:0.23.0
|
||||
name: nginx-ingress-controller
|
||||
imagePullPolicy: IfNotPresent
|
||||
readinessProbe:
|
|
@ -19,7 +19,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: metrics-server
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/metrics-server-amd64:v0.2.1
|
||||
image: {{default "k8s.gcr.io" .ImageRepository}}/metrics-server-ARCHTAG:v0.2.1
|
||||
imagePullPolicy: Always
|
||||
command:
|
||||
- /metrics-server
|
|
@ -51,7 +51,7 @@ spec:
|
|||
hostNetwork: true
|
||||
containers:
|
||||
- name: storage-provisioner
|
||||
image: {{default "gcr.io/k8s-minikube" .ImageRepository}}/storage-provisioner:v1.8.1
|
||||
image: {{default "gcr.io/k8s-minikube" .ImageRepository}}/storage-provisioner-ARCHTAG_NONE:v1.8.1
|
||||
command: ["/storage-provisioner"]
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
|
@ -4,7 +4,7 @@ metadata:
|
|||
namespace: kube-system
|
||||
name: standard
|
||||
annotations:
|
||||
storageclass.beta.kubernetes.io/is-default-class: "true"
|
||||
storageclass.kubernetes.io/is-default-class: "true"
|
||||
labels:
|
||||
addonmanager.kubernetes.io/mode: EnsureExists
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
[
|
||||
{
|
||||
"name": "v1.0.1",
|
||||
"checksums": {
|
||||
"darwin": "0af8a3f582c9284ffe10e99444b60a75241325f2bc9ab43ec758802f2b89e1db",
|
||||
"linux": "7b56374955990ef2dd0289e6ecb62cf2b4587cab2b481d95f58de5db56799868",
|
||||
"windows": "58abb5fb3e694a451102963e04ce13ea0cea46b7bf5c7947f40fdfc673282ac9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "v1.0.0",
|
||||
"checksums": {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
FROM s390x/ubuntu:16.04
|
||||
COPY out/storage-provisioner storage-provisioner
|
||||
CMD ["/storage-provisioner"]
|
|
@ -5,7 +5,26 @@ To use this feature, you can use the `--extra-config` flag on the `minikube star
|
|||
|
||||
This flag is repeated, so you can pass it several times with several different values to set multiple options.
|
||||
|
||||
## Kubeadm bootstrapper
|
||||
|
||||
## Selecting a Kubernetes version
|
||||
|
||||
minikube defaults to the latest stable version of Kubernetes. You may select a different Kubernetes release by using the `--kubernetes-version` flag, for example:
|
||||
|
||||
`minikube start --kubernetes-version=v1.10.13`
|
||||
|
||||
minikube follows the [Kubernetes Version and Version Skew Support Policy](https://kubernetes.io/docs/setup/version-skew-policy/), so we guarantee support for the latest build for the last 3 minor Kubernetes releases. When practical, minikube extends this policy two additional minor releases so that users can emulate legacy environments.
|
||||
|
||||
As of April 2019, this means that minikube supports and actively tests against the latest builds of:
|
||||
|
||||
* v1.14 (default)
|
||||
* v1.13
|
||||
* v1.12
|
||||
* v1.11 (best effort)
|
||||
* v1.10 (best effort)
|
||||
|
||||
For more up to date information, see `OldestKubernetesVersion` and `NewestKubernetesVersion` in [constants.go](https://github.com/kubernetes/minikube/blob/master/pkg/minikube/constants/constants.go)
|
||||
|
||||
## kubeadm
|
||||
|
||||
The kubeadm bootstrapper can be configured by the `--extra-config` flag on the `minikube start` command. It takes a string of the form `component.key=value` where `component` is one of the strings
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
## Build a new ISO
|
||||
|
||||
Major releases always get a new ISO. Minor bugfixes may or may not require it: check for changes in the `deploy/iso` folder.
|
||||
To check, run `git log -- deploy/iso` from the root directory and see if there has been a commit since the most recent release.
|
||||
|
||||
Note: you can build the ISO using the `hack/jenkins/build_iso.sh` script locally.
|
||||
|
||||
|
@ -27,13 +28,7 @@ Edit the minikube `Makefile`, updating the version number values at the top:
|
|||
* `VERSION_MAJOR`, `VERSION_MINOR`, `VERSION_BUILD` as necessary
|
||||
* `ISO_VERSION` - defaults to MAJOR.MINOR.0 - update if point release requires a new ISO to be built.
|
||||
|
||||
## Run Local Integration Test
|
||||
|
||||
Once the ISO build completes, run run the integration tests with the updated Makefile:
|
||||
|
||||
```shell
|
||||
env TEST_ARGS="-minikube-start-args=--vm-driver=kvm2" make integration
|
||||
```
|
||||
Make sure the integration tests run against this PR, once the new ISO is built.
|
||||
|
||||
## Ad-Hoc testing of other platforms
|
||||
|
||||
|
@ -94,7 +89,7 @@ These are downstream packages that are being maintained by others and how to upg
|
|||
|
||||
| Package Manager | URL | TODO |
|
||||
| --- | --- | --- |
|
||||
| Arch Linux AUR | <https://aur.archlinux.org/packages/minikube/> | "Flag as package out-of-date"
|
||||
| Arch Linux AUR | <https://aur.archlinux.org/packages/minikube-bin/> | "Flag as package out-of-date"
|
||||
| Brew Cask | <https://github.com/Homebrew/homebrew-cask/blob/master/Casks/minikube.rb> | The release job creates a new PR in [Homebrew/homebrew-cask](https://github.com/Homebrew/homebrew-cask) with an updated version and SHA256, double check that it's created.
|
||||
|
||||
WARNING: The Brew cask automation is error-prone. please ensure that a PR was created.
|
||||
|
@ -107,10 +102,12 @@ Verify release checksums by running`make check-release`
|
|||
|
||||
If there are major changes, please send a PR to update <https://kubernetes.io/docs/setup/minikube/>
|
||||
|
||||
## Announce!
|
||||
## Announce
|
||||
|
||||
Places we generally announce releases:
|
||||
Please mention the new release https://github.com/kubernetes/minikube/blob/master/README.md
|
||||
|
||||
Other places:
|
||||
|
||||
- #minikube on Slack
|
||||
- minikube-dev, minikube-users mailing list
|
||||
- Twitter
|
||||
- Twitter (optional!)
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
# This script should be run from the minikube repo root, and requires
|
||||
# the following env variables to be set:
|
||||
# VERSION_MAJOR
|
||||
# VERSION_MINOR
|
||||
# VERSION_BUILD
|
||||
# BOT_PASSWORD
|
||||
|
||||
set -eux -o pipefail
|
||||
|
||||
readonly REPO_DIR=$PWD
|
||||
readonly NEW_VERSION=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD}
|
||||
readonly NEW_SHA256=$(awk '{ print $1 }' "${REPO_DIR}/out/minikube-darwin-amd64.sha256")
|
||||
readonly BUILD_DIR=$(mktemp -d)
|
||||
readonly GITHUB_USER="minikube-bot"
|
||||
|
||||
if [ -z "${NEW_SHA256}" ]; then
|
||||
echo "SHA256 is empty :("
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git config --global user.name "${GITHUB_USER}"
|
||||
git config --global user.email "${GITHUB_USER}@google.com"
|
||||
|
||||
cd "${BUILD_DIR}"
|
||||
git clone --depth 1 "git@github.com:${GITHUB_USER}/homebrew-cask.git"
|
||||
cd homebrew-cask
|
||||
git remote add upstream https://github.com/Homebrew/homebrew-cask.git
|
||||
git fetch upstream
|
||||
|
||||
git checkout upstream/master
|
||||
git checkout -b "${NEW_VERSION}"
|
||||
sed -e "s/\$PKG_VERSION/${NEW_VERSION}/g" \
|
||||
-e "s/\$MINIKUBE_DARWIN_SHA256/${NEW_SHA256}/g" \
|
||||
"${REPO_DIR}/installers/darwin/brew-cask/minikube.rb.tmpl" > Casks/minikube.rb
|
||||
git add Casks/minikube.rb
|
||||
git commit -F- <<EOF
|
||||
Update minikube to ${NEW_VERSION}
|
||||
|
||||
- [x] brew cask audit --download {{cask_file}} is error-free.
|
||||
- [x] brew cask style --fix {{cask_file}} reports no offenses.
|
||||
- [x] The commit message includes the cask’s name and version.
|
||||
|
||||
EOF
|
||||
|
||||
git push origin "${NEW_VERSION}"
|
||||
curl -v -k -u "${GITHUB_USER}:${BOT_PASSWORD}" -X POST https://api.github.com/repos/Homebrew/homebrew-cask/pulls \
|
||||
-d @- <<EOF
|
||||
|
||||
{
|
||||
"title": "Update minikube to ${NEW_VERSION}",
|
||||
"head": "${GITHUB_USER}:${NEW_VERSION}",
|
||||
"base": "master",
|
||||
"body": "cc @balopat"
|
||||
}
|
||||
EOF
|
||||
|
||||
rm -Rf "${BUILD_DIR}"
|
|
@ -1,90 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
git config --global user.name "minikube-bot"
|
||||
git config --global user.email "minikube-bot@google.com"
|
||||
|
||||
REPLACE_PKG_VERSION=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD}
|
||||
REPLACE_MINIKUBE_LINUX_SHA256=$(awk '{ print $1 }' out/minikube-linux-amd64.sha256)
|
||||
REPLACE_MINIKUBE_DRIVER_KVM_SHA256=$(awk '{ print $1 }' out/docker-machine-driver-kvm2.sha256)
|
||||
REPLACE_MINIKUBE_DARWIN_SHA256=$(awk '{ print $1 }' out/minikube-darwin-amd64.sha256)
|
||||
MINIKUBE_ROOT=$PWD
|
||||
|
||||
git clone ssh://aur@aur.archlinux.org/minikube-bin.git aur-minikube-bin
|
||||
pushd aur-minikube-bin >/dev/null
|
||||
sed -e "s/\$PKG_VERSION/${REPLACE_PKG_VERSION}/g" \
|
||||
-e "s/\$MINIKUBE_LINUX_SHA256/${REPLACE_MINIKUBE_LINUX_SHA256}/g" \
|
||||
$MINIKUBE_ROOT/installers/linux/archlinux/PKGBUILD > PKGBUILD
|
||||
sed -e "s/\$PKG_VERSION/${REPLACE_PKG_VERSION}/g" \
|
||||
-e "s/\$MINIKUBE_LINUX_SHA256/${REPLACE_MINIKUBE_LINUX_SHA256}/g" \
|
||||
$MINIKUBE_ROOT/installers/linux/archlinux/.SRCINFO > .SRCINFO
|
||||
git add PKGBUILD .SRCINFO
|
||||
git commit -m "Upgrade to version ${REPLACE_PKG_VERSION}"
|
||||
|
||||
git push origin master
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
|
||||
git clone ssh://aur@aur.archlinux.org/docker-machine-driver-kvm2.git aur-minikube-driver-kvm
|
||||
pushd aur-minikube-driver-kvm >/dev/null
|
||||
sed -e "s/\$PKG_VERSION/${REPLACE_PKG_VERSION}/g" \
|
||||
sed -e "s/\$MINIKUBE_DRIVER_KVM_SHA256/${REPLACE_MINIKUBE_DRIVER_KVM_SHA256}/g" \
|
||||
$MINIKUBE_ROOT/installers/linux/archlinux-drivers/
|
||||
sed -e "s/\$PKG_VERSION/${REPLACE_PKG_VERSION}/g" \
|
||||
-e "s/\$MINIKUBE_DRIVER_KVM_SHA256/${REPLACE_MINIKUBE_DRIVER_KVM_SHA256}/g" \
|
||||
$MINIKUBE_ROOT/installers/linux/archlinux-drivers/.SRCINFO > .SRCINFO
|
||||
git add PKGBUILD .SRCINFO
|
||||
git commit -m "Upgrade to version ${REPLACE_PKG_VERSION}"
|
||||
|
||||
git push origin master
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
git clone --depth 1 git@github.com:minikube-bot/homebrew-cask.git # don't pull entire history
|
||||
|
||||
pushd homebrew-cask >/dev/null
|
||||
git remote add upstream https://github.com/Homebrew/homebrew-cask.git
|
||||
git fetch upstream
|
||||
git checkout upstream/master
|
||||
git checkout -b ${REPLACE_PKG_VERSION}
|
||||
sed -e "s/\$PKG_VERSION/${REPLACE_PKG_VERSION}/g" \
|
||||
-e "s/\$MINIKUBE_DARWIN_SHA256/${REPLACE_MINIKUBE_DARWIN_SHA256}/g" \
|
||||
$MINIKUBE_ROOT/installers/darwin/brew-cask/minikube.rb.tmpl > Casks/minikube.rb
|
||||
git add Casks/minikube.rb
|
||||
git commit -F- <<EOF
|
||||
Update minikube to ${REPLACE_PKG_VERSION}
|
||||
|
||||
- [x] brew cask audit --download {{cask_file}} is error-free.
|
||||
- [x] brew cask style --fix {{cask_file}} reports no offenses.
|
||||
- [x] The commit message includes the cask’s name and version.
|
||||
|
||||
EOF
|
||||
git push origin ${REPLACE_PKG_VERSION}
|
||||
curl -v -k -u minikube-bot:${BOT_PASSWORD} -X POST https://api.github.com/repos/Homebrew/homebrew-cask/pulls \
|
||||
-d @- <<EOF
|
||||
|
||||
{
|
||||
"title": "Update minikube to ${REPLACE_PKG_VERSION}",
|
||||
"head": "minikube-bot:${REPLACE_PKG_VERSION}",
|
||||
"base": "master",
|
||||
"body": "cc @balopat"
|
||||
}
|
||||
|
||||
EOF
|
||||
popd >/dev/null
|
||||
|
||||
rm -rf aur-minikube aur-minikube-driver-kvm homebrew-cask
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2019 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) == 1 {
|
||||
fmt.Println("Usage: go run update_kubernetes_version.go <kubernetes_version>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
v := os.Args[1]
|
||||
if !strings.HasPrefix(v, "v") {
|
||||
v = "v" + v
|
||||
}
|
||||
|
||||
constantsFile := "../../pkg/minikube/constants/constants.go"
|
||||
cf, err := ioutil.ReadFile(constantsFile)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
info, err := os.Stat(constantsFile)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
mode := info.Mode()
|
||||
|
||||
re := regexp.MustCompile(`var DefaultKubernetesVersion = .*`)
|
||||
f := re.ReplaceAllString(string(cf), "var DefaultKubernetesVersion = \""+v+"\"")
|
||||
|
||||
re = regexp.MustCompile(`var NewestKubernetesVersion = .*`)
|
||||
f = re.ReplaceAllString(f, "var NewestKubernetesVersion = \""+v+"\"")
|
||||
|
||||
ioutil.WriteFile(constantsFile, []byte(f), mode)
|
||||
|
||||
testData := "../../pkg/minikube/bootstrapper/kubeadm/testdata"
|
||||
|
||||
err = filepath.Walk(testData, func(path string, info os.FileInfo, err error) error {
|
||||
if strings.HasSuffix(path, "default.yaml") {
|
||||
cf, err = ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
// Keep going if this errors out
|
||||
fmt.Println(err)
|
||||
}
|
||||
re = regexp.MustCompile(`kubernetesVersion: .*`)
|
||||
cf = []byte(re.ReplaceAllString(string(cf), "kubernetesVersion: "+v))
|
||||
ioutil.WriteFile(path, cf, info.Mode())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -87,7 +87,7 @@ func (*ExecRunner) Copy(f assets.CopyableFile) error {
|
|||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating file at %s", targetPath)
|
||||
}
|
||||
perms, err := strconv.Atoi(f.GetPermissions())
|
||||
perms, err := strconv.ParseInt(f.GetPermissions(), 8, 0)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error converting permissions %s to integer", f.GetPermissions())
|
||||
}
|
||||
|
|
|
@ -464,7 +464,6 @@ func (k *Bootstrapper) UpdateCluster(cfg config.KubernetesConfig) error {
|
|||
}
|
||||
err = k.c.Run(`
|
||||
sudo systemctl daemon-reload &&
|
||||
sudo systemctl enable kubelet &&
|
||||
sudo systemctl start kubelet
|
||||
`)
|
||||
if err != nil {
|
||||
|
|
|
@ -301,13 +301,7 @@ func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error
|
|||
exit.WithError("error getting driver", err)
|
||||
}
|
||||
|
||||
err = CacheISO(config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to cache ISO")
|
||||
}
|
||||
|
||||
driver := def.ConfigCreator(config)
|
||||
|
||||
data, err := json.Marshal(driver)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "marshal")
|
||||
|
|
|
@ -75,6 +75,8 @@ func TestOutStyle(t *testing.T) {
|
|||
[]interface{}{"encode '%' signs", "%s%%%d"},
|
||||
" - Message with params: encode '%' signs %s%%%d\n",
|
||||
},
|
||||
{"issue", "true", "No separators for long ints: %d", []interface{}{10000}, " ▪ No separators for long ints: 10000\n"},
|
||||
{"issue", "false", "No separators for long ints: %d", []interface{}{5000}, " - No separators for long ints: 5000\n"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.style+"-"+tc.envValue, func(t *testing.T) {
|
||||
|
@ -103,7 +105,7 @@ func TestOut(t *testing.T) {
|
|||
var tests = []struct {
|
||||
format string
|
||||
lang language.Tag
|
||||
arg string
|
||||
arg interface{}
|
||||
want string
|
||||
}{
|
||||
{format: "xyz123", want: "xyz123"},
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"golang.org/x/text/message"
|
||||
"golang.org/x/text/number"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -137,6 +138,11 @@ func lowPrefix(s style) string {
|
|||
// Apply styling to a format string
|
||||
func applyStyle(style string, useColor bool, format string, a ...interface{}) (string, error) {
|
||||
p := message.NewPrinter(preferredLanguage)
|
||||
for i, x := range a {
|
||||
if _, ok := x.(int); ok {
|
||||
a[i] = number.Decimal(x, number.NoSeparator())
|
||||
}
|
||||
}
|
||||
out := p.Sprintf(format, a...)
|
||||
|
||||
s, ok := styles[style]
|
||||
|
|
|
@ -51,6 +51,15 @@ func GetMinipath() string {
|
|||
return filepath.Join(os.Getenv(MinikubeHome), ".minikube")
|
||||
}
|
||||
|
||||
// ArchTag returns the archtag for images
|
||||
func ArchTag(hasTag bool) string {
|
||||
if runtime.GOARCH == "amd64" && hasTag == false {
|
||||
return ":"
|
||||
} else {
|
||||
return "-" + runtime.GOARCH + ":"
|
||||
}
|
||||
}
|
||||
|
||||
// SupportedVMDrivers is a list of supported drivers on all platforms. Currently
|
||||
// used in gendocs.
|
||||
var SupportedVMDrivers = [...]string{
|
||||
|
@ -266,17 +275,17 @@ func GetKubeadmCachedImages(imageRepository string, kubernetesVersionStr string)
|
|||
var images []string
|
||||
if v1_12plus(kubernetesVersion) {
|
||||
images = append(images, []string{
|
||||
imageRepository + "kube-proxy:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-scheduler:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-controller-manager:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-apiserver:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-proxy" + ArchTag(false) + kubernetesVersionStr,
|
||||
imageRepository + "kube-scheduler" + ArchTag(false) + kubernetesVersionStr,
|
||||
imageRepository + "kube-controller-manager" + ArchTag(false) + kubernetesVersionStr,
|
||||
imageRepository + "kube-apiserver" + ArchTag(false) + kubernetesVersionStr,
|
||||
}...)
|
||||
} else {
|
||||
images = append(images, []string{
|
||||
imageRepository + "kube-proxy-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-scheduler-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-controller-manager-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-apiserver-amd64:" + kubernetesVersionStr,
|
||||
imageRepository + "kube-proxy" + ArchTag(true) + kubernetesVersionStr,
|
||||
imageRepository + "kube-scheduler" + ArchTag(true) + kubernetesVersionStr,
|
||||
imageRepository + "kube-controller-manager" + ArchTag(true) + kubernetesVersionStr,
|
||||
imageRepository + "kube-apiserver" + ArchTag(true) + kubernetesVersionStr,
|
||||
}...)
|
||||
}
|
||||
|
||||
|
@ -285,21 +294,21 @@ func GetKubeadmCachedImages(imageRepository string, kubernetesVersionStr string)
|
|||
podInfraContainerImage = imageRepository + "pause:3.1"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.13",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.13",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.13",
|
||||
imageRepository + "etcd:3.3.10",
|
||||
imageRepository + "coredns:1.3.1",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.13",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.13",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.13",
|
||||
imageRepository + "etcd" + ArchTag(false) + "3.3.10",
|
||||
imageRepository + "coredns" + ArchTag(false) + "1.3.1",
|
||||
}...)
|
||||
|
||||
} else if v1_13(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause:3.1"
|
||||
podInfraContainerImage = imageRepository + "pause" + ArchTag(false) + "3.1"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd:3.2.24",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "etcd" + ArchTag(false) + "3.2.24",
|
||||
imageRepository + "coredns:1.2.6",
|
||||
}...)
|
||||
|
||||
|
@ -307,62 +316,62 @@ func GetKubeadmCachedImages(imageRepository string, kubernetesVersionStr string)
|
|||
podInfraContainerImage = imageRepository + "pause:3.1"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd:3.2.24",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "etcd" + ArchTag(false) + "3.2.24",
|
||||
imageRepository + "coredns:1.2.2",
|
||||
}...)
|
||||
|
||||
} else if v1_11(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause:3.1"
|
||||
podInfraContainerImage = imageRepository + "pause" + ArchTag(false) + "3.1"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd-amd64:3.2.18",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "etcd" + ArchTag(true) + "3.2.18",
|
||||
imageRepository + "coredns:1.1.3",
|
||||
}...)
|
||||
|
||||
} else if v1_10(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause:3.1"
|
||||
podInfraContainerImage = imageRepository + "pause" + ArchTag(false) + "3.1"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.8",
|
||||
imageRepository + "etcd-amd64:3.1.12",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.8",
|
||||
imageRepository + "etcd" + ArchTag(true) + "3.1.12",
|
||||
}...)
|
||||
|
||||
} else if v1_9(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause:3.0"
|
||||
podInfraContainerImage = imageRepository + "pause" + ArchTag(false) + "3.0"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.7",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.7",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.7",
|
||||
imageRepository + "etcd-amd64:3.1.10",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.7",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.7",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.7",
|
||||
imageRepository + "etcd" + ArchTag(true) + "3.1.10",
|
||||
}...)
|
||||
|
||||
} else if v1_8(kubernetesVersion) {
|
||||
podInfraContainerImage = imageRepository + "pause:3.0"
|
||||
podInfraContainerImage = imageRepository + "pause" + ArchTag(false) + "3.0"
|
||||
images = append(images, []string{
|
||||
podInfraContainerImage,
|
||||
imageRepository + "k8s-dns-kube-dns-amd64:1.14.5",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny-amd64:1.14.5",
|
||||
imageRepository + "k8s-dns-sidecar-amd64:1.14.5",
|
||||
imageRepository + "etcd-amd64:3.0.17",
|
||||
imageRepository + "k8s-dns-kube-dns" + ArchTag(true) + "1.14.5",
|
||||
imageRepository + "k8s-dns-dnsmasq-nanny" + ArchTag(true) + "1.14.5",
|
||||
imageRepository + "k8s-dns-sidecar" + ArchTag(true) + "1.14.5",
|
||||
imageRepository + "etcd" + ArchTag(true) + "3.0.17",
|
||||
}...)
|
||||
|
||||
} else {
|
||||
podInfraContainerImage = imageRepository + "pause:3.0"
|
||||
podInfraContainerImage = imageRepository + "pause" + ArchTag(false) + "3.0"
|
||||
}
|
||||
|
||||
images = append(images, []string{
|
||||
imageRepository + "kubernetes-dashboard-amd64:v1.10.1",
|
||||
imageRepository + "kube-addon-manager:v9.0",
|
||||
minikubeRepository + "storage-provisioner:v1.8.1",
|
||||
imageRepository + "kubernetes-dashboard" + ArchTag(true) + "v1.10.1",
|
||||
imageRepository + "kube-addon-manager" + ArchTag(false) + "v9.0",
|
||||
minikubeRepository + "storage-provisioner" + ArchTag(false) + "v1.8.1",
|
||||
}...)
|
||||
|
||||
return podInfraContainerImage, images
|
||||
|
|
|
@ -381,7 +381,7 @@ func TestEnable(t *testing.T) {
|
|||
want map[string]serviceState
|
||||
}{
|
||||
{"docker", map[string]serviceState{
|
||||
"docker": Restarted,
|
||||
"docker": Running,
|
||||
"docker.socket": Running,
|
||||
"containerd": Exited,
|
||||
"crio": Exited,
|
||||
|
|
|
@ -73,7 +73,7 @@ func (r *Docker) Enable() error {
|
|||
if err := disableOthers(r, r.Runner); err != nil {
|
||||
glog.Warningf("disableOthers: %v", err)
|
||||
}
|
||||
return r.Runner.Run("sudo systemctl restart docker")
|
||||
return r.Runner.Run("sudo systemctl start docker")
|
||||
}
|
||||
|
||||
// Disable idempotently disables Docker on a host
|
||||
|
|
|
@ -85,7 +85,7 @@ func CacheBinary(binary, version string) (string, error) {
|
|||
|
||||
// CopyBinary copies previously cached binaries into the path
|
||||
func CopyBinary(cr bootstrapper.CommandRunner, binary, path string) error {
|
||||
f, err := assets.NewFileAsset(path, "/usr/bin", binary, "0641")
|
||||
f, err := assets.NewFileAsset(path, "/usr/bin", binary, "0755")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "new file asset")
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@ var vmProblems = map[string]match{
|
|||
Advice: "In some environments, this message is incorrect. Try 'minikube start --no-vtx-check'",
|
||||
Issues: []int{3900},
|
||||
},
|
||||
"VBOX_THIRD_PARTY": {
|
||||
Regexp: re(`The virtual machine * has terminated unexpectedly during startup with exit code 1`),
|
||||
Advice: "A third-party program may be interfering with VirtualBox. Try disabling any real-time antivirus software, reinstalling VirtualBox and rebooting.",
|
||||
Issues: []int{3910},
|
||||
},
|
||||
"KVM2_NOT_FOUND": {
|
||||
Regexp: re(`Driver "kvm2" not found. Do you have the plugin binary .* accessible in your PATH`),
|
||||
Advice: "Please install the minikube kvm2 VM driver, or select an alternative --vm-driver",
|
||||
|
@ -61,6 +66,11 @@ var vmProblems = map[string]match{
|
|||
Advice: "Disable Hyper-V when you want to run VirtualBox to boot the VM",
|
||||
Issues: []int{4051},
|
||||
},
|
||||
"HYPERV_NO_VSWITCH": {
|
||||
Regexp: re(`no External vswitch found. A valid vswitch must be available for this command to run.`),
|
||||
Advice: "Configure an external network switch following the official documentation, then add `--hyperv-virtual-switch=<switch-name>` to `minikube start`",
|
||||
URL: "https://docs.docker.com/machine/drivers/hyper-v/",
|
||||
},
|
||||
}
|
||||
|
||||
// proxyDoc is the URL to proxy documentation
|
||||
|
|
|
@ -27,6 +27,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/minikube/pkg/minikube/tunnel"
|
||||
|
@ -76,7 +78,7 @@ func testTunnel(t *testing.T) {
|
|||
t.Fatal(errors.Wrap(err, "waiting for nginx pods"))
|
||||
}
|
||||
|
||||
if err := commonutil.WaitForService(client, "default", "nginx-svc", true, time.Millisecond*500, time.Minute*10); err != nil {
|
||||
if err := commonutil.WaitForService(client, "default", "nginx-svc", true, 1*time.Second, 2*time.Minute); err != nil {
|
||||
t.Fatal(errors.Wrap(err, "Error waiting for nginx service to be up"))
|
||||
}
|
||||
|
||||
|
@ -84,18 +86,34 @@ func testTunnel(t *testing.T) {
|
|||
|
||||
nginxIP := ""
|
||||
|
||||
for i := 1; i < 3 && len(nginxIP) == 0; i++ {
|
||||
stdout, err := kubectlRunner.RunCommand([]string{"get", "svc", "nginx-svc", "-o", "jsonpath={.status.loadBalancer.ingress[0].ip}"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("error listing nginx service: %s", err)
|
||||
err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
|
||||
cmd := []string{"get", "svc", "nginx-svc", "-o", "jsonpath={.status.loadBalancer.ingress[0].ip}"}
|
||||
stdout, err := kubectlRunner.RunCommand(cmd)
|
||||
switch {
|
||||
case err == nil:
|
||||
nginxIP = string(stdout)
|
||||
return len(stdout) != 0, nil
|
||||
case !commonutil.IsRetryableAPIError(err):
|
||||
t.Errorf("`%s` failed with non retriable error: %v", cmd, err)
|
||||
return false, err
|
||||
default:
|
||||
t.Errorf("`%s` failed: %v", cmd, err)
|
||||
return false, nil
|
||||
}
|
||||
nginxIP = string(stdout)
|
||||
time.Sleep(1 * time.Second)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error getting ingress IP for nginx: %s", err)
|
||||
}
|
||||
|
||||
if len(nginxIP) == 0 {
|
||||
t.Fatal("svc should have ingress after tunnel is created, but it was empty!")
|
||||
stdout, err := kubectlRunner.RunCommand([]string{"get", "svc", "nginx-svc", "-o", "jsonpath={.status}"})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error debugging nginx service: %s", err)
|
||||
}
|
||||
|
||||
t.Fatalf("svc should have ingress after tunnel is created, but it was empty! Result of `kubectl describe svc nginx-svc`:\n %s", string(stdout))
|
||||
}
|
||||
|
||||
responseBody, err := getResponseBody(nginxIP)
|
||||
|
|
|
@ -66,7 +66,9 @@ func (w *CodeWriter) WriteGoFile(filename, pkg string) {
|
|||
func (w *CodeWriter) WriteVersionedGoFile(filename, pkg string) {
|
||||
tags := buildTags()
|
||||
if tags != "" {
|
||||
filename = insertVersion(filename, UnicodeVersion())
|
||||
pattern := fileToPattern(filename)
|
||||
updateBuildTags(pattern)
|
||||
filename = fmt.Sprintf(pattern, UnicodeVersion())
|
||||
}
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
|
@ -82,7 +84,9 @@ func (w *CodeWriter) WriteVersionedGoFile(filename, pkg string) {
|
|||
// writes it as a Go file to the given writer with the given package name.
|
||||
func (w *CodeWriter) WriteGo(out io.Writer, pkg, tags string) (n int, err error) {
|
||||
sz := w.Size
|
||||
w.WriteComment("Total table size %d bytes (%dKiB); checksum: %X\n", sz, sz/1024, w.Hash.Sum32())
|
||||
if sz > 0 {
|
||||
w.WriteComment("Total table size %d bytes (%dKiB); checksum: %X\n", sz, sz/1024, w.Hash.Sum32())
|
||||
}
|
||||
defer w.buf.Reset()
|
||||
return WriteGo(out, pkg, tags, w.buf.Bytes())
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
@ -83,25 +84,21 @@ func CLDRVersion() string {
|
|||
}
|
||||
|
||||
var tags = []struct{ version, buildTags string }{
|
||||
{"10.0.0", "go1.10"},
|
||||
{"", "!go1.10"},
|
||||
{"9.0.0", "!go1.10"},
|
||||
{"10.0.0", "go1.10,!go1.13"},
|
||||
{"11.0.0", "go1.13"},
|
||||
}
|
||||
|
||||
// buildTags reports the build tags used for the current Unicode version.
|
||||
func buildTags() string {
|
||||
v := UnicodeVersion()
|
||||
for _, x := range tags {
|
||||
// We should do a numeric comparison, but including the collate package
|
||||
// would create an import cycle. We approximate it by assuming that
|
||||
// longer version strings are later.
|
||||
if len(x.version) <= len(v) {
|
||||
return x.buildTags
|
||||
}
|
||||
if len(x.version) == len(v) && x.version <= v {
|
||||
return x.buildTags
|
||||
for _, e := range tags {
|
||||
if e.version == v {
|
||||
return e.buildTags
|
||||
}
|
||||
}
|
||||
return tags[0].buildTags
|
||||
log.Fatalf("Unknown build tags for Unicode version %q.", v)
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsLocal reports whether data files are available locally.
|
||||
|
@ -269,12 +266,29 @@ func WriteGoFile(filename, pkg string, b []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func insertVersion(filename, version string) string {
|
||||
func fileToPattern(filename string) string {
|
||||
suffix := ".go"
|
||||
if strings.HasSuffix(filename, "_test.go") {
|
||||
suffix = "_test.go"
|
||||
}
|
||||
return fmt.Sprint(filename[:len(filename)-len(suffix)], version, suffix)
|
||||
prefix := filename[:len(filename)-len(suffix)]
|
||||
return fmt.Sprint(prefix, "%s", suffix)
|
||||
}
|
||||
|
||||
func updateBuildTags(pattern string) {
|
||||
for _, t := range tags {
|
||||
oldFile := fmt.Sprintf(pattern, t.version)
|
||||
b, err := ioutil.ReadFile(oldFile)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
build := fmt.Sprintf("// +build %s", t.buildTags)
|
||||
b = regexp.MustCompile(`// \+build .*`).ReplaceAll(b, []byte(build))
|
||||
err = ioutil.WriteFile(oldFile, b, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WriteVersionedGoFile prepends a standard file comment, adds build tags to
|
||||
|
@ -282,16 +296,16 @@ func insertVersion(filename, version string) string {
|
|||
// the given bytes, applies gofmt, and writes them to a file with the given
|
||||
// name. It will call log.Fatal if there are any errors.
|
||||
func WriteVersionedGoFile(filename, pkg string, b []byte) {
|
||||
tags := buildTags()
|
||||
if tags != "" {
|
||||
filename = insertVersion(filename, UnicodeVersion())
|
||||
}
|
||||
pattern := fileToPattern(filename)
|
||||
updateBuildTags(pattern)
|
||||
filename = fmt.Sprintf(pattern, UnicodeVersion())
|
||||
|
||||
w, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file %s: %v", filename, err)
|
||||
}
|
||||
defer w.Close()
|
||||
if _, err = WriteGo(w, pkg, tags, b); err != nil {
|
||||
if _, err = WriteGo(w, pkg, buildTags(), b); err != nil {
|
||||
log.Fatalf("Error writing file %s: %v", filename, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,20 @@ package number
|
|||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[ToNearestEven-0]
|
||||
_ = x[ToNearestZero-1]
|
||||
_ = x[ToNearestAway-2]
|
||||
_ = x[ToPositiveInf-3]
|
||||
_ = x[ToNegativeInf-4]
|
||||
_ = x[ToZero-5]
|
||||
_ = x[AwayFromZero-6]
|
||||
_ = x[numModes-7]
|
||||
}
|
||||
|
||||
const _RoundingMode_name = "ToNearestEvenToNearestZeroToNearestAwayToPositiveInfToNegativeInfToZeroAwayFromZeronumModes"
|
||||
|
||||
var _RoundingMode_index = [...]uint8{0, 13, 26, 39, 52, 65, 71, 83, 91}
|
||||
|
|
|
@ -530,7 +530,7 @@ func (r Region) String() string {
|
|||
// Note that not all regions have a 3-letter ISO code.
|
||||
// In such cases this method returns "ZZZ".
|
||||
func (r Region) ISO3() string {
|
||||
return r.regionID.String()
|
||||
return r.regionID.ISO3()
|
||||
}
|
||||
|
||||
// M49 returns the UN M.49 encoding of r, or 0 if this encoding
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package number formats numbers according to the customs of different locales.
|
||||
//
|
||||
// The number formats of this package allow for greater formatting flexibility
|
||||
// than passing values to message.Printf calls as is. It currently supports the
|
||||
// builtin Go types and anything that implements the Convert interface
|
||||
// (currently internal).
|
||||
//
|
||||
// p := message.NewPrinter(language.English)
|
||||
//
|
||||
// p.Printf("%v bottles of beer on the wall.", number.Decimal(1234))
|
||||
// // Prints: 1,234 bottles of beer on the wall.
|
||||
//
|
||||
// p.Printf("%v of gophers lose too much fur", number.Percent(0.12))
|
||||
// // Prints: 12% of gophers lose too much fur.
|
||||
//
|
||||
// p := message.NewPrinter(language.Dutch)
|
||||
//
|
||||
// p.Printf("There are %v bikes per household.", number.Decimal(1.2))
|
||||
// // Prints: Er zijn 1,2 fietsen per huishouden.
|
||||
//
|
||||
//
|
||||
// The width and scale specified in the formatting directives override the
|
||||
// configuration of the formatter.
|
||||
package number
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package number
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/feature/plural"
|
||||
"golang.org/x/text/internal/format"
|
||||
"golang.org/x/text/internal/number"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// A FormatFunc formates a number.
|
||||
type FormatFunc func(x interface{}, opts ...Option) Formatter
|
||||
|
||||
// NewFormat creates a FormatFunc based on another FormatFunc and new options.
|
||||
// Use NewFormat to cash the creation of formatters.
|
||||
func NewFormat(format FormatFunc, opts ...Option) FormatFunc {
|
||||
o := *format(nil).options
|
||||
n := len(o.options)
|
||||
o.options = append(o.options[:n:n], opts...)
|
||||
return func(x interface{}, opts ...Option) Formatter {
|
||||
return newFormatter(&o, opts, x)
|
||||
}
|
||||
}
|
||||
|
||||
type options struct {
|
||||
verbs string
|
||||
initFunc initFunc
|
||||
options []Option
|
||||
pluralFunc func(t language.Tag, scale int) (f plural.Form, n int)
|
||||
}
|
||||
|
||||
type optionFlag uint16
|
||||
|
||||
const (
|
||||
hasScale optionFlag = 1 << iota
|
||||
hasPrecision
|
||||
noSeparator
|
||||
exact
|
||||
)
|
||||
|
||||
type initFunc func(f *number.Formatter, t language.Tag)
|
||||
|
||||
func newFormatter(o *options, opts []Option, value interface{}) Formatter {
|
||||
if len(opts) > 0 {
|
||||
n := *o
|
||||
n.options = opts
|
||||
o = &n
|
||||
}
|
||||
return Formatter{o, value}
|
||||
}
|
||||
|
||||
func newOptions(verbs string, f initFunc) *options {
|
||||
return &options{verbs: verbs, initFunc: f}
|
||||
}
|
||||
|
||||
type Formatter struct {
|
||||
*options
|
||||
value interface{}
|
||||
}
|
||||
|
||||
// Format implements format.Formatter. It is for internal use only for now.
|
||||
func (f Formatter) Format(state format.State, verb rune) {
|
||||
// TODO: consider implementing fmt.Formatter instead and using the following
|
||||
// piece of code. This allows numbers to be rendered mostly as expected
|
||||
// when using fmt. But it may get weird with the spellout options and we
|
||||
// may need more of format.State over time.
|
||||
// lang := language.Und
|
||||
// if s, ok := state.(format.State); ok {
|
||||
// lang = s.Language()
|
||||
// }
|
||||
|
||||
lang := state.Language()
|
||||
if !strings.Contains(f.verbs, string(verb)) {
|
||||
fmt.Fprintf(state, "%%!%s(%T=%v)", string(verb), f.value, f.value)
|
||||
return
|
||||
}
|
||||
var p number.Formatter
|
||||
f.initFunc(&p, lang)
|
||||
for _, o := range f.options.options {
|
||||
o(lang, &p)
|
||||
}
|
||||
if w, ok := state.Width(); ok {
|
||||
p.FormatWidth = uint16(w)
|
||||
}
|
||||
if prec, ok := state.Precision(); ok {
|
||||
switch verb {
|
||||
case 'd':
|
||||
p.SetScale(0)
|
||||
case 'f':
|
||||
p.SetScale(prec)
|
||||
case 'e':
|
||||
p.SetPrecision(prec + 1)
|
||||
case 'g':
|
||||
p.SetPrecision(prec)
|
||||
}
|
||||
}
|
||||
var d number.Decimal
|
||||
d.Convert(p.RoundingContext, f.value)
|
||||
state.Write(p.Format(nil, &d))
|
||||
}
|
||||
|
||||
// Digits returns information about which logical digits will be presented to
|
||||
// the user. This information is relevant, for instance, to determine plural
|
||||
// forms.
|
||||
func (f Formatter) Digits(buf []byte, tag language.Tag, scale int) number.Digits {
|
||||
var p number.Formatter
|
||||
f.initFunc(&p, tag)
|
||||
if scale >= 0 {
|
||||
// TODO: this only works well for decimal numbers, which is generally
|
||||
// fine.
|
||||
p.SetScale(scale)
|
||||
}
|
||||
var d number.Decimal
|
||||
d.Convert(p.RoundingContext, f.value)
|
||||
return number.FormatDigits(&d, p.RoundingContext)
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package number
|
||||
|
||||
// TODO:
|
||||
// p.Printf("The gauge was at %v.", number.Spell(number.Percent(23)))
|
||||
// // Prints: The gauge was at twenty-three percent.
|
||||
//
|
||||
// p.Printf("From here to %v!", number.Spell(math.Inf()))
|
||||
// // Prints: From here to infinity!
|
||||
//
|
||||
|
||||
import (
|
||||
"golang.org/x/text/internal/number"
|
||||
)
|
||||
|
||||
const (
|
||||
decimalVerbs = "vfgd"
|
||||
scientificVerbs = "veg"
|
||||
)
|
||||
|
||||
// Decimal formats a number as a floating point decimal.
|
||||
func Decimal(x interface{}, opts ...Option) Formatter {
|
||||
return newFormatter(decimalOptions, opts, x)
|
||||
}
|
||||
|
||||
var decimalOptions = newOptions(decimalVerbs, (*number.Formatter).InitDecimal)
|
||||
|
||||
// Scientific formats a number in scientific format.
|
||||
func Scientific(x interface{}, opts ...Option) Formatter {
|
||||
return newFormatter(scientificOptions, opts, x)
|
||||
}
|
||||
|
||||
var scientificOptions = newOptions(scientificVerbs, (*number.Formatter).InitScientific)
|
||||
|
||||
// Engineering formats a number using engineering notation, which is like
|
||||
// scientific notation, but with the exponent normalized to multiples of 3.
|
||||
func Engineering(x interface{}, opts ...Option) Formatter {
|
||||
return newFormatter(engineeringOptions, opts, x)
|
||||
}
|
||||
|
||||
var engineeringOptions = newOptions(scientificVerbs, (*number.Formatter).InitEngineering)
|
||||
|
||||
// Percent formats a number as a percentage. A value of 1.0 means 100%.
|
||||
func Percent(x interface{}, opts ...Option) Formatter {
|
||||
return newFormatter(percentOptions, opts, x)
|
||||
}
|
||||
|
||||
var percentOptions = newOptions(decimalVerbs, (*number.Formatter).InitPercent)
|
||||
|
||||
// PerMille formats a number as a per mille indication. A value of 1.0 means
|
||||
// 1000‰.
|
||||
func PerMille(x interface{}, opts ...Option) Formatter {
|
||||
return newFormatter(perMilleOptions, opts, x)
|
||||
}
|
||||
|
||||
var perMilleOptions = newOptions(decimalVerbs, (*number.Formatter).InitPerMille)
|
||||
|
||||
// TODO:
|
||||
// - Shortest: akin to verb 'g' of 'G'
|
||||
//
|
||||
// TODO: RBNF forms:
|
||||
// - Compact: 1M 3.5T
|
||||
// - CompactBinary: 1Mi 3.5Ti
|
||||
// - Long: 1 million
|
||||
// - Ordinal:
|
||||
// - Roman: MCMIIXX
|
||||
// - RomanSmall: mcmiixx
|
||||
// - Text: numbers as it typically appears in running text, allowing
|
||||
// language-specific choices for when to use numbers and when to use words.
|
||||
// - Spell?: spelled-out number. Maybe just allow as an option?
|
||||
|
||||
// NOTE: both spelled-out numbers and ordinals, to render correctly, need
|
||||
// detailed linguistic information from the translated string into which they
|
||||
// are substituted. We will need to implement that first.
|
|
@ -0,0 +1,177 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package number
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/text/internal/number"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// An Option configures a Formatter.
|
||||
type Option option
|
||||
|
||||
type option func(tag language.Tag, f *number.Formatter)
|
||||
|
||||
// TODO: SpellOut requires support of the ICU RBNF format.
|
||||
// func SpellOut() Option
|
||||
|
||||
// NoSeparator causes a number to be displayed without grouping separators.
|
||||
func NoSeparator() Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
f.GroupingSize = [2]uint8{}
|
||||
}
|
||||
}
|
||||
|
||||
// MaxIntegerDigits limits the number of integer digits, eliminating the
|
||||
// most significant digits.
|
||||
func MaxIntegerDigits(max int) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
if max >= 1<<8 {
|
||||
max = (1 << 8) - 1
|
||||
}
|
||||
f.MaxIntegerDigits = uint8(max)
|
||||
}
|
||||
}
|
||||
|
||||
// MinIntegerDigits specifies the minimum number of integer digits, adding
|
||||
// leading zeros when needed.
|
||||
func MinIntegerDigits(min int) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
if min >= 1<<8 {
|
||||
min = (1 << 8) - 1
|
||||
}
|
||||
f.MinIntegerDigits = uint8(min)
|
||||
}
|
||||
}
|
||||
|
||||
// MaxFractionDigits specifies the maximum number of fractional digits.
|
||||
func MaxFractionDigits(max int) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
if max >= 1<<15 {
|
||||
max = (1 << 15) - 1
|
||||
}
|
||||
f.MaxFractionDigits = int16(max)
|
||||
}
|
||||
}
|
||||
|
||||
// MinFractionDigits specifies the minimum number of fractional digits.
|
||||
func MinFractionDigits(min int) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
if min >= 1<<8 {
|
||||
min = (1 << 8) - 1
|
||||
}
|
||||
f.MinFractionDigits = uint8(min)
|
||||
}
|
||||
}
|
||||
|
||||
// Precision sets the maximum number of significant digits. A negative value
|
||||
// means exact.
|
||||
func Precision(prec int) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
f.SetPrecision(prec)
|
||||
}
|
||||
}
|
||||
|
||||
// Scale simultaneously sets MinFractionDigits and MaxFractionDigits to the
|
||||
// given value.
|
||||
func Scale(decimals int) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
f.SetScale(decimals)
|
||||
}
|
||||
}
|
||||
|
||||
// IncrementString sets the incremental value to which numbers should be
|
||||
// rounded. For instance: Increment("0.05") will cause 1.44 to round to 1.45.
|
||||
// IncrementString also sets scale to the scale of the increment.
|
||||
func IncrementString(decimal string) Option {
|
||||
increment := 0
|
||||
scale := 0
|
||||
d := decimal
|
||||
p := 0
|
||||
for ; p < len(d) && '0' <= d[p] && d[p] <= '9'; p++ {
|
||||
increment *= 10
|
||||
increment += int(d[p]) - '0'
|
||||
}
|
||||
if p < len(d) && d[p] == '.' {
|
||||
for p++; p < len(d) && '0' <= d[p] && d[p] <= '9'; p++ {
|
||||
increment *= 10
|
||||
increment += int(d[p]) - '0'
|
||||
scale++
|
||||
}
|
||||
}
|
||||
if p < len(d) {
|
||||
increment = 0
|
||||
scale = 0
|
||||
}
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
f.Increment = uint32(increment)
|
||||
f.IncrementScale = uint8(scale)
|
||||
f.SetScale(scale)
|
||||
}
|
||||
}
|
||||
|
||||
func noop(language.Tag, *number.Formatter) {}
|
||||
|
||||
// PatternOverrides allows users to specify alternative patterns for specific
|
||||
// languages. The Pattern will be overridden for all languages in a subgroup as
|
||||
// well. The function will panic for invalid input. It is best to create this
|
||||
// option at startup time.
|
||||
// PatternOverrides must be the first Option passed to a formatter.
|
||||
func PatternOverrides(patterns map[string]string) Option {
|
||||
// TODO: make it so that it does not have to be the first option.
|
||||
// TODO: use -x-nochild to indicate it does not override child tags.
|
||||
m := map[language.Tag]*number.Pattern{}
|
||||
for k, v := range patterns {
|
||||
tag := language.MustParse(k)
|
||||
p, err := number.ParsePattern(v)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("number: PatternOverrides: %v", err))
|
||||
}
|
||||
m[tag] = p
|
||||
}
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
// TODO: Use language grouping relation instead of parent relation.
|
||||
// TODO: Should parent implement the grouping relation?
|
||||
for lang := t; ; lang = t.Parent() {
|
||||
if p, ok := m[lang]; ok {
|
||||
f.Pattern = *p
|
||||
break
|
||||
}
|
||||
if lang == language.Und {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FormatWidth sets the total format width.
|
||||
func FormatWidth(n int) Option {
|
||||
if n <= 0 {
|
||||
return noop
|
||||
}
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
f.FormatWidth = uint16(n)
|
||||
if f.PadRune == 0 {
|
||||
f.PadRune = ' '
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pad sets the rune to be used for filling up to the format width.
|
||||
func Pad(r rune) Option {
|
||||
return func(t language.Tag, f *number.Formatter) {
|
||||
f.PadRune = r
|
||||
}
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - FormatPosition (using type aliasing?)
|
||||
// - Multiplier: find a better way to represent and figure out what to do
|
||||
// with clashes with percent/permille.
|
||||
// - NumberingSystem(nu string): not accessable in number.Info now. Also, should
|
||||
// this be keyed by language or generic?
|
||||
// - SymbolOverrides(symbols map[string]map[number.SymbolType]string) Option
|
|
@ -493,7 +493,7 @@ func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err erro
|
|||
return dstL.n, srcL.p, err
|
||||
}
|
||||
|
||||
// Deprecated: use runes.Remove instead.
|
||||
// Deprecated: Use runes.Remove instead.
|
||||
func RemoveFunc(f func(r rune) bool) Transformer {
|
||||
return removeF(f)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.10
|
||||
// +build go1.10,!go1.13
|
||||
|
||||
package bidi
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -96,7 +96,7 @@ func (cldr *CLDR) RawLDML(loc string) *LDML {
|
|||
// LDML returns the fully resolved LDML XML for loc, which must be one of
|
||||
// the strings returned by Locales.
|
||||
//
|
||||
// Deprecated: use RawLDML and implement inheritance manually or using the
|
||||
// Deprecated: Use RawLDML and implement inheritance manually or using the
|
||||
// internal cldrtree package.
|
||||
// Inheritance has changed quite a bit since the onset of this package and in
|
||||
// practice data often represented in a way where knowledge of how it was
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.10
|
||||
// +build go1.10,!go1.13
|
||||
|
||||
package norm
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.10
|
||||
// +build go1.10,!go1.13
|
||||
|
||||
package rangetable
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue