github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/install/explain/preflight.go (about)

     1  package explain
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/apprenda/kismatic/pkg/ansible"
    10  	"github.com/apprenda/kismatic/pkg/inspector/rule"
    11  	"github.com/apprenda/kismatic/pkg/util"
    12  	"github.com/gosuri/uilive"
    13  )
    14  
    15  // PreflightExplainer is an explainer to be used when running preflight checks.
    16  func PreflightExplainer(verbose bool, out io.Writer) AnsibleEventExplainer {
    17  	if verbose || !isTerminal(out) {
    18  		return &verbosePreflightExplainer{
    19  			out:       out,
    20  			explainer: verboseExplainer{out: out},
    21  		}
    22  	}
    23  	w := uilive.New()
    24  	w.Out = out
    25  	w.Start()
    26  	return &updatingPreflightExplainer{
    27  		out:       w,
    28  		explainer: updatingExplainer{out: w},
    29  	}
    30  }
    31  
    32  type updatingPreflightExplainer struct {
    33  	out       *uilive.Writer
    34  	explainer updatingExplainer
    35  }
    36  
    37  func (exp *updatingPreflightExplainer) ExplainEvent(ansibleEvent ansible.Event) {
    38  	switch event := ansibleEvent.(type) {
    39  	default:
    40  		exp.explainer.ExplainEvent(ansibleEvent)
    41  	case *ansible.RunnerFailedEvent:
    42  		buf := &bytes.Buffer{}
    43  		// only print this header this is the first failure
    44  		if !exp.explainer.failureOccurred {
    45  			util.PrettyPrintErr(buf, "%s", exp.explainer.currentPlayName)
    46  			fmt.Fprintln(buf, "- Task: "+exp.explainer.currentTask)
    47  		}
    48  		results := []rule.Result{}
    49  		if err := json.Unmarshal([]byte(event.Result.Stdout), &results); err != nil {
    50  			exp.explainer.ExplainEvent(event)
    51  			return
    52  		}
    53  		// print info about pre-flight checks that failed
    54  		util.PrintColor(buf, util.Red, "=> The following checks failed on %q:\n", event.Host)
    55  		for _, r := range results {
    56  			if !r.Success && r.Error != "" {
    57  				util.PrintColor(buf, util.Red, "   - %s: %v\n", r.Name, r.Error)
    58  			} else if !r.Success {
    59  				util.PrintColor(buf, util.Red, "   - %s\n", r.Name)
    60  			}
    61  		}
    62  		fmt.Fprintf(exp.out.Bypass(), buf.String())
    63  		exp.explainer.failureOccurred = true
    64  	}
    65  }
    66  
    67  type verbosePreflightExplainer struct {
    68  	out       io.Writer
    69  	explainer verboseExplainer
    70  }
    71  
    72  func (exp *verbosePreflightExplainer) ExplainEvent(ansibleEvent ansible.Event) {
    73  	switch event := ansibleEvent.(type) {
    74  	default:
    75  		exp.explainer.ExplainEvent(ansibleEvent)
    76  	case *ansible.RunnerFailedEvent:
    77  		results := []rule.Result{}
    78  		if err := json.Unmarshal([]byte(event.Result.Stdout), &results); err != nil {
    79  			exp.explainer.ExplainEvent(event)
    80  			return
    81  		}
    82  		// print info about pre-flight checks that failed
    83  		util.PrintColor(exp.out, util.Red, "=> The following checks failed on %q:\n", event.Host)
    84  		for _, r := range results {
    85  			if !r.Success && r.Error != "" {
    86  				util.PrintColor(exp.out, util.Red, "   - %s: %v\n", r.Name, r.Error)
    87  			} else if !r.Success {
    88  				util.PrintColor(exp.out, util.Red, "   - %s\n", r.Name)
    89  			}
    90  		}
    91  		util.PrintColor(exp.out, util.Green, "=> Successful pre-flight checks:\n")
    92  		for _, r := range results {
    93  			if r.Success {
    94  				util.PrintColor(exp.out, util.Green, "   - %s\n", r.Name)
    95  			}
    96  		}
    97  		exp.explainer.printPlayStatus = false
    98  	}
    99  }