From e6eca604f8661ea324294b1f204751bb81968f67 Mon Sep 17 00:00:00 2001 From: joyceliu Date: Fri, 7 Jun 2024 16:00:34 +0800 Subject: [PATCH] feat: add pretty log Signed-off-by: joyceliu --- cmd/kk/app/options/option.go | 9 +++++--- go.mod | 7 ++++-- go.sum | 18 +++++++++++---- pkg/executor/executor.go | 44 +++++++++++++++++++++++++++--------- 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/cmd/kk/app/options/option.go b/cmd/kk/app/options/option.go index ba6b42e7..bb215670 100644 --- a/cmd/kk/app/options/option.go +++ b/cmd/kk/app/options/option.go @@ -149,10 +149,11 @@ func genConfig(configFile string) (*kubekeyv1.Config, error) { if err != nil { return nil, fmt.Errorf("read config file error: %w", err) } - if err := yaml.Unmarshal(cdata, defaultConfig); err != nil { + config := &kubekeyv1.Config{} + if err := yaml.Unmarshal(cdata, config); err != nil { return nil, fmt.Errorf("unmarshal config file error: %w", err) } - + return config, nil } return defaultConfig, nil @@ -165,10 +166,12 @@ func genInventory(inventoryFile string) (*kubekeyv1.Inventory, error) { klog.V(4).ErrorS(err, "read config file error") return nil, err } - if err := yaml.Unmarshal(cdata, defaultInventory); err != nil { + inventory := &kubekeyv1.Inventory{} + if err := yaml.Unmarshal(cdata, inventory); err != nil { klog.V(4).ErrorS(err, "unmarshal config file error") return nil, err } + return inventory, nil } return defaultInventory, nil diff --git a/go.mod b/go.mod index d8e7cb12..f8170f7c 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/google/gops v0.3.28 github.com/pkg/errors v0.9.1 github.com/pkg/sftp v1.13.6 + github.com/schollz/progressbar/v3 v3.14.3 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 @@ -70,6 +71,7 @@ require ( github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kr/fs v0.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -79,6 +81,7 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/skeema/knownhosts v1.2.1 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect @@ -102,8 +105,8 @@ require ( golang.org/x/net v0.20.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect diff --git a/go.sum b/go.sum index b4cb8199..f062a5a4 100644 --- a/go.sum +++ b/go.sum @@ -137,6 +137,7 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -152,6 +153,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -179,9 +183,13 @@ github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqSc github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.14.3 h1:oOuWW19ka12wxYU1XblR4n16wF/2Y1dBLMarMo6p4xU= +github.com/schollz/progressbar/v3 v3.14.3/go.mod h1:aT3UQ7yGm+2ZjeXPqsjTenwL3ddUiuZ0kfQ/2tHlyNI= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -312,16 +320,18 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/pkg/executor/executor.go b/pkg/executor/executor.go index 97685adc..8342f7bd 100644 --- a/pkg/executor/executor.go +++ b/pkg/executor/executor.go @@ -19,8 +19,10 @@ package executor import ( "context" "fmt" + "os" "path" + "github.com/schollz/progressbar/v3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/json" @@ -348,11 +350,18 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o host := h wg.StartWithContext(ctx, func(ctx context.Context) { var stdout, stderr string - defer func() { - if stderr != "" { - klog.Errorf("[Task %s] run failed: %s", ctrlclient.ObjectKeyFromObject(task), stderr) - } + // progress bar for task + var bar = progressbar.NewOptions(1, + progressbar.OptionEnableColorCodes(true), + progressbar.OptionSetDescription(fmt.Sprintf("[%s] running...", h)), + progressbar.OptionOnCompletion(func() { + os.Stdout.Write([]byte("\n")) + }), + progressbar.OptionShowElapsedTimeOnFinish(), + progressbar.OptionSetPredictTime(false), + ) + defer func() { if task.Spec.Register != "" { // set variable to parent location if err := e.variable.Merge(variable.MergeRuntimeVariable(host, map[string]any{ @@ -365,6 +374,12 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o return } } + + if stderr != "" { + klog.Errorf("[Task %s] run failed: %s", ctrlclient.ObjectKeyFromObject(task), stderr) + bar.Describe(fmt.Sprintf("[%s] failed", h)) + } + bar.Finish() // fill result dataChan <- kubekeyv1alpha1.TaskHostResult{ Host: host, @@ -378,6 +393,14 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o stderr = fmt.Sprintf("get variable error: %v", err) return } + // execute module with loop + loop, err := e.execLoop(ctx, ha.(map[string]any), task) + if err != nil { + stderr = fmt.Sprintf("parse loop vars error: %v", err) + return + } + bar.ChangeMax(len(loop)*3 + 1) + // check when condition if len(task.Spec.When) > 0 { ok, err := tmpl.ParseBool(ha.(map[string]any), task.Spec.When) @@ -387,17 +410,11 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o } if !ok { stdout = "skip" + bar.Describe(fmt.Sprintf("[%s] skip", h)) return } } - // execute module with loop - loop, err := e.execLoop(ctx, ha.(map[string]any), task) - if err != nil { - stderr = fmt.Sprintf("parse loop vars error: %v", err) - return - } - for _, item := range loop { // set item to runtime variable if err := e.variable.Merge(variable.MergeRuntimeVariable(host, map[string]any{ @@ -406,6 +423,7 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o stderr = fmt.Sprintf("set loop item to variable error: %v", err) return } + bar.Add(1) stdout, stderr = e.executeModule(ctx, task, modules.ExecOptions{ Args: task.Spec.Module.Args, Host: host, @@ -413,6 +431,7 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o Task: *task, Pipeline: *e.pipeline, }) + bar.Add(1) // delete item if err := e.variable.Merge(variable.MergeRuntimeVariable(host, map[string]any{ "item": nil, @@ -420,7 +439,10 @@ func (e executor) executeTask(ctx context.Context, task *kubekeyv1alpha1.Task, o stderr = fmt.Sprintf("clean loop item to variable error: %v", err) return } + bar.Add(1) } + + bar.Describe(fmt.Sprintf("[%s] success", h)) }) } go func() {