Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Cai <jcai@gitlab.com>2021-11-10 23:45:33 +0300
committerJohn Cai <jcai@gitlab.com>2021-11-18 20:35:32 +0300
commit08e17fddcf3da9ca8e25005c8356c42e15e1790c (patch)
tree328f3b47792c9adebff533b01ee6d861e9b05f41
parent51b78efbabefe3abd586a7d5fee12a52905a4af0 (diff)
praefect: print verbose output in check subcommand
When an admin runs the praefect startup checks, it would be useful to print more information about each check. This change refactors some of the code to allow that to happen, and also a -q flag that the user can pass to silence this detailed outpt. Changelog: changed
-rw-r--r--cmd/praefect/subcmd.go9
-rw-r--r--cmd/praefect/subcmd_accept_dataloss.go5
-rw-r--r--cmd/praefect/subcmd_check.go16
-rw-r--r--cmd/praefect/subcmd_check_test.go161
-rw-r--r--cmd/praefect/subcmd_dial_nodes.go11
-rw-r--r--cmd/praefect/subcmd_dial_nodes_test.go4
-rw-r--r--internal/praefect/checks.go10
-rw-r--r--internal/praefect/checks_test.go132
-rw-r--r--internal/praefect/nodes/ping.go16
-rw-r--r--internal/praefect/nodes/ping_test.go3
10 files changed, 262 insertions, 105 deletions
diff --git a/cmd/praefect/subcmd.go b/cmd/praefect/subcmd.go
index 05718b073..fc67c7471 100644
--- a/cmd/praefect/subcmd.go
+++ b/cmd/praefect/subcmd.go
@@ -23,12 +23,17 @@ type subcmd interface {
Exec(flags *flag.FlagSet, config config.Config) error
}
-const defaultDialTimeout = 30 * time.Second
+const (
+ defaultDialTimeout = 30 * time.Second
+ paramVirtualStorage = "virtual-storage"
+ paramRelativePath = "repository"
+ paramAuthoritativeStorage = "authoritative-storage"
+)
var subcommands = map[string]subcmd{
sqlPingCmdName: &sqlPingSubcommand{},
sqlMigrateCmdName: &sqlMigrateSubcommand{},
- dialNodesCmdName: newDialNodesSubcommand(logger),
+ dialNodesCmdName: newDialNodesSubcommand(os.Stdout),
sqlMigrateDownCmdName: &sqlMigrateDownSubcommand{},
sqlMigrateStatusCmdName: &sqlMigrateStatusSubcommand{},
datalossCmdName: newDatalossSubcommand(),
diff --git a/cmd/praefect/subcmd_accept_dataloss.go b/cmd/praefect/subcmd_accept_dataloss.go
index 04b076743..944c55e89 100644
--- a/cmd/praefect/subcmd_accept_dataloss.go
+++ b/cmd/praefect/subcmd_accept_dataloss.go
@@ -10,10 +10,7 @@ import (
)
const (
- acceptDatalossCmdName = "accept-dataloss"
- paramVirtualStorage = "virtual-storage"
- paramRelativePath = "repository"
- paramAuthoritativeStorage = "authoritative-storage"
+ acceptDatalossCmdName = "accept-dataloss"
)
type acceptDatalossSubcommand struct {
diff --git a/cmd/praefect/subcmd_check.go b/cmd/praefect/subcmd_check.go
index 246e6e0bf..5755b2008 100644
--- a/cmd/praefect/subcmd_check.go
+++ b/cmd/praefect/subcmd_check.go
@@ -18,6 +18,7 @@ const (
type checkSubcommand struct {
w io.Writer
+ quiet bool
checkFuncs []praefect.CheckFunc
}
@@ -30,6 +31,7 @@ func newCheckSubcommand(writer io.Writer, checkFuncs ...praefect.CheckFunc) *che
func (cmd *checkSubcommand) FlagSet() *flag.FlagSet {
fs := flag.NewFlagSet(checkCmdName, flag.ExitOnError)
+ fs.BoolVar(&cmd.quiet, "q", false, "do not print out verbose output about each check")
fs.Usage = func() {
printfErr("Description:\n" +
" This command runs startup checks for Praefect.")
@@ -44,7 +46,7 @@ var errFatalChecksFailed = errors.New("checks failed")
func (cmd *checkSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) error {
var allChecks []*praefect.Check
for _, checkFunc := range cmd.checkFuncs {
- allChecks = append(allChecks, checkFunc(cfg))
+ allChecks = append(allChecks, checkFunc(cfg, cmd.w, cmd.quiet))
}
bgContext := context.Background()
@@ -54,7 +56,8 @@ func (cmd *checkSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) error {
ctx, cancel := context.WithTimeout(bgContext, 5*time.Second)
defer cancel()
- fmt.Fprintf(cmd.w, "Checking %s...", check.Name)
+ cmd.printCheckDetails(check)
+
if err := check.Run(ctx); err != nil {
failedChecks++
if check.Severity == praefect.Fatal {
@@ -81,3 +84,12 @@ func (cmd *checkSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) error {
return nil
}
+
+func (cmd *checkSubcommand) printCheckDetails(check *praefect.Check) {
+ if cmd.quiet {
+ fmt.Fprintf(cmd.w, "Checking %s...", check.Name)
+ return
+ }
+
+ fmt.Fprintf(cmd.w, "Checking %s - %s [%s]\n", check.Name, check.Description, check.Severity)
+}
diff --git a/cmd/praefect/subcmd_check_test.go b/cmd/praefect/subcmd_check_test.go
index ec9108a54..ef6d489d5 100644
--- a/cmd/praefect/subcmd_check_test.go
+++ b/cmd/praefect/subcmd_check_test.go
@@ -5,6 +5,7 @@ import (
"context"
"errors"
"flag"
+ "io"
"testing"
"github.com/stretchr/testify/assert"
@@ -16,106 +17,166 @@ func TestCheckSubcommand_Exec(t *testing.T) {
t.Parallel()
testCases := []struct {
- desc string
- checks []praefect.CheckFunc
- expectedOutput string
- expectedError error
+ desc string
+ checks []praefect.CheckFunc
+ expectedQuietOutput string
+ expectedOutput string
+ expectedError error
}{
{
desc: "all checks pass",
checks: []praefect.CheckFunc{
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 1",
- Run: func(ctx context.Context) error { return nil },
- Severity: praefect.Fatal,
+ Name: "check 1",
+ Description: "checks a",
+ Run: func(ctx context.Context) error { return nil },
+ Severity: praefect.Fatal,
}
},
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 2",
- Run: func(ctx context.Context) error { return nil },
- Severity: praefect.Fatal,
+ Name: "check 2",
+ Description: "checks b",
+ Run: func(ctx context.Context) error { return nil },
+ Severity: praefect.Fatal,
}
},
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 3",
- Run: func(ctx context.Context) error { return nil },
- Severity: praefect.Fatal,
+ Name: "check 3",
+ Description: "checks c",
+ Run: func(ctx context.Context) error { return nil },
+ Severity: praefect.Fatal,
}
},
},
- expectedOutput: "Checking check 1...Passed\nChecking check 2...Passed\nChecking check 3...Passed\n\nAll checks passed.\n",
- expectedError: nil,
+ expectedOutput: `Checking check 1 - checks a [fatal]
+Passed
+Checking check 2 - checks b [fatal]
+Passed
+Checking check 3 - checks c [fatal]
+Passed
+
+All checks passed.
+`,
+ expectedQuietOutput: `Checking check 1...Passed
+Checking check 2...Passed
+Checking check 3...Passed
+
+All checks passed.
+`,
+ expectedError: nil,
},
{
desc: "a fatal check fails",
checks: []praefect.CheckFunc{
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 1",
- Run: func(ctx context.Context) error { return nil },
- Severity: praefect.Fatal,
+ Name: "check 1",
+ Description: "checks a",
+ Run: func(ctx context.Context) error { return nil },
+ Severity: praefect.Fatal,
}
},
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 2",
- Run: func(ctx context.Context) error { return errors.New("i failed") },
- Severity: praefect.Fatal,
+ Name: "check 2",
+ Description: "checks b",
+ Run: func(ctx context.Context) error { return errors.New("i failed") },
+ Severity: praefect.Fatal,
}
},
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 3",
- Run: func(ctx context.Context) error { return nil },
- Severity: praefect.Fatal,
+ Name: "check 3",
+ Description: "checks c",
+ Run: func(ctx context.Context) error { return nil },
+ Severity: praefect.Fatal,
}
},
},
- expectedOutput: "Checking check 1...Passed\nChecking check 2...Failed (fatal) error: i failed\nChecking check 3...Passed\n\n1 check(s) failed, at least one was fatal.\n",
- expectedError: errFatalChecksFailed,
+ expectedOutput: `Checking check 1 - checks a [fatal]
+Passed
+Checking check 2 - checks b [fatal]
+Failed (fatal) error: i failed
+Checking check 3 - checks c [fatal]
+Passed
+
+1 check(s) failed, at least one was fatal.
+`,
+ expectedQuietOutput: `Checking check 1...Passed
+Checking check 2...Failed (fatal) error: i failed
+Checking check 3...Passed
+
+1 check(s) failed, at least one was fatal.
+`,
+ expectedError: errFatalChecksFailed,
},
{
desc: "only warning checks fail",
checks: []praefect.CheckFunc{
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 1",
- Run: func(ctx context.Context) error { return nil },
- Severity: praefect.Fatal,
+ Name: "check 1",
+ Description: "checks a",
+ Run: func(ctx context.Context) error { return nil },
+ Severity: praefect.Fatal,
}
},
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 2",
- Run: func(ctx context.Context) error { return errors.New("i failed but not too badly") },
- Severity: praefect.Warning,
+ Name: "check 2",
+ Description: "checks b",
+ Run: func(ctx context.Context) error { return errors.New("i failed but not too badly") },
+ Severity: praefect.Warning,
}
},
- func(cfg config.Config) *praefect.Check {
+ func(cfg config.Config, w io.Writer, quiet bool) *praefect.Check {
return &praefect.Check{
- Name: "check 3",
- Run: func(ctx context.Context) error { return errors.New("i failed but not too badly") },
- Severity: praefect.Warning,
+ Name: "check 3",
+ Description: "checks c",
+ Run: func(ctx context.Context) error { return errors.New("i failed but not too badly") },
+ Severity: praefect.Warning,
}
},
},
- expectedOutput: "Checking check 1...Passed\nChecking check 2...Failed (warning) error: i failed but not too badly\nChecking check 3...Failed (warning) error: i failed but not too badly\n\n2 check(s) failed, but none are fatal.\n",
- expectedError: nil,
+ expectedOutput: `Checking check 1 - checks a [fatal]
+Passed
+Checking check 2 - checks b [warning]
+Failed (warning) error: i failed but not too badly
+Checking check 3 - checks c [warning]
+Failed (warning) error: i failed but not too badly
+
+2 check(s) failed, but none are fatal.
+`,
+ expectedQuietOutput: `Checking check 1...Passed
+Checking check 2...Failed (warning) error: i failed but not too badly
+Checking check 3...Failed (warning) error: i failed but not too badly
+
+2 check(s) failed, but none are fatal.
+`,
+ expectedError: nil,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
var cfg config.Config
- var stdout bytes.Buffer
- checkCmd := checkSubcommand{w: &stdout, checkFuncs: tc.checks}
+ t.Run("quiet", func(t *testing.T) {
+ var stdout bytes.Buffer
+ checkCmd := checkSubcommand{w: &stdout, checkFuncs: tc.checks, quiet: true}
+ assert.Equal(t, tc.expectedError, checkCmd.Exec(flag.NewFlagSet("", flag.PanicOnError), cfg))
+ assert.Equal(t, tc.expectedQuietOutput, stdout.String())
+ })
- assert.Equal(t, tc.expectedError, checkCmd.Exec(flag.NewFlagSet("", flag.PanicOnError), cfg))
- assert.Equal(t, tc.expectedOutput, stdout.String())
+ t.Run("normal", func(t *testing.T) {
+ var stdout bytes.Buffer
+ checkCmd := checkSubcommand{w: &stdout, checkFuncs: tc.checks, quiet: false}
+ assert.Equal(t, tc.expectedError, checkCmd.Exec(flag.NewFlagSet("", flag.PanicOnError), cfg))
+ assert.Equal(t, tc.expectedOutput, stdout.String())
+ })
})
}
}
diff --git a/cmd/praefect/subcmd_dial_nodes.go b/cmd/praefect/subcmd_dial_nodes.go
index 215a5496e..06d7719ec 100644
--- a/cmd/praefect/subcmd_dial_nodes.go
+++ b/cmd/praefect/subcmd_dial_nodes.go
@@ -3,6 +3,7 @@ package main
import (
"context"
"flag"
+ "io"
"gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config"
"gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes"
@@ -10,12 +11,14 @@ import (
const dialNodesCmdName = "dial-nodes"
-func newDialNodesSubcommand(p nodes.Printer) *dialNodesSubcommand {
- return &dialNodesSubcommand{p}
+func newDialNodesSubcommand(w io.Writer) *dialNodesSubcommand {
+ return &dialNodesSubcommand{
+ w: w,
+ }
}
type dialNodesSubcommand struct {
- p nodes.Printer
+ w io.Writer
}
func (s *dialNodesSubcommand) FlagSet() *flag.FlagSet {
@@ -24,5 +27,5 @@ func (s *dialNodesSubcommand) FlagSet() *flag.FlagSet {
func (s *dialNodesSubcommand) Exec(flags *flag.FlagSet, conf config.Config) error {
ctx := context.Background()
- return nodes.PingAll(ctx, conf, s.p)
+ return nodes.PingAll(ctx, conf, nodes.NewTextPrinter(s.w), false)
}
diff --git a/cmd/praefect/subcmd_dial_nodes_test.go b/cmd/praefect/subcmd_dial_nodes_test.go
index 9714b031e..9817b32ad 100644
--- a/cmd/praefect/subcmd_dial_nodes_test.go
+++ b/cmd/praefect/subcmd_dial_nodes_test.go
@@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config"
- "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes"
"gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"
)
@@ -105,9 +104,8 @@ func TestSubCmdDialNodes(t *testing.T) {
tt.conf.SocketPath = ln.Addr().String()
output := &bytes.Buffer{}
- p := nodes.NewTextPrinter(output)
- cmd := newDialNodesSubcommand(p)
+ cmd := newDialNodesSubcommand(output)
require.NoError(t, cmd.Exec(nil, tt.conf))
require.Equal(t, tt.logs, output.String())
diff --git a/internal/praefect/checks.go b/internal/praefect/checks.go
index 2b520739a..d3eea33ec 100644
--- a/internal/praefect/checks.go
+++ b/internal/praefect/checks.go
@@ -3,7 +3,7 @@ package praefect
import (
"context"
"fmt"
- "log"
+ "io"
"time"
migrate "github.com/rubenv/sql-migrate"
@@ -35,10 +35,10 @@ type Check struct {
}
// CheckFunc is a function type that takes a praefect config and returns a Check
-type CheckFunc func(conf config.Config) *Check
+type CheckFunc func(conf config.Config, w io.Writer, quiet bool) *Check
// NewPraefectMigrationCheck returns a Check that checks if all praefect migrations have run
-func NewPraefectMigrationCheck(conf config.Config) *Check {
+func NewPraefectMigrationCheck(conf config.Config, w io.Writer, quiet bool) *Check {
return &Check{
Name: "praefect migrations",
Description: "confirms whether or not all praefect migrations have run",
@@ -77,13 +77,13 @@ func NewPraefectMigrationCheck(conf config.Config) *Check {
}
// NewGitalyNodeConnectivityCheck returns a check that ensures Praefect can talk to all nodes of all virtual storages
-func NewGitalyNodeConnectivityCheck(conf config.Config) *Check {
+func NewGitalyNodeConnectivityCheck(conf config.Config, w io.Writer, quiet bool) *Check {
return &Check{
Name: "gitaly node connectivity & disk access",
Description: "confirms if praefect can reach all of its gitaly nodes, and " +
"whether or not the gitaly nodes can read/write from and to its storages.",
Run: func(ctx context.Context) error {
- return nodes.PingAll(ctx, conf, log.Default())
+ return nodes.PingAll(ctx, conf, nodes.NewTextPrinter(w), quiet)
},
Severity: Fatal,
}
diff --git a/internal/praefect/checks_test.go b/internal/praefect/checks_test.go
index 0a56801e9..645584751 100644
--- a/internal/praefect/checks_test.go
+++ b/internal/praefect/checks_test.go
@@ -1,8 +1,10 @@
package praefect
import (
+ "bytes"
"context"
"fmt"
+ "io"
"net"
"path/filepath"
"testing"
@@ -71,7 +73,7 @@ func TestPraefectMigrations_success(t *testing.T) {
require.NoError(t, tc.prepare(cfg))
- migrationCheck := NewPraefectMigrationCheck(cfg)
+ migrationCheck := NewPraefectMigrationCheck(cfg, io.Discard, false)
assert.Equal(t, "praefect migrations", migrationCheck.Name)
assert.Equal(t, "confirms whether or not all praefect migrations have run", migrationCheck.Description)
assert.Equal(t, tc.expectedErr, migrationCheck.Run(ctx))
@@ -193,35 +195,8 @@ func TestGitalyNodeConnectivityCheck(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
- tmp := testhelper.TempDir(t)
- var cfgNodes []*config.Node
-
- for _, n := range tc.nodes {
- socket := filepath.Join(tmp, n.storage)
- ln, err := net.Listen("unix", socket)
- require.NoError(t, err)
- healthSrv := health.NewServer()
- healthSrv.SetServingStatus("", n.servingStatus)
-
- srvSrv := &mockServerServer{
- node: n,
- }
-
- srv := grpc.NewServer()
- grpc_health_v1.RegisterHealthServer(srv, healthSrv)
- gitalypb.RegisterServerServiceServer(srv, srvSrv)
- defer srv.Stop()
- go func() {
- assert.NoError(t, srv.Serve(ln))
- }()
-
- cfgNodes = append(cfgNodes, &config.Node{
- Storage: n.storage,
- Token: n.token,
- Address: fmt.Sprintf("%s://%s", ln.Addr().Network(), ln.Addr().String()),
- })
- }
-
+ cfgNodes, cleanup := runNodes(t, tc.nodes)
+ defer cleanup()
check := NewGitalyNodeConnectivityCheck(
config.Config{
VirtualStorages: []*config.VirtualStorage{
@@ -231,6 +206,8 @@ func TestGitalyNodeConnectivityCheck(t *testing.T) {
},
},
},
+ io.Discard,
+ false,
)
ctx, cancel := testhelper.Context()
@@ -266,6 +243,8 @@ func TestGitalyNodeConnectivityCheck(t *testing.T) {
},
},
},
+ io.Discard,
+ false,
)
ctx, cancel := testhelper.Context(testhelper.ContextWithTimeout(1 * time.Second))
@@ -273,4 +252,97 @@ func TestGitalyNodeConnectivityCheck(t *testing.T) {
assert.Errorf(t, check.Run(ctx), "the following nodes are not healthy: %s", socketAddr)
})
+
+ t.Run("output check details", func(t *testing.T) {
+ quietSettings := []bool{true, false}
+ nodes := []nodeAssertion{
+ {
+ storage: "storage-0",
+ token: "token-0",
+ servingStatus: grpc_health_v1.HealthCheckResponse_SERVING,
+ serverReadable: true,
+ serverWriteable: true,
+ },
+ }
+ expectedLogLines := []string{
+ "dialing...",
+ "dialed successfully!",
+ "checking health...",
+ "SUCCESS: node is healthy!",
+ "checking consistency...",
+ "SUCCESS: confirmed Gitaly storage \"storage-0\" in virtual storages [default] is served",
+ "SUCCESS: node configuration is consistent!",
+ }
+
+ for _, isQuiet := range quietSettings {
+ var output bytes.Buffer
+ cfgNodes, cleanup := runNodes(t, nodes)
+ defer cleanup()
+ check := NewGitalyNodeConnectivityCheck(
+ config.Config{
+ VirtualStorages: []*config.VirtualStorage{
+ {
+ Name: "default",
+ Nodes: cfgNodes,
+ },
+ },
+ },
+ &output,
+ isQuiet,
+ )
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ require.NoError(t, check.Run(ctx))
+
+ for _, logLine := range expectedLogLines {
+ if isQuiet {
+ assert.NotContains(t, output.String(), logLine)
+ continue
+ }
+ assert.Contains(t, output.String(), logLine)
+ }
+ }
+ })
+}
+
+func runNodes(t *testing.T, nodes []nodeAssertion) ([]*config.Node, func()) {
+ tmp := testhelper.TempDir(t)
+ var cfgNodes []*config.Node
+
+ var cleanupFns []func()
+
+ for _, n := range nodes {
+ socket := filepath.Join(tmp, n.storage)
+ ln, err := net.Listen("unix", socket)
+ require.NoError(t, err)
+ healthSrv := health.NewServer()
+ healthSrv.SetServingStatus("", n.servingStatus)
+
+ srvSrv := &mockServerServer{
+ node: n,
+ }
+
+ srv := grpc.NewServer()
+ grpc_health_v1.RegisterHealthServer(srv, healthSrv)
+ gitalypb.RegisterServerServiceServer(srv, srvSrv)
+ cleanupFns = append(cleanupFns, srv.Stop)
+
+ go func() {
+ assert.NoError(t, srv.Serve(ln))
+ }()
+
+ cfgNodes = append(cfgNodes, &config.Node{
+ Storage: n.storage,
+ Token: n.token,
+ Address: fmt.Sprintf("%s://%s", ln.Addr().Network(), ln.Addr().String()),
+ })
+ }
+
+ return cfgNodes, func() {
+ for _, cleanupFn := range cleanupFns {
+ cleanupFn()
+ }
+ }
}
diff --git a/internal/praefect/nodes/ping.go b/internal/praefect/nodes/ping.go
index 4b8847be2..3b511852b 100644
--- a/internal/praefect/nodes/ping.go
+++ b/internal/praefect/nodes/ping.go
@@ -21,7 +21,7 @@ type (
gitalyStorage string
)
-func newPingSet(conf config.Config, printer Printer) map[string]*Ping {
+func newPingSet(conf config.Config, printer Printer, quiet bool) map[string]*Ping {
nodeByAddress := map[string]*Ping{} // key is address
// flatten nodes between virtual storages
@@ -36,6 +36,7 @@ func newPingSet(conf config.Config, printer Printer) map[string]*Ping {
storages: map[gitalyStorage][]virtualStorage{},
vStorages: map[virtualStorage]struct{}{},
printer: printer,
+ quiet: quiet,
}
}
n.address = node.Address
@@ -60,6 +61,7 @@ type Ping struct {
token string // auth token
err error // any error during dial/ping
printer Printer
+ quiet bool
}
// Address returns the address of the node
@@ -155,11 +157,17 @@ func (p *Ping) isConsistent(ctx context.Context, cc *grpc.ClientConn) bool {
}
func (p *Ping) log(msg string, args ...interface{}) {
+ if p.quiet {
+ return
+ }
+
p.printer.Printf("[%s]: %s", p.address, fmt.Sprintf(msg, args...))
}
// Printer is an interface for Ping to print messages
type Printer interface {
+ // Printf prints a message, taking into account whether
+ // or not the verbose flag has been set
Printf(format string, args ...interface{})
}
@@ -170,7 +178,7 @@ type TextPrinter struct {
// NewTextPrinter creates a new TextPrinter instance
func NewTextPrinter(w io.Writer) *TextPrinter {
- return &TextPrinter{w}
+ return &TextPrinter{w: w}
}
// Printf prints the message and adds a newline
@@ -224,8 +232,8 @@ func (p *Ping) Error() error {
}
// PingAll loops through all the pings and calls CheckNode on them
-func PingAll(ctx context.Context, cfg config.Config, printer Printer) error {
- pings := newPingSet(cfg, printer)
+func PingAll(ctx context.Context, cfg config.Config, printer Printer, quiet bool) error {
+ pings := newPingSet(cfg, printer, quiet)
var wg sync.WaitGroup
for _, n := range pings {
diff --git a/internal/praefect/nodes/ping_test.go b/internal/praefect/nodes/ping_test.go
index 7457c1d5b..4857f8e80 100644
--- a/internal/praefect/nodes/ping_test.go
+++ b/internal/praefect/nodes/ping_test.go
@@ -33,7 +33,7 @@ func TestNewPingSet(t *testing.T) {
},
}
- actual := newPingSet(conf, nil)
+ actual := newPingSet(conf, nil, true)
expected := map[string]*Ping{
"tcp://example.com": {
address: "tcp://example.com",
@@ -46,6 +46,7 @@ func TestNewPingSet(t *testing.T) {
"woof": {},
},
token: "abc",
+ quiet: true,
},
}