Skip to content

Commit 7126dc9

Browse files
feat: improve feedback to user (#63)
* feat: improve feedback to user this pr adds more visible feedback to the users while the installation is taking place. this introduces no functional change, we only added some spinning while installing add-ons and improved the messages being written to the screen. * chore: fixed unit test
1 parent 3fae97e commit 7126dc9

File tree

13 files changed

+132
-52
lines changed

13 files changed

+132
-52
lines changed

cmd/helmvm/bundle.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ var bundleCommand = &cli.Command{
5353
return fmt.Errorf("unable to open bundle file: %w", err)
5454
}
5555
defer dst.Close()
56-
loading := pb.Start(nil)
56+
loading := pb.Start()
5757
loading.Infof("Downloading base images bundle.")
5858
src, err := goods.DownloadImagesBundle(defaults.K0sVersion)
5959
if err != nil {
@@ -75,7 +75,7 @@ var bundleCommand = &cli.Command{
7575
}
7676
images = append(images, embed...)
7777
for _, img := range images {
78-
loading = pb.Start(nil)
78+
loading = pb.Start()
7979
loading.Infof(fmt.Sprintf("Pulling image %s", img))
8080
if err := pullImage(c.Context, img); err != nil {
8181
loading.Close()

cmd/helmvm/install.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ import (
3232
// runPostApply is meant to run things that can't be run automatically with
3333
// k0sctl. Iterates over all hosts and calls runPostApply on each.
3434
func runPostApply(ctx context.Context) error {
35-
logrus.Infof("Running post-apply script on nodes")
36-
loading := pb.Start(nil)
35+
mask := func(raw string) string {
36+
logrus.StandardLogger().Writer().Write([]byte(raw))
37+
return fmt.Sprintf("Creating systemd unit for %s", defaults.BinaryName())
38+
}
39+
loading := pb.Start(pb.WithMask(mask))
3740
orig := log.Log
3841
rig.SetLogger(loading)
3942
defer func() {
40-
loading.Closef("Post apply process finished")
43+
loading.Close()
4144
log.Log = orig
4245
}()
4346
cfg, err := config.ReadConfigFile(defaults.PathToConfig("k0sctl.yaml"))
@@ -253,15 +256,29 @@ func ensureK0sctlConfig(c *cli.Context, nodes []infra.Node, useprompt bool) erro
253256
// runK0sctlApply runs `k0sctl apply` refering to the k0sctl.yaml file found on
254257
// the configuration directory. Returns when the command is finished.
255258
func runK0sctlApply(ctx context.Context) error {
259+
message := "Applying cluster configuration"
260+
mask := func(raw string) string {
261+
logrus.StandardLogger().Writer().Write([]byte(raw))
262+
if !strings.Contains(raw, "Running phase:") {
263+
return message
264+
}
265+
slices := strings.SplitN(raw, ":", 2)
266+
message = strings.ReplaceAll(slices[1], `"`, "")
267+
message = strings.TrimSpace(message)
268+
message = strings.ReplaceAll(message, "k0s", defaults.BinaryName())
269+
message = strings.ReplaceAll(message, "Upload", "Copy")
270+
message = fmt.Sprintf("Phase: %s", message)
271+
return message
272+
}
256273
bin := defaults.PathToHelmVMBinary("k0sctl")
257-
loading := pb.Start(nil)
274+
loading := pb.Start(pb.WithMask(mask))
258275
defer func() {
259-
loading.Close()
276+
loading.Closef("Finished applying cluster configuration")
260277
}()
261278
cfgpath := defaults.PathToConfig("k0sctl.yaml")
262279
kctl := exec.Command(bin, "apply", "-c", cfgpath, "--disable-telemetry")
263-
kctl.Stderr = logrus.StandardLogger().Writer()
264-
kctl.Stdout = logrus.StandardLogger().Writer()
280+
kctl.Stderr = loading
281+
kctl.Stdout = loading
265282
return kctl.Run()
266283
}
267284

pkg/addons/adminconsole/adminconsole.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"helm.sh/helm/v3/pkg/release"
1616

1717
"github.com/replicatedhq/helmvm/pkg/addons/adminconsole/charts"
18+
pb "github.com/replicatedhq/helmvm/pkg/progressbar"
1819
"github.com/replicatedhq/helmvm/pkg/prompts"
1920
)
2021

@@ -94,6 +95,9 @@ func (a *AdminConsole) Apply(ctx context.Context) error {
9495
if err != nil {
9596
return fmt.Errorf("unable to ask for password: %w", err)
9697
}
98+
loading := pb.Start()
99+
loading.Infof("Applying AdminConsole addon")
100+
defer loading.Close()
97101
helmValues["password"] = pass
98102
act := action.NewInstall(a.config)
99103
act.Namespace = a.namespace
@@ -111,6 +115,9 @@ func (a *AdminConsole) Apply(ctx context.Context) error {
111115
return fmt.Errorf("unable to downgrade from %s to %s", installedVersion, version)
112116
}
113117

118+
loading := pb.Start()
119+
loading.Infof("Applying AdminConsole addon")
120+
defer loading.Close()
114121
a.logger("Updating Admin Console from %s to %s", installedVersion, version)
115122
act := action.NewUpgrade(a.config)
116123
act.Namespace = a.namespace

pkg/addons/applier.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,10 @@ func (a *Applier) Apply(ctx context.Context) error {
5656
if err != nil {
5757
return fmt.Errorf("unable to load addons: %w", err)
5858
}
59-
for name, addon := range addons {
60-
logrus.Infof("Apply addon %s.", name)
59+
for _, addon := range addons {
6160
if err := addon.Apply(ctx); err != nil {
6261
return err
6362
}
64-
logrus.Infof("Addon %s applied.", name)
6563
}
6664
return nil
6765
}
@@ -147,9 +145,9 @@ func (a *Applier) kubeClient() (client.Client, error) {
147145
// waitForKubernetes waits until we manage to make a successful connection to the
148146
// Kubernetes API server.
149147
func (a *Applier) waitForKubernetes(ctx context.Context) error {
150-
loading := pb.Start(nil)
148+
loading := pb.Start()
151149
defer func() {
152-
loading.Closef("Kubernetes API server is ready.")
150+
loading.Closef("Kubernetes API server is ready")
153151
}()
154152
kcli, err := a.kubeClient()
155153
if err != nil {
@@ -158,7 +156,7 @@ func (a *Applier) waitForKubernetes(ctx context.Context) error {
158156
ticker := time.NewTicker(3 * time.Second)
159157
defer ticker.Stop()
160158
counter := 1
161-
loading.Infof("1/n Waiting for Kubernetes API server to be ready.")
159+
loading.Infof("1/n Waiting for Kubernetes API server to be ready")
162160
for {
163161
select {
164162
case <-ticker.C:

pkg/addons/custom/custom.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"sigs.k8s.io/yaml"
1919

2020
"github.com/replicatedhq/helmvm/pkg/hembed"
21+
pb "github.com/replicatedhq/helmvm/pkg/progressbar"
2122
)
2223

2324
type Custom struct {
@@ -102,6 +103,9 @@ func (c *Custom) chartHasBeenDisabled(chart *chart.Chart) bool {
102103
}
103104

104105
func (c *Custom) applyChart(ctx context.Context, chart *chart.Chart, values map[string]interface{}) error {
106+
loading := pb.Start()
107+
loading.Infof("Applying %s addon", chart.Name())
108+
defer loading.Close()
105109
installed, err := c.installedRelease(chart.Name())
106110
if err != nil {
107111
return fmt.Errorf("unable to check if release %s is installed: %w", chart.Name(), err)

pkg/addons/openebs/openebs.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"helm.sh/helm/v3/pkg/release"
1616

1717
"github.com/replicatedhq/helmvm/pkg/addons/openebs/charts"
18+
pb "github.com/replicatedhq/helmvm/pkg/progressbar"
1819
)
1920

2021
const (
@@ -56,6 +57,9 @@ func (o *OpenEBS) HostPreflights() (*v1beta2.HostPreflightSpec, error) {
5657
}
5758

5859
func (o *OpenEBS) Apply(ctx context.Context) error {
60+
loading := pb.Start()
61+
loading.Infof("Applying OpenEBS addon")
62+
defer loading.Close()
5963
version, err := o.latest()
6064
if err != nil {
6165
return fmt.Errorf("unable to get latest version: %w", err)

pkg/config/host.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package config
22

33
import (
4+
"fmt"
5+
46
"github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster"
57
"github.com/k0sproject/rig"
68
"github.com/k0sproject/rig/log"
9+
"github.com/sirupsen/logrus"
710

811
"github.com/replicatedhq/helmvm/pkg/infra"
912
pb "github.com/replicatedhq/helmvm/pkg/progressbar"
@@ -42,7 +45,11 @@ func (h *hostcfg) render() *cluster.Host {
4245

4346
// testConnection attempts to connect to the host via SSH.
4447
func (h *hostcfg) testConnection() error {
45-
loading := pb.Start(nil)
48+
mask := func(raw string) string {
49+
logrus.StandardLogger().Writer().Write([]byte(raw))
50+
return fmt.Sprintf("Validating host %s", h.Address)
51+
}
52+
loading := pb.Start(pb.WithMask(mask))
4653
orig := log.Log
4754
defer func() {
4855
loading.Close()

pkg/infra/infra.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Node struct {
2828

2929
// ApplyFn is the function that actually applies the infrastructure using terraform
3030
// library. This exists so we can make tests that don't actually run terraform.
31-
type ApplyFn func(context.Context, string, pb.MessageWriter) (map[string]tfexec.OutputMeta, error)
31+
type ApplyFn func(context.Context, string, *pb.MessageWriter) (map[string]tfexec.OutputMeta, error)
3232

3333
// Infra is a struct that holds functions to apply and create infrastructure.
3434
type Infra struct {
@@ -44,7 +44,7 @@ func New() *Infra {
4444
// Apply uses "terraform apply" to apply the infrastructe defined in the
4545
// directory passed as argument.
4646
func (inf *Infra) Apply(ctx context.Context, dir string, useprompt bool) ([]Node, error) {
47-
loading := pb.Start(nil)
47+
loading := pb.Start()
4848
loading.Infof("Applying infrastructure from %s", dir)
4949
applyfn := inf.runApply
5050
if inf.apply != nil {
@@ -56,7 +56,6 @@ func (inf *Infra) Apply(ctx context.Context, dir string, useprompt bool) ([]Node
5656
return nil, fmt.Errorf("unable to apply infrastructure: %w", err)
5757
}
5858
loading.Close()
59-
fmt.Println("Infrastructure applied successfully")
6059
nodes, err := inf.ReadNodes(outputs)
6160
if err != nil {
6261
return nil, fmt.Errorf("unable to process terraform output: %w", err)
@@ -102,7 +101,7 @@ func (inf *Infra) ReadNodes(outputs map[string]tfexec.OutputMeta) ([]Node, error
102101

103102
// runApply actually runs the terraform apply. This expects the terraform output to contain a
104103
// property 'instance_ips' which is a list of the created or updated node ip addresses.
105-
func (inf *Infra) runApply(ctx context.Context, dir string, log pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
104+
func (inf *Infra) runApply(ctx context.Context, dir string, log *pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
106105
log.Infof("Reading terraform infrastructure from %s", dir)
107106
exe := defaults.PathToHelmVMBinary("terraform")
108107
tf, err := tfexec.NewTerraform(dir, exe)

pkg/infra/infra_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,31 +47,31 @@ var validTerraformOutput = []byte(`
4747

4848
func TestApply(t *testing.T) {
4949
infra := New()
50-
infra.apply = func(context.Context, string, pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
50+
infra.apply = func(context.Context, string, *pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
5151
return nil, fmt.Errorf("test error")
5252
}
5353
_, err := infra.Apply(context.Background(), "", false)
5454
assert.ErrorContains(t, err, "test error", "error should contain 'test error'")
5555

5656
buf := bytes.NewBuffer(nil)
5757
infra.printf = writeTo(buf)
58-
infra.apply = func(context.Context, string, pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
58+
infra.apply = func(context.Context, string, *pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
5959
return map[string]tfexec.OutputMeta{"nodes": {Value: []byte(`[]`)}}, nil
6060
}
6161
_, err = infra.Apply(context.Background(), "", false)
6262
assert.ErrorContains(t, err, "no nodes found in terraform output")
6363

6464
buf = bytes.NewBuffer(nil)
6565
infra.printf = writeTo(buf)
66-
infra.apply = func(context.Context, string, pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
66+
infra.apply = func(context.Context, string, *pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
6767
return map[string]tfexec.OutputMeta{"nodes": {Value: []byte(`{this is not a valid/json{`)}}, nil
6868
}
6969
_, err = infra.Apply(context.Background(), "", false)
7070
assert.ErrorContains(t, err, "unable to unmarshal terraform output")
7171

7272
buf = bytes.NewBuffer(nil)
7373
infra.printf = writeTo(buf)
74-
infra.apply = func(context.Context, string, pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
74+
infra.apply = func(context.Context, string, *pb.MessageWriter) (map[string]tfexec.OutputMeta, error) {
7575
return map[string]tfexec.OutputMeta{"nodes": {Value: validTerraformOutput}}, nil
7676
}
7777
nodes, err := infra.Apply(context.Background(), "", false)

pkg/preflights/preflights.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func startProgressbar(addr string) (func(), error) {
115115
logfile := logrus.New()
116116
logfile.SetLevel(logrus.DebugLevel)
117117
logfile.SetOutput(fp)
118-
loading := pb.Start(nil)
118+
loading := pb.Start()
119119
loading.Infof("Running host preflight on %s", addr)
120120
orig := log.Log
121121
rig.SetLogger(logfile)

0 commit comments

Comments
 (0)