Skip to content

Commit c3ab895

Browse files
feat: tidy up install output (#56)
* set global loglevel * always log to file * tidy * write k0sctl logs to standard writer * save logfile with date * use fmt for printing final info messages * Update cmd/helmvm/main.go Co-authored-by: Ricardo Maraschini <[email protected]> * add logging package description * make logging last import * Write logs to .helmvm/logs * use fmt for more important user messages * add newlines to token output * remove pointless newline * filter stdout for join token * fix e2e token test * increase pull request timeout * fix unused err --------- Co-authored-by: Ricardo Maraschini <[email protected]>
1 parent f898eb6 commit c3ab895

File tree

7 files changed

+160
-26
lines changed

7 files changed

+160
-26
lines changed

cmd/helmvm/install.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,8 @@ func runK0sctlApply(ctx context.Context) error {
264264
cfgpath := defaults.PathToConfig("k0sctl.yaml")
265265
_, _ = messages.Write([]byte("Running k0sctl apply"))
266266
kctl := exec.Command(bin, "apply", "-c", cfgpath, "--disable-telemetry")
267-
kctl.Stderr = messages
268-
kctl.Stdout = messages
267+
kctl.Stderr = logrus.StandardLogger().Writer()
268+
kctl.Stdout = logrus.StandardLogger().Writer()
269269
return kctl.Run()
270270
}
271271

@@ -314,14 +314,14 @@ func dumpApplyLogs() {
314314
// applyK0sctl runs the k0sctl apply command and waits for it to finish. If
315315
// no configuration is found one is generated.
316316
func applyK0sctl(c *cli.Context, useprompt bool, nodes []infra.Node) error {
317-
logrus.Infof("Processing cluster configuration")
317+
fmt.Println("Processing cluster configuration")
318318
if err := ensureK0sctlConfig(c, nodes, useprompt); err != nil {
319319
return fmt.Errorf("unable to create config file: %w", err)
320320
}
321321
if err := runHostPreflights(c); err != nil {
322322
return fmt.Errorf("unable to finish preflight checks: %w", err)
323323
}
324-
logrus.Infof("Applying cluster configuration")
324+
fmt.Println("Applying cluster configuration")
325325
if err := runK0sctlApply(c.Context); err != nil {
326326
logrus.Errorf("Installation or upgrade failed.")
327327
if !useprompt {
@@ -425,11 +425,11 @@ var installCommand = &cli.Command{
425425
if err := runPostApply(c.Context); err != nil {
426426
return fmt.Errorf("unable to run post apply: %w", err)
427427
}
428-
logrus.Infof("Cluster configuration has been applied")
429-
logrus.Infof("Kubeconfig file has been placed at at %s", kcfg)
430-
logrus.Infof("Cluster configuration file has been placed at %s", ccfg)
431-
logrus.Infof("You can now access your cluster with kubectl by running:")
432-
logrus.Infof(" %s shell", os.Args[0])
428+
fmt.Println("Cluster configuration has been applied")
429+
fmt.Printf("Kubeconfig file has been placed at at %s\n", kcfg)
430+
fmt.Printf("Cluster configuration file has been placed at %s\n", ccfg)
431+
fmt.Println("You can now access your cluster with kubectl by running:")
432+
fmt.Printf(" %s shell\n", os.Args[0])
433433
return nil
434434
},
435435
}

cmd/helmvm/main.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,29 @@ import (
77

88
"github.com/sirupsen/logrus"
99
"github.com/urfave/cli/v2"
10+
11+
"github.com/replicatedhq/helmvm/pkg/logging"
1012
)
1113

1214
func main() {
15+
16+
logging.SetupLogging()
17+
1318
name := path.Base(os.Args[0])
1419
var app = &cli.App{
15-
Name: name,
20+
Name: name,
21+
Flags: []cli.Flag{
22+
&cli.BoolFlag{
23+
Name: "debug",
24+
Usage: "Output all setup messages to stdout",
25+
Aliases: []string{"d"},
26+
Value: false,
27+
Action: func(ctx *cli.Context, v bool) error {
28+
logging.Debug = v
29+
return nil
30+
},
31+
},
32+
},
1633
Usage: fmt.Sprintf("Installs or updates %s.", name),
1734
Commands: []*cli.Command{
1835
installCommand,
@@ -26,4 +43,5 @@ func main() {
2643
if err := app.Run(os.Args); err != nil {
2744
logrus.Fatal(err)
2845
}
46+
2947
}

cmd/helmvm/token.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ var tokenCreateCommand = &cli.Command{
8686
return fmt.Errorf("failed to set decentralized install: %w", err)
8787
}
8888
}
89-
logrus.Infof("Token created successfully.")
90-
logrus.Infof("This token is valid for %s hours.", dur)
91-
logrus.Infof("You can now run the following command in a remote node to add it")
92-
logrus.Infof("to the cluster as a %q node:", role)
89+
fmt.Println("Token created successfully.")
90+
fmt.Printf("This token is valid for %s hours.\n", dur)
91+
fmt.Println("You can now run the following command in a remote node to add it")
92+
fmt.Printf("to the cluster as a %q node:\n", role)
9393
fmt.Printf("%s node join --role %s %s", defaults.BinaryName(), role, buf.String())
9494
return nil
9595
},

e2e/install_test.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package e2e
22

33
import (
4+
"bufio"
45
"strings"
56
"testing"
67

@@ -33,11 +34,28 @@ func TestTokenBasedMultiNodeInstallation(t *testing.T) {
3334
stdout, _, err := RunCommandOnNode(t, tc, 0, line)
3435
if err != nil {
3536
t.Fatalf("fail to generate token on node %s: %v", tc.Nodes[0], err)
37+
38+
}
39+
40+
var joinCommand []string
41+
42+
// scan stdout for our command that starts with `helmvm`
43+
newScanner := bufio.NewScanner(strings.NewReader(stdout))
44+
for newScanner.Scan() {
45+
line := newScanner.Text()
46+
if strings.HasPrefix(line, "helmvm") {
47+
joinCommand = strings.Split(line, " ")
48+
break
49+
}
50+
}
51+
52+
if joinCommand == nil {
53+
t.Fatalf("could not find token in stdout")
3654
}
55+
3756
for i := 1; i <= 2; i++ {
3857
t.Logf("joining node %d to the cluster", i)
39-
join := strings.Split(stdout, " ")
40-
if _, _, err := RunCommandOnNode(t, tc, i, join); err != nil {
58+
if _, _, err := RunCommandOnNode(t, tc, i, joinCommand); err != nil {
4159
t.Fatalf("fail to join node %d: %v", i, err)
4260
}
4361
}

pkg/config/config.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func askUserForHostSSHKey(keys []string, host *hostcfg) error {
101101

102102
// askUserForHostConfig collects a host SSH configuration interactively.
103103
func askUserForHostConfig(keys []string, host *hostcfg) error {
104-
logrus.Infof("Please provide SSH configuration for the host.")
104+
fmt.Println("Please provide SSH configuration for the host.")
105105
host.Address = quiz.Input("Node address:", host.Address, true)
106106
host.User = quiz.Input("SSH user:", host.User, true)
107107
var err error
@@ -200,10 +200,10 @@ func interactiveHosts(ctx context.Context) ([]*cluster.Host, error) {
200200
}
201201

202202
func askForLoadBalancer() (string, error) {
203-
logrus.Infof("You have configured more than one controller. To ensure a highly available")
204-
logrus.Infof("cluster with multiple controllers, configure a load balancer address that")
205-
logrus.Infof("forwards traffic to the controllers on TCP ports 6443, 8132, and 9443.")
206-
logrus.Infof("Optionally, you can press enter to skip load balancer configuration.")
203+
fmt.Println("You have configured more than one controller. To ensure a highly available")
204+
fmt.Println("cluster with multiple controllers, configure a load balancer address that")
205+
fmt.Println("forwards traffic to the controllers on TCP ports 6443, 8132, and 9443.")
206+
fmt.Println("Optionally, you can press enter to skip load balancer configuration.")
207207
return quiz.Input("Load balancer address:", "", false), nil
208208
}
209209

@@ -212,7 +212,7 @@ func askForLoadBalancer() (string, error) {
212212
func renderMultiNodeConfig(ctx context.Context, nodes []infra.Node) (*v1beta1.Cluster, error) {
213213
var err error
214214
var hosts []*cluster.Host
215-
logrus.Infof("You are about to configure a new cluster.")
215+
fmt.Println("You are about to configure a new cluster.")
216216
if len(nodes) == 0 {
217217
if hosts, err = interactiveHosts(ctx); err != nil {
218218
return nil, fmt.Errorf("unable to collect hosts: %w", err)

pkg/infra/infra.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func Apply(ctx context.Context, dir string, useprompt bool) ([]Node, error) {
3939
}
4040
log.Close()
4141
<-end
42-
logrus.Infof("Infrastructure applied successfully")
42+
fmt.Println("Infrastructure applied successfully")
4343
nodes, err := readNodes(outputs)
4444
if err != nil {
4545
return nil, fmt.Errorf("unable to process terraform output: %w", err)
@@ -48,7 +48,7 @@ func Apply(ctx context.Context, dir string, useprompt bool) ([]Node, error) {
4848
if !useprompt {
4949
return nodes, nil
5050
}
51-
logrus.Info("You may want to take note of the output for later use")
51+
fmt.Println("You may want to take note of the output for later use")
5252
prompts.New().PressEnter("Press enter to continue")
5353
return nodes, nil
5454
}
@@ -59,14 +59,14 @@ func printNodes(nodes []Node) {
5959
logrus.Warnf("No node found in terraform output")
6060
return
6161
}
62-
logrus.Infof("These are the nodes configuration applied by your configuration:")
62+
fmt.Println("These are the nodes configuration applied by your configuration:")
6363
writer := table.NewWriter()
6464
writer.AppendHeader(table.Row{"Address", "Role", "SSH Port", "SSH User", "SSH Key Path"})
6565
for _, node := range nodes {
6666
writer.AppendRow(table.Row{node.Address, node.Role, node.Port, node.User, node.KeyPath})
6767
}
6868
fmt.Printf("%s\n", writer.Render())
69-
logrus.Infof("These are going to be used as your cluster configuration")
69+
fmt.Println("These are going to be used as your cluster configuration")
7070
}
7171

7272
// readIPAddresses reads the nodes from the instance_ips terraform output.

pkg/logging/logging.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Package logging manages setup of common logging interfaces and settings.
2+
package logging
3+
4+
import (
5+
"fmt"
6+
"io"
7+
"os"
8+
"path/filepath"
9+
"time"
10+
11+
"github.com/replicatedhq/helmvm/pkg/defaults"
12+
"github.com/sirupsen/logrus"
13+
)
14+
15+
type LogrusFileHook struct {
16+
file *os.File
17+
flag int
18+
chmod os.FileMode
19+
formatter *logrus.TextFormatter
20+
}
21+
22+
var Debug bool
23+
24+
func NewLogrusFileHook(file string, flag int, chmod os.FileMode) (*LogrusFileHook, error) {
25+
plainFormatter := &logrus.TextFormatter{DisableColors: true}
26+
logFile, err := os.OpenFile(file, flag, chmod)
27+
if err != nil {
28+
fmt.Fprintf(os.Stderr, "unable to write file on filehook %v", err)
29+
return nil, err
30+
}
31+
32+
return &LogrusFileHook{logFile, flag, chmod, plainFormatter}, err
33+
}
34+
35+
func (hook *LogrusFileHook) Fire(entry *logrus.Entry) error {
36+
37+
plainformat, err := hook.formatter.Format(entry)
38+
if err != nil {
39+
fmt.Fprintf(os.Stderr, "unable to parse line %v", err)
40+
return err
41+
}
42+
line := string(plainformat)
43+
_, err = hook.file.WriteString(line)
44+
if err != nil {
45+
fmt.Fprintf(os.Stderr, "unable to write file on filehook(entry.String) %v", err)
46+
return err
47+
}
48+
49+
return nil
50+
}
51+
52+
func (hook *LogrusFileHook) Levels() []logrus.Level {
53+
return logrus.AllLevels
54+
}
55+
56+
type StandardHook struct {
57+
Writer io.Writer
58+
LogLevels []logrus.Level
59+
Formatter *logrus.TextFormatter
60+
}
61+
62+
func (hook *StandardHook) Fire(entry *logrus.Entry) error {
63+
text, err := hook.Formatter.Format(entry)
64+
if err != nil {
65+
return err
66+
}
67+
68+
if !Debug && entry.Level == logrus.InfoLevel || entry.Level == logrus.DebugLevel {
69+
return nil
70+
}
71+
72+
_, err = hook.Writer.Write(text)
73+
return err
74+
}
75+
76+
func (hook *StandardHook) Levels() []logrus.Level {
77+
return hook.LogLevels
78+
}
79+
80+
func SetupLogging() {
81+
logrus.SetOutput(io.Discard)
82+
83+
logrus.AddHook(&StandardHook{
84+
Writer: os.Stderr,
85+
LogLevels: logrus.AllLevels,
86+
Formatter: &logrus.TextFormatter{ForceColors: true},
87+
})
88+
89+
now := time.Now().Format("20060102150405")
90+
91+
dir := defaults.HelmVMLogsSubDir()
92+
path := filepath.Join(dir, "helmvm-"+now+".log")
93+
94+
fileHook, err := NewLogrusFileHook(path, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
95+
if err == nil {
96+
logrus.AddHook(fileHook)
97+
}
98+
}

0 commit comments

Comments
 (0)