Rebased on master
commit
f92b308f9a
|
@ -9,12 +9,11 @@ env:
|
|||
- GOPROXY=https://proxy.golang.org
|
||||
matrix:
|
||||
include:
|
||||
- language: python
|
||||
name: Check Boilerplate
|
||||
- language: go
|
||||
name: Check Boilerplate
|
||||
go: 1.12.12
|
||||
env:
|
||||
- TESTSUITE=boilerplate
|
||||
before_install:
|
||||
- pip install flake8 && flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
script: make test
|
||||
|
||||
- language: go
|
||||
|
@ -36,6 +35,8 @@ matrix:
|
|||
script: make test
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
travisBuddy:
|
||||
regex: (FAIL:|\.go:\d+:|^panic:|failed$)
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
|
|
22
CHANGELOG.md
22
CHANGELOG.md
|
@ -1,5 +1,27 @@
|
|||
# Release Notes
|
||||
|
||||
## Version 1.5.0 - 2019-10-25
|
||||
|
||||
* Default to best-available local hypervisor rather than VirtualBox [#5700](https://github.com/kubernetes/minikube/pull/5700)
|
||||
* Update default Kubernetes version to v1.16.2 [#5731](https://github.com/kubernetes/minikube/pull/5731)
|
||||
* Add json output for status [#5611](https://github.com/kubernetes/minikube/pull/5611)
|
||||
* gvisor: Use chroot instead of LD_LIBRARY_PATH [#5735](https://github.com/kubernetes/minikube/pull/5735)
|
||||
* Hide innocuous viper ConfigFileNotFoundError [#5732](https://github.com/kubernetes/minikube/pull/5732)
|
||||
|
||||
Thank you to our contributors!
|
||||
|
||||
- Anders F Björklund
|
||||
- duohedron
|
||||
- Javis Zhou
|
||||
- Josh Woodcock
|
||||
- Kenta Iso
|
||||
- Marek Schwarz
|
||||
- Medya Ghazizadeh
|
||||
- Nanik T
|
||||
- Rob Bruce
|
||||
- Sharif Elgamal
|
||||
- Thomas Strömberg
|
||||
|
||||
## Version 1.5.0-beta.0 - 2019-10-21
|
||||
|
||||
* Fix node InternalIP not matching host-only address [#5427](https://github.com/kubernetes/minikube/pull/5427)
|
||||
|
|
14
Makefile
14
Makefile
|
@ -15,12 +15,12 @@
|
|||
# Bump these on release - and please check ISO_VERSION for correctness.
|
||||
VERSION_MAJOR ?= 1
|
||||
VERSION_MINOR ?= 5
|
||||
VERSION_BUILD ?= 0-beta.0
|
||||
VERSION_BUILD ?= 0
|
||||
RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).${VERSION_BUILD}
|
||||
VERSION ?= v$(RAW_VERSION)
|
||||
|
||||
# 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-beta.0
|
||||
ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0
|
||||
# Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta
|
||||
DEB_VERSION ?= $(subst -,~,$(RAW_VERSION))
|
||||
RPM_VERSION ?= $(DEB_VERSION)
|
||||
|
@ -51,7 +51,7 @@ MINIKUBE_RELEASES_URL=https://github.com/kubernetes/minikube/releases/download
|
|||
|
||||
KERNEL_VERSION ?= 4.19.76
|
||||
# latest from https://github.com/golangci/golangci-lint/releases
|
||||
GOLINT_VERSION ?= v1.20.0
|
||||
GOLINT_VERSION ?= v1.21.0
|
||||
# Limit number of default jobs, to avoid the CI builds running out of memory
|
||||
GOLINT_JOBS ?= 4
|
||||
# see https://github.com/golangci/golangci-lint#memory-usage-of-golangci-lint
|
||||
|
@ -59,9 +59,11 @@ GOLINT_GOGC ?= 100
|
|||
# options for lint (golangci-lint)
|
||||
GOLINT_OPTIONS = --timeout 4m \
|
||||
--build-tags "${MINIKUBE_INTEGRATION_BUILD_TAGS}" \
|
||||
--enable goimports,gocritic,golint,gocyclo,misspell,nakedret,stylecheck,unconvert,unparam \
|
||||
--enable goimports,gocritic,golint,gocyclo,misspell,nakedret,stylecheck,unconvert,unparam,dogsled \
|
||||
--exclude 'variable on range scope.*in function literal|ifElseChain'
|
||||
|
||||
# Major version of gvisor image. Increment when there are breaking changes.
|
||||
GVISOR_IMAGE_VERSION ?= 2
|
||||
|
||||
export GO111MODULE := on
|
||||
|
||||
|
@ -480,11 +482,11 @@ out/gvisor-addon: pkg/minikube/assets/assets.go pkg/minikube/translate/translati
|
|||
|
||||
.PHONY: gvisor-addon-image
|
||||
gvisor-addon-image: out/gvisor-addon
|
||||
docker build -t $(REGISTRY)/gvisor-addon:latest -f deploy/gvisor/Dockerfile .
|
||||
docker build -t $(REGISTRY)/gvisor-addon:$(GVISOR_IMAGE_VERSION) -f deploy/gvisor/Dockerfile .
|
||||
|
||||
.PHONY: push-gvisor-addon-image
|
||||
push-gvisor-addon-image: gvisor-addon-image
|
||||
gcloud docker -- push $(REGISTRY)/gvisor-addon:latest
|
||||
gcloud docker -- push $(REGISTRY)/gvisor-addon:$(GVISOR_IMAGE_VERSION)
|
||||
|
||||
.PHONY: release-iso
|
||||
release-iso: minikube_iso checksum
|
||||
|
|
|
@ -201,12 +201,6 @@ var settings = []Setting{
|
|||
validations: []setFn{IsValidAddon},
|
||||
callbacks: []setFn{EnableOrDisableAddon},
|
||||
},
|
||||
{
|
||||
name: "default-storageclass",
|
||||
set: SetBool,
|
||||
validations: []setFn{IsValidAddon},
|
||||
callbacks: []setFn{EnableOrDisableStorageClasses},
|
||||
},
|
||||
{
|
||||
name: "storage-provisioner",
|
||||
set: SetBool,
|
||||
|
|
|
@ -235,9 +235,11 @@ func initConfig() {
|
|||
configPath := localpath.ConfigFile
|
||||
viper.SetConfigFile(configPath)
|
||||
viper.SetConfigType("json")
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
glog.Warningf("Error reading config file at %s: %v", configPath, err)
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
// This config file is optional, so don't emit errors if missing
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
||||
glog.Warningf("Error reading config file at %s: %v", configPath, err)
|
||||
}
|
||||
}
|
||||
setupViper()
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ import (
|
|||
"k8s.io/minikube/pkg/minikube/notify"
|
||||
"k8s.io/minikube/pkg/minikube/out"
|
||||
"k8s.io/minikube/pkg/minikube/proxy"
|
||||
"k8s.io/minikube/pkg/minikube/translate"
|
||||
pkgutil "k8s.io/minikube/pkg/util"
|
||||
"k8s.io/minikube/pkg/util/lock"
|
||||
"k8s.io/minikube/pkg/util/retry"
|
||||
|
@ -194,7 +195,7 @@ func initKubernetesFlags() {
|
|||
|
||||
// initDriverFlags inits the commandline flags for vm drivers
|
||||
func initDriverFlags() {
|
||||
startCmd.Flags().String("vm-driver", "", fmt.Sprintf("Driver is one of: %v (defaults to %s)", driver.SupportedDrivers(), driver.Default()))
|
||||
startCmd.Flags().String("vm-driver", "", fmt.Sprintf("Driver is one of: %v (defaults to auto-detect)", driver.SupportedDrivers()))
|
||||
startCmd.Flags().Bool(disableDriverMounts, false, "Disables the filesystem mounts provided by the hypervisors")
|
||||
|
||||
// kvm2
|
||||
|
@ -289,6 +290,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
|
||||
driverName := selectDriver(oldConfig)
|
||||
glog.Infof("selected: %v", driverName)
|
||||
err = autoSetDriverOptions(cmd, driverName)
|
||||
if err != nil {
|
||||
glog.Errorf("Error autoSetOptions : %v", err)
|
||||
|
@ -297,11 +299,14 @@ func runStart(cmd *cobra.Command, args []string) {
|
|||
validateFlags(driverName)
|
||||
validateUser(driverName)
|
||||
|
||||
v, err := version.GetSemverVersion()
|
||||
if err != nil {
|
||||
out.WarningT("Error parsing minikube version: {{.error}}", out.V{"error": err})
|
||||
} else if err := driver.InstallOrUpdate(driverName, localpath.MakeMiniPath("bin"), v, viper.GetBool(interactive), viper.GetBool(autoUpdate)); err != nil {
|
||||
out.WarningT("Unable to update {{.driver}} driver: {{.error}}", out.V{"driver": driverName, "error": err})
|
||||
// No need to install a driver in download-only mode
|
||||
if !viper.GetBool(downloadOnly) {
|
||||
v, err := version.GetSemverVersion()
|
||||
if err != nil {
|
||||
out.WarningT("Error parsing minikube version: {{.error}}", out.V{"error": err})
|
||||
} else if err := driver.InstallOrUpdate(driverName, localpath.MakeMiniPath("bin"), v, viper.GetBool(interactive), viper.GetBool(autoUpdate)); err != nil {
|
||||
out.WarningT("Unable to update {{.driver}} driver: {{.error}}", out.V{"driver": driverName, "error": err})
|
||||
}
|
||||
}
|
||||
|
||||
k8sVersion, isUpgrade := getKubernetesVersion(oldConfig)
|
||||
|
@ -541,17 +546,41 @@ func showKubectlInfo(kcs *kubeconfig.Settings, k8sVersion string) error {
|
|||
|
||||
func selectDriver(oldConfig *cfg.Config) string {
|
||||
name := viper.GetString("vm-driver")
|
||||
// By default, the driver is whatever we used last time
|
||||
glog.Infof("selectDriver: flag=%q, old=%v", name, oldConfig)
|
||||
if name == "" {
|
||||
name = driver.Default()
|
||||
// By default, the driver is whatever we used last time
|
||||
if oldConfig != nil {
|
||||
return oldConfig.MachineConfig.VMDriver
|
||||
}
|
||||
options := driver.Choices()
|
||||
pick, alts := driver.Choose(options)
|
||||
if len(options) > 1 {
|
||||
out.T(out.Sparkle, `Automatically selected the '{{.driver}}' driver (alternates: {{.alternates}})`, out.V{"driver": pick.Name, "alternates": alts})
|
||||
} else {
|
||||
out.T(out.Sparkle, `Automatically selected the '{{.driver}}' driver`, out.V{"driver": pick.Name})
|
||||
}
|
||||
|
||||
if pick.Name == "" {
|
||||
exit.WithCodeT(exit.Config, "Unable to determine a default driver to use. Try specifying --vm-driver, or see https://minikube.sigs.k8s.io/docs/start/")
|
||||
}
|
||||
|
||||
name = pick.Name
|
||||
}
|
||||
if !driver.Supported(name) {
|
||||
exit.WithCodeT(exit.Failure, "The driver '{{.driver}}' is not supported on {{.os}}", out.V{"driver": name, "os": runtime.GOOS})
|
||||
}
|
||||
|
||||
st := driver.Status(name)
|
||||
if st.Error != nil {
|
||||
out.ErrLn("")
|
||||
out.WarningT("'{{.driver}}' driver reported a possible issue: {{.error}}", out.V{"driver": name, "error": st.Error, "fix": st.Fix})
|
||||
out.ErrT(out.Tip, "Suggestion: {{.fix}}", out.V{"fix": translate.T(st.Fix)})
|
||||
if st.Doc != "" {
|
||||
out.ErrT(out.Documentation, "Documentation: {{.url}}", out.V{"url": st.Doc})
|
||||
}
|
||||
out.ErrLn("")
|
||||
}
|
||||
|
||||
// Detect if our driver conflicts with a previously created VM. If we run into any errors, just move on.
|
||||
api, err := machine.NewAPIClient()
|
||||
if err != nil {
|
||||
|
|
|
@ -24,50 +24,28 @@ spec:
|
|||
hostPID: true
|
||||
containers:
|
||||
- name: gvisor
|
||||
image: {{default "gcr.io/k8s-minikube" .ImageRepository}}/gvisor-addon:latest
|
||||
image: {{default "gcr.io/k8s-minikube" .ImageRepository}}/gvisor-addon:2
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- mountPath: /node/
|
||||
name: node
|
||||
- mountPath: /usr/libexec/sudo
|
||||
name: sudo
|
||||
- mountPath: /var/run
|
||||
name: varrun
|
||||
- mountPath: /usr/bin
|
||||
name: usrbin
|
||||
- mountPath: /usr/lib
|
||||
name: usrlib
|
||||
- mountPath: /bin
|
||||
name: bin
|
||||
name: node-root
|
||||
- mountPath: /node/run
|
||||
name: node-run
|
||||
- mountPath: /tmp/gvisor
|
||||
name: gvisor
|
||||
name: node-tmp
|
||||
env:
|
||||
- name: PATH
|
||||
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/node/bin
|
||||
- name: SYSTEMD_IGNORE_CHROOT
|
||||
value: "yes"
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumes:
|
||||
- name: node
|
||||
- name: node-root
|
||||
hostPath:
|
||||
path: /
|
||||
- name: sudo
|
||||
- name: node-run
|
||||
hostPath:
|
||||
path: /usr/libexec/sudo
|
||||
- name: varrun
|
||||
hostPath:
|
||||
path: /var/run
|
||||
- name: usrlib
|
||||
hostPath:
|
||||
path: /usr/lib
|
||||
- name: usrbin
|
||||
hostPath:
|
||||
path: /usr/bin
|
||||
- name: bin
|
||||
hostPath:
|
||||
path: /bin
|
||||
- name: gvisor
|
||||
path: /run
|
||||
- name: node-tmp
|
||||
hostPath:
|
||||
path: /tmp/gvisor
|
||||
restartPolicy: Always
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{{ define "main" }}
|
||||
<div style="padding-top:20px">
|
||||
{{ .Render "content" }}
|
||||
</div>
|
||||
{{ end }}
|
|
@ -0,0 +1,5 @@
|
|||
{{ define "main" }}
|
||||
<div style="padding-top:20px">
|
||||
{{ .Render "content" }}
|
||||
</div>
|
||||
{{ end }}
|
|
@ -0,0 +1,5 @@
|
|||
{{ define "main" }}
|
||||
<div style="padding-top:60px">
|
||||
{{ .Render "content" }}
|
||||
</div>
|
||||
{{ end }}
|
|
@ -0,0 +1,5 @@
|
|||
{{ define "main" }}
|
||||
<div style="padding-top:20px">
|
||||
{{ .Render "content" }}
|
||||
</div>
|
||||
{{ end }}
|
|
@ -12,9 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM ubuntu:18.04
|
||||
RUN apt-get update && \
|
||||
apt-get install -y kmod gcc wget xz-utils libc6-dev bc libelf-dev bison flex openssl libssl-dev libidn2-0 sudo libcap2 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
# Need an image with chroot
|
||||
FROM alpine:3
|
||||
COPY out/gvisor-addon /gvisor-addon
|
||||
CMD ["/gvisor-addon"]
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
[
|
||||
{
|
||||
"name": "v1.5.0",
|
||||
"checksums": {
|
||||
"darwin": "eb716c176f404bb555966ff3947d5d9c5fb63eb902d11c83839fda492ff4b1fc",
|
||||
"linux": "ca50dcc7c83d4dde484d650a5a1934ea1bef692340af3aa831d34c6e847b2770",
|
||||
"windows": "bdd61e446f49570428848ad15337264edfecc55d1dd4aed4499d559f9c8383b9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "v1.4.0",
|
||||
"checksums": {
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
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 (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
boilerplatedir = flag.String("boilerplate-dir", ".", "Boilerplate directory for boilerplate files")
|
||||
rootdir = flag.String("rootdir", "../../", "Root directory to examine")
|
||||
verbose = flag.Bool("v", false, "Verbose")
|
||||
skippedPaths = regexp.MustCompile(`Godeps|third_party|_gopath|_output|\.git|cluster/env.sh|vendor|test/e2e/generated/bindata.go|site/themes/docsy`)
|
||||
windowdNewLine = regexp.MustCompile(`\r`)
|
||||
txtExtension = regexp.MustCompile(`\.txt`)
|
||||
goBuildTag = regexp.MustCompile(`(?m)^(// \+build.*\n)+\n`)
|
||||
shebang = regexp.MustCompile(`(?m)^(#!.*\n)\n*`)
|
||||
copyright = regexp.MustCompile(`Copyright YEAR`)
|
||||
copyrightReal = regexp.MustCompile(`Copyright \d{4}`)
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
refs, err := extensionToBoilerplate(*boilerplatedir)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if len(refs) == 0 {
|
||||
log.Fatal("no references in ", *boilerplatedir)
|
||||
}
|
||||
files, err := filesToCheck(*rootdir, refs)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, file := range files {
|
||||
pass, err := filePasses(file, refs[filepath.Ext(file)])
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if !pass {
|
||||
path, err := filepath.Abs(file)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
fmt.Println(path)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// extensionToBoilerplate returns a map of file extension to required boilerplate text.
|
||||
func extensionToBoilerplate(dir string) (map[string][]byte, error) {
|
||||
refs := make(map[string][]byte)
|
||||
files, _ := filepath.Glob(dir + "/*.txt")
|
||||
for _, filename := range files {
|
||||
extension := strings.ToLower(filepath.Ext(txtExtension.ReplaceAllString(filename, "")))
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refs[extension] = windowdNewLine.ReplaceAll(data, nil)
|
||||
}
|
||||
if *verbose {
|
||||
dir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return refs, err
|
||||
}
|
||||
fmt.Printf("Found %v boilerplates in %v for the following extensions:", len(refs), dir)
|
||||
for ext := range refs {
|
||||
fmt.Printf(" %v", ext)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
// filePasses checks whether the processed file is valid. Returning false means that the file does not the proper boilerplate template.
|
||||
func filePasses(filename string, expectedBoilerplate []byte) (bool, error) {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
data = windowdNewLine.ReplaceAll(data, nil)
|
||||
|
||||
extension := filepath.Ext(filename)
|
||||
|
||||
// remove build tags from the top of Go files
|
||||
if extension == ".go" {
|
||||
data = goBuildTag.ReplaceAll(data, nil)
|
||||
}
|
||||
|
||||
// remove shebang from the top of shell files
|
||||
if extension == ".sh" {
|
||||
data = shebang.ReplaceAll(data, nil)
|
||||
}
|
||||
|
||||
// if our test file is smaller than the reference it surely fails!
|
||||
if len(data) < len(expectedBoilerplate) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
data = data[:len(expectedBoilerplate)]
|
||||
|
||||
// Search for "Copyright YEAR" which exists in the boilerplate, but shouldn't in the real thing
|
||||
if copyright.Match(data) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Replace all occurrences of the regex "Copyright \d{4}" with "Copyright YEAR"
|
||||
data = copyrightReal.ReplaceAll(data, []byte(`Copyright YEAR`))
|
||||
|
||||
return bytes.Equal(data, expectedBoilerplate), nil
|
||||
}
|
||||
|
||||
// filesToCheck returns the list of the filers that will be checked for the boilerplate.
|
||||
func filesToCheck(rootDir string, extensions map[string][]byte) ([]string, error) {
|
||||
var outFiles []string
|
||||
err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
|
||||
// remove current workdir from the beginig of the path in case it matches the skipped path
|
||||
cwd, _ := os.Getwd()
|
||||
// replace "\" with "\\" for windows style path
|
||||
re := regexp.MustCompile(`\\`)
|
||||
re = regexp.MustCompile(`^` + re.ReplaceAllString(cwd, `\\`))
|
||||
if !info.IsDir() && !skippedPaths.MatchString(re.ReplaceAllString(filepath.Dir(path), "")) {
|
||||
if extensions[strings.ToLower(filepath.Ext(path))] != nil {
|
||||
outFiles = append(outFiles, path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if *verbose {
|
||||
rootDir, err = filepath.Abs(rootDir)
|
||||
if err != nil {
|
||||
return outFiles, err
|
||||
}
|
||||
fmt.Printf("Found %v files to check in %v\n\n", len(outFiles), rootDir)
|
||||
}
|
||||
return outFiles, nil
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2015 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 __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import json
|
||||
import mmap
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("filenames", help="list of files to check, all files if unspecified", nargs='*')
|
||||
|
||||
rootdir = os.path.dirname(__file__) + "/../../"
|
||||
rootdir = os.path.abspath(rootdir)
|
||||
parser.add_argument("--rootdir", default=rootdir, help="root directory to examine")
|
||||
|
||||
default_boilerplate_dir = os.path.join(rootdir, "hack/boilerplate")
|
||||
parser.add_argument("--boilerplate-dir", default=default_boilerplate_dir)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
def get_refs():
|
||||
refs = {}
|
||||
|
||||
for path in glob.glob(os.path.join(args.boilerplate_dir, "boilerplate.*.txt")):
|
||||
extension = os.path.basename(path).split(".")[1]
|
||||
|
||||
ref_file = open(path, 'r')
|
||||
ref = ref_file.read().splitlines()
|
||||
ref_file.close()
|
||||
refs[extension] = ref
|
||||
|
||||
return refs
|
||||
|
||||
def file_passes(filename, refs, regexs):
|
||||
try:
|
||||
f = open(filename, 'r')
|
||||
except:
|
||||
return False
|
||||
|
||||
data = f.read()
|
||||
f.close()
|
||||
|
||||
basename = os.path.basename(filename)
|
||||
extension = file_extension(filename)
|
||||
if extension != "":
|
||||
ref = refs[extension]
|
||||
else:
|
||||
ref = refs[basename]
|
||||
|
||||
# remove build tags from the top of Go files
|
||||
if extension == "go":
|
||||
p = regexs["go_build_constraints"]
|
||||
(data, found) = p.subn("", data, 1)
|
||||
|
||||
# remove shebang from the top of shell files
|
||||
if extension == "sh":
|
||||
p = regexs["shebang"]
|
||||
(data, found) = p.subn("", data, 1)
|
||||
|
||||
data = data.splitlines()
|
||||
|
||||
# if our test file is smaller than the reference it surely fails!
|
||||
if len(ref) > len(data):
|
||||
return False
|
||||
|
||||
# trim our file to the same number of lines as the reference file
|
||||
data = data[:len(ref)]
|
||||
|
||||
p = regexs["year"]
|
||||
for d in data:
|
||||
if p.search(d):
|
||||
return False
|
||||
|
||||
# Replace all occurrences of the regex "2018|2017|2016|2015|2014" with "YEAR"
|
||||
p = regexs["date"]
|
||||
for i, d in enumerate(data):
|
||||
(data[i], found) = p.subn('YEAR', d)
|
||||
if found != 0:
|
||||
break
|
||||
|
||||
# if we don't match the reference at this point, fail
|
||||
if ref != data:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def file_extension(filename):
|
||||
return os.path.splitext(filename)[1].split(".")[-1].lower()
|
||||
|
||||
skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', 'cluster/env.sh', "vendor", "test/e2e/generated/bindata.go"]
|
||||
|
||||
def normalize_files(files):
|
||||
newfiles = []
|
||||
for pathname in files:
|
||||
if any(x in pathname for x in skipped_dirs):
|
||||
continue
|
||||
newfiles.append(pathname)
|
||||
for i, pathname in enumerate(newfiles):
|
||||
if not os.path.isabs(pathname):
|
||||
newfiles[i] = os.path.join(rootdir, pathname)
|
||||
return newfiles
|
||||
|
||||
def get_files(extensions):
|
||||
files = []
|
||||
if len(args.filenames) > 0:
|
||||
files = args.filenames
|
||||
else:
|
||||
for root, dirs, walkfiles in os.walk(args.rootdir):
|
||||
# don't visit certain dirs. This is just a performance improvement
|
||||
# as we would prune these later in normalize_files(). But doing it
|
||||
# cuts down the amount of filesystem walking we do and cuts down
|
||||
# the size of the file list
|
||||
for d in skipped_dirs:
|
||||
if d in dirs:
|
||||
dirs.remove(d)
|
||||
|
||||
for name in walkfiles:
|
||||
pathname = os.path.join(root, name)
|
||||
files.append(pathname)
|
||||
|
||||
files = normalize_files(files)
|
||||
outfiles = []
|
||||
for pathname in files:
|
||||
basename = os.path.basename(pathname)
|
||||
extension = file_extension(pathname)
|
||||
if extension in extensions or basename in extensions:
|
||||
outfiles.append(pathname)
|
||||
return outfiles
|
||||
|
||||
def get_regexs():
|
||||
regexs = {}
|
||||
# Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing
|
||||
regexs["year"] = re.compile( 'YEAR' )
|
||||
# dates can be 2010 to 2039
|
||||
regexs["date"] = re.compile( '(20[123]\d)' )
|
||||
# strip // +build \n\n build constraints
|
||||
regexs["go_build_constraints"] = re.compile(r"^(// \+build.*\n)+\n", re.MULTILINE)
|
||||
# strip #!.* from shell scripts
|
||||
regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE)
|
||||
return regexs
|
||||
|
||||
def main():
|
||||
regexs = get_regexs()
|
||||
refs = get_refs()
|
||||
filenames = get_files(refs.keys())
|
||||
|
||||
for filename in filenames:
|
||||
if not file_passes(filename, refs, regexs):
|
||||
print(filename, file=sys.stdout)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
|
@ -21,7 +21,9 @@ function prepend() {
|
|||
local pattern=$1
|
||||
local ref=$2
|
||||
local headers=$3
|
||||
local files=$(hack/boilerplate/boilerplate.py --rootdir ${ROOT_DIR} | grep -v "$ignore" | grep "$pattern")
|
||||
pushd hack/boilerplate > /dev/null
|
||||
local files=$(go run boilerplate.go -rootdir ${ROOT_DIR} -boilerplate-dir ${ROOT_DIR}/hack/boilerplate | grep -v "$ignore" | grep "$pattern")
|
||||
popd > /dev/null
|
||||
for f in ${files}; do
|
||||
echo ${f};
|
||||
local copyright="$(cat hack/boilerplate/boilerplate.${ref}.txt | sed s/YEAR/$(date +%Y)/g)"
|
||||
|
|
|
@ -165,7 +165,7 @@ if type -P vboxmanage; then
|
|||
vboxmanage unregistervm "${guid}" || true
|
||||
done
|
||||
|
||||
ifaces=$(vboxmanage list hostonlyifs | grep -E "^Name:" | awk '{ printf $2 }')
|
||||
ifaces=$(vboxmanage list hostonlyifs | grep -E "^Name:" | awk '{ print $2 }')
|
||||
for if in $ifaces; do
|
||||
vboxmanage hostonlyif remove "${if}" || true
|
||||
done
|
||||
|
@ -245,22 +245,25 @@ mkdir -p "${TEST_HOME}"
|
|||
export MINIKUBE_HOME="${TEST_HOME}/.minikube"
|
||||
export KUBECONFIG="${TEST_HOME}/kubeconfig"
|
||||
|
||||
# Build the gvisor image. This will be copied into minikube and loaded by ctr.
|
||||
# Used by TestContainerd for Gvisor Test.
|
||||
# TODO: move this to integration test setup.
|
||||
|
||||
# Build the gvisor image so that we can integration test changes to pkg/gvisor
|
||||
chmod +x ./testdata/gvisor-addon
|
||||
# skipping gvisor mac because ofg https://github.com/kubernetes/minikube/issues/5137
|
||||
if [ "$(uname)" != "Darwin" ]; then
|
||||
docker build -t gcr.io/k8s-minikube/gvisor-addon:latest -f testdata/gvisor-addon-Dockerfile ./testdata
|
||||
# Should match GVISOR_IMAGE_VERSION in Makefile
|
||||
docker build -t gcr.io/k8s-minikube/gvisor-addon:2 -f testdata/gvisor-addon-Dockerfile ./testdata
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo ">> Starting ${E2E_BIN} at $(date)"
|
||||
set -x
|
||||
${SUDO_PREFIX}${E2E_BIN} \
|
||||
-minikube-start-args="--vm-driver=${VM_DRIVER} ${EXTRA_START_ARGS}" \
|
||||
-expected-default-driver="${EXPECTED_DEFAULT_DRIVER}" \
|
||||
-test.timeout=60m \
|
||||
-test.parallel=${PARALLEL_COUNT} \
|
||||
-binary="${MINIKUBE_BIN}" && result=$? || result=$?
|
||||
set +x
|
||||
echo ">> ${E2E_BIN} exited with ${result} at $(date)"
|
||||
echo ""
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ OS_ARCH="linux-amd64"
|
|||
VM_DRIVER="kvm2"
|
||||
JOB_NAME="KVM_Linux"
|
||||
PARALLEL_COUNT=4
|
||||
EXPECTED_DEFAULT_DRIVER="kvm2"
|
||||
|
||||
# Download files and set permissions
|
||||
source ./common.sh
|
||||
|
|
|
@ -31,6 +31,7 @@ VM_DRIVER="none"
|
|||
JOB_NAME="none_Linux"
|
||||
EXTRA_ARGS="--bootstrapper=kubeadm"
|
||||
PARALLEL_COUNT=1
|
||||
EXPECTED_DEFAULT_DRIVER="kvm2"
|
||||
|
||||
SUDO_PREFIX="sudo -E "
|
||||
export KUBECONFIG="/root/.kube/config"
|
||||
|
|
|
@ -29,6 +29,7 @@ OS_ARCH="linux-amd64"
|
|||
VM_DRIVER="virtualbox"
|
||||
JOB_NAME="VirtualBox_Linux"
|
||||
PARALLEL_COUNT=4
|
||||
EXPECTED_DEFAULT_DRIVER="kvm2"
|
||||
|
||||
# Download files and set permissions
|
||||
source ./common.sh
|
||||
|
|
|
@ -32,6 +32,8 @@ JOB_NAME="HyperKit_macOS"
|
|||
EXTRA_ARGS="--bootstrapper=kubeadm"
|
||||
EXTRA_START_ARGS=""
|
||||
PARALLEL_COUNT=3
|
||||
EXPECTED_DEFAULT_DRIVER="hyperkit"
|
||||
|
||||
|
||||
# Download files and set permissions
|
||||
source common.sh
|
||||
|
|
|
@ -30,6 +30,10 @@ VM_DRIVER="virtualbox"
|
|||
JOB_NAME="VirtualBox_macOS"
|
||||
EXTRA_ARGS="--bootstrapper=kubeadm"
|
||||
PARALLEL_COUNT=3
|
||||
# hyperkit behaves better, so it has higher precedence.
|
||||
# Assumes that hyperkit is also installed on the VirtualBox CI host.
|
||||
EXPECTED_DEFAULT_DRIVER="hyperkit"
|
||||
|
||||
|
||||
# Download files and set permissions
|
||||
source common.sh
|
||||
|
|
|
@ -19,7 +19,7 @@ gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/testdata .
|
|||
|
||||
./out/minikube-windows-amd64.exe delete
|
||||
|
||||
out/e2e-windows-amd64.exe -minikube-start-args="--vm-driver=hyperv --hyperv-virtual-switch=primary-virtual-switch" -binary=out/minikube-windows-amd64.exe -test.v -test.timeout=65m
|
||||
out/e2e-windows-amd64.exe --expected-default-driver=hyperv -minikube-start-args="--vm-driver=hyperv --hyperv-virtual-switch=primary-virtual-switch" -binary=out/minikube-windows-amd64.exe -test.v -test.timeout=65m
|
||||
$env:result=$lastexitcode
|
||||
# If the last exit code was 0->success, x>0->error
|
||||
If($env:result -eq 0){$env:status="success"}
|
||||
|
|
|
@ -19,7 +19,7 @@ gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/testdata .
|
|||
|
||||
./out/minikube-windows-amd64.exe delete
|
||||
|
||||
out/e2e-windows-amd64.exe -minikube-start-args="--vm-driver=virtualbox" -binary=out/minikube-windows-amd64.exe -test.v -test.timeout=30m
|
||||
out/e2e-windows-amd64.exe -minikube-start-args="--vm-driver=virtualbox" -expected-default-driver=hyperv -binary=out/minikube-windows-amd64.exe -test.v -test.timeout=30m
|
||||
$env:result=$lastexitcode
|
||||
# If the last exit code was 0->success, x>0->error
|
||||
If($env:result -eq 0){$env:status="success"}
|
||||
|
|
|
@ -4,7 +4,7 @@ publish = "site/public/"
|
|||
command = "pwd && cd themes/docsy && git submodule update -f --init && cd ../.. && hugo"
|
||||
|
||||
[build.environment]
|
||||
HUGO_VERSION = "0.55.6"
|
||||
HUGO_VERSION = "0.59.0"
|
||||
|
||||
[context.production.environment]
|
||||
HUGO_ENV = "production"
|
||||
|
|
|
@ -157,7 +157,7 @@ func copyConfigFiles() error {
|
|||
if err := mcnutils.CopyFile(filepath.Join(nodeDir, containerdConfigTomlPath), filepath.Join(nodeDir, storedContainerdConfigTomlPath)); err != nil {
|
||||
return errors.Wrap(err, "copying default config.toml")
|
||||
}
|
||||
log.Print("Copying containerd config.toml with gvisor...")
|
||||
log.Printf("Copying %s asset to %s", constants.GvisorConfigTomlTargetName, filepath.Join(nodeDir, containerdConfigTomlPath))
|
||||
if err := copyAssetToDest(constants.GvisorConfigTomlTargetName, filepath.Join(nodeDir, containerdConfigTomlPath)); err != nil {
|
||||
return errors.Wrap(err, "copying gvisor version of config.toml")
|
||||
}
|
||||
|
@ -171,8 +171,13 @@ func copyAssetToDest(targetName, dest string) error {
|
|||
asset = a
|
||||
}
|
||||
}
|
||||
if asset == nil {
|
||||
return fmt.Errorf("no asset matching target %s among %+v", targetName, assets.Addons["gvisor"])
|
||||
}
|
||||
|
||||
// Now, copy the data from this asset to dest
|
||||
src := filepath.Join(constants.GvisorFilesPath, asset.GetTargetName())
|
||||
log.Printf("%s asset path: %s", targetName, src)
|
||||
contents, err := ioutil.ReadFile(src)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "getting contents of %s", asset.GetAssetName())
|
||||
|
@ -182,6 +187,8 @@ func copyAssetToDest(targetName, dest string) error {
|
|||
return errors.Wrapf(err, "removing %s", dest)
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("creating %s", dest)
|
||||
f, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "creating %s", dest)
|
||||
|
@ -193,28 +200,24 @@ func copyAssetToDest(targetName, dest string) error {
|
|||
}
|
||||
|
||||
func restartContainerd() error {
|
||||
dir := filepath.Join(nodeDir, "usr/libexec/sudo")
|
||||
if err := os.Setenv("LD_LIBRARY_PATH", dir); err != nil {
|
||||
return errors.Wrap(err, dir)
|
||||
}
|
||||
log.Print("restartContainerd black magic happening")
|
||||
|
||||
log.Print("Stopping rpc-statd.service...")
|
||||
// first, stop rpc-statd.service
|
||||
cmd := exec.Command("sudo", "-E", "systemctl", "stop", "rpc-statd.service")
|
||||
cmd := exec.Command("/usr/sbin/chroot", "/node", "sudo", "systemctl", "stop", "rpc-statd.service")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
fmt.Println(string(out))
|
||||
return errors.Wrap(err, "stopping rpc-statd.service")
|
||||
}
|
||||
// restart containerd
|
||||
|
||||
log.Print("Restarting containerd...")
|
||||
cmd = exec.Command("sudo", "-E", "systemctl", "restart", "containerd")
|
||||
cmd = exec.Command("/usr/sbin/chroot", "/node", "sudo", "systemctl", "restart", "containerd")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
log.Print(string(out))
|
||||
return errors.Wrap(err, "restarting containerd")
|
||||
}
|
||||
// start rpc-statd.service
|
||||
|
||||
log.Print("Starting rpc-statd...")
|
||||
cmd = exec.Command("sudo", "-E", "systemctl", "start", "rpc-statd.service")
|
||||
cmd = exec.Command("/usr/sbin/chroot", "/node", "sudo", "systemctl", "start", "rpc-statd.service")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
log.Print(string(out))
|
||||
return errors.Wrap(err, "restarting rpc-statd.service")
|
||||
|
|
|
@ -66,7 +66,7 @@ Wants=crio.service
|
|||
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=/var/run/crio/crio.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.2/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=/var/run/crio/crio.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
|
||||
|
||||
[Install]
|
||||
`,
|
||||
|
@ -84,7 +84,7 @@ Wants=containerd.service
|
|||
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.2/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
|
||||
|
||||
[Install]
|
||||
`,
|
||||
|
@ -109,7 +109,7 @@ Wants=containerd.service
|
|||
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.200 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.2/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --fail-swap-on=false --hostname-override=minikube --image-service-endpoint=unix:///run/containerd/containerd.sock --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.200 --pod-manifest-path=/etc/kubernetes/manifests --runtime-request-timeout=15m
|
||||
|
||||
[Install]
|
||||
`,
|
||||
|
@ -128,7 +128,7 @@ Wants=docker.socket
|
|||
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.1/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-infra-container-image=docker-proxy-image.io/google_containers/pause:3.1 --pod-manifest-path=/etc/kubernetes/manifests
|
||||
ExecStart=/var/lib/minikube/binaries/v1.16.2/kubelet --authorization-mode=Webhook --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --cgroup-driver=cgroupfs --client-ca-file=/var/lib/minikube/certs/ca.crt --cluster-dns=10.96.0.10 --cluster-domain=cluster.local --container-runtime=docker --fail-swap-on=false --hostname-override=minikube --kubeconfig=/etc/kubernetes/kubelet.conf --node-ip=192.168.1.100 --pod-infra-container-image=docker-proxy-image.io/google_containers/pause:3.1 --pod-manifest-path=/etc/kubernetes/manifests
|
||||
|
||||
[Install]
|
||||
`,
|
||||
|
|
|
@ -433,15 +433,11 @@ func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error
|
|||
}
|
||||
}
|
||||
|
||||
def, err := registry.Driver(config.VMDriver)
|
||||
if err != nil {
|
||||
if err == registry.ErrDriverNotFound {
|
||||
return nil, fmt.Errorf("unsupported/missing driver: %s", config.VMDriver)
|
||||
}
|
||||
return nil, errors.Wrap(err, "error getting driver")
|
||||
def := registry.Driver(config.VMDriver)
|
||||
if def.Empty() {
|
||||
return nil, fmt.Errorf("unsupported/missing driver: %s", config.VMDriver)
|
||||
}
|
||||
|
||||
dd := def.ConfigCreator(config)
|
||||
dd := def.Config(config)
|
||||
data, err := json.Marshal(dd)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "marshal")
|
||||
|
|
|
@ -22,8 +22,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
// Register drivers
|
||||
_ "k8s.io/minikube/pkg/minikube/registry/drvs"
|
||||
// Driver used by testdata
|
||||
_ "k8s.io/minikube/pkg/minikube/registry/drvs/virtualbox"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/docker/machine/libmachine/host"
|
||||
|
@ -47,18 +47,13 @@ func createMockDriverHost(c config.MachineConfig) interface{} {
|
|||
|
||||
func RegisterMockDriver(t *testing.T) {
|
||||
t.Helper()
|
||||
_, err := registry.Driver(driver.Mock)
|
||||
// Already registered
|
||||
if err == nil {
|
||||
if !registry.Driver(driver.Mock).Empty() {
|
||||
return
|
||||
}
|
||||
err = registry.Register(registry.DriverDef{
|
||||
Name: driver.Mock,
|
||||
Builtin: true,
|
||||
ConfigCreator: createMockDriverHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return &tests.MockDriver{T: t}
|
||||
},
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: driver.Mock,
|
||||
Config: createMockDriverHost,
|
||||
Init: func() drivers.Driver { return &tests.MockDriver{T: t} },
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("register failed: %v", err)
|
||||
|
@ -103,7 +98,7 @@ func TestCreateHost(t *testing.T) {
|
|||
}
|
||||
|
||||
found := false
|
||||
for _, def := range registry.ListDrivers() {
|
||||
for _, def := range registry.List() {
|
||||
if h.DriverName == def.Name {
|
||||
found = true
|
||||
break
|
||||
|
@ -111,7 +106,7 @@ func TestCreateHost(t *testing.T) {
|
|||
}
|
||||
|
||||
if !found {
|
||||
t.Fatalf("Wrong driver name: %v. It should be among drivers %v", h.DriverName, registry.ListDrivers())
|
||||
t.Fatalf("Wrong driver name: %v. It should be among drivers %v", h.DriverName, registry.List())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@ import (
|
|||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
)
|
||||
|
||||
type configTestCase struct {
|
||||
|
@ -48,10 +46,10 @@ var configTestCases = []configTestCase{
|
|||
"log_dir": "/etc/hosts",
|
||||
"show-libmachine-logs": true,
|
||||
"v": 5,
|
||||
"vm-driver": "kvm2"
|
||||
"vm-driver": "test-driver"
|
||||
}`,
|
||||
config: map[string]interface{}{
|
||||
"vm-driver": driver.KVM2,
|
||||
"vm-driver": "test-driver",
|
||||
"cpus": 4,
|
||||
"disk-size": "20g",
|
||||
"v": 5,
|
||||
|
@ -132,7 +130,7 @@ func TestReadConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
expectedConfig := map[string]interface{}{
|
||||
"vm-driver": driver.KVM2,
|
||||
"vm-driver": "test-driver",
|
||||
"cpus": 4,
|
||||
"disk-size": "20g",
|
||||
"show-libmachine-logs": true,
|
||||
|
@ -151,7 +149,7 @@ func TestWriteConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
cfg := map[string]interface{}{
|
||||
"vm-driver": driver.KVM2,
|
||||
"vm-driver": "test-driver",
|
||||
"cpus": 4,
|
||||
"disk-size": "20g",
|
||||
"show-libmachine-logs": true,
|
||||
|
|
|
@ -44,7 +44,7 @@ func (p *Profile) IsValid() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// check if the profile is an internal keywords
|
||||
// ProfileNameInReservedKeywords checks if the profile is an internal keywords
|
||||
func ProfileNameInReservedKeywords(name string) bool {
|
||||
for _, v := range keywords {
|
||||
if strings.EqualFold(v, name) {
|
||||
|
|
|
@ -65,10 +65,10 @@ var DefaultISOURL = fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.i
|
|||
var DefaultISOSHAURL = DefaultISOURL + SHASuffix
|
||||
|
||||
// DefaultKubernetesVersion is the default kubernetes version
|
||||
var DefaultKubernetesVersion = "v1.16.1"
|
||||
var DefaultKubernetesVersion = "v1.16.2"
|
||||
|
||||
// NewestKubernetesVersion is the newest Kubernetes version to test against
|
||||
var NewestKubernetesVersion = "v1.16.1"
|
||||
var NewestKubernetesVersion = "v1.16.2"
|
||||
|
||||
// OldestKubernetesVersion is the oldest Kubernetes version to test against
|
||||
var OldestKubernetesVersion = "v1.11.10"
|
||||
|
|
|
@ -19,6 +19,10 @@ package driver
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -33,6 +37,11 @@ const (
|
|||
Parallels = "parallels"
|
||||
)
|
||||
|
||||
var (
|
||||
// systemdResolvConf is path to systemd's DNS configuration. https://github.com/kubernetes/minikube/issues/3511
|
||||
systemdResolvConf = "/run/systemd/resolve/resolv.conf"
|
||||
)
|
||||
|
||||
// SupportedDrivers returns a list of supported drivers
|
||||
func SupportedDrivers() []string {
|
||||
return supportedDrivers
|
||||
|
@ -62,14 +71,12 @@ type FlagHints struct {
|
|||
// FlagDefaults returns suggested defaults based on a driver
|
||||
func FlagDefaults(name string) FlagHints {
|
||||
if name != None {
|
||||
return FlagHints{}
|
||||
return FlagHints{CacheImages: true}
|
||||
}
|
||||
|
||||
// for more info see: https://github.com/kubernetes/minikube/issues/3511
|
||||
f := "/run/systemd/resolve/resolv.conf"
|
||||
extraOpts := ""
|
||||
if _, err := os.Stat(f); err == nil {
|
||||
extraOpts = fmt.Sprintf("kubelet.resolv-conf=%s", f)
|
||||
if _, err := os.Stat(systemdResolvConf); err == nil {
|
||||
extraOpts = fmt.Sprintf("kubelet.resolv-conf=%s", systemdResolvConf)
|
||||
}
|
||||
return FlagHints{
|
||||
ExtraOptions: extraOpts,
|
||||
|
@ -77,7 +84,50 @@ func FlagDefaults(name string) FlagHints {
|
|||
}
|
||||
}
|
||||
|
||||
// Default returns the default driver on this hos
|
||||
func Default() string {
|
||||
return VirtualBox
|
||||
// Choices returns a list of drivers which are possible on this system
|
||||
func Choices() []registry.DriverState {
|
||||
options := []registry.DriverState{}
|
||||
for _, ds := range registry.Installed() {
|
||||
if !ds.State.Healthy {
|
||||
glog.Warningf("%q is installed, but unhealthy: %v", ds.Name, ds.State.Error)
|
||||
continue
|
||||
}
|
||||
options = append(options, ds)
|
||||
}
|
||||
|
||||
// Descending priority for predictability and appearance
|
||||
sort.Slice(options, func(i, j int) bool {
|
||||
return options[i].Priority > options[j].Priority
|
||||
})
|
||||
return options
|
||||
}
|
||||
|
||||
// Choose returns a suggested driver from a set of options
|
||||
func Choose(options []registry.DriverState) (registry.DriverState, []registry.DriverState) {
|
||||
pick := registry.DriverState{}
|
||||
for _, ds := range options {
|
||||
if ds.Priority <= registry.Discouraged {
|
||||
glog.Infof("not recommending %q due to priority: %d", ds.Name, ds.Priority)
|
||||
continue
|
||||
}
|
||||
if ds.Priority > pick.Priority {
|
||||
glog.V(1).Infof("%q has a higher priority (%d) than %q (%d)", ds.Name, ds.Priority, pick.Name, pick.Priority)
|
||||
pick = ds
|
||||
}
|
||||
}
|
||||
|
||||
alternates := []registry.DriverState{}
|
||||
for _, ds := range options {
|
||||
if ds != pick {
|
||||
alternates = append(alternates, ds)
|
||||
}
|
||||
}
|
||||
glog.Infof("Picked: %+v", pick)
|
||||
glog.Infof("Alternatives: %+v", alternates)
|
||||
return pick, alternates
|
||||
}
|
||||
|
||||
// Status returns the status of a driver
|
||||
func Status(name string) registry.State {
|
||||
return registry.Status(name)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
Copyright 2018 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 driver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
)
|
||||
|
||||
func TestSupportedDrivers(t *testing.T) {
|
||||
got := SupportedDrivers()
|
||||
found := false
|
||||
for _, s := range SupportedDrivers() {
|
||||
if s == VirtualBox {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if found == false {
|
||||
t.Errorf("%s not in supported drivers: %v", VirtualBox, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSupported(t *testing.T) {
|
||||
if !Supported(VirtualBox) {
|
||||
t.Errorf("Supported(%s) is false", VirtualBox)
|
||||
}
|
||||
if Supported("yabba?") {
|
||||
t.Errorf("Supported(yabba?) is true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBareMetal(t *testing.T) {
|
||||
if !BareMetal(None) {
|
||||
t.Errorf("Supported(%s) is false", None)
|
||||
}
|
||||
if BareMetal(VirtualBox) {
|
||||
t.Errorf("Supported(%s) is true", VirtualBox)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagDefaults(t *testing.T) {
|
||||
expected := FlagHints{CacheImages: true}
|
||||
if diff := cmp.Diff(FlagDefaults(VirtualBox), expected); diff != "" {
|
||||
t.Errorf("defaults mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
|
||||
tf, err := ioutil.TempFile("", "resolv.conf")
|
||||
if err != nil {
|
||||
t.Fatalf("tempfile: %v", err)
|
||||
}
|
||||
defer os.Remove(tf.Name()) // clean up
|
||||
|
||||
expected = FlagHints{
|
||||
CacheImages: false,
|
||||
ExtraOptions: fmt.Sprintf("kubelet.resolv-conf=%s", tf.Name()),
|
||||
}
|
||||
systemdResolvConf = tf.Name()
|
||||
if diff := cmp.Diff(FlagDefaults(None), expected); diff != "" {
|
||||
t.Errorf("defaults mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChoices(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
def registry.DriverDef
|
||||
choices []string
|
||||
pick string
|
||||
alts []string
|
||||
}{
|
||||
{
|
||||
def: registry.DriverDef{
|
||||
Name: "unhealthy",
|
||||
Priority: registry.Default,
|
||||
Status: func() registry.State { return registry.State{Installed: true, Healthy: false} },
|
||||
},
|
||||
choices: []string{},
|
||||
pick: "",
|
||||
alts: []string{},
|
||||
},
|
||||
{
|
||||
def: registry.DriverDef{
|
||||
Name: "discouraged",
|
||||
Priority: registry.Discouraged,
|
||||
Status: func() registry.State { return registry.State{Installed: true, Healthy: true} },
|
||||
},
|
||||
choices: []string{"discouraged"},
|
||||
pick: "",
|
||||
alts: []string{"discouraged"},
|
||||
},
|
||||
{
|
||||
def: registry.DriverDef{
|
||||
Name: "default",
|
||||
Priority: registry.Default,
|
||||
Status: func() registry.State { return registry.State{Installed: true, Healthy: true} },
|
||||
},
|
||||
choices: []string{"default", "discouraged"},
|
||||
pick: "default",
|
||||
alts: []string{"discouraged"},
|
||||
},
|
||||
{
|
||||
def: registry.DriverDef{
|
||||
Name: "preferred",
|
||||
Priority: registry.Preferred,
|
||||
Status: func() registry.State { return registry.State{Installed: true, Healthy: true} },
|
||||
},
|
||||
choices: []string{"preferred", "default", "discouraged"},
|
||||
pick: "preferred",
|
||||
alts: []string{"default", "discouraged"},
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.def.Name, func(t *testing.T) {
|
||||
if err := registry.Register(tc.def); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
got := Choices()
|
||||
gotNames := []string{}
|
||||
for _, c := range got {
|
||||
gotNames = append(gotNames, c.Name)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(gotNames, tc.choices); diff != "" {
|
||||
t.Errorf("choices mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
|
||||
pick, alts := Choose(got)
|
||||
if pick.Name != tc.pick {
|
||||
t.Errorf("pick = %q, expected %q", pick.Name, tc.pick)
|
||||
}
|
||||
|
||||
gotAlts := []string{}
|
||||
for _, a := range alts {
|
||||
gotAlts = append(gotAlts, a.Name)
|
||||
}
|
||||
if diff := cmp.Diff(gotAlts, tc.alts); diff != "" {
|
||||
t.Errorf("alts mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
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 driver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExtractVMDriverVersion(t *testing.T) {
|
||||
v := extractVMDriverVersion("")
|
||||
if len(v) != 0 {
|
||||
t.Error("Expected empty string")
|
||||
}
|
||||
|
||||
v = extractVMDriverVersion("random text")
|
||||
if len(v) != 0 {
|
||||
t.Error("Expected empty string")
|
||||
}
|
||||
|
||||
expectedVersion := "1.2.3"
|
||||
|
||||
v = extractVMDriverVersion("version: v1.2.3")
|
||||
if expectedVersion != v {
|
||||
t.Errorf("Expected version: %s, got: %s", expectedVersion, v)
|
||||
}
|
||||
|
||||
v = extractVMDriverVersion("version: 1.2.3")
|
||||
if expectedVersion != v {
|
||||
t.Errorf("Expected version: %s, got: %s", expectedVersion, v)
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package machine
|
|||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -81,17 +82,15 @@ type LocalClient struct {
|
|||
|
||||
// NewHost creates a new Host
|
||||
func (api *LocalClient) NewHost(drvName string, rawDriver []byte) (*host.Host, error) {
|
||||
var def registry.DriverDef
|
||||
var err error
|
||||
if def, err = registry.Driver(drvName); err != nil {
|
||||
return nil, err
|
||||
} else if !def.Builtin || def.DriverCreator == nil {
|
||||
def := registry.Driver(drvName)
|
||||
if def.Empty() {
|
||||
return nil, fmt.Errorf("driver %q does not exist", drvName)
|
||||
}
|
||||
if def.Init == nil {
|
||||
return api.legacyClient.NewHost(drvName, rawDriver)
|
||||
}
|
||||
|
||||
d := def.DriverCreator()
|
||||
|
||||
err = json.Unmarshal(rawDriver, d)
|
||||
d := def.Init()
|
||||
err := json.Unmarshal(rawDriver, d)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error getting driver %s", string(rawDriver))
|
||||
}
|
||||
|
@ -127,14 +126,14 @@ func (api *LocalClient) Load(name string) (*host.Host, error) {
|
|||
return nil, errors.Wrapf(err, "filestore %q", name)
|
||||
}
|
||||
|
||||
var def registry.DriverDef
|
||||
if def, err = registry.Driver(h.DriverName); err != nil {
|
||||
return nil, err
|
||||
} else if !def.Builtin || def.DriverCreator == nil {
|
||||
def := registry.Driver(h.DriverName)
|
||||
if def.Empty() {
|
||||
return nil, fmt.Errorf("driver %q does not exist", h.DriverName)
|
||||
}
|
||||
if def.Init == nil {
|
||||
return api.legacyClient.Load(name)
|
||||
}
|
||||
|
||||
h.Driver = def.DriverCreator()
|
||||
h.Driver = def.Init()
|
||||
return h, json.Unmarshal(h.RawDriver, h.Driver)
|
||||
}
|
||||
|
||||
|
@ -163,9 +162,11 @@ func CommandRunner(h *host.Host) (command.Runner, error) {
|
|||
|
||||
// Create creates the host
|
||||
func (api *LocalClient) Create(h *host.Host) error {
|
||||
if def, err := registry.Driver(h.DriverName); err != nil {
|
||||
return err
|
||||
} else if !def.Builtin || def.DriverCreator == nil {
|
||||
def := registry.Driver(h.DriverName)
|
||||
if def.Empty() {
|
||||
return fmt.Errorf("driver %q does not exist", h.DriverName)
|
||||
}
|
||||
if def.Init == nil {
|
||||
return api.legacyClient.Create(h)
|
||||
}
|
||||
|
||||
|
@ -271,12 +272,9 @@ func (cg *CertGenerator) ValidateCertificate(addr string, authOptions *auth.Opti
|
|||
}
|
||||
|
||||
func registerDriver(drvName string) {
|
||||
def, err := registry.Driver(drvName)
|
||||
if err != nil {
|
||||
if err == registry.ErrDriverNotFound {
|
||||
exit.UsageT("unsupported or missing driver: {{.name}}", out.V{"name": drvName})
|
||||
}
|
||||
exit.WithError("error getting driver", err)
|
||||
def := registry.Driver(drvName)
|
||||
if def.Empty() {
|
||||
exit.UsageT("unsupported or missing driver: {{.name}}", out.V{"name": drvName})
|
||||
}
|
||||
plugin.RegisterDriver(def.DriverCreator())
|
||||
plugin.RegisterDriver(def.Init())
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ var styles = map[StyleEnum]style{
|
|||
Check: {Prefix: "✅ "},
|
||||
Celebration: {Prefix: "🎉 "},
|
||||
Workaround: {Prefix: "👉 ", LowPrefix: lowIndent},
|
||||
Sparkle: {Prefix: "✨ "},
|
||||
|
||||
// Specialized purpose styles
|
||||
ISODownload: {Prefix: "💿 "},
|
||||
|
|
|
@ -83,4 +83,5 @@ const (
|
|||
Fileserver
|
||||
Empty
|
||||
Workaround
|
||||
Sparkle
|
||||
)
|
||||
|
|
|
@ -20,30 +20,38 @@ package hyperkit
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/pborman/uuid"
|
||||
|
||||
"k8s.io/minikube/pkg/drivers/hyperkit"
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
)
|
||||
|
||||
const (
|
||||
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/hyperkit/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: driver.HyperKit,
|
||||
Builtin: false,
|
||||
ConfigCreator: createHyperkitHost,
|
||||
Name: driver.HyperKit,
|
||||
Config: configure,
|
||||
Status: status,
|
||||
Priority: registry.Preferred,
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createHyperkitHost(config cfg.MachineConfig) interface{} {
|
||||
uuID := config.UUID
|
||||
if uuID == "" {
|
||||
uuID = uuid.NewUUID().String()
|
||||
func configure(config cfg.MachineConfig) interface{} {
|
||||
u := config.UUID
|
||||
if u == "" {
|
||||
u = uuid.NewUUID().String()
|
||||
}
|
||||
|
||||
return &hyperkit.Driver{
|
||||
|
@ -58,9 +66,24 @@ func createHyperkitHost(config cfg.MachineConfig) interface{} {
|
|||
CPU: config.CPUs,
|
||||
NFSShares: config.NFSShare,
|
||||
NFSSharesRoot: config.NFSSharesRoot,
|
||||
UUID: uuID,
|
||||
UUID: u,
|
||||
VpnKitSock: config.HyperkitVpnKitSock,
|
||||
VSockPorts: config.HyperkitVSockPorts,
|
||||
Cmdline: "loglevel=3 console=ttyS0 console=tty0 noembed nomodeset norestore waitusb=10 systemd.legacy_systemd_cgroup_controller=yes random.trust_cpu=on hw_rng_model=virtio base host=" + cfg.GetMachineName(),
|
||||
}
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
path, err := exec.LookPath("hyperkit")
|
||||
if err != nil {
|
||||
return registry.State{Error: err, Fix: "Run 'brew install hyperkit'", Doc: docURL}
|
||||
}
|
||||
|
||||
cmd := exec.Command(path, "-v")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return registry.State{Installed: true, Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), out), Fix: "Run 'brew install hyperkit'", Doc: docURL}
|
||||
}
|
||||
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -19,28 +19,37 @@ limitations under the License.
|
|||
package hyperv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/machine/drivers/hyperv"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(registry.DriverDef{
|
||||
Name: driver.HyperV,
|
||||
Builtin: true,
|
||||
ConfigCreator: createHypervHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return hyperv.NewDriver("", "")
|
||||
},
|
||||
})
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: driver.HyperV,
|
||||
Init: func() drivers.Driver { return hyperv.NewDriver("", "") },
|
||||
Config: configure,
|
||||
Status: status,
|
||||
Priority: registry.Preferred,
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createHypervHost(config cfg.MachineConfig) interface{} {
|
||||
func configure(config cfg.MachineConfig) interface{} {
|
||||
d := hyperv.NewDriver(cfg.GetMachineName(), localpath.MiniPath())
|
||||
|
||||
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
|
||||
d.VSwitch = config.HypervVirtualSwitch
|
||||
d.MemSize = config.Memory
|
||||
|
@ -48,6 +57,19 @@ func createHypervHost(config cfg.MachineConfig) interface{} {
|
|||
d.DiskSize = config.DiskSize
|
||||
d.SSHUser = "docker"
|
||||
d.DisableDynamicMemory = true // default to disable dynamic memory as minikube is unlikely to work properly with dynamic memory
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
path, err := exec.LookPath("powershell")
|
||||
if err != nil {
|
||||
return registry.State{Error: err}
|
||||
}
|
||||
|
||||
cmd := exec.Command(path, "Get-WindowsOptionalFeature", "-FeatureName", "Microsoft-Hyper-V-All", "-Online")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return registry.State{Installed: false, Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), out), Fix: "Start PowerShell as Administrator, and run: 'Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All'", Doc: docURL}
|
||||
}
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -20,27 +20,34 @@ package kvm2
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/kvm2/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: driver.KVM2,
|
||||
Builtin: false,
|
||||
ConfigCreator: createKVM2Host,
|
||||
Name: driver.KVM2,
|
||||
Config: configure,
|
||||
Status: status,
|
||||
Priority: registry.Preferred,
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register failed: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// Delete this once the following PR is merged:
|
||||
// https://github.com/dhiltgen/docker-machine-kvm/pull/68
|
||||
// This is duplicate of kvm.Driver. Avoids importing the kvm2 driver, which requires cgo & libvirt.
|
||||
type kvmDriver struct {
|
||||
*drivers.BaseDriver
|
||||
|
||||
|
@ -57,9 +64,9 @@ type kvmDriver struct {
|
|||
ConnectionURI string
|
||||
}
|
||||
|
||||
func createKVM2Host(mc config.MachineConfig) interface{} {
|
||||
func configure(mc config.MachineConfig) interface{} {
|
||||
name := config.GetMachineName()
|
||||
return &kvmDriver{
|
||||
return kvmDriver{
|
||||
BaseDriver: &drivers.BaseDriver{
|
||||
MachineName: name,
|
||||
StorePath: localpath.MiniPath(),
|
||||
|
@ -78,3 +85,33 @@ func createKVM2Host(mc config.MachineConfig) interface{} {
|
|||
ConnectionURI: mc.KVMQemuURI,
|
||||
}
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
path, err := exec.LookPath("virsh")
|
||||
if err != nil {
|
||||
return registry.State{Error: err, Fix: "Install libvirt", Doc: docURL}
|
||||
}
|
||||
|
||||
cmd := exec.Command(path, "domcapabilities", "--virttype", "kvm")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return registry.State{
|
||||
Installed: true,
|
||||
Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out))),
|
||||
Fix: "Follow your Linux distribution instructions for configuring KVM",
|
||||
Doc: docURL,
|
||||
}
|
||||
}
|
||||
|
||||
cmd = exec.Command("virsh", "list")
|
||||
out, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return registry.State{
|
||||
Installed: true,
|
||||
Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), strings.TrimSpace(string(out))),
|
||||
Fix: "Check that libvirtd is properly installed and that you are a member of the appropriate libvirt group",
|
||||
Doc: docURL,
|
||||
}
|
||||
}
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors All rights reserved.
|
||||
|
||||
|
@ -18,6 +20,7 @@ package none
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"k8s.io/minikube/pkg/drivers/none"
|
||||
|
@ -29,22 +32,28 @@ import (
|
|||
|
||||
func init() {
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: driver.None,
|
||||
Builtin: true,
|
||||
ConfigCreator: createNoneHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return none.NewDriver(none.Config{})
|
||||
},
|
||||
Name: driver.None,
|
||||
Config: configure,
|
||||
Init: func() drivers.Driver { return none.NewDriver(none.Config{}) },
|
||||
Status: status,
|
||||
Priority: registry.Discouraged, // requires root
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register failed: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// createNoneHost creates a none Driver from a MachineConfig
|
||||
func createNoneHost(mc config.MachineConfig) interface{} {
|
||||
func configure(mc config.MachineConfig) interface{} {
|
||||
return none.NewDriver(none.Config{
|
||||
MachineName: config.GetMachineName(),
|
||||
StorePath: localpath.MiniPath(),
|
||||
ContainerRuntime: mc.ContainerRuntime,
|
||||
})
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
_, err := exec.LookPath("systemctl")
|
||||
if err != nil {
|
||||
return registry.State{Error: err, Fix: "Use a systemd based Linux distribution", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
|
||||
}
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -20,6 +20,7 @@ package parallels
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
parallels "github.com/Parallels/docker-machine-parallels"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
|
@ -31,12 +32,11 @@ import (
|
|||
|
||||
func init() {
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: driver.Parallels,
|
||||
Builtin: true,
|
||||
ConfigCreator: createParallelsHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return parallels.NewDriver("", "")
|
||||
},
|
||||
Name: driver.Parallels,
|
||||
Config: configure,
|
||||
Status: status,
|
||||
Priority: registry.Default,
|
||||
Init: func() drivers.Driver { return parallels.NewDriver("", "") },
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to register: %v", err))
|
||||
|
@ -44,7 +44,7 @@ func init() {
|
|||
|
||||
}
|
||||
|
||||
func createParallelsHost(config cfg.MachineConfig) interface{} {
|
||||
func configure(config cfg.MachineConfig) interface{} {
|
||||
d := parallels.NewDriver(cfg.GetMachineName(), localpath.MiniPath()).(*parallels.Driver)
|
||||
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
|
||||
d.Memory = config.Memory
|
||||
|
@ -52,3 +52,11 @@ func createParallelsHost(config cfg.MachineConfig) interface{} {
|
|||
d.DiskSize = config.DiskSize
|
||||
return d
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
_, err := exec.LookPath("docker-machine-driver-parallels")
|
||||
if err != nil {
|
||||
return registry.State{Error: err, Fix: "Install docker-machine-driver-parallels", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/parallels/"}
|
||||
}
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 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 virtualbox
|
|
@ -18,34 +18,38 @@ package virtualbox
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/machine/drivers/virtualbox"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
)
|
||||
|
||||
const defaultVirtualboxNicType = "virtio"
|
||||
const (
|
||||
defaultVirtualboxNicType = "virtio"
|
||||
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/virtualbox/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: driver.VirtualBox,
|
||||
Builtin: true,
|
||||
ConfigCreator: createVirtualboxHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return virtualbox.NewDriver("", "")
|
||||
},
|
||||
Name: driver.VirtualBox,
|
||||
Config: configure,
|
||||
Status: status,
|
||||
Priority: registry.Fallback,
|
||||
Init: func() drivers.Driver { return virtualbox.NewDriver("", "") },
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createVirtualboxHost(mc config.MachineConfig) interface{} {
|
||||
func configure(mc config.MachineConfig) interface{} {
|
||||
d := virtualbox.NewDriver(config.GetMachineName(), localpath.MiniPath())
|
||||
|
||||
d.Boot2DockerURL = mc.Downloader.GetISOFileURI(mc.MinikubeISO)
|
||||
d.Memory = mc.Memory
|
||||
d.CPU = mc.CPUs
|
||||
|
@ -57,6 +61,31 @@ func createVirtualboxHost(mc config.MachineConfig) interface{} {
|
|||
d.HostOnlyNicType = defaultVirtualboxNicType
|
||||
d.DNSProxy = mc.DNSProxy
|
||||
d.HostDNSResolver = mc.HostDNSResolver
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
// Re-use this function as it's particularly helpful for Windows
|
||||
tryPath := driver.VBoxManagePath()
|
||||
path, err := exec.LookPath(tryPath)
|
||||
if err != nil {
|
||||
return registry.State{
|
||||
Error: fmt.Errorf("unable to find VBoxManage in $PATH"),
|
||||
Fix: "Install VirtualBox",
|
||||
Doc: docURL,
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command(path, "list", "hostinfo")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return registry.State{
|
||||
Installed: true,
|
||||
Error: fmt.Errorf("%s failed:\n%s", strings.Join(cmd.Args, " "), out),
|
||||
Fix: "Install the latest version of VirtualBox",
|
||||
Doc: docURL,
|
||||
}
|
||||
}
|
||||
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -18,6 +18,7 @@ package vmware
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
vmwcfg "github.com/machine-drivers/docker-machine-driver-vmware/pkg/drivers/vmware/config"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
|
@ -28,16 +29,17 @@ import (
|
|||
|
||||
func init() {
|
||||
err := registry.Register(registry.DriverDef{
|
||||
Name: driver.VMware,
|
||||
Builtin: false,
|
||||
ConfigCreator: createVMwareHost,
|
||||
Name: driver.VMware,
|
||||
Config: configure,
|
||||
Priority: registry.Default,
|
||||
Status: status,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createVMwareHost(mc config.MachineConfig) interface{} {
|
||||
func configure(mc config.MachineConfig) interface{} {
|
||||
d := vmwcfg.NewConfig(config.GetMachineName(), localpath.MiniPath())
|
||||
d.Boot2DockerURL = mc.Downloader.GetISOFileURI(mc.MinikubeISO)
|
||||
d.Memory = mc.Memory
|
||||
|
@ -49,3 +51,15 @@ func createVMwareHost(mc config.MachineConfig) interface{} {
|
|||
d.ISO = d.ResolveStorePath("boot2docker.iso")
|
||||
return d
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
_, err := exec.LookPath("docker-machine-driver-vmware")
|
||||
if err != nil {
|
||||
return registry.State{Error: err, Fix: "Install docker-machine-driver-vmware", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/vmware/"}
|
||||
}
|
||||
_, err = exec.LookPath("vmrun")
|
||||
if err != nil {
|
||||
return registry.State{Error: err, Fix: "Install vmrun", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/vmware/"}
|
||||
}
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -20,30 +20,31 @@ package vmwarefusion
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/docker/machine/drivers/vmwarefusion"
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
cfg "k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
"k8s.io/minikube/pkg/minikube/registry"
|
||||
"k8s.io/minikube/pkg/minikube/driver"
|
||||
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := registry.Register(registry.DriverDef{
|
||||
Name: driver.VMwareFusion,
|
||||
Builtin: true,
|
||||
ConfigCreator: createVMwareFusionHost,
|
||||
DriverCreator: func() drivers.Driver {
|
||||
return vmwarefusion.NewDriver("", "")
|
||||
},
|
||||
Name: driver.VMwareFusion,
|
||||
Config: configure,
|
||||
Status: status,
|
||||
Init: func() drivers.Driver { return vmwarefusion.NewDriver("", "") },
|
||||
Priority: registry.Deprecated,
|
||||
}); err != nil {
|
||||
panic(fmt.Sprintf("register: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func createVMwareFusionHost(config cfg.MachineConfig) interface{} {
|
||||
func configure(config cfg.MachineConfig) interface{} {
|
||||
d := vmwarefusion.NewDriver(cfg.GetMachineName(), localpath.MiniPath()).(*vmwarefusion.Driver)
|
||||
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
|
||||
d.Memory = config.Memory
|
||||
|
@ -55,3 +56,11 @@ func createVMwareFusionHost(config cfg.MachineConfig) interface{} {
|
|||
d.ISO = d.ResolveStorePath("boot2docker.iso")
|
||||
return d
|
||||
}
|
||||
|
||||
func status() registry.State {
|
||||
_, err := exec.LookPath("vmrun")
|
||||
if err != nil {
|
||||
return registry.State{Error: errors.Wrap(err, "vmrun path check"), Fix: "Install VMWare Fusion", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/vmwarefusion/"}
|
||||
}
|
||||
return registry.State{Installed: true, Healthy: true}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright 2018 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 registry
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
var (
|
||||
// globalRegistry is a globally accessible driver registry
|
||||
globalRegistry = newRegistry()
|
||||
)
|
||||
|
||||
// DriverState is metadata relating to a driver and status
|
||||
type DriverState struct {
|
||||
Name string
|
||||
Priority Priority
|
||||
State State
|
||||
}
|
||||
|
||||
func (d DriverState) String() string {
|
||||
return d.Name
|
||||
}
|
||||
|
||||
// List lists drivers in global registry
|
||||
func List() []DriverDef {
|
||||
return globalRegistry.List()
|
||||
}
|
||||
|
||||
// Register registers driver with the global registry
|
||||
func Register(driver DriverDef) error {
|
||||
return globalRegistry.Register(driver)
|
||||
}
|
||||
|
||||
// Driver gets a named driver from the global registry
|
||||
func Driver(name string) DriverDef {
|
||||
return globalRegistry.Driver(name)
|
||||
}
|
||||
|
||||
// Installed returns a list of installed drivers in the global registry
|
||||
func Installed() []DriverState {
|
||||
sts := []DriverState{}
|
||||
glog.Infof("Querying for installed drivers using PATH=%s", os.Getenv("PATH"))
|
||||
|
||||
for _, d := range globalRegistry.List() {
|
||||
if d.Status == nil {
|
||||
glog.Errorf("%q does not implement Status", d.Name)
|
||||
continue
|
||||
}
|
||||
s := d.Status()
|
||||
glog.Infof("%s priority: %d, state: %+v", d.Name, d.Priority, s)
|
||||
|
||||
if !s.Installed {
|
||||
glog.Infof("%q not installed: %v", d.Name, s.Error)
|
||||
continue
|
||||
}
|
||||
sts = append(sts, DriverState{Name: d.Name, Priority: d.Priority, State: s})
|
||||
}
|
||||
return sts
|
||||
}
|
||||
|
||||
// Status returns the state of a driver within the global registry
|
||||
func Status(name string) State {
|
||||
d := globalRegistry.Driver(name)
|
||||
if d.Empty() {
|
||||
return State{}
|
||||
}
|
||||
return d.Status()
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright 2018 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 registry
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestGlobalRegister(t *testing.T) {
|
||||
globalRegistry = newRegistry()
|
||||
foo := DriverDef{Name: "foo"}
|
||||
if err := Register(foo); err != nil {
|
||||
t.Errorf("Register = %v, expected nil", err)
|
||||
}
|
||||
if err := Register(foo); err == nil {
|
||||
t.Errorf("Register = nil, expected duplicate err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalDriver(t *testing.T) {
|
||||
foo := DriverDef{Name: "foo"}
|
||||
globalRegistry = newRegistry()
|
||||
|
||||
if err := Register(foo); err != nil {
|
||||
t.Errorf("Register = %v, expected nil", err)
|
||||
}
|
||||
|
||||
d := Driver("foo")
|
||||
if d.Empty() {
|
||||
t.Errorf("driver.Empty = true, expected false")
|
||||
}
|
||||
|
||||
d = Driver("bar")
|
||||
if !d.Empty() {
|
||||
t.Errorf("driver.Empty = false, expected true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalList(t *testing.T) {
|
||||
foo := DriverDef{Name: "foo"}
|
||||
globalRegistry = newRegistry()
|
||||
if err := Register(foo); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(List(), []DriverDef{foo}); diff != "" {
|
||||
t.Errorf("list mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalInstalled(t *testing.T) {
|
||||
globalRegistry = newRegistry()
|
||||
|
||||
if err := Register(DriverDef{Name: "foo"}); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
bar := DriverDef{
|
||||
Name: "bar",
|
||||
Priority: Default,
|
||||
Status: func() State { return State{Installed: true} },
|
||||
}
|
||||
if err := Register(bar); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := []DriverState{
|
||||
DriverState{
|
||||
Name: "bar",
|
||||
Priority: Default,
|
||||
State: State{
|
||||
Installed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(Installed(), expected); diff != "" {
|
||||
t.Errorf("installed mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalStatus(t *testing.T) {
|
||||
globalRegistry = newRegistry()
|
||||
|
||||
if err := Register(DriverDef{Name: "foo"}); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
expected := State{Installed: true, Healthy: true}
|
||||
bar := DriverDef{
|
||||
Name: "bar",
|
||||
Priority: Default,
|
||||
Status: func() State { return expected },
|
||||
}
|
||||
if err := Register(bar); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(Status("bar"), expected); diff != "" {
|
||||
t.Errorf("status mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
|
@ -21,18 +21,21 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/docker/machine/libmachine/drivers"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrDriverNameExist is the error returned when trying to register a driver
|
||||
// which already exists in registry
|
||||
ErrDriverNameExist = errors.New("registry: duplicated driver name")
|
||||
// Priority is how we determine what driver to default to
|
||||
type Priority int
|
||||
|
||||
// ErrDriverNotFound is the error returned when driver of a given name does
|
||||
// not exist in registry
|
||||
ErrDriverNotFound = errors.New("registry: driver not found")
|
||||
const (
|
||||
Unknown Priority = iota
|
||||
Discouraged
|
||||
Deprecated
|
||||
Fallback
|
||||
Default
|
||||
Preferred
|
||||
StronglyPreferred
|
||||
)
|
||||
|
||||
// Registry contains all the supported driver definitions on the host
|
||||
|
@ -47,31 +50,49 @@ type Registry interface {
|
|||
List() []DriverDef
|
||||
}
|
||||
|
||||
// ConfigFactory is a function that creates a driver config from MachineConfig
|
||||
type ConfigFactory func(config.MachineConfig) interface{}
|
||||
// Configurator emits a struct to be marshalled into JSON for Machine Driver
|
||||
type Configurator func(config.MachineConfig) interface{}
|
||||
|
||||
// DriverFactory is a function that loads a byte stream and creates a driver.
|
||||
type DriverFactory func() drivers.Driver
|
||||
// Loader is a function that loads a byte stream and creates a driver.
|
||||
type Loader func() drivers.Driver
|
||||
|
||||
// DriverDef defines a machine driver metadata. It tells minikube how to initialize
|
||||
// and load drivers.
|
||||
// StatusChecker checks if a driver is available, offering a
|
||||
type StatusChecker func() State
|
||||
|
||||
// State is the current state of the driver and its dependencies
|
||||
type State struct {
|
||||
Installed bool
|
||||
Healthy bool
|
||||
Error error
|
||||
Fix string
|
||||
Doc string
|
||||
}
|
||||
|
||||
// DriverDef defines how to initialize and load a machine driver
|
||||
type DriverDef struct {
|
||||
// Name of the machine driver. It has to be unique.
|
||||
Name string
|
||||
|
||||
// BuiltIn indicates if the driver is builtin minikube binary, or the driver is
|
||||
// triggered through RPC.
|
||||
Builtin bool
|
||||
// Config is a function that emits a configured driver struct
|
||||
Config Configurator
|
||||
|
||||
// ConfigCreator generates a raw driver object by minikube's machine config.
|
||||
ConfigCreator ConfigFactory
|
||||
// Init is a function that initializes a machine driver, if built-in to the minikube binary
|
||||
Init Loader
|
||||
|
||||
// DriverCreator is the factory method that creates a machine driver instance.
|
||||
DriverCreator DriverFactory
|
||||
// Status returns the installation status of the driver
|
||||
Status StatusChecker
|
||||
|
||||
// Priority returns the prioritization for selecting a driver by default.
|
||||
Priority Priority
|
||||
}
|
||||
|
||||
// Empty returns true if the driver is nil
|
||||
func (d DriverDef) Empty() bool {
|
||||
return d.Name == ""
|
||||
}
|
||||
|
||||
func (d DriverDef) String() string {
|
||||
return fmt.Sprintf("{name: %s, builtin: %t}", d.Name, d.Builtin)
|
||||
return d.Name
|
||||
}
|
||||
|
||||
type driverRegistry struct {
|
||||
|
@ -79,43 +100,26 @@ type driverRegistry struct {
|
|||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func createRegistry() *driverRegistry {
|
||||
func newRegistry() *driverRegistry {
|
||||
return &driverRegistry{
|
||||
drivers: make(map[string]DriverDef),
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
registry = createRegistry()
|
||||
)
|
||||
|
||||
// ListDrivers lists all drivers in registry
|
||||
func ListDrivers() []DriverDef {
|
||||
return registry.List()
|
||||
}
|
||||
|
||||
// Register registers driver
|
||||
func Register(driver DriverDef) error {
|
||||
return registry.Register(driver)
|
||||
}
|
||||
|
||||
// Driver gets a named driver
|
||||
func Driver(name string) (DriverDef, error) {
|
||||
return registry.Driver(name)
|
||||
}
|
||||
|
||||
// Register registers a driver
|
||||
func (r *driverRegistry) Register(def DriverDef) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
if _, ok := r.drivers[def.Name]; ok {
|
||||
return ErrDriverNameExist
|
||||
return fmt.Errorf("%q is already registered: %+v", def.Name, def)
|
||||
}
|
||||
|
||||
r.drivers[def.Name] = def
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns a list of registered drivers
|
||||
func (r *driverRegistry) List() []DriverDef {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
@ -129,13 +133,9 @@ func (r *driverRegistry) List() []DriverDef {
|
|||
return result
|
||||
}
|
||||
|
||||
func (r *driverRegistry) Driver(name string) (DriverDef, error) {
|
||||
// Driver returns a driver given a name
|
||||
func (r *driverRegistry) Driver(name string) DriverDef {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
if driver, ok := r.drivers[name]; ok {
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
return DriverDef{}, ErrDriverNotFound
|
||||
return r.drivers[name]
|
||||
}
|
||||
|
|
|
@ -19,107 +19,47 @@ package registry
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestDriverString(t *testing.T) {
|
||||
bar := DriverDef{
|
||||
Name: "bar",
|
||||
Builtin: true,
|
||||
ConfigCreator: func(_ config.MachineConfig) interface{} {
|
||||
return nil
|
||||
},
|
||||
func TestRegister(t *testing.T) {
|
||||
r := newRegistry()
|
||||
foo := DriverDef{Name: "foo"}
|
||||
if err := r.Register(foo); err != nil {
|
||||
t.Errorf("Register = %v, expected nil", err)
|
||||
}
|
||||
s := bar.String()
|
||||
if s != "{name: bar, builtin: true}" {
|
||||
t.Fatalf("Driver bar.String() returned unexpected: %v", s)
|
||||
if err := r.Register(foo); err == nil {
|
||||
t.Errorf("Register = nil, expected duplicate err")
|
||||
}
|
||||
}
|
||||
|
||||
func testDriver(name string) DriverDef {
|
||||
return DriverDef{
|
||||
Name: name,
|
||||
Builtin: true,
|
||||
ConfigCreator: func(_ config.MachineConfig) interface{} {
|
||||
return nil
|
||||
},
|
||||
func TestDriver(t *testing.T) {
|
||||
foo := DriverDef{Name: "foo"}
|
||||
r := newRegistry()
|
||||
|
||||
if err := r.Register(foo); err != nil {
|
||||
t.Errorf("Register = %v, expected nil", err)
|
||||
}
|
||||
|
||||
d := r.Driver("foo")
|
||||
if d.Empty() {
|
||||
t.Errorf("driver.Empty = true, expected false")
|
||||
}
|
||||
|
||||
d = r.Driver("bar")
|
||||
if !d.Empty() {
|
||||
t.Errorf("driver.Empty = false, expected true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegistry1(t *testing.T) {
|
||||
foo := testDriver("foo")
|
||||
bar := testDriver("bar")
|
||||
func TestList(t *testing.T) {
|
||||
foo := DriverDef{Name: "foo"}
|
||||
r := newRegistry()
|
||||
if err := r.Register(foo); err != nil {
|
||||
t.Errorf("register returned error: %v", err)
|
||||
}
|
||||
|
||||
registry := createRegistry()
|
||||
t.Run("registry.Register", func(t *testing.T) {
|
||||
t.Run("foo", func(t *testing.T) {
|
||||
if err := registry.Register(foo); err != nil {
|
||||
t.Fatalf("error not expected but got %v", err)
|
||||
}
|
||||
})
|
||||
t.Run("fooAlreadyExist", func(t *testing.T) {
|
||||
if err := registry.Register(foo); err != ErrDriverNameExist {
|
||||
t.Fatalf("expect ErrDriverNameExist but got: %v", err)
|
||||
}
|
||||
})
|
||||
t.Run("bar", func(t *testing.T) {
|
||||
if err := registry.Register(bar); err != nil {
|
||||
t.Fatalf("error not expect but got: %v", err)
|
||||
}
|
||||
})
|
||||
})
|
||||
t.Run("registry.List", func(t *testing.T) {
|
||||
list := registry.List()
|
||||
if !(list[0].Name == "bar" && list[1].Name == "foo" ||
|
||||
list[0].Name == "foo" && list[1].Name == "bar") {
|
||||
t.Fatalf("expect registry.List return %s; got %s", []string{"bar", "foo"}, list)
|
||||
}
|
||||
if drivers := ListDrivers(); len(list) == len(drivers) {
|
||||
t.Fatalf("Expectect ListDrivers and registry.List() to return same number of items, but got: drivers=%v and list=%v", drivers, list)
|
||||
} else if len(list) == len(drivers) {
|
||||
t.Fatalf("expect len(list) to be %d; got %d", 2, len(list))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegistry2(t *testing.T) {
|
||||
foo := testDriver("foo")
|
||||
bar := testDriver("bar")
|
||||
|
||||
registry := createRegistry()
|
||||
if err := registry.Register(foo); err != nil {
|
||||
t.Skipf("error not expect but got: %v", err)
|
||||
}
|
||||
if err := registry.Register(bar); err != nil {
|
||||
t.Skipf("error not expect but got: %v", err)
|
||||
}
|
||||
t.Run("Driver", func(t *testing.T) {
|
||||
name := "foo"
|
||||
d, err := registry.Driver(name)
|
||||
if err != nil {
|
||||
t.Fatalf("expect nil for registering foo driver, but got: %v", err)
|
||||
}
|
||||
if d.Name != name {
|
||||
t.Fatalf("expect registry.Driver(%s) returns registered driver, but got: %s", name, d.Name)
|
||||
}
|
||||
})
|
||||
t.Run("NotExistingDriver", func(t *testing.T) {
|
||||
_, err := registry.Driver("foo2")
|
||||
if err != ErrDriverNotFound {
|
||||
t.Fatalf("expect ErrDriverNotFound bug got: %v", err)
|
||||
}
|
||||
})
|
||||
t.Run("Driver", func(t *testing.T) {
|
||||
if _, err := Driver("no_such_driver"); err == nil {
|
||||
t.Fatal("expect to get error for not existing driver")
|
||||
}
|
||||
})
|
||||
if _, err := Driver("foo"); err == nil {
|
||||
t.Fatal("expect to not get error during existing driver foo")
|
||||
}
|
||||
t.Run("Register", func(t *testing.T) {
|
||||
if err := Register(foo); err != nil {
|
||||
t.Fatalf("expect to not get error during registering driver foo, but got: %v", err)
|
||||
}
|
||||
})
|
||||
if diff := cmp.Diff(r.List(), []DriverDef{foo}); diff != "" {
|
||||
t.Errorf("list mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ theme = ["docsy"]
|
|||
enableGitInfo = true
|
||||
|
||||
# Language settings
|
||||
contentDir = "content/en"
|
||||
contentDir = "content/en"
|
||||
defaultContentLanguage = "en"
|
||||
defaultContentLanguageInSubdir = false
|
||||
# Useful when translating.
|
||||
|
@ -33,6 +33,30 @@ pygmentsStyle = "tango"
|
|||
[permalinks]
|
||||
blog = "/:section/:year/:month/:day/:slug/"
|
||||
|
||||
[module]
|
||||
[[module.mounts]]
|
||||
source = "../deploy/addons/gvisor/"
|
||||
target = "content/gvisor/"
|
||||
[[module.mounts]]
|
||||
source = "../deploy/addons/helm-tiller/"
|
||||
target = "content/helm-tiller/"
|
||||
[[module.mounts]]
|
||||
source = "../deploy/addons/ingress-dns/"
|
||||
target = "content/ingress-dns/"
|
||||
[[module.mounts]]
|
||||
source = "../deploy/addons/storage-provisioner-gluster/"
|
||||
target = "content/storage-provisioner-gluster/"
|
||||
[[module.mounts]]
|
||||
source = "../deploy/addons/layouts/"
|
||||
target = "layouts"
|
||||
|
||||
[[module.mounts]]
|
||||
source = "content/en"
|
||||
target = "content"
|
||||
[[module.mounts]]
|
||||
source = "layouts"
|
||||
target = "layouts"
|
||||
|
||||
## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
|
||||
[blackfriday]
|
||||
plainIDAnchors = true
|
||||
|
@ -68,7 +92,7 @@ weight = 1
|
|||
[params]
|
||||
copyright = "The Kubernetes Authors -- "
|
||||
# The latest release of minikube
|
||||
latest_release = "1.4.0"
|
||||
latest_release = "1.5.0"
|
||||
|
||||
privacy_policy = ""
|
||||
|
||||
|
|
|
@ -39,3 +39,7 @@ Stop your local cluster:
|
|||
Delete your local cluster:
|
||||
|
||||
`minikube delete`
|
||||
|
||||
Delete all local clusters and profiles
|
||||
|
||||
`minikube delete --all`
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## Usage
|
||||
|
||||
minikube currently uses VirtualBox by default, but it can also be explicitly set:
|
||||
Start a cluster using the virtualbox driver:
|
||||
|
||||
```shell
|
||||
minikube start --vm-driver=virtualbox
|
||||
|
|
|
@ -20,10 +20,10 @@ minikube has a set of built-in addons that, when enabled, can be used within Kub
|
|||
* [nvidia-driver-installer](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/nvidia-driver-installer/minikube)
|
||||
* [nvidia-gpu-device-plugin](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu)
|
||||
* [logviewer](https://github.com/ivans3/minikube-log-viewer)
|
||||
* [gvisor](../deploy/addons/gvisor/README.md)
|
||||
* [storage-provisioner-gluster](../deploy/addons/storage-provisioner-gluster/README.md)
|
||||
* [helm-tiller](../deploy/addons/helm-tiller/README.md)
|
||||
* [ingress-dns](../deploy/addons/ingress-dns/README.md)
|
||||
* [gvisor](../../../gvisor/readme/)
|
||||
* [storage-provisioner-gluster](../../../storage-provisioner-gluster/readme)
|
||||
* [helm-tiller](../../../helm-tiller/readme)
|
||||
* [ingress-dns](../../../ingress-dns/readme)
|
||||
|
||||
## Listing available addons
|
||||
|
||||
|
|
9
test.sh
9
test.sh
|
@ -33,9 +33,11 @@ fi
|
|||
if [[ "$TESTSUITE" = "boilerplate" ]] || [[ "$TESTSUITE" = "all" ]]
|
||||
then
|
||||
echo "= boilerplate ==========================================================="
|
||||
readonly PYTHON=$(type -P python || echo docker run --rm -it -v $(pwd):/minikube -w /minikube python python)
|
||||
readonly BDIR="./hack/boilerplate"
|
||||
missing="$($PYTHON ${BDIR}/boilerplate.py --rootdir . --boilerplate-dir ${BDIR} | egrep -v '/assets.go|/translations.go|/site/themes/|/site/node_modules|\./out|/hugo/' || true)"
|
||||
readonly ROOT_DIR=$(pwd)
|
||||
readonly BDIR="${ROOT_DIR}/hack/boilerplate"
|
||||
pushd . >/dev/null
|
||||
cd ${BDIR}
|
||||
missing="$(go run boilerplate.go -rootdir ${ROOT_DIR} -boilerplate-dir ${BDIR} | egrep -v '/assets.go|/translations.go|/site/themes/|/site/node_modules|\./out|/hugo/' || true)"
|
||||
if [[ -n "${missing}" ]]; then
|
||||
echo "boilerplate missing: $missing"
|
||||
echo "consider running: ${BDIR}/fix.sh"
|
||||
|
@ -43,6 +45,7 @@ then
|
|||
else
|
||||
echo "ok"
|
||||
fi
|
||||
popd >/dev/null
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ To run all tests from the minikube root directory:
|
|||
|
||||
Run a single test on an active cluster:
|
||||
|
||||
`make integration -e TEST_ARGS="-test.v -test.run TestFunctional/parallel/MountCmd --profile=minikube --cleanup=false"`
|
||||
`make integration -e TEST_ARGS="-test.run TestFunctional/parallel/MountCmd --profile=minikube --cleanup=false"`
|
||||
|
||||
WARNING: For this to work repeatedly, the test must be written so that it cleans up after itself.
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package integration
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -29,15 +30,20 @@ import (
|
|||
"time"
|
||||
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
|
||||
"k8s.io/minikube/pkg/minikube/config"
|
||||
"k8s.io/minikube/pkg/minikube/constants"
|
||||
"k8s.io/minikube/pkg/minikube/localpath"
|
||||
)
|
||||
|
||||
func TestDownloadAndDeleteAll(t *testing.T) {
|
||||
func TestDownloadOnly(t *testing.T) {
|
||||
profile := UniqueProfileName("download")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer Cleanup(t, profile, cancel)
|
||||
|
||||
// Stores the startup run result for later error messages
|
||||
var rrr *RunResult
|
||||
var err error
|
||||
|
||||
t.Run("group", func(t *testing.T) {
|
||||
versions := []string{
|
||||
constants.OldestKubernetesVersion,
|
||||
|
@ -46,22 +52,28 @@ func TestDownloadAndDeleteAll(t *testing.T) {
|
|||
}
|
||||
for _, v := range versions {
|
||||
t.Run(v, func(t *testing.T) {
|
||||
args := append([]string{"start", "--download-only", "-p", profile, fmt.Sprintf("--kubernetes-version=%s", v)}, StartArgs()...)
|
||||
_, err := Run(t, exec.CommandContext(ctx, Target(), args...))
|
||||
// Explicitly does not pass StartArgs() to test driver default
|
||||
// --force to avoid uid check
|
||||
args := []string{"start", "--download-only", "-p", profile, "--force", "--alsologtostderr", fmt.Sprintf("--kubernetes-version=%s", v)}
|
||||
|
||||
// Preserve the initial run-result for debugging
|
||||
if rrr == nil {
|
||||
rrr, err = Run(t, exec.CommandContext(ctx, Target(), args...))
|
||||
} else {
|
||||
_, err = Run(t, exec.CommandContext(ctx, Target(), args...))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%s failed: %v", args, err)
|
||||
}
|
||||
|
||||
// None driver does not cache images, so this test will fail
|
||||
if !NoneDriver() {
|
||||
imgs := images.CachedImages("", v)
|
||||
for _, img := range imgs {
|
||||
img = strings.Replace(img, ":", "_", 1) // for example kube-scheduler:v1.15.2 --> kube-scheduler_v1.15.2
|
||||
fp := filepath.Join(localpath.MiniPath(), "cache", "images", img)
|
||||
_, err := os.Stat(fp)
|
||||
if err != nil {
|
||||
t.Errorf("expected image file exist at %q but got error: %v", fp, err)
|
||||
}
|
||||
imgs := images.CachedImages("", v)
|
||||
for _, img := range imgs {
|
||||
img = strings.Replace(img, ":", "_", 1) // for example kube-scheduler:v1.15.2 --> kube-scheduler_v1.15.2
|
||||
fp := filepath.Join(localpath.MiniPath(), "cache", "images", img)
|
||||
_, err := os.Stat(fp)
|
||||
if err != nil {
|
||||
t.Errorf("expected image file exist at %q but got error: %v", fp, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,8 +87,40 @@ func TestDownloadAndDeleteAll(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Check that the profile we've created has the expected driver
|
||||
t.Run("ExpectedDefaultDriver", func(t *testing.T) {
|
||||
if ExpectedDefaultDriver() == "" {
|
||||
t.Skipf("--expected-default-driver is unset, skipping test")
|
||||
return
|
||||
}
|
||||
rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "--output", "json"))
|
||||
if err != nil {
|
||||
t.Errorf("%s failed: %v", rr.Args, err)
|
||||
}
|
||||
var ps map[string][]config.Profile
|
||||
err = json.Unmarshal(rr.Stdout.Bytes(), &ps)
|
||||
if err != nil {
|
||||
t.Errorf("%s failed: %v", rr.Args, err)
|
||||
}
|
||||
|
||||
got := ""
|
||||
for _, p := range ps["valid"] {
|
||||
if p.Name == profile {
|
||||
got = p.Config.MachineConfig.VMDriver
|
||||
}
|
||||
}
|
||||
|
||||
if got != ExpectedDefaultDriver() {
|
||||
t.Errorf("got driver %q, expected %q\nstart output: %s", got, ExpectedDefaultDriver(), rrr.Output())
|
||||
}
|
||||
})
|
||||
|
||||
// This is a weird place to test profile deletion, but this test is serial, and we have a profile to delete!
|
||||
t.Run("DeleteAll", func(t *testing.T) {
|
||||
if !CanCleanup() {
|
||||
t.Skip("skipping, as cleanup is disabled")
|
||||
}
|
||||
rr, err := Run(t, exec.CommandContext(ctx, Target(), "delete", "--all"))
|
||||
if err != nil {
|
||||
t.Errorf("%s failed: %v", rr.Args, err)
|
||||
|
@ -84,6 +128,9 @@ func TestDownloadAndDeleteAll(t *testing.T) {
|
|||
})
|
||||
// Delete should always succeed, even if previously partially or fully deleted.
|
||||
t.Run("DeleteAlwaysSucceeds", func(t *testing.T) {
|
||||
if !CanCleanup() {
|
||||
t.Skip("skipping, as cleanup is disabled")
|
||||
}
|
||||
rr, err := Run(t, exec.CommandContext(ctx, Target(), "delete", "-p", profile))
|
||||
if err != nil {
|
||||
t.Errorf("%s failed: %v", rr.Args, err)
|
|
@ -35,6 +35,13 @@ func TestGvisorAddon(t *testing.T) {
|
|||
profile := UniqueProfileName("gvisor")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)
|
||||
defer func() {
|
||||
if t.Failed() {
|
||||
rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "logs", "gvisor", "-n", "kube-system"))
|
||||
if err != nil {
|
||||
t.Logf("failed to get gvisor post-mortem logs: %v", err)
|
||||
}
|
||||
t.Logf("gvisor post-mortem: %s:\n%s\n", rr.Command(), rr.Output())
|
||||
}
|
||||
CleanupWithLogs(t, profile, cancel)
|
||||
}()
|
||||
|
||||
|
@ -44,10 +51,10 @@ func TestGvisorAddon(t *testing.T) {
|
|||
t.Fatalf("%s failed: %v", rr.Args, err)
|
||||
}
|
||||
|
||||
// TODO: Re-examine if we should be pulling in an image which users don't normally invoke
|
||||
rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "cache", "add", "gcr.io/k8s-minikube/gvisor-addon:latest"))
|
||||
// If it exists, include a locally built gvisor image
|
||||
rr, err = Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "cache", "add", "gcr.io/k8s-minikube/gvisor-addon:2"))
|
||||
if err != nil {
|
||||
t.Errorf("%s failed: %v", rr.Args, err)
|
||||
t.Logf("%s failed: %v (won't test local image)", rr.Args, err)
|
||||
}
|
||||
|
||||
// NOTE: addons are global, but the addon must assert that the runtime is containerd
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
|
||||
// General configuration: used to set the VM Driver
|
||||
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")
|
||||
var defaultDriver = flag.String("expected-default-driver", "", "Expected default driver")
|
||||
|
||||
// Flags for faster local integration testing
|
||||
var forceProfile = flag.String("profile", "", "force tests to run against a particular profile")
|
||||
|
@ -65,3 +66,13 @@ func NoneDriver() bool {
|
|||
func HyperVDriver() bool {
|
||||
return strings.Contains(*startArgs, "--vm-driver=hyperv")
|
||||
}
|
||||
|
||||
// ExpectedDefaultDriver returns the expected default driver, if any
|
||||
func ExpectedDefaultDriver() string {
|
||||
return *defaultDriver
|
||||
}
|
||||
|
||||
// CanCleanup returns if cleanup is allowed
|
||||
func CanCleanup() bool {
|
||||
return *cleanup
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue