提交 cfd80072 编写于 作者: T Thomas Stromberg

Merge branch 'master' into crio

......@@ -3,7 +3,7 @@ os: linux
sudo: required
go:
- 1.10.x
- 1.x
go_import_path: k8s.io/minikube
install:
......
......@@ -2,8 +2,8 @@
# Version 0.30.0 - 10/04/2018
* **Fix for [CVE-2018-1002103](https://github.com/kubernetes/minikube/issues/3208): Dashboard vulnerable to DNS rebinding attack** [#3210](https://github.com/kubernetes/minikube/pull/3210)
* Initial support for Kubernetes 1.12+ [#3180](https://github.com/kubernetes/minikube/pull/3180)
* Use "kubectl proxy" instead of a NodePort to expose the dashboard [#3210](https://github.com/kubernetes/minikube/pull/3210)
* Enhance the Ingress Addon [#3099](https://github.com/kubernetes/minikube/pull/3099)
* Upgrade cni and cni-plugins to release version [#3152](https://github.com/kubernetes/minikube/pull/3152)
* ensure that /dev has settled before operating [#3195](https://github.com/kubernetes/minikube/pull/3195)
......@@ -12,6 +12,7 @@
* Install crictl from binary instead of from source [#3160](https://github.com/kubernetes/minikube/pull/3160)
* Switch the source of libmachine to machine-drivers. [#3185](https://github.com/kubernetes/minikube/pull/3185)
* Add psmisc package, for pstree command [#3161](https://github.com/kubernetes/minikube/pull/3161)
* Significant improvements to kvm2 networking [#3148](https://github.com/kubernetes/minikube/pull/3148)
Huge thank you for this release towards our contributors:
- Anders F Björklund
......@@ -20,6 +21,7 @@ Huge thank you for this release towards our contributors:
- Denis Gladkikh
- dlorenc
- Fernando Diaz
- Marcus Heese
- oilbeater
- Raunak Ramakrishnan
- Rui Cao
......
......@@ -19,6 +19,10 @@
Minikube is a tool that makes it easy to run Kubernetes locally. Minikube runs a single-node Kubernetes cluster inside a VM on your laptop for users looking to try out Kubernetes or develop with it day-to-day.
# Newsflash
- 2018-10-05: minikube v0.30.0 released, addressing **[CVE-2018-1002103](https://github.com/kubernetes/minikube/issues/3208): Dashboard vulnerable to DNS rebinding attack**
## Installation
### macOS
```shell
......@@ -124,7 +128,8 @@ We also released a Debian package and Windows installer on our [releases page](h
## Quickstart
Here's a brief demo of Minikube usage.
If you want to change the VM driver add the appropriate `--vm-driver=xxx` flag to `minikube start`. Minikube supports
- If you want to change the container runtime, network details, consult notes from your container runtime provider.
- If you want to change the VM driver add the appropriate `--vm-driver=xxx` flag to `minikube start`. Minikube supports
the following drivers:
* virtualbox
......@@ -134,7 +139,7 @@ the following drivers:
* [hyperkit](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperkit-driver)
* [xhyve](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#xhyve-driver)
* [hyperv](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperV-driver)
* none (**Linux-only**) - this driver can be used to run the Kubernetes cluster components on the host instead of in a VM. This can be useful for CI workloads which do not support nested virtualization.
* none (**Linux + docker daemon as container runtime only**) - this driver can be used to run the Kubernetes cluster components on the host instead of in a VM. This can be useful for CI workloads which do not support nested virtualization.
```shell
$ minikube start
......
......@@ -18,12 +18,13 @@ package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
cmdConfig "k8s.io/minikube/cmd/minikube/cmd/config"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/machine"
"os"
)
// cacheCmd represents the cache command
......@@ -41,12 +42,12 @@ var addCacheCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
// Cache and load images into docker daemon
if err := machine.CacheAndLoadImages(args); err != nil {
fmt.Fprintf(os.Stderr, "Error caching and loading images: %s\n", err)
fmt.Fprintf(os.Stderr, "Error caching and loading images: %v\n", err)
os.Exit(1)
}
// Add images to config file
if err := cmdConfig.AddToConfigMap(constants.Cache, args); err != nil {
fmt.Fprintf(os.Stderr, "Error adding cached images to config file: %s\n", err)
fmt.Fprintf(os.Stderr, "Error adding cached images to config file: %v\n", err)
os.Exit(1)
}
},
......@@ -60,12 +61,12 @@ var deleteCacheCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
// Delete images from config file
if err := cmdConfig.DeleteFromConfigMap(constants.Cache, args); err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images from config file: %s\n", err)
fmt.Fprintf(os.Stderr, "Error deleting images from config file: %v\n", err)
os.Exit(1)
}
// Delete images from cache/images directory
if err := machine.DeleteFromImageCacheDir(args); err != nil {
fmt.Fprintf(os.Stderr, "Error deleting images: %s\n", err)
fmt.Fprintf(os.Stderr, "Error deleting images: %v\n", err)
os.Exit(1)
}
},
......
......@@ -41,11 +41,11 @@ var listCacheCmd = &cobra.Command{
// list images from config file
images, err := cmdConfig.ListConfigMap(constants.Cache)
if err != nil {
fmt.Fprintf(os.Stderr, "Error listing image entries from config: %s\n", err)
fmt.Fprintf(os.Stderr, "Error listing image entries from config: %v\n", err)
os.Exit(1)
}
if err := cacheList(images); err != nil {
fmt.Fprintf(os.Stderr, "Error listing images: %s\n", err)
fmt.Fprintf(os.Stderr, "Error listing images: %v\n", err)
os.Exit(1)
}
},
......@@ -62,13 +62,13 @@ func cacheList(images []string) error {
for _, image := range images {
tmpl, err := template.New("list").Parse(cacheListFormat)
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating list template: %s\n", err)
fmt.Fprintf(os.Stderr, "Error creating list template: %v\n", err)
os.Exit(1)
}
listTmplt := CacheListTemplate{image}
err = tmpl.Execute(os.Stdout, listTmplt)
if err != nil {
fmt.Fprintf(os.Stderr, "Error executing list template: %s\n", err)
fmt.Fprintf(os.Stderr, "Error executing list template: %v\n", err)
os.Exit(1)
}
}
......
......@@ -106,8 +106,7 @@ func GenerateBashCompletion(w io.Writer, cmd *cobra.Command) error {
}
func GenerateZshCompletion(out io.Writer, cmd *cobra.Command) error {
zsh_initialization := `
#compdef minikube
zsh_initialization := `#compdef minikube
__minikube_bash_source() {
alias shopt=':'
......
......@@ -47,10 +47,10 @@ var configTestCases = []configTestCase{
"vm-driver": "kvm"
}`,
config: map[string]interface{}{
"vm-driver": "kvm",
"cpus": 4,
"disk-size": "20g",
"v": 5,
"vm-driver": "kvm",
"cpus": 4,
"disk-size": "20g",
"v": 5,
"show-libmachine-logs": true,
"log_dir": "/etc/hosts",
"ReminderWaitPeriodInHours": 99,
......@@ -80,7 +80,7 @@ func TestHiddenPrint(t *testing.T) {
}
result, err := concealableAskForStaticValue(b, "hello", false)
if err != nil && !test.ShouldError {
t.Errorf("Error asking for concealable static value: %s", err)
t.Errorf("Error asking for concealable static value: %v", err)
continue
}
if result != test.TestString {
......@@ -94,7 +94,7 @@ func TestWriteConfig(t *testing.T) {
for _, tt := range configTestCases {
err := encode(&b, tt.config)
if err != nil {
t.Errorf("Error encoding: %s", err)
t.Errorf("Error encoding: %v", err)
}
if b.String() != tt.data {
t.Errorf("Did not write config correctly, \n\n expected:\n %+v \n\n actual:\n %+v", tt.data, b.String())
......
......@@ -105,8 +105,8 @@ var addonsConfigureCmd = &cobra.Command{
"aws-assume-role": awsRole,
},
map[string]string{
"app": "registry-creds",
"cloud": "ecr",
"app": "registry-creds",
"cloud": "ecr",
"kubernetes.io/minikube-addons": "registry-creds",
})
......@@ -120,11 +120,11 @@ var addonsConfigureCmd = &cobra.Command{
"registry-creds-gcr",
map[string]string{
"application_default_credentials.json": gcrApplicationDefaultCredentials,
"gcrurl": gcrURL,
"gcrurl": gcrURL,
},
map[string]string{
"app": "registry-creds",
"cloud": "gcr",
"app": "registry-creds",
"cloud": "gcr",
"kubernetes.io/minikube-addons": "registry-creds",
})
......@@ -142,8 +142,8 @@ var addonsConfigureCmd = &cobra.Command{
"DOCKER_PRIVATE_REGISTRY_PASSWORD": dockerPass,
},
map[string]string{
"app": "registry-creds",
"cloud": "dpr",
"app": "registry-creds",
"cloud": "dpr",
"kubernetes.io/minikube-addons": "registry-creds",
})
......
......@@ -61,7 +61,7 @@ var addonsOpenCmd = &cobra.Command{
//TODO(r2d4): config should not reference API, pull this out
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......@@ -91,7 +91,7 @@ minikube addons enable %s`, addonName, addonName))
serviceList, err := service.GetServiceListByLabel(namespace, key, addonName)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting service with namespace: %s and labels %s:%s: %s\n", namespace, key, addonName, err)
fmt.Fprintf(os.Stderr, "Error getting service with namespace: %s and labels %s:%s: %v\n", namespace, key, addonName, err)
os.Exit(1)
}
if len(serviceList.Items) == 0 {
......
......@@ -104,7 +104,7 @@ func EnableOrDisableAddon(name string, val string) error {
//TODO(r2d4): config package should not reference API, pull this out
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -38,7 +38,7 @@ func TestFindSettingNotFound(t *testing.T) {
func TestFindSetting(t *testing.T) {
s, err := findSetting("vm-driver")
if err != nil {
t.Fatalf("Couldn't find setting, vm-driver: %s", err)
t.Fatalf("Couldn't find setting, vm-driver: %v", err)
}
if s.name != "vm-driver" {
t.Fatalf("Found wrong setting, expected vm-driver, got %s", s.name)
......@@ -48,14 +48,14 @@ func TestFindSetting(t *testing.T) {
func TestSetString(t *testing.T) {
err := SetString(minikubeConfig, "vm-driver", "virtualbox")
if err != nil {
t.Fatalf("Couldnt set string: %s", err)
t.Fatalf("Couldnt set string: %v", err)
}
}
func TestSetInt(t *testing.T) {
err := SetInt(minikubeConfig, "cpus", "22")
if err != nil {
t.Fatalf("Couldn't set int in config: %s", err)
t.Fatalf("Couldn't set int in config: %v", err)
}
val, ok := minikubeConfig["cpus"].(int)
if !ok {
......@@ -69,7 +69,7 @@ func TestSetInt(t *testing.T) {
func TestSetBool(t *testing.T) {
err := SetBool(minikubeConfig, "show-libmachine-logs", "true")
if err != nil {
t.Fatalf("Couldn't set bool in config: %s", err)
t.Fatalf("Couldn't set bool in config: %v", err)
}
val, ok := minikubeConfig["show-libmachine-logs"].(bool)
if !ok {
......
......@@ -59,7 +59,7 @@ var dashboardCmd = &cobra.Command{
}()
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating client: %v\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
cluster.EnsureMinikubeRunningOrExit(api, 1)
......
......@@ -44,7 +44,7 @@ associated files.`,
fmt.Println("Deleting local Kubernetes cluster...")
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -302,13 +302,13 @@ var dockerEnvCmd = &cobra.Command{
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
host, err := cluster.CheckIfHostExistsAndLoad(api, config.GetMachineName())
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting host: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting host: %v\n", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
......
......@@ -248,7 +248,7 @@ func TestShellCfgSet(t *testing.T) {
t.Errorf("Shell cfgs differ: expected %+v, \n\n got %+v", test.expectedShellCfg, shellCfg)
}
if err != nil && !test.shouldErr {
t.Errorf("Test should have failed but didn't return error: %s, error: %s", test.description, err)
t.Errorf("Test should have failed but didn't return error: %s, error: %v", test.description, err)
}
if err == nil && test.shouldErr {
t.Errorf("Test didn't return error but should have: %s", test.description)
......
......@@ -34,7 +34,7 @@ var ipCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -41,13 +41,13 @@ var logsCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
clusterBootstrapper, err := GetClusterBootstrapper(api, viper.GetString(cmdcfg.Bootstrapper))
if err != nil {
glog.Exitf("Error getting cluster bootstrapper: %s", err)
glog.Exitf("Error getting cluster bootstrapper: %v", err)
}
err = clusterBootstrapper.GetClusterLogsTo(follow, os.Stdout)
......
......@@ -93,7 +93,7 @@ var mountCmd = &cobra.Command{
}
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -70,7 +70,7 @@ var RootCmd = &cobra.Command{
PersistentPreRun: func(cmd *cobra.Command, args []string) {
for _, path := range dirs {
if err := os.MkdirAll(path, 0777); err != nil {
glog.Exitf("Error creating minikube directory: %s", err)
glog.Exitf("Error creating minikube directory: %v", err)
}
}
......@@ -143,7 +143,7 @@ func initConfig() {
viper.SetConfigType("json")
err := viper.ReadInConfig()
if err != nil {
glog.Warningf("Error reading config file at %s: %s", configPath, err)
glog.Warningf("Error reading config file at %s: %v", configPath, err)
}
setupViper()
}
......
......@@ -65,7 +65,7 @@ var serviceCmd = &cobra.Command{
svc := args[0]
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......@@ -74,7 +74,7 @@ var serviceCmd = &cobra.Command{
err = service.WaitAndMaybeOpenService(api, namespace, svc,
serviceURLTemplate, serviceURLMode, https, wait, interval)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening service: %s\n", err)
fmt.Fprintf(os.Stderr, "Error opening service: %v\n", err)
os.Exit(1)
}
},
......
......@@ -39,7 +39,7 @@ var serviceListCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -36,13 +36,13 @@ var sshCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
host, err := cluster.CheckIfHostExistsAndLoad(api, config.GetMachineName())
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting host: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting host: %v\n", err)
os.Exit(1)
}
if host.Driver.DriverName() == "none" {
......
......@@ -112,14 +112,14 @@ func runStart(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
exists, err := api.Exists(cfg.GetMachineName())
if err != nil {
glog.Exitf("checking if machine exists: %s", err)
glog.Exitf("checking if machine exists: %v", err)
}
diskSize := viper.GetString(humanReadableDiskSize)
......@@ -165,7 +165,7 @@ func runStart(cmd *cobra.Command, args []string) {
start := func() (err error) {
host, err = cluster.StartHost(api, config)
if err != nil {
glog.Errorf("Error starting host: %s.\n\n Retrying.\n", err)
glog.Errorf("Error starting host: %v.\n\n Retrying.\n", err)
}
return err
}
......@@ -228,7 +228,7 @@ func runStart(cmd *cobra.Command, args []string) {
k8sBootstrapper, err := GetClusterBootstrapper(api, clusterBootstrapper)
if err != nil {
glog.Exitf("Error getting cluster bootstrapper: %s", err)
glog.Exitf("Error getting cluster bootstrapper: %v", err)
}
// Write profile cluster configuration to file
......@@ -321,12 +321,12 @@ func runStart(cmd *cobra.Command, args []string) {
}
err = mountCmd.Start()
if err != nil {
glog.Errorf("Error running command minikube mount %s", err)
glog.Errorf("Error running command minikube mount %v", err)
cmdutil.MaybeReportErrorAndExit(err)
}
err = ioutil.WriteFile(filepath.Join(constants.GetMinipath(), constants.MountProcessFileName), []byte(strconv.Itoa(mountCmd.Process.Pid)), 0644)
if err != nil {
glog.Errorf("Error writing mount process pid to file: %s", err)
glog.Errorf("Error writing mount process pid to file: %v", err)
cmdutil.MaybeReportErrorAndExit(err)
}
}
......
......@@ -61,7 +61,7 @@ var statusCmd = &cobra.Command{
var returnCode = 0
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(internalErrorCode)
}
defer api.Close()
......@@ -77,7 +77,7 @@ var statusCmd = &cobra.Command{
if ms == state.Running.String() {
clusterBootstrapper, err := GetClusterBootstrapper(api, viper.GetString(cmdcfg.Bootstrapper))
if err != nil {
glog.Errorf("Error getting cluster bootstrapper: %s", err)
glog.Errorf("Error getting cluster bootstrapper: %v", err)
cmdUtil.MaybeReportErrorAndExitWithCode(err, internalErrorCode)
}
cs, err = clusterBootstrapper.GetClusterStatus()
......
......@@ -36,7 +36,7 @@ itself, leaving all files intact. The cluster can be started again with the "sta
fmt.Println("Stopping local Kubernetes cluster...")
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -39,7 +39,7 @@ var updateContextCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
fmt.Fprintf(os.Stderr, "Error getting client: %v\n", err)
os.Exit(1)
}
defer api.Close()
......
......@@ -28,7 +28,7 @@ import (
func main() {
// Glog requires that /tmp exists.
if err := os.MkdirAll("/tmp", 0755); err != nil {
fmt.Printf("Error creating tmpdir: %s\n", err)
fmt.Printf("Error creating tmpdir: %v\n", err)
os.Exit(1)
}
flag.Parse()
......
......@@ -48,7 +48,7 @@ func TestFormatError(t *testing.T) {
_, err := FormatError(testErr)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
t.Fatalf("Unexpected error: %v", err)
}
}
......@@ -59,7 +59,7 @@ func TestMarshallError(t *testing.T) {
errMsg, _ := FormatError(testErr)
if _, err := MarshallError(errMsg, "default", version.GetVersion()); err != nil {
t.Fatalf("Unexpected error: %s", err)
t.Fatalf("Unexpected error: %v", err)
}
}
......@@ -75,7 +75,7 @@ func TestUploadError(t *testing.T) {
}))
if err := UploadError(jsonErrMsg, server.URL); err != nil {
t.Fatalf("Unexpected error: %s", err)
t.Fatalf("Unexpected error: %v", err)
}
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
......
......@@ -50,7 +50,7 @@ func getShaFromURL(url string) (string, error) {
func TestReleasesJson(t *testing.T) {
releases, err := notify.GetAllVersionsFromURL(constants.GithubMinikubeReleasesURL)
if err != nil {
t.Fatalf("Error getting releases.json: %s", err)
t.Fatalf("Error getting releases.json: %v", err)
}
for _, r := range releases {
......@@ -59,7 +59,7 @@ func TestReleasesJson(t *testing.T) {
fmt.Printf("Checking SHA for %s.\n", platform)
actualSha, err := getShaFromURL(util.GetBinaryDownloadURL(r.Name, platform))
if err != nil {
t.Errorf("Error calculating SHA for %s-%s. Error: %s", r.Name, platform, err)
t.Errorf("Error calculating SHA for %s-%s. Error: %v", r.Name, platform, err)
continue
}
if actualSha != sha {
......
......@@ -10,7 +10,7 @@ create a new docker machine driver.
First of all, before started, you need to understand your driver in terms of:
- Which operating system is your driver running on?
- Is your driver builtin the minikube binary or triggerred through RPC?
- Is your driver builtin the minikube binary or triggered through RPC?
- How to translate minikube config to driver config?
- If builtin, how to instantiate the driver instance?
......
# Steps to Release Minikube
## Create a Release Notes PR
## Build a new ISO
Collect the release notes, and edit them as necessary:
You only need to build the minikube ISO when the there are changes in the `deploy/iso` folder.
Note: you can build the ISO using the `hack/jenkins/build_iso.sh` script locally.
```shell
hack/release_notes.sh
```
Then merge into the CHANGELOG.md file. See [this PR](https://github.com/kubernetes/minikube/pull/164) for an example.
## Build and Release a New ISO
* navigate to the minikube ISO jenkins job
* Ensure that you are logged in (top right)
* For `ISO_VERSION`, type in the intended release version (same as the minikube binary's version)
* For `ISO_BUCKET`, type in `minikube/iso`
* Click *Build*
This step isn't always required. Check if there were changes in the deploy directory.
If you do this, bump the ISO URL to point to the new ISO, and send a PR.
To do this, build the new ISO by running:
```shell
deploy/iso/build.sh
```
This will generate a new ISO at 'deploy/iso/minikube.iso'. Then upload the ISO and shasum using the following command:
```shell
gsutil cp deploy/iso/minikube.iso gs://minikube/minikube-<increment.version>.iso
gsutil cp deploy/iso/minikube.iso.sha256 gs://minikube/minikube-<increment.version>.iso.sha256
```
The build will take roughly 50 minutes.
## Run integration tests
## Update Makefile
Run this command:
```shell
make integration
```
Investigate and fix any failures.
Edit the minikube `Makefile`, updating the version number values at the top:
## Bump the version in the Makefile and Update Docs to reflect this
* `VERSION_MINOR` (and `VERSION_MAJOR`, `VERSION_BUILD` as necessary)
* `ISO_VERSION` (only update this if there is a new ISO release)
See [this PR](https://github.com/kubernetes/minikube/pull/165) for an example.
## Run Local Integration Test
##Send an initial commit with the Makefile change:
With the updated Makefile, run the integration tests and ensure that all tests pass:
Send a PR for the Makefile change and wait until it is merged. Once the commit is merged, continue.
```shell
env TEST_ARGS="-minikube-start-args=--vm-driver=kvm2" make integration
```
## Build the Release
## Ad-Hoc testing of other platforms
Run this command:
If there are supported platforms which do not have functioning Jenkins workers (Windows), you may use the following to build a sanity check:
```shell
BUILD_IN_DOCKER=y make cross checksum
```
## Add the version to the releases.json file
## Send out Makefile PR
Add an entry **to the top** of deploy/minikube/releases.json with the **version** and **checksums**.
Send a PR.
This file controls the auto update notifications in minikube.
Only add entries to this file that should be released to all users (no pre-release, alpha or beta releases).
The file must be uploaded to GCS before notifications will go out. That step comes at the end.
This will update users of HEAD to the new ISO.
The schema for this file can be found in deploy/minikube/schema.json.
Please pay attention to test failures, as this is our integration test across platforms. If there are known acceptable failures, please add a PR comment linking to the appropriate issue.
An automated test to verify the schema runs in Travis before each submit.
## Update Release Notes
## Upload to GCS:
Run the following script to update the release notes:
```shell
gsutil cp out/minikube-linux-amd64 gs://minikube/releases/$RELEASE/
gsutil cp out/minikube-linux-amd64.sha256 gs://minikube/releases/$RELEASE/
gsutil cp out/minikube-darwin-amd64 gs://minikube/releases/$RELEASE/
gsutil cp out/minikube-darwin-amd64.sha256 gs://minikube/releases/$RELEASE/
gsutil cp out/minikube-windows-amd64.exe gs://minikube/releases/$RELEASE/
gsutil cp out/minikube-windows-amd64.exe.sha256 gs://minikube/releases/$RELEASE/
hack/release_notes.sh
```
Merge the output into CHANGELOG.md. See [PR#3175](https://github.com/kubernetes/minikube/pull/3175) as an example. Then get the PR submitted.
## Tag the Release
Run a command like this to tag it locally: `git tag -a v0.2.0 -m "0.2.0 Release"`.
Run a command like this to tag it locally: `git tag -a v<version> -m "<version> Release"`.
And run a command like this to push the tag: `git push upstream v<version>`.
## Build the Release
This step uses the git tag to publish new binaries to GCS and create a github release:
And run a command like this to push the tag: `git push upstream v0.2.0`.
* navigate to the minikube "Release" jenkins job
* Ensure that you are logged in (top right)
* `VERSION_MAJOR`, `VERSION_MINOR`, and `VERSION_BUILD` should reflect the values in your Makefile
* For `ISO_SHA256`, run: `gsutil cat gs://minikube/iso/minikube-v<version>.iso.sha256
* Click *Build*
## Create a Release in Github
## Update releases.json
Create a new release based on your tag, like [this one](https://github.com/kubernetes/minikube/releases/tag/v0.2.0).
minikube-bot will send out a PR to update the release checksums at the top of `deploy/minikube/releases.json`. Make sure it is submitted, or hack one together yourself.
Upload the files, and calculated checksums.
This file is used for auto-update notifications, but is not active until releases.json is copied to GCS.
## Upload the releases.json file to GCS
## Upload releases.json to GCS
This step makes the new release trigger update notifications in old versions of Minikube.
Use this command from a clean git repo:
......@@ -95,7 +86,7 @@ gsutil cp deploy/minikube/releases.json gs://minikube/releases.json
## Mark the release as `latest` in GCS:
```shell
gsutil cp -r gs://minikube/releases/$RELEASE/* gs://minikube/releases/latest/
gsutil cp -r 'gs://minikube/releases/$RELEASE/*' gs://minikube/releases/latest/
```
## Package managers which include minikube
......@@ -116,11 +107,11 @@ The repository is tracked in this repo under a submodule `installers/linux/arch_
To actually update the package, you should bump the version and update the sha512 checksum. You should also run `makepkg --printsrcinfo > .SRCINFO` to update the srcinfo file. You can edit this manually if you don't have `makepkg` on your machine.
## Release Verification
## Verification
After you've finished the release, run this command from the release commit to verify the release was done correctly:
`make check-release`.
## Update kubernetes.io docs
If there are major changes, please send a PR upstream for this file https://github.com/kubernetes/kubernetes.github.io/blob/master/docs/getting-started-guides/minikube.md in order to keep the getting started guide up to date.
If there are major changes, please send a PR to update the official setup guide: [Running Kubernetes Locally via Minikube](https://kubernetes.io/docs/setup/minikube/)
......@@ -41,10 +41,8 @@ $ newgrp libvirt
Then install the driver itself:
```shell
curl -Lo docker-machine-driver-kvm2 https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2 \
&& chmod +x docker-machine-driver-kvm2 \
&& sudo cp docker-machine-driver-kvm2 /usr/local/bin/ \
&& rm docker-machine-driver-kvm2
curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-kvm2 \
&& sudo install docker-machine-driver-kvm2 /usr/local/bin/
```
To use the driver you would do:
......@@ -88,12 +86,8 @@ It is built from the minikube source tree, and uses [moby/hyperkit](http://githu
To install the hyperkit driver:
```shell
curl -Lo docker-machine-driver-hyperkit https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit \
&& chmod +x docker-machine-driver-hyperkit \
&& sudo cp docker-machine-driver-hyperkit /usr/local/bin/ \
&& rm docker-machine-driver-hyperkit \
&& sudo chown root:wheel /usr/local/bin/docker-machine-driver-hyperkit \
&& sudo chmod u+s /usr/local/bin/docker-machine-driver-hyperkit
curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit \
&& sudo install -o root -g wheel -m 4755 docker-machine-driver-hyperkit /usr/local/bin/
```
The hyperkit driver currently requires running as root to use the vmnet framework to setup networking.
......
# vm-driver=none
## Overview
This document is written for system integrators who are familiar with minikube, and wish to run it within a customized VM environment.
`--vm-driver=none` allows advanced minikube users to skip VM creation, allowing minikube to be run on a user-supplied VM.
## What operating systems are supported?
`--vm-driver=none` supports releases of Debian, Fedora, and buildroot that are less than 2 years old.
While the standard minikube guest VM uses buildroot, minikube integration tests are also regularly run against Debian 9 for compatibility. In practice, any systemd-based modern distribution is likely to work, and we will happily accept pull requests which improve compatibility with other systems.
## Should vm-driver=none be used on a personal development machine? No.
No. Please do not do this, ever.
minikube was designed to run Kubernetes within a dedicated VM, and when used with `--vm-driver=none`, may overwrite system binaries, configuration files, and system logs. Executing `minikube --vm-driver=none` outside of a VM could result in data loss, system instability and decreased security.
Usage of `--vm-driver=none` outside of a VM could also result in services being exposed in a way that may make them accessible to the public internet. Even if your host is protected by a firewall, these services still be vulnerable to [CSRF](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)) or [DNS rebinding](https://en.wikipedia.org/wiki/DNS_rebinding) attacks.
## Can vm-driver=none be used outside of a VM?
Yes, but only after appropriate security and reliability precautions have been made. `minikube --vm-driver=none` assumes complete control over the environment is is executing within, and may overwrite system binaries, configuration files, and system logs.
The host running `minikube --vm-driver=none` should be:
* Isolated from the rest of the network with a firewall
* Disposable and easily reprovisioned, as this mode may overwrite system binaries, configuration files, and system logs
If you find yourself running a web browser on the same host running `--vm-driver=none`, please see __Should vm-driver=none be used on a personal development machine? No.__
## Known Issues
* You cannot run more than one `--vm-driver=none` instance on a single host #2781
* `--vm-driver=none` deletes other local docker images #2705
* `--vm-driver=none` fails on distro's which do not use systemd #2704
* Many `minikube` commands are not supported, such as: `dashboard`, `mount`, `ssh`, `stop` #3127
......@@ -151,7 +151,7 @@ func (d *Driver) Kill() error {
func (d *Driver) Remove() error {
s, err := d.GetState()
if err != nil || s == state.Error {
log.Infof("Error checking machine status: %s, assuming it has been removed already", err)
log.Infof("Error checking machine status: %v, assuming it has been removed already", err)
}
if s == state.Running {
if err := d.Stop(); err != nil {
......@@ -229,7 +229,8 @@ func (d *Driver) Start() error {
time.Sleep(time.Second * 30)
err = d.setupNFSShare()
if err != nil {
log.Errorf("NFS setup failed: %s", err.Error())
// TODO(tstromberg): Check that logging an and error and return it is appropriate. Seems weird.
log.Errorf("NFS setup failed: %v", err)
return err
}
}
......@@ -350,13 +351,13 @@ func (d *Driver) getPid() int {
f, err := os.Open(pidPath)
if err != nil {
log.Warnf("Error reading pid file: %s", err)
log.Warnf("Error reading pid file: %v", err)
return 0
}
dec := json.NewDecoder(f)
config := hyperkit.HyperKit{}
if err := dec.Decode(&config); err != nil {
log.Warnf("Error decoding pid file: %s", err)
log.Warnf("Error decoding pid file: %v", err)
return 0
}
......@@ -368,12 +369,12 @@ func (d *Driver) cleanupNfsExports() {
log.Infof("You must be root to remove NFS shared folders. Please type root password.")
for _, share := range d.NFSShares {
if _, err := nfsexports.Remove("", d.nfsExportIdentifier(share)); err != nil {
log.Errorf("failed removing nfs share (%s): %s", share, err.Error())
log.Errorf("failed removing nfs share (%s): %v", share, err)
}
}
if err := nfsexports.ReloadDaemon(); err != nil {
log.Errorf("failed to reload the nfs daemon: %s", err.Error())
log.Errorf("failed to reload the nfs daemon: %v", err)
}
}
}
......@@ -370,7 +370,7 @@ func (d *Driver) Remove() error {
// Tear down network if it exists and is not in use by another minikube instance
log.Debug("Trying to delete the networks (if possible)")
if err := d.deleteNetwork(); err != nil {
log.Warnf("Deleting of networks failed: %s", err.Error())
log.Warnf("Deleting of networks failed: %v", err)
} else {
log.Info("Successfully deleted networks")
}
......
......@@ -277,7 +277,7 @@ func (d *Driver) lookupIPFromStatusFile(conn *libvirt.Connect) (string, error) {
bridge, err := network.GetBridgeName()
if err != nil {
log.Warnf("Failed to get network bridge: %s", err)
log.Warnf("Failed to get network bridge: %v", err)
return "", err
}
statusFile := fmt.Sprintf("/var/lib/libvirt/dnsmasq/%s.status", bridge)
......
......@@ -124,7 +124,7 @@ func (d *Driver) Kill() error {
} {
cmd := exec.Command("sudo", cmdStr...)
if out, err := cmd.CombinedOutput(); err != nil {
glog.Warningf("Error %s running command: %s. Output: %s", err, cmdStr, string(out))
glog.Warningf("Error %v running command: %s. Output: %s", err, cmdStr, out)
}
}
return nil
......@@ -138,7 +138,7 @@ func (d *Driver) Remove() error {
for _, cmdStr := range []string{rmCmd, dockerkillcmd} {
if out, err := runCommand(cmdStr, true); err != nil {
glog.Warningf("Error %s running command: %s, Output: %s", err, cmdStr, out)
glog.Warningf("Error %v running command: %s, Output: %s", err, cmdStr, out)
}
}
......@@ -192,7 +192,7 @@ fi
}
}
if out, err := runCommand(dockerstopcmd, false); err != nil {
glog.Warningf("Error %s running command %s. Output: %s", err, dockerstopcmd, out)
glog.Warningf("Error %v running command %s. Output: %s", err, dockerstopcmd, out)
}
return nil
}
......
......@@ -44,7 +44,7 @@ func TestSetupCerts(t *testing.T) {
}
if err := SetupCerts(f, k8s); err != nil {
t.Fatalf("Error starting cluster: %s", err)
t.Fatalf("Error starting cluster: %v", err)
}
for _, cert := range filesToBeTransferred {
_, err := f.GetFileToContents(cert)
......
......@@ -234,7 +234,7 @@ schedulerExtraArgs:
t.Run(test.description, func(t *testing.T) {
actualCfg, err := generateConfig(test.cfg)
if err != nil && !test.shouldErr {
t.Errorf("got unexpected error generating config: %s", err)
t.Errorf("got unexpected error generating config: %v", err)
return
}
if err == nil && test.shouldErr {
......
......@@ -96,7 +96,7 @@ func TestVersionIsBetween(t *testing.T) {
func TestParseKubernetesVersion(t *testing.T) {
version, err := ParseKubernetesVersion("v1.8.0-alpha.5")
if err != nil {
t.Fatalf("Error parsing version: %s", err)
t.Fatalf("Error parsing version: %v", err)
}
if version.NE(semver.MustParse("1.8.0-alpha.5")) {
t.Errorf("Expected: %s, Actual:%s", "1.8.0-alpha.5", version)
......@@ -141,7 +141,7 @@ func TestParseFeatureArgs(t *testing.T) {
kubeadm, component, err := ParseFeatureArgs(test.featureGates)
if err != nil {
t.Fatalf("Error parsing feature args: %s", err)
t.Fatalf("Error parsing feature args: %v", err)
}
if !reflect.DeepEqual(kubeadm, test.expectedKubeadmFeatureArgs) {
......
......@@ -217,7 +217,7 @@ func createHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error
if config.VMDriver != "none" {
if err := config.Downloader.CacheMinikubeISOFromURL(config.MinikubeISO); err != nil {
return nil, errors.Wrap(err, "Error attempting to cache minikube ISO from URL")
return nil, errors.Wrap(err, "unable to cache ISO")
}
}
......
......@@ -229,7 +229,7 @@ func TestDeleteHost(t *testing.T) {
createHost(api, defaultMachineConfig)
if err := DeleteHost(api); err != nil {
t.Fatalf("Unexpected error deleting host: %s", err)
t.Fatalf("Unexpected error deleting host: %v", err)
}
}
......@@ -274,7 +274,7 @@ func TestDeleteHostMultipleErrors(t *testing.T) {
expectedErrors := []string{"error removing " + config.GetMachineName(), "error deleting machine"}
for _, expectedError := range expectedErrors {
if !strings.Contains(err.Error(), expectedError) {
t.Fatalf("Error %s expected to contain: %s.", err, expectedError)
t.Fatalf("Error %v expected to contain: %s.", err, expectedError)
}
}
}
......@@ -285,7 +285,7 @@ func TestGetHostStatus(t *testing.T) {
checkState := func(expected string) {
s, err := GetHostStatus(api)
if err != nil {
t.Fatalf("Unexpected error getting status: %s", err)
t.Fatalf("Unexpected error getting status: %v", err)
}
if s != expected {
t.Fatalf("Expected status: %s, got %s", s, expected)
......@@ -319,7 +319,7 @@ func TestGetHostDockerEnv(t *testing.T) {
envMap, err := GetHostDockerEnv(api)
if err != nil {
t.Fatalf("Unexpected error getting env: %s", err)
t.Fatalf("Unexpected error getting env: %v", err)
}
dockerEnvKeys := [...]string{
......@@ -352,7 +352,7 @@ func TestGetHostDockerEnvIPv6(t *testing.T) {
envMap, err := GetHostDockerEnv(api)
if err != nil {
t.Fatalf("Unexpected error getting env: %s", err)
t.Fatalf("Unexpected error getting env: %v", err)
}
expected := "tcp://[fe80::215:5dff:fe00:a903]:2376"
......@@ -368,7 +368,7 @@ func TestCreateSSHShell(t *testing.T) {
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %s", err)
t.Fatalf("Error starting ssh server: %v", err)
}
d := &tests.MockDriver{
......@@ -383,7 +383,7 @@ func TestCreateSSHShell(t *testing.T) {
cliArgs := []string{"exit"}
if err := CreateSSHShell(api, cliArgs); err != nil {
t.Fatalf("Error running ssh command: %s", err)
t.Fatalf("Error running ssh command: %v", err)
}
if !s.IsSessionRequested() {
......
......@@ -62,7 +62,7 @@ func detectVBoxManageCmd() string {
func findVBoxInstallDirInRegistry() (string, error) {
registryKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Oracle\VirtualBox`, registry.QUERY_VALUE)
if err != nil {
errorMessage := fmt.Sprintf("Can't find VirtualBox registry entries, is VirtualBox really installed properly? %s", err)
errorMessage := fmt.Sprintf("Can't find VirtualBox registry entries, is VirtualBox really installed properly? %v", err)
glog.Errorf(errorMessage)
return "", errors.New(errorMessage)
}
......@@ -71,7 +71,7 @@ func findVBoxInstallDirInRegistry() (string, error) {
installDir, _, err := registryKey.GetStringValue("InstallDir")
if err != nil {
errorMessage := fmt.Sprintf("Can't find InstallDir registry key within VirtualBox registries entries, is VirtualBox really installed properly? %s", err)
errorMessage := fmt.Sprintf("Can't find InstallDir registry key within VirtualBox registries entries, is VirtualBox really installed properly? %v", err)
glog.Errorf(errorMessage)
return "", errors.New(errorMessage)
}
......
......@@ -65,13 +65,13 @@ func ReadConfig() (MinikubeConfig, error) {
if os.IsNotExist(err) {
return make(map[string]interface{}), nil
}
return nil, fmt.Errorf("Could not open file %s: %s", constants.ConfigFile, err)
return nil, fmt.Errorf("Could not open file %s: %v", constants.ConfigFile, err)
}
defer f.Close()
m, err := decode(f)
if err != nil {
return nil, fmt.Errorf("Could not decode config %s: %s", constants.ConfigFile, err)
return nil, fmt.Errorf("Could not decode config %s: %v", constants.ConfigFile, err)
}
return m, nil
......
......@@ -47,10 +47,10 @@ var configTestCases = []configTestCase{
"vm-driver": "kvm"
}`,
config: map[string]interface{}{
"vm-driver": "kvm",
"cpus": 4,
"disk-size": "20g",
"v": 5,
"vm-driver": "kvm",
"cpus": 4,
"disk-size": "20g",
"v": 5,
"show-libmachine-logs": true,
"log_dir": "/etc/hosts",
"ReminderWaitPeriodInHours": 99,
......
......@@ -26,7 +26,7 @@ import (
func TestReplaceWinDriveLetterToVolumeName(t *testing.T) {
path, err := ioutil.TempDir("", "repwindl2vn")
if err != nil {
t.Fatalf("Error make tmp directory: %s", err)
t.Fatalf("Error make tmp directory: %v", err)
}
defer os.RemoveAll(path)
......@@ -40,7 +40,7 @@ func TestReplaceWinDriveLetterToVolumeName(t *testing.T) {
}
if _, err := replaceWinDriveLetterToVolumeName(path); err != nil {
t.Errorf("Error replace a Windows drive letter to a volume name: %s", err)
t.Errorf("Error replace a Windows drive letter to a volume name: %v", err)
}
}
......
......@@ -102,7 +102,7 @@ func TestLocalClientNewHost(t *testing.T) {
}
}
if err != nil && !test.err {
t.Errorf("Unexpected error: %s", err)
t.Errorf("Unexpected error: %v", err)
}
if err == nil && test.err {
t.Errorf("No error returned, but expected err")
......
......@@ -60,7 +60,7 @@ type DriverDef struct {
Name string
// BuiltIn indicates if the driver is builtin minikube binary, or the driver is
// triggerred through RPC.
// triggered through RPC.
Builtin bool
// ConfigCreator generate a raw driver object by minikube's machine config.
......
......@@ -78,7 +78,7 @@ func (*K8sClientGetter) GetClientset() (*kubernetes.Clientset, error) {
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
clientConfig, err := kubeConfig.ClientConfig()
if err != nil {
return nil, fmt.Errorf("Error creating kubeConfig: %s", err)
return nil, fmt.Errorf("Error creating kubeConfig: %v", err)
}
clientConfig.Timeout = 1 * time.Second
client, err := kubernetes.NewForConfig(clientConfig)
......
......@@ -236,7 +236,7 @@ func TestPrintURLsForService(t *testing.T) {
t.Parallel()
urls, err := printURLsForService(client, "127.0.0.1", test.serviceName, test.namespace, test.tmpl)
if err != nil && !test.err {
t.Errorf("Error: %s", err)
t.Errorf("Error: %v", err)
}
if err == nil && test.err {
t.Errorf("Expected error but got none")
......@@ -258,30 +258,30 @@ func TestOptionallyHttpsFormattedUrlString(t *testing.T) {
expectedIsHTTPSchemedURL bool
}{
{
description: "no https for http schemed with no https option",
bareURLString: "http://192.168.99.100:30563",
https: false,
description: "no https for http schemed with no https option",
bareURLString: "http://192.168.99.100:30563",
https: false,
expectedHTTPSFormattedURLString: "http://192.168.99.100:30563",
expectedIsHTTPSchemedURL: true,
},
{
description: "no https for non-http schemed with no https option",
bareURLString: "xyz.http.myservice:30563",
https: false,
description: "no https for non-http schemed with no https option",
bareURLString: "xyz.http.myservice:30563",
https: false,
expectedHTTPSFormattedURLString: "xyz.http.myservice:30563",
expectedIsHTTPSchemedURL: false,
},
{
description: "https for http schemed with https option",
bareURLString: "http://192.168.99.100:30563",
https: true,
description: "https for http schemed with https option",
bareURLString: "http://192.168.99.100:30563",
https: true,
expectedHTTPSFormattedURLString: "https://192.168.99.100:30563",
expectedIsHTTPSchemedURL: true,
},
{
description: "no https for non-http schemed with https option and http substring",
bareURLString: "xyz.http.myservice:30563",
https: true,
description: "no https for non-http schemed with https option and http substring",
bareURLString: "xyz.http.myservice:30563",
https: true,
expectedHTTPSFormattedURLString: "xyz.http.myservice:30563",
expectedIsHTTPSchemedURL: false,
},
......@@ -364,7 +364,7 @@ func TestGetServiceURLs(t *testing.T) {
}
urls, err := GetServiceURLs(test.api, test.namespace, defaultTemplate)
if err != nil && !test.err {
t.Errorf("Error GetServiceURLs %s", err)
t.Errorf("Error GetServiceURLs %v", err)
}
if err == nil && test.err {
t.Errorf("Test should have failed, but didn't")
......@@ -431,7 +431,7 @@ func TestGetServiceURLsForService(t *testing.T) {
}
urls, err := GetServiceURLsForService(test.api, test.namespace, test.service, defaultTemplate)
if err != nil && !test.err {
t.Errorf("Error GetServiceURLsForService %s", err)
t.Errorf("Error GetServiceURLsForService %v", err)
}
if err == nil && test.err {
t.Errorf("Test should have failed, but didn't")
......
......@@ -28,7 +28,7 @@ func TestNewSSHClient(t *testing.T) {
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %s", err)
t.Fatalf("Error starting ssh server: %v", err)
}
d := &tests.MockDriver{
Port: port,
......@@ -39,7 +39,7 @@ func TestNewSSHClient(t *testing.T) {
}
c, err := NewSSHClient(d)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
t.Fatalf("Unexpected error: %v", err)
}
cmd := "foo"
......@@ -75,7 +75,7 @@ func TestNewSSHHost(t *testing.T) {
h, err := newSSHHost(&d)
if err != nil {
t.Fatalf("Unexpected error creating host: %s", err)
t.Fatalf("Unexpected error creating host: %v", err)
}
if h.SSHKeyPath != sshKeyPath {
......
......@@ -120,7 +120,7 @@ func (s *SSHServer) Start() (int, error) {
// Note: string(req.Payload) adds additional characters to start of input.
var cmd execRequest
if err := ssh.Unmarshal(req.Payload, &cmd); err != nil {
glog.Errorf("Unmarshall encountered error: %s with req: %v", err, req.Type)
glog.Errorf("Unmarshall encountered error: %v with req: %v", err, req.Type)
return
}
s.Commands[cmd.Command] = 1
......
......@@ -208,7 +208,7 @@ CRIO_MINIKUBE_OPTIONS='{{ range .EngineOptions.InsecureRegistry }}--insecure-reg
// This is unlikely to cause issues unless the user has explicitly requested CRIO, so just log a warning.
if err := p.Service("crio", serviceaction.Restart); err != nil {
log.Warn("Unable to restart crio service. Error: %s", err)
log.Warn("Unable to restart crio service. Error: %v", err)
}
return nil
......@@ -264,7 +264,7 @@ func configureAuth(p *BuildrootProvisioner) error {
})
if err != nil {
return fmt.Errorf("error generating server cert: %s", err)
return fmt.Errorf("error generating server cert: %v", err)
}
remoteCerts := map[string]string{
......
......@@ -66,19 +66,19 @@ func setElement(e reflect.Value, v string) error {
case net.IPNet:
_, cidr, err := net.ParseCIDR(v)
if err != nil {
return fmt.Errorf("Error converting input %s to a CIDR: %s", v, err)
return fmt.Errorf("Error converting input %s to a CIDR: %v", v, err)
}
e.Set(reflect.ValueOf(*cidr))
case utilnet.PortRange:
pr, err := utilnet.ParsePortRange(v)
if err != nil {
return fmt.Errorf("Error converting input %s to PortRange: %s", v, err)
return fmt.Errorf("Error converting input %s to PortRange: %v", v, err)
}
e.Set(reflect.ValueOf(*pr))
case time.Duration:
dur, err := time.ParseDuration(v)
if err != nil {
return fmt.Errorf("Error converting input %s to Duration: %s", v, err)
return fmt.Errorf("Error converting input %s to Duration: %v", v, err)
}
e.Set(reflect.ValueOf(dur))
case []string:
......@@ -126,7 +126,7 @@ func convertMap(e reflect.Value, v string) error {
func convertInt(e reflect.Value, v string) error {
i, err := strconv.Atoi(v)
if err != nil {
return fmt.Errorf("Error converting input %s to an integer: %s", v, err)
return fmt.Errorf("Error converting input %s to an integer: %v", v, err)
}
e.SetInt(int64(i))
return nil
......@@ -140,7 +140,7 @@ func convertString(e reflect.Value, v string) error {
func convertFloat(e reflect.Value, v string) error {
f, err := strconv.ParseFloat(v, 64)
if err != nil {
return fmt.Errorf("Error converting input %s to a float: %s", v, err)
return fmt.Errorf("Error converting input %s to a float: %v", v, err)
}
e.SetFloat(f)
return nil
......@@ -149,7 +149,7 @@ func convertFloat(e reflect.Value, v string) error {
func convertBool(e reflect.Value, v string) error {
b, err := strconv.ParseBool(v)
if err != nil {
return fmt.Errorf("Error converting input %s to a bool: %s", v, err)
return fmt.Errorf("Error converting input %s to a bool: %v", v, err)
}
e.SetBool(b)
return nil
......
......@@ -104,7 +104,7 @@ func TestFindNestedStrings(t *testing.T) {
} {
v, err := findNestedElement(tc.input, &a)
if err != nil {
t.Fatalf("Did not expect error. Got: %s", err)
t.Fatalf("Did not expect error. Got: %v", err)
}
if v.String() != tc.output {
t.Fatalf("Expected: %s, got %s", tc.output, v.String())
......@@ -126,7 +126,7 @@ func TestFindNestedInts(t *testing.T) {
} {
v, err := findNestedElement(tc.input, &a)
if err != nil {
t.Fatalf("Did not expect error. Got: %s", err)
t.Fatalf("Did not expect error. Got: %v", err)
}
if v.Int() != tc.output {
t.Fatalf("Expected: %d, got %d", tc.output, v.Int())
......@@ -151,7 +151,7 @@ func TestFindNestedFloats(t *testing.T) {
} {
v, err := findNestedElement(tc.input, &a)
if err != nil {
t.Fatalf("Did not expect error. Got: %s", err)
t.Fatalf("Did not expect error. Got: %v", err)
}
// Floating point comparison is tricky.
......@@ -187,7 +187,7 @@ func TestSetElement(t *testing.T) {
} {
a := buildConfig()
if err := FindAndSet(tc.path, &a, tc.newval); err != nil {
t.Fatalf("Error setting value: %s", err)
t.Fatalf("Error setting value: %v", err)
}
if !tc.checker(a) {
t.Fatalf("Error, values not correct: %v, %s, %s", a, tc.newval, tc.path)
......
......@@ -50,7 +50,7 @@ func GenerateCACert(certPath, keyPath string, name string) error {
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
IsCA: true,
}
return writeCertsAndKeys(&template, certPath, priv, keyPath, &template, priv)
......
......@@ -74,14 +74,14 @@ func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
fmt.Println("Downloading Minikube ISO")
if err := download.ToFile(isoURL, f.GetISOCacheFilepath(isoURL), options); err != nil {
return errors.Wrap(err, "Error downloading Minikube ISO")
return errors.Wrap(err, isoURL)
}
return nil
}
func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool {
// store the miniube-iso inside the .minikube dir
// store the minikube-iso inside the .minikube dir
urlObj, err := url.Parse(isoURL)
if err != nil {
......
......@@ -59,7 +59,7 @@ func TestCacheMinikubeISOFromURL(t *testing.T) {
}))
isoURL := server.URL + "/minikube-test.iso"
if err := dler.CacheMinikubeISOFromURL(isoURL); err != nil {
t.Fatalf("Unexpected error from CacheMinikubeISOFromURL: %s", err)
t.Fatalf("Unexpected error from CacheMinikubeISOFromURL: %v", err)
}
transferred, err := ioutil.ReadFile(filepath.Join(isoPath))
......
......@@ -70,7 +70,7 @@ func TestValidFlags(t *testing.T) {
var e ExtraOptionSlice
flags.Var(&e, "e", "usage")
if err := flags.Parse(tc.args); err != nil {
t.Errorf("Unexpected error: %s for %s.", err, tc)
t.Errorf("Unexpected error: %v for %s.", err, tc)
}
if !reflect.DeepEqual(e, tc.values) {
......
......@@ -220,7 +220,7 @@ func decode(data []byte) (*api.Config, error) {
return config.(*api.Config), nil
}
// GetKubeConfigStatus verifys the ip stored in kubeconfig.
// GetKubeConfigStatus verifies the ip stored in kubeconfig.
func GetKubeConfigStatus(ip net.IP, filename string, machineName string) (bool, error) {
if ip == nil {
return false, fmt.Errorf("Error, empty ip passed")
......
......@@ -143,7 +143,7 @@ func TestSetupKubeConfig(t *testing.T) {
t.Parallel()
tmpDir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("Error making temp directory %s", err)
t.Fatalf("Error making temp directory %v", err)
}
test.cfg.SetKubeConfigFile(filepath.Join(tmpDir, "kubeconfig"))
if len(test.existingCfg) != 0 {
......@@ -151,14 +151,14 @@ func TestSetupKubeConfig(t *testing.T) {
}
err = SetupKubeConfig(test.cfg)
if err != nil && !test.err {
t.Errorf("Got unexpected error: %s", err)
t.Errorf("Got unexpected error: %v", err)
}
if err == nil && test.err {
t.Errorf("Expected error but got none")
}
config, err := ReadConfigOrNew(test.cfg.GetKubeConfigFile())
if err != nil {
t.Errorf("Error reading kubeconfig file: %s", err)
t.Errorf("Error reading kubeconfig file: %v", err)
}
if test.cfg.KeepContext && config.CurrentContext == test.cfg.ClusterName {
t.Errorf("Context was changed even though KeepContext was true")
......@@ -213,10 +213,10 @@ func TestGetKubeConfigStatus(t *testing.T) {
configFilename := tempFile(t, test.existing)
statusActual, err := GetKubeConfigStatus(test.ip, configFilename, "minikube")
if err != nil && !test.err {
t.Errorf("Got unexpected error: %s", err)
t.Errorf("Got unexpected error: %v", err)
}
if err == nil && test.err {
t.Errorf("Expected error but got none: %s", err)
t.Errorf("Expected error but got none: %v", err)
}
if test.status != statusActual {
t.Errorf("Expected status %t, but got %t", test.status, statusActual)
......@@ -270,10 +270,10 @@ func TestUpdateKubeconfigIP(t *testing.T) {
configFilename := tempFile(t, test.existing)
statusActual, err := UpdateKubeconfigIP(test.ip, configFilename, "minikube")
if err != nil && !test.err {
t.Errorf("Got unexpected error: %s", err)
t.Errorf("Got unexpected error: %v", err)
}
if err == nil && test.err {
t.Errorf("Expected error but got none: %s", err)
t.Errorf("Expected error but got none: %v", err)
}
if test.status != statusActual {
t.Errorf("Expected status %t, but got %t", test.status, statusActual)
......@@ -357,10 +357,10 @@ func TestGetIPFromKubeConfig(t *testing.T) {
configFilename := tempFile(t, test.cfg)
ip, err := getIPFromKubeConfig(configFilename, "minikube")
if err != nil && !test.err {
t.Errorf("Got unexpected error: %s", err)
t.Errorf("Got unexpected error: %v", err)
}
if err == nil && test.err {
t.Errorf("Expected error but got none: %s", err)
t.Errorf("Expected error but got none: %v", err)
}
if !ip.Equal(test.ip) {
t.Errorf("IP returned: %s does not match ip given: %s", ip, test.ip)
......
......@@ -66,7 +66,7 @@ func GetClient() (kubernetes.Interface, error) {
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
config, err := kubeConfig.ClientConfig()
if err != nil {
return nil, fmt.Errorf("Error creating kubeConfig: %s", err)
return nil, fmt.Errorf("Error creating kubeConfig: %v", err)
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
......
......@@ -46,7 +46,7 @@ func (r RetriableError) Error() string { return "Temporary Error: " + r.Err.Erro
func CalculateDiskSizeInMB(humanReadableDiskSize string) int {
diskSize, err := units.FromHumanSize(humanReadableDiskSize)
if err != nil {
glog.Errorf("Invalid disk size: %s", err)
glog.Errorf("Invalid disk size: %v", err)
}
return int(diskSize / units.MB)
}
......
......@@ -130,12 +130,12 @@ func TestMultiError(t *testing.T) {
expected := `Error 1
Error 2`
if err.Error() != expected {
t.Fatalf("%s != %s", err, expected)
t.Fatalf("%s != %s", err.Error(), expected)
}
m = MultiError{}
if err := m.ToError(); err != nil {
t.Fatalf("Unexpected error: %s", err)
t.Fatalf("Unexpected error: %v", err)
}
}
......
......@@ -48,7 +48,7 @@ func testClusterDNS(t *testing.T) {
// The query result is not as important as service reachability
out, err := kr.RunCommand([]string{"exec", busybox, "nslookup", "localhost"})
if err != nil {
t.Errorf("nslookup within busybox failed: %s", err)
t.Errorf("nslookup within busybox failed: %v", err)
}
clusterIP := []byte("10.96.0.1")
if !bytes.Contains(out, clusterIP) {
......@@ -73,7 +73,7 @@ func busyBoxPod(t *testing.T, c kubernetes.Interface, kr *util.KubectlRunner) st
}
// TODO(tstromberg): Refactor WaitForBusyboxRunning to return name of pod.
if err := util.WaitForBusyboxRunning(t, "default"); err != nil {
t.Fatalf("Waiting for busybox pod to be up: %s", err)
t.Fatalf("Waiting for busybox pod to be up: %v", err)
}
pods, err := c.CoreV1().Pods("default").List(metav1.ListOptions{LabelSelector: "integration-test=busybox"})
......
......@@ -19,6 +19,7 @@ limitations under the License.
package integration
import (
"os"
"os/exec"
"testing"
"time"
......@@ -26,16 +27,30 @@ import (
"k8s.io/minikube/test/integration/util"
)
// Assert that docker-env subcommand outputs usable information for "docker ps"
func testClusterEnv(t *testing.T) {
t.Parallel()
minikubeRunner := NewMinikubeRunner(t)
r := NewMinikubeRunner(t)
dockerEnvVars := minikubeRunner.RunCommand("docker-env", true)
if err := minikubeRunner.SetEnvFromEnvCmdOutput(dockerEnvVars); err != nil {
t.Fatalf("Error parsing output: %v", err)
// Set a specific shell syntax so that we don't have to handle every possible user shell
envOut := r.RunCommand("docker-env --shell=bash", true)
vars := r.ParseEnvCmdOutput(envOut)
if len(vars) == 0 {
t.Fatalf("Failed to parse env vars:\n%s", envOut)
}
for k, v := range vars {
t.Logf("Found: %s=%s", k, v)
if err := os.Setenv(k, v); err != nil {
t.Errorf("failed to set %s=%s: %v", k, v, err)
}
}
path, err := exec.LookPath("docker")
if err != nil {
t.Fatalf("Unable to complete test: docker is not installed in PATH")
}
t.Logf("Using docker installed at %s", path)
var output []byte
dockerPs := func() error {
......@@ -47,6 +62,6 @@ func testClusterEnv(t *testing.T) {
return nil
}
if err := util.Retry(t, dockerPs, 3*time.Second, 5); err != nil {
t.Fatalf("Error running command: %s. Error: %s Output: %s", "docker ps", err, output)
t.Fatalf("Error running command: %s. Error: %v Output: %s", "docker ps", err, output)
}
}
......@@ -32,8 +32,7 @@ func TestDocker(t *testing.T) {
}
minikubeRunner.RunCommand("delete", false)
startCmd := fmt.Sprintf("start %s %s %s", minikubeRunner.StartArgs, minikubeRunner.Args,
"--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true")
startCmd := fmt.Sprintf("start %s %s %s", minikubeRunner.StartArgs, minikubeRunner.Args, "--docker-env=FOO=BAR --docker-env=BAZ=BAT --docker-opt=debug --docker-opt=icc=true")
minikubeRunner.RunCommand(startCmd, true)
minikubeRunner.EnsureRunning()
......
......@@ -32,7 +32,7 @@ func TestMain(m *testing.M) {
var binaryPath = flag.String("binary", "../../out/minikube", "path to minikube binary")
var args = flag.String("minikube-args", "", "Arguments to pass to minikube")
var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to minikube start")
var testdataDir = flag.String("testdata-dir", "testdata", "source of testdata relative to test/integration")
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")
func NewMinikubeRunner(t *testing.T) util.MinikubeRunner {
return util.MinikubeRunner{
......
......@@ -74,7 +74,7 @@ func testPackages(t *testing.T) {
for _, pkg := range packages {
if output, err := minikubeRunner.SSH(fmt.Sprintf("which %s", pkg)); err != nil {
t.Errorf("Error finding package: %s. Error: %s. Output: %s", pkg, err, output)
t.Errorf("Error finding package: %s. Error: %v. Output: %s", pkg, err, output)
}
}
......@@ -94,7 +94,7 @@ func testPersistence(t *testing.T) {
} {
output, err := minikubeRunner.SSH(fmt.Sprintf("df %s | tail -n 1 | awk '{print $1}'", dir))
if err != nil {
t.Errorf("Error checking device for %s. Error: %s.", dir, err)
t.Errorf("Error checking device for %s. Error: %v", dir, err)
}
if !strings.Contains(output, "/dev/sda1") {
t.Errorf("Path %s is not mounted persistently. %s", dir, output)
......
......@@ -23,6 +23,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
......@@ -34,6 +35,9 @@ import (
func testMounting(t *testing.T) {
t.Parallel()
if runtime.GOOS == "darwin" {
t.Skip("mount tests disabled in darwin due to timeout (issue#3200)")
}
if strings.Contains(*args, "--vm-driver=none") {
t.Skip("skipping test for none driver as it does not need mount")
}
......@@ -65,7 +69,7 @@ func testMounting(t *testing.T) {
path := filepath.Join(tempDir, file)
err = ioutil.WriteFile(path, []byte(expected), 0644)
if err != nil {
t.Fatalf("Unexpected error while writing file %s: %s.", path, err)
t.Fatalf("Unexpected error while writing file %s: %v", path, err)
}
}
......@@ -123,13 +127,13 @@ func testMounting(t *testing.T) {
// test that frompodremove can be deleted on the host
path = filepath.Join(tempDir, "frompodremove")
if err := os.Remove(path); err != nil {
t.Fatalf("Unexpected error removing file %s: %s", path, err)
t.Fatalf("Unexpected error removing file %s: %v", path, err)
}
return nil
}
if err := util.Retry(t, mountTest, 5*time.Second, 40); err != nil {
t.Fatal("mountTest failed with error:", err)
t.Fatalf("mountTest failed with error: %v", err)
}
}
......@@ -60,7 +60,7 @@ func testProvisioning(t *testing.T) {
if len(scl.Items) > 0 {
return nil
}
return fmt.Errorf("no StorageClass yet")
return fmt.Errorf("No default StorageClass yet.")
}
if err := util.Retry(t, checkStorageClass, 5*time.Second, 20); err != nil {
......@@ -83,13 +83,13 @@ func testProvisioning(t *testing.T) {
}
if err := checkPodRunning(); err != nil {
t.Fatal("Check storage-provisioner pod running failed with error: ", err)
t.Fatalf("Check storage-provisioner pod running failed with error: %v", err)
}
// Now create the PVC
pvcPath := filepath.Join(*testdataDir, "pvc.yaml")
if _, err := kubectlRunner.RunCommand([]string{"create", "-f", pvcPath}); err != nil {
t.Fatalf("Error creating pvc")
t.Fatalf("Error creating pvc: %v", err)
}
// And check that it gets bound to a PV.
......@@ -106,7 +106,7 @@ func testProvisioning(t *testing.T) {
}
if err := util.Retry(t, checkStorage, 2*time.Second, 5); err != nil {
t.Fatal("PV Creation failed with error:", err)
t.Fatalf("PV Creation failed with error: %v", err)
}
}
......@@ -22,7 +22,6 @@ import (
"encoding/json"
"fmt"
"math/rand"
"os"
"os/exec"
"path/filepath"
"regexp"
......@@ -76,7 +75,7 @@ func (m *MinikubeRunner) RunCommand(command string, checkError bool) string {
if exitError, ok := err.(*exec.ExitError); ok {
m.T.Fatalf("Error running command: %s %s. Output: %s", command, exitError.Stderr, stdout)
} else {
m.T.Fatalf("Error running command: %s %s. Output: %s", command, err, stdout)
m.T.Fatalf("Error running command: %s %v. Output: %s", command, err, stdout)
}
}
return string(stdout)
......@@ -88,7 +87,7 @@ func (m *MinikubeRunner) RunDaemon(command string) (*exec.Cmd, *bufio.Reader) {
cmd := exec.Command(path, commandArr...)
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
m.T.Fatalf("stdout pipe failed: %v", err)
m.T.Fatalf("stdout pipe failed: %s %v", command, err)
}
err = cmd.Start()
......@@ -121,19 +120,14 @@ func (m *MinikubeRunner) EnsureRunning() {
m.CheckStatus("Running")
}
func (m *MinikubeRunner) SetEnvFromEnvCmdOutput(dockerEnvVars string) error {
// ParseEnvCmdOutput parses the output of `env` (assumes bash)
func (m *MinikubeRunner) ParseEnvCmdOutput(out string) map[string]string {
env := map[string]string{}
re := regexp.MustCompile(`(\w+?) ?= ?"?(.+?)"?\n`)
matches := re.FindAllStringSubmatch(dockerEnvVars, -1)
seenEnvVar := false
for _, m := range matches {
seenEnvVar = true
key, val := m[1], m[2]
os.Setenv(key, val)
for _, m := range re.FindAllStringSubmatch(out, -1) {
env[m[1]] = m[2]
}
if !seenEnvVar {
return fmt.Errorf("Error: No environment variables were found in docker-env command output: %s", dockerEnvVars)
}
return nil
return env
}
func (m *MinikubeRunner) GetStatus() string {
......@@ -189,7 +183,7 @@ func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) {
cmd := exec.Command(k.BinaryPath, args...)
stdout, err = cmd.CombinedOutput()
if err != nil {
k.T.Logf("Error %s running command %s. Return code: %s", stdout, args, err)
k.T.Logf("Error %s running command %s. Return code: %v", stdout, args, err)
return &commonutil.RetriableError{Err: fmt.Errorf("Error running command: %v. Output: %s", err, stdout)}
}
return nil
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册