Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send preflight results event when preflights fail #1553

Merged
merged 11 commits into from
Dec 5, 2024
19 changes: 12 additions & 7 deletions cmd/installer/cli/install_runpreflights.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/replicatedhq/embedded-cluster/pkg/dryrun"
"github.com/replicatedhq/embedded-cluster/pkg/goods"
"github.com/replicatedhq/embedded-cluster/pkg/helpers"
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
"github.com/replicatedhq/embedded-cluster/pkg/preflights"
"github.com/replicatedhq/embedded-cluster/pkg/prompts"
"github.com/replicatedhq/embedded-cluster/pkg/release"
Expand Down Expand Up @@ -378,10 +379,10 @@ func RunHostPreflights(cmd *cobra.Command, applier *addons.Applier, replicatedAP
return nil
}

return runHostPreflights(cmd, hpf, proxy, assumeYes)
return runHostPreflights(cmd, hpf, proxy, assumeYes, replicatedAPIURL)
}

func runHostPreflights(cmd *cobra.Command, hpf *v1beta2.HostPreflightSpec, proxy *ecv1beta1.ProxySpec, assumeYes bool) error {
func runHostPreflights(cmd *cobra.Command, hpf *v1beta2.HostPreflightSpec, proxy *ecv1beta1.ProxySpec, assumeYes bool, replicatedAPIURL string) error {
Copy link
Member

@emosbaugh emosbaugh Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this function is called from many different commands, wouldn't it be helpful to report which command was run? also, is it your intention to report for the run-preflights commands? and not related to this change, but why prompt at all for those commands?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the reporting to include the command that was called (install, run-preflights, join etc)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and not related to this change, but why prompt at all for those commands?

Because it's the same codepath, but we hide the 'skip-host-preflights' and 'ignore-host-preflight' flags on those commands, so there shouldn't be prompts (the code we're using expects the flags to exist, which is why they're there at all)

if len(hpf.Collectors) == 0 && len(hpf.Analyzers) == 0 {
return nil
}
Expand Down Expand Up @@ -437,9 +438,11 @@ func runHostPreflights(cmd *cobra.Command, hpf *v1beta2.HostPreflightSpec, proxy
}
if ignoreHostPreflightsFlag {
if assumeYes {
metrics.ReportPreflightsFailed(cmd.Context(), replicatedAPIURL, *output, true)
return nil
}
if prompts.New().Confirm("Are you sure you want to ignore these failures and continue installing?", false) {
metrics.ReportPreflightsFailed(cmd.Context(), replicatedAPIURL, *output, true)
return nil // user continued after host preflights failed
}
}
Expand All @@ -449,7 +452,7 @@ func runHostPreflights(cmd *cobra.Command, hpf *v1beta2.HostPreflightSpec, proxy
} else {
logrus.Info("Please address this issue and try again.")
}

metrics.ReportPreflightsFailed(cmd.Context(), replicatedAPIURL, *output, false)
return ErrPreflightsHaveFail
}

Expand All @@ -465,15 +468,17 @@ func runHostPreflights(cmd *cobra.Command, hpf *v1beta2.HostPreflightSpec, proxy
// so we just print the warnings and continue
pb.Close()
output.PrintTableWithoutInfo()
metrics.ReportPreflightsFailed(cmd.Context(), replicatedAPIURL, *output, true)
return nil
}
pb.Close()
output.PrintTableWithoutInfo()
if !prompts.New().Confirm("Do you want to continue?", false) {
pb.Close()
return fmt.Errorf("user aborted")
if prompts.New().Confirm("Do you want to continue?", false) {
metrics.ReportPreflightsFailed(cmd.Context(), replicatedAPIURL, *output, true)
return nil
}
return nil
metrics.ReportPreflightsFailed(cmd.Context(), replicatedAPIURL, *output, false)
return fmt.Errorf("user aborted")
}

// No failures or warnings
Expand Down
2 changes: 1 addition & 1 deletion cmd/installer/cli/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ func RunHostPreflightsForRestore(cmd *cobra.Command, applier *addons.Applier, pr
return fmt.Errorf("unable to read host preflights: %w", err)
}

return runHostPreflights(cmd, hpf, proxy, assumeYes)
return runHostPreflights(cmd, hpf, proxy, assumeYes, "")
}

// ensureK0sConfigForRestore creates a new k0s.yaml configuration file for restore operations.
Expand Down
35 changes: 35 additions & 0 deletions pkg/metrics/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package metrics

import (
"context"
"encoding/json"
"os"
"strings"
"sync"
Expand All @@ -12,6 +13,7 @@ import (

"github.com/replicatedhq/embedded-cluster/pkg/helpers"
"github.com/replicatedhq/embedded-cluster/pkg/metrics/types"
"github.com/replicatedhq/embedded-cluster/pkg/preflights"
"github.com/replicatedhq/embedded-cluster/pkg/release"
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
"github.com/replicatedhq/embedded-cluster/pkg/versions"
Expand Down Expand Up @@ -159,3 +161,36 @@ func ReportApplyFinished(ctx context.Context, licenseFlag string, err error) {
}
ReportInstallationSucceeded(ctx, License(licenseFlag))
}

// ReportPreflightsFailed reports that the preflights failed but were bypassed.
func ReportPreflightsFailed(ctx context.Context, url string, output preflights.Output, bypassed bool) {
if url == "" {
url = BaseURL(nil)
}

hostname, err := os.Hostname()
if err != nil {
logrus.Warnf("unable to get hostname: %s", err)
hostname = "unknown"
}

eventType := "PreflightsFailed"
if bypassed {
eventType = "PreflightsBypassed"
}

outputJSON, err := json.Marshal(output)
if err != nil {
logrus.Warnf("unable to marshal preflight output: %s", err)
return
}

ev := types.PreflightsFailed{
ClusterID: ClusterID(),
Version: versions.Version,
NodeName: hostname,
PreflightOutput: string(outputJSON),
EventType: eventType,
}
go Send(ctx, url, ev)
}
15 changes: 15 additions & 0 deletions pkg/metrics/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,18 @@ type JoinFailed struct {
func (e JoinFailed) Title() string {
return "JoinFailed"
}

// PreflightsFailed event is send back home when the preflights failed but were bypassed.
type PreflightsFailed struct {
ClusterID uuid.UUID `json:"clusterID"`
Version string `json:"version"`
NodeName string `json:"nodeName"`
PreflightOutput string `json:"preflightOutput"`
EventType string `json:"eventType"`
}

// Title returns the name of the event.
func (e PreflightsFailed) Title() string {
// GenericEvents are added to the events table, but do not update the cluster status
return "GenericEvent"
}
Loading