diff --git a/README.md b/README.md index 4d3994dc13..0e285191b2 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ Other drivers which are not yet part of our continuous integration system are: * [hyperv](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperV-driver) * [vmware](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#vmware-unified-driver) +* [parallels](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#parallels-driver) ## Quick Start diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go index 413e8823ed..668ee9815a 100644 --- a/cmd/minikube/cmd/status.go +++ b/cmd/minikube/cmd/status.go @@ -18,28 +18,47 @@ package cmd import ( "os" + "text/template" "github.com/docker/machine/libmachine/state" "github.com/golang/glog" - "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" "github.com/spf13/viper" cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config" "k8s.io/minikube/cmd/util" "k8s.io/minikube/pkg/minikube/cluster" "k8s.io/minikube/pkg/minikube/config" - pkg_config "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/machine" pkgutil "k8s.io/minikube/pkg/util" ) +var statusFormat string + +// Status represents the status +type Status struct { + Host string + Kubelet string + APIServer string + Kubeconfig string +} + +const ( + minikubeNotRunningStatusFlag = 1 << 0 + clusterNotRunningStatusFlag = 1 << 1 + k8sNotRunningStatusFlag = 1 << 2 +) + // statusCmd represents the status command var statusCmd = &cobra.Command{ Use: "status", Short: "Gets the status of a local kubernetes cluster", - Long: `Gets the status of a local kubernetes cluster.`, + Long: `Gets the status of a local kubernetes cluster. + Exit status contains the status of minikube's VM, cluster and kubernetes encoded on it's bits in this order from right to left. + Eg: 7 meaning: 1 (for minikube NOK) + 2 (for cluster NOK) + 4 (for kubernetes NOK)`, Run: func(cmd *cobra.Command, args []string) { + var returnCode = 0 api, err := machine.NewAPIClient() if err != nil { exit.WithCode(exit.Unavailable, "Error getting client: %v", err) @@ -60,10 +79,12 @@ var statusCmd = &cobra.Command{ if err != nil { exit.WithError("Error getting bootstrapper", err) } - kubeletSt, err = clusterBootstrapper.GetKubeletStatus() if err != nil { glog.Warningf("kubelet err: %v", err) + returnCode |= clusterNotRunningStatusFlag + } else if kubeletSt != state.Running.String() { + returnCode |= clusterNotRunningStatusFlag } ip, err := cluster.GetHostDriverIP(api, config.GetMachineName()) @@ -80,34 +101,47 @@ var statusCmd = &cobra.Command{ apiserverSt, err = clusterBootstrapper.GetAPIServerStatus(ip, apiserverPort) if err != nil { glog.Errorln("Error apiserver status:", err) + } else if apiserverSt != state.Running.String() { + returnCode |= clusterNotRunningStatusFlag } ks, err := pkgutil.GetKubeConfigStatus(ip, util.GetKubeConfigPath(), config.GetMachineName()) if err != nil { glog.Errorln("Error kubeconfig status:", err) } - if ks { kubeconfigSt = "Correctly Configured: pointing to minikube-vm at " + ip.String() } else { kubeconfigSt = "Misconfigured: pointing to stale minikube-vm." + "\nTo fix the kubectl context, run minikube update-context" + returnCode |= k8sNotRunningStatusFlag } + } else { + returnCode |= minikubeNotRunningStatusFlag } - var data [][]string - data = append(data, []string{pkg_config.GetMachineName(), hostSt, kubeletSt, apiserverSt, kubeconfigSt}) + status := Status{ + Host: hostSt, + Kubelet: kubeletSt, + APIServer: apiserverSt, + Kubeconfig: kubeconfigSt, + } + tmpl, err := template.New("status").Parse(statusFormat) + if err != nil { + exit.WithError("Error creating status template", err) + } + err = tmpl.Execute(os.Stdout, status) + if err != nil { + exit.WithError("Error executing status template", err) + } - table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"Profile", "Host", "Kubelet", "APIServer", "Kubectl"}) - table.SetAutoFormatHeaders(false) - table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true}) - table.SetCenterSeparator("|") - table.AppendBulk(data) // Add Bulk Data - table.Render() + os.Exit(returnCode) }, } func init() { + statusCmd.Flags().StringVar(&statusFormat, "format", constants.DefaultStatusFormat, + `Go template format string for the status output. The format for Go templates can be found here: https://golang.org/pkg/text/template/ +For the list accessible variables for the template, see the struct values here: https://godoc.org/k8s.io/minikube/cmd/minikube/cmd#Status`) RootCmd.AddCommand(statusCmd) } diff --git a/deploy/iso/minikube-iso/package/conmon-master/conmon-master.hash b/deploy/iso/minikube-iso/package/conmon-master/conmon-master.hash index cc13eb0cc8..14ed1bd8e9 100644 --- a/deploy/iso/minikube-iso/package/conmon-master/conmon-master.hash +++ b/deploy/iso/minikube-iso/package/conmon-master/conmon-master.hash @@ -1 +1,3 @@ +# Locally computed sha256 4f978a59c6ee516f7e3febfb3b0360a17d1be2c283313e1aeb27adcb8c8f9166 dde3ccf93f01ce5a3e0f7a2c97053697cc3ed152.tar.gz +sha256 75fad6e66b43c5039719edbd82ba072723aea6a9d4d8be4e7ac1c245a291ab1b 8455ce1ef385120deb827d0f0588c04357bad4c4.tar.gz diff --git a/deploy/iso/minikube-iso/package/conmon-master/conmon-master.mk b/deploy/iso/minikube-iso/package/conmon-master/conmon-master.mk index 0586253f1c..17bca7e61e 100644 --- a/deploy/iso/minikube-iso/package/conmon-master/conmon-master.mk +++ b/deploy/iso/minikube-iso/package/conmon-master/conmon-master.mk @@ -1,4 +1,11 @@ -CONMON_MASTER_VERSION = dde3ccf93f01ce5a3e0f7a2c97053697cc3ed152 +################################################################################ +# +# conmon +# +################################################################################ + +# HEAD as of 2019-06-13 +CONMON_MASTER_VERSION = 8455ce1ef385120deb827d0f0588c04357bad4c4 CONMON_MASTER_SITE = https://github.com/containers/conmon/archive CONMON_MASTER_SOURCE = $(CONMON_MASTER_VERSION).tar.gz CONMON_MASTER_LICENSE = Apache-2.0 diff --git a/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.hash b/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.hash index d3446fe770..45cfdaa419 100644 --- a/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.hash +++ b/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.hash @@ -1,2 +1,3 @@ sha256 ccf83574556793ceb01717dc91c66b70f183c60c2bbec70283939aae8fdef768 crictl-v1.11.1-linux-amd64.tar.gz sha256 9bdbea7a2b382494aff2ff014da328a042c5aba9096a7772e57fdf487e5a1d51 crictl-v1.13.0-linux-amd64.tar.gz +sha256 c3b71be1f363e16078b51334967348aab4f72f46ef64a61fe7754e029779d45a crictl-v1.15.0-linux-amd64.tar.gz diff --git a/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.mk b/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.mk index 72db6c1647..9ed0e23688 100644 --- a/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.mk +++ b/deploy/iso/minikube-iso/package/crictl-bin/crictl-bin.mk @@ -4,7 +4,7 @@ # ################################################################################ -CRICTL_BIN_VERSION = v1.13.0 +CRICTL_BIN_VERSION = v1.15.0 CRICTL_BIN_SITE = https://github.com/kubernetes-sigs/cri-tools/releases/download/$(CRICTL_BIN_VERSION) CRICTL_BIN_SOURCE = crictl-$(CRICTL_BIN_VERSION)-linux-amd64.tar.gz CRICTL_BIN_STRIP_COMPONENTS = 0 diff --git a/deploy/iso/minikube-iso/package/podman/podman.hash b/deploy/iso/minikube-iso/package/podman/podman.hash index 7f270bdbb3..2a11dc7028 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.hash +++ b/deploy/iso/minikube-iso/package/podman/podman.hash @@ -6,3 +6,6 @@ sha256 f7a462563dd587208eff3c3c0689bc4d01071a8f7933bec2a13126be123f63a8 v1.0.0.t sha256 b4d6843e13c0f2f1557ab20b4364bb42ea9102442ee3f1be806c06128aa687d8 v1.2.0.tar.gz sha256 548a82b62ff183ca9e68f164779d6ded94fce07261242ceb96faa267fcecf56b v1.3.0.tar.gz sha256 7ccbfa80900cd438468986911038da4c38382ef507a2fa717217faefb738fbc4 v1.3.1.tar.gz +sha256 17fdf68e85106d0848e89825e191198a4079bb6d9ca6dd3e415e5c010192db9e v1.4.0.tar.gz +sha256 45eb7bccd81a1431b0c7a0697829c0bcc397048595d143fd91179b31d22a3c63 v1.4.1.tar.gz +sha256 2e027c1b935f3a03f27ef7f17823ccf334607a17d033d4ce53a90b98294e7f68 v1.4.4.tar.gz diff --git a/deploy/iso/minikube-iso/package/podman/podman.mk b/deploy/iso/minikube-iso/package/podman/podman.mk index 5ee095a225..7286736598 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.mk +++ b/deploy/iso/minikube-iso/package/podman/podman.mk @@ -1,5 +1,5 @@ -PODMAN_VERSION = v1.3.1 -PODMAN_COMMIT = 7210727e205c333af9a2d0ed0bb66adcf92a6369 +PODMAN_VERSION = v1.4.4 +PODMAN_COMMIT = b3f10c8be229bcc58c1673b0431285fd5fce1293 PODMAN_SITE = https://github.com/containers/libpod/archive PODMAN_SOURCE = $(PODMAN_VERSION).tar.gz PODMAN_LICENSE = Apache-2.0 diff --git a/docs/drivers.md b/docs/drivers.md index 103b7ec565..40ade7d5fd 100644 --- a/docs/drivers.md +++ b/docs/drivers.md @@ -13,6 +13,7 @@ the host PATH: * [Hyperkit](#hyperkit-driver) * [HyperV](#hyperv-driver) * [VMware](#vmware-unified-driver) +* [Parallels](#parallels-driver) ## KVM2 driver @@ -214,6 +215,30 @@ and run minikube as usual: minikube start ``` +## Parallels driver + +This driver is useful for users who own Parallels Desktop for Mac that do not have VT-x hardware support required by the hyperkit driver. + +Pre-requisites: Parallels Desktop for Mac + +Install the [Parallels docker-machine driver](https://github.com/Parallels/docker-machine-parallels) using [brew](https://brew.sh): + +```shell +brew install docker-machine-parallels +``` + +To use the driver: + +```shell +minikube start --vm-driver parallels +``` + +or, to use parallels as a default driver for minikube: + +```shell +minikube config set vm-driver parallels +``` + ## Troubleshooting minikube is currently unable to display the error message received back from the VM driver. Users can however reveal the error by passing `--alsologtostderr -v=8` to `minikube start`. For instance: diff --git a/hack/prow/run_tests.py b/hack/prow/run_tests.py index 9fdae01e70..80711191bb 100755 --- a/hack/prow/run_tests.py +++ b/hack/prow/run_tests.py @@ -20,15 +20,16 @@ https://k8s-testgrid.appspot.com """ +from __future__ import print_function import os, sys, json, re, argparse, calendar, time, subprocess, shlex def get_classname(test_script): """ parse out the test classname from the full path of the test script""" - classname = os.path.basename(test).split('.')[0] + classname = os.path.basename(test_script).split('.')[0] return classname def write_results(outdir, started, finished, test_results): - """ write current results into artifacts/junit_runner.xml + """ write current results into artifacts/junit_runner.xml format: @@ -36,7 +37,7 @@ def write_results(outdir, started, finished, test_results): ... - write the started.json and finish.json files + write the started.json and finish.json files format: started.json: {"timestamp":STARTTIMEINSECONDSINCEEPOCH} finished.json: {"timestamp":FINISHTIMEINSECONDSINCEEPOCH, @@ -67,9 +68,9 @@ def write_results(outdir, started, finished, test_results): junit_xml.write('') junit_xml.close() - started_json.write(json.dumps(started)) + started_json.write(json.dumps(started)) started_json.close() - finished_json.write(json.dumps(finished)) + finished_json.write(json.dumps(finished)) finished_json.close() return @@ -86,12 +87,12 @@ def upload_results(outdir, test_script, buildnum, bucket): classname = get_classname(test_script) args = shlex.split("gsutil cp -R gcs_out/ gs://%s/logs/%s/%s" % (bucket, classname, buildnum)) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - for line in p.stdout: - print line + for line in str(p.stdout): + print(line) def run_tests(test_script, log_path, exit_status, started, finished, test_results): """ execute the test script, grab the start time, finish time, build logs and exit status - Pull test results and important information out of the build log + Pull test results and important information out of the build log test results format should be: === RUN TestFunctional/Mounting --- PASS: TestFunctional (42.87s) @@ -109,9 +110,9 @@ def run_tests(test_script, log_path, exit_status, started, finished, test_result classname = get_classname(test_script) build_log_file = open(log_path, 'w') p = subprocess.Popen(['bash','-x',test_script], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - for line in p.stdout: + for line in str(p.stdout): build_log_file.write(line) - print line.rstrip() + print(line.rstrip()) if '--- PASS' in line: match = re.match('.*--- PASS: ([^ ]+) \(([0-9.]+)s\)', line) (name, seconds) = match.group(1, 2) diff --git a/pkg/minikube/bootstrapper/kubeadm/templates.go b/pkg/minikube/bootstrapper/kubeadm/templates.go index 85c4c36b44..70ae1aad28 100644 --- a/pkg/minikube/bootstrapper/kubeadm/templates.go +++ b/pkg/minikube/bootstrapper/kubeadm/templates.go @@ -171,7 +171,8 @@ Documentation=http://kubernetes.io/docs/ ExecStart=/usr/bin/kubelet Restart=always StartLimitInterval=0 -RestartSec=10 +# Tuned for local dev: faster than upstream default (10s), but slower than systemd default (100ms) +RestartSec=600ms [Install] WantedBy=multi-user.target diff --git a/pkg/minikube/constants/constants.go b/pkg/minikube/constants/constants.go index 7739a78c70..d52f913115 100644 --- a/pkg/minikube/constants/constants.go +++ b/pkg/minikube/constants/constants.go @@ -163,6 +163,12 @@ const ( MinimumDiskSize = "2000mb" // DefaultVMDriver is the default virtual machine driver name DefaultVMDriver = DriverVirtualbox + // DefaultStatusFormat is the default format of a host + DefaultStatusFormat = `host: {{.Host}} +kubelet: {{.Kubelet}} +apiserver: {{.APIServer}} +kubectl: {{.Kubeconfig}} +` // DefaultAddonListFormat is the default format of addon list DefaultAddonListFormat = "- {{.AddonName}}: {{.AddonStatus}}\n" // DefaultConfigViewFormat is the default format of config view diff --git a/pkg/minikube/extract/extract_test.go b/pkg/minikube/extract/extract_test.go index 135e430fea..c0ac9914f9 100644 --- a/pkg/minikube/extract/extract_test.go +++ b/pkg/minikube/extract/extract_test.go @@ -19,6 +19,8 @@ package extract import ( "encoding/json" "io/ioutil" + "os" + "path/filepath" "reflect" "testing" ) @@ -30,8 +32,22 @@ func TestExtract(t *testing.T) { // The function we care about functions := []string{"extract.PrintToScreen"} - // The directory where the sample translation file is in - output := "testdata/" + tempdir, err := ioutil.TempDir("", "temptestdata") + if err != nil { + t.Fatalf("Creating temp dir: %v", err) + } + defer os.RemoveAll(tempdir) + + src, err := ioutil.ReadFile("testdata/test.json") + if err != nil { + t.Fatalf("Reading json file: %v", err) + } + + tempfile := filepath.Join(tempdir, "tmpdata.json") + err = ioutil.WriteFile(tempfile, src, 0666) + if err != nil { + t.Fatalf("Writing temp json file: %v", err) + } expected := map[string]interface{}{ "Hint: This is not a URL, come on.": "", @@ -41,18 +57,18 @@ func TestExtract(t *testing.T) { "Wow another string: %s": "", } - err := TranslatableStrings(paths, functions, output) - + err = TranslatableStrings(paths, functions, tempdir) if err != nil { t.Fatalf("Error translating strings: %v", err) } - var got map[string]interface{} - f, err := ioutil.ReadFile("testdata/test.json") + f, err := ioutil.ReadFile(tempfile) if err != nil { - t.Fatalf("Reading json file: %s", err) + t.Fatalf("Reading resulting json file: %v", err) } + var got map[string]interface{} + err = json.Unmarshal(f, &got) if err != nil { t.Fatalf("Error unmarshalling json: %v", err)