Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions src/pixie_cli/pkg/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ func waitForHealthCheckTaskGenerator(cloudAddr string, clusterID uuid.UUID) func
}
// The health check warning error indicates the cluster successfully deployed, but there are some warnings.
// Return the error to end the polling and show the warnings.
if _, ok := err.(*vizier.HealthCheckWarning); ok {
if _, ok := err.(*components.UIWarning); ok {
return err
}
time.Sleep(5 * time.Second)
Expand All @@ -642,15 +642,13 @@ func waitForHealthCheck(cloudAddr string, clusterID uuid.UUID, clientset *kubern
hc := utils.NewSerialTaskRunner(healthCheckJobs)
err := hc.RunAndMonitor()
if err != nil {
if _, ok := err.(*vizier.HealthCheckWarning); ok {
utils.WithError(err).Error("Pixie healthcheck detected the following warnings:")
} else {
_ = pxanalytics.Client().Enqueue(&analytics.Track{
UserId: pxconfig.Cfg().UniqueClientID,
Event: "Deploy Healthcheck Failed",
Properties: analytics.NewProperties().
Set("err", err.Error()),
})
_ = pxanalytics.Client().Enqueue(&analytics.Track{
UserId: pxconfig.Cfg().UniqueClientID,
Event: "Deploy Healthcheck Failed",
Properties: analytics.NewProperties().
Set("err", err.Error()),
})
if _, ok := err.(*components.UIWarning); !ok {
utils.WithError(err).Fatal("Failed Pixie healthcheck")
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/pixie_cli/pkg/components/spinner.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ func (d *statusDecorator) Decor(stat *decor.Statistics) string {
return ""
}
if d.err != nil {
if _, ok := d.err.(*UIWarning); ok {
return StatusWarn(d.width)
}
return StatusErr(d.width)
}
return StatusOK(d.width)
Expand Down Expand Up @@ -136,6 +139,9 @@ func (d *errorViewDecorator) Decor(stat *decor.Statistics) string {
if d.err == nil {
return ""
}
if _, ok := d.err.(*UIWarning); ok {
return color.YellowString(fmt.Sprintf(" WARN: %s", d.err.Error()))
}
return color.RedString(fmt.Sprintf(" ERR: %s", d.err.Error()))
}

Expand Down
26 changes: 24 additions & 2 deletions src/pixie_cli/pkg/components/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,26 @@ import (
)

var (
statusOK = "\u2714"
statusErr = "\u2715"
statusOK = "\u2714"
statusErr = "\u2715"
statusWarn = "\u26a0"
)

// UIWarning is a wrapper type that marks errors as warnings for UI display.
// Errors wrapped in UIWarning will be displayed with yellow warning colors
// instead of red error colors in the spinner table.
type UIWarning struct {
Err error
}

func (w UIWarning) Error() string {
return w.Err.Error()
}

func (w UIWarning) Unwrap() error {
return w.Err
}

func computePadding(s string, pad int) (int, int) {
var padS, padE int
pad -= len([]rune(s))
Expand All @@ -55,3 +71,9 @@ func StatusErr(pad int) string {
padS, padE := computePadding(statusErr, pad)
return strings.Repeat(" ", padS) + color.RedString(statusErr) + strings.Repeat(" ", padE)
}

// StatusWarn prints out the default Warn symbol, center padded to the size specified.
func StatusWarn(pad int) string {
padS, padE := computePadding(statusWarn, pad)
return strings.Repeat(" ", padS) + color.YellowString(statusWarn) + strings.Repeat(" ", padE)
}
3 changes: 2 additions & 1 deletion src/pixie_cli/pkg/vizier/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"

"px.dev/pixie/src/pixie_cli/pkg/components"
"px.dev/pixie/src/utils/script"
"px.dev/pixie/src/utils/shared/k8s"
)
Expand Down Expand Up @@ -132,7 +133,7 @@ func (c *LogCollector) CollectPixieLogs(fName string) error {
outputCh, err := RunSimpleHealthCheckScript(c.br, c.cloudAddr, clusterID)
if err != nil {
entry := log.WithError(err)
if _, ok := err.(*HealthCheckWarning); ok {
if _, ok := err.(*components.UIWarning); ok {
entry.Warn("healthcheck script detected the following warnings:")
} else {
entry.Warn("failed to run healthcheck script")
Expand Down
23 changes: 6 additions & 17 deletions src/pixie_cli/pkg/vizier/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ import (
)

const (
equalityThreshold = 0.01
headersInstalledPercColumn = "headers_installed_percent" // must match the column in px/agent_status_diagnostics
equalityThreshold = 0.01
headersInstalledPercColumn = "headers_installed_percent" // must match the column in px/agent_status_diagnostics
missingKernelHeadersMsg = "Detected missing kernel headers on your cluster's nodes. This may cause issues with the Pixie agent. Please see https://px.dev/kernel-headers for more details."
missingKernelHeadersSuspectedMsg = "Detected missing kernel headers on your cluster's nodes. This may cause issues with the Pixie agent. Please see https://px.dev/kernel-headers for more details. If you are using a distro kernel, this is expected and can be ignored."
)

type taskWrapper struct {
Expand Down Expand Up @@ -266,18 +268,6 @@ func RunScript(ctx context.Context, conns []*Connector, execScript *script.Execu
return mergedResponses, nil
}

type HealthCheckWarning struct {
message string
}

func (h *HealthCheckWarning) Error() string {
return h.message
}

func newHealthCheckWarning(message string) error {
return &HealthCheckWarning{message}
}

func evaluateHealthCheckResult(output string) error {
jsonData := make(map[string]interface{})

Expand All @@ -289,12 +279,11 @@ func evaluateHealthCheckResult(output string) error {
switch t := v.(type) {
case float64:
if math.Abs(1.0-t) > equalityThreshold {
msg := "Detected missing kernel headers on your cluster's nodes. This may cause issues with the Pixie agent. Please install kernel headers on all nodes."
return newHealthCheckWarning(msg)
return &components.UIWarning{Err: fmt.Errorf("%s", missingKernelHeadersMsg)}
}
}
} else {
return newHealthCheckWarning("Unable to detect if the cluster's nodes have the distro kernel headers installed (vizier too old to perform this check). Please ensure that the kernel headers are installed on all nodes.")
return &components.UIWarning{Err: fmt.Errorf("%s", missingKernelHeadersSuspectedMsg)}
}
return nil
}
Expand Down