From f68716e2da76f939c224088c749748fbd2a50b53 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Mon, 6 Jul 2020 15:12:13 -0400 Subject: [PATCH] Set up logic for steps --- cmd/minikube/cmd/start.go | 6 +- go.mod | 1 + pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 2 + pkg/minikube/node/config.go | 2 + pkg/minikube/node/start.go | 3 +- pkg/minikube/out/out.go | 7 +- .../out/{ => register}/cloud_events.go | 16 +++- pkg/minikube/out/register/json.go | 23 ++++++ pkg/minikube/out/register/log.go | 75 +++++++++++++++++++ pkg/minikube/out/{ => register}/register.go | 43 ++++++----- 10 files changed, 151 insertions(+), 27 deletions(-) rename pkg/minikube/out/{ => register}/cloud_events.go (73%) create mode 100644 pkg/minikube/out/register/json.go create mode 100644 pkg/minikube/out/register/log.go rename pkg/minikube/out/{ => register}/register.go (59%) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index cf885bad1c..7691502f45 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -57,6 +57,8 @@ import ( "k8s.io/minikube/pkg/minikube/node" "k8s.io/minikube/pkg/minikube/notify" "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/out/register" + "k8s.io/minikube/pkg/minikube/registry" "k8s.io/minikube/pkg/minikube/translate" "k8s.io/minikube/pkg/util" @@ -348,6 +350,7 @@ func displayVersion(version string) { prefix = fmt.Sprintf("[%s] ", ClusterFlagValue()) } + register.Reg.SetStep(register.InitialSetup) out.T(out.Happy, "{{.prefix}}minikube {{.version}} on {{.platform}}", out.V{"prefix": prefix, "version": version, "platform": platform()}) } @@ -364,6 +367,7 @@ func displayEnviron(env []string) { } func showKubectlInfo(kcs *kubeconfig.Settings, k8sVersion string, machineName string) error { + register.Reg.SetStep(register.Done) if kcs.KeepContext { out.T(out.Kubectl, "To connect to this cluster, use: kubectl --context={{.name}}", out.V{"name": kcs.ClusterName}) } else { @@ -476,7 +480,7 @@ func kubectlVersion(path string) (string, error) { func selectDriver(existing *config.ClusterConfig) (registry.DriverState, []registry.DriverState, bool) { // Technically unrelated, but important to perform before detection driver.SetLibvirtURI(viper.GetString(kvmQemuURI)) - + register.Reg.SetStep(register.SelectingDriver) // By default, the driver is whatever we used last time if existing != nil { old := hostDriver(existing) diff --git a/go.mod b/go.mod index 7306c6896c..d16121bdeb 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/google/go-containerregistry v0.0.0-20200601195303-96cf69f03a3c github.com/google/go-github v17.0.0+incompatible github.com/google/slowjam v0.0.0-20200530021616-df27e642fe7b + github.com/google/uuid v1.1.1 github.com/googleapis/gnostic v0.3.0 // indirect github.com/hashicorp/go-getter v1.4.0 github.com/hashicorp/go-retryablehttp v0.6.6 diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 78c44a99e6..b4b2650e5f 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -55,6 +55,7 @@ import ( "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/machine" "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/out/register" "k8s.io/minikube/pkg/minikube/sysinit" "k8s.io/minikube/pkg/minikube/vmpath" "k8s.io/minikube/pkg/util" @@ -394,6 +395,7 @@ func (k *Bootstrapper) WaitForNode(cfg config.ClusterConfig, n config.Node, time return nil } + register.Reg.SetStep(register.VerifyingKubernetes) out.T(out.HealthCheck, "Verifying Kubernetes components...") // TODO: #7706: for better performance we could use k.client inside minikube to avoid asking for external IP:PORT diff --git a/pkg/minikube/node/config.go b/pkg/minikube/node/config.go index 5b646d24d1..2b1db4e9a9 100644 --- a/pkg/minikube/node/config.go +++ b/pkg/minikube/node/config.go @@ -32,11 +32,13 @@ import ( "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/localpath" "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/out/register" "k8s.io/minikube/pkg/util/lock" ) func showVersionInfo(k8sVersion string, cr cruntime.Manager) { version, _ := cr.Version() + register.Reg.SetStep(register.PreparingKubernetes) out.T(cr.Style(), "Preparing Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}} ...", out.V{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version}) for _, v := range config.DockerOpt { out.T(out.Option, "opt {{.docker_option}}", out.V{"docker_option": v}) diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index fd3d19cf92..873d7df3a3 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -53,6 +53,7 @@ import ( "k8s.io/minikube/pkg/minikube/machine" "k8s.io/minikube/pkg/minikube/mustload" "k8s.io/minikube/pkg/minikube/out" + "k8s.io/minikube/pkg/minikube/out/register" "k8s.io/minikube/pkg/minikube/proxy" "k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/util/retry" @@ -205,7 +206,7 @@ func Start(starter Starter, apiServer bool) (*kubeconfig.Settings, error) { // Provision provisions the machine/container for the node func Provision(cc *config.ClusterConfig, n *config.Node, apiServer bool, delOnFail bool) (command.Runner, bool, libmachine.API, *host.Host, error) { - + register.Reg.SetStep(register.StartingNode) name := driver.MachineName(*cc, *n) if apiServer { out.T(out.ThumbsUp, "Starting control plane node {{.name}} in cluster {{.cluster}}", out.V{"name": name, "cluster": cc.Name}) diff --git a/pkg/minikube/out/out.go b/pkg/minikube/out/out.go index 24cf20b770..d413d5bf13 100644 --- a/pkg/minikube/out/out.go +++ b/pkg/minikube/out/out.go @@ -26,6 +26,7 @@ import ( "github.com/golang/glog" isatty "github.com/mattn/go-isatty" + "k8s.io/minikube/pkg/minikube/out/register" "k8s.io/minikube/pkg/minikube/translate" ) @@ -69,7 +70,11 @@ type V map[string]interface{} // T writes a stylized and templated message to stdout func T(style StyleEnum, format string, a ...V) { outStyled := ApplyTemplateFormatting(style, useColor, format, a...) - String(outStyled) + if JSON { + register.PrintStep(outStyled) + } else { + String(outStyled) + } } // String writes a basic formatted string to stdout diff --git a/pkg/minikube/out/cloud_events.go b/pkg/minikube/out/register/cloud_events.go similarity index 73% rename from pkg/minikube/out/cloud_events.go rename to pkg/minikube/out/register/cloud_events.go index ecbf85cd71..edef563efa 100644 --- a/pkg/minikube/out/cloud_events.go +++ b/pkg/minikube/out/register/cloud_events.go @@ -14,22 +14,30 @@ See the License for the specific language governing permissions and limitations under the License. */ -package out +package register import ( "fmt" cloudevents "github.com/cloudevents/sdk-go/v2" + "github.com/golang/glog" + guuid "github.com/google/uuid" ) -func printAsCloudEvent(eventType string, data map[string]string) { +const ( + specVersion = "1.0" +) + +func printAsCloudEvent(log Log, data map[string]string) { event := cloudevents.NewEvent() event.SetSource("https://minikube.sigs.k8s.io/") - event.SetType(eventType) + event.SetType(log.Type()) + event.SetSpecVersion(specVersion) event.SetData(cloudevents.ApplicationJSON, data) + event.SetID(guuid.New().String()) json, err := event.MarshalJSON() if err != nil { - fmt.Println(err) + glog.Warningf("error marashalling event: %v", err) } fmt.Println(string(json)) } diff --git a/pkg/minikube/out/register/json.go b/pkg/minikube/out/register/json.go new file mode 100644 index 0000000000..4521796bd2 --- /dev/null +++ b/pkg/minikube/out/register/json.go @@ -0,0 +1,23 @@ +/* +Copyright 2020 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 register + +// PrintStep prints a Step type in JSON format +func PrintStep(message string) { + s := NewStep(message) + printAsCloudEvent(s, s.data) +} diff --git a/pkg/minikube/out/register/log.go b/pkg/minikube/out/register/log.go new file mode 100644 index 0000000000..5b1d24e577 --- /dev/null +++ b/pkg/minikube/out/register/log.go @@ -0,0 +1,75 @@ +/* +Copyright 2020 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 register + +// Log represents the different types of logs that can be output as JSON +// This includes: Step, Download, DownloadProgress, Warning, Info, Error +type Log interface { + Type() string +} + +type Step struct { + data map[string]string +} + +func (s *Step) Type() string { + return "io.k8s.sigs.minikube.step" +} + +func NewStep(message string) *Step { + return &Step{data: map[string]string{ + "totalsteps": string(Reg.totalSteps()), + "currentstep": string(Reg.currentStep()), + "message": message, + "name": string(Reg.current), + }} +} + +type Download struct { +} + +func (s *Download) Type() string { + return "io.k8s.sigs.minikube.download" +} + +type DownloadProgress struct { +} + +func (s *DownloadProgress) Type() string { + return "io.k8s.sigs.minikube.download.progress" +} + +type Warning struct { +} + +func (s *Warning) Type() string { + return "io.k8s.sigs.minikube.warning" +} + +type Info struct { +} + +func (s *Info) Type() string { + return "io.k8s.sigs.minikube.info" +} + +type Error struct { +} + +func (s *Error) Type() string { + return "io.k8s.sigs.minikube.error" +} diff --git a/pkg/minikube/out/register.go b/pkg/minikube/out/register/register.go similarity index 59% rename from pkg/minikube/out/register.go rename to pkg/minikube/out/register/register.go index 3b8fbf7431..eba8141d04 100644 --- a/pkg/minikube/out/register.go +++ b/pkg/minikube/out/register/register.go @@ -14,27 +14,30 @@ See the License for the specific language governing permissions and limitations under the License. */ -package out +// Package register contains all the logic to print out `minikube start` in JSON +package register + +import "fmt" const ( - InitialSetup Step = "Initial Minikube Setup" - SelectingDriver Step = "Selecting Driver" - DownloadingArtifacts Step = "Downloading Artifacts" - StartingNode Step = "Starting Node" - PreparingKubernetes Step = "Preparing Kubernetes" - VerifyingKubernetes Step = "Verifying Kubernetes" - EnablingAddons Step = "Enabling Addons" - Done Step = "Done" + InitialSetup RegStep = "Initial Minikube Setup" + SelectingDriver RegStep = "Selecting Driver" + DownloadingArtifacts RegStep = "Downloading Artifacts" + StartingNode RegStep = "Starting Node" + PreparingKubernetes RegStep = "Preparing Kubernetes" + VerifyingKubernetes RegStep = "Verifying Kubernetes" + EnablingAddons RegStep = "Enabling Addons" + Done RegStep = "Done" ) -// Step is a type representing a distinct step of `minikube start` -type Step string +// RegStep is a type representing a distinct step of `minikube start` +type RegStep string // Register holds all of the steps we could see in `minikube start` // and keeps track of the current step type Register struct { - steps []Step - current Step + steps []RegStep + current RegStep } // Reg is a package level register that keep track @@ -43,7 +46,7 @@ var Reg Register func init() { Reg = Register{ - steps: []Step{ + steps: []RegStep{ InitialSetup, SelectingDriver, DownloadingArtifacts, @@ -58,21 +61,21 @@ func init() { } // totalSteps returns the total number of steps in the register -func (r *Register) totalSteps() int { - return len(r.steps) +func (r *Register) totalSteps() string { + return fmt.Sprintf("%d", len(r.steps)) } // currentStep returns the current step we are on -func (r *Register) currentStep() int { +func (r *Register) currentStep() string { for i, s := range r.steps { if r.current == s { - return i + return fmt.Sprintf("%d", i) } } - return -1 + return "" } // SetStep sets the current step -func (r *Register) SetStep(s Step) { +func (r *Register) SetStep(s RegStep) { r.current = s }