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

     1  package explain
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	"github.com/apprenda/kismatic/pkg/ansible"
     8  	"github.com/apprenda/kismatic/pkg/util"
     9  )
    10  
    11  type verboseExplainer struct {
    12  	out              io.Writer
    13  	printPlayMessage bool
    14  	printPlayStatus  bool
    15  	lastPlay         string
    16  	currentTask      string
    17  }
    18  
    19  func (explainer *verboseExplainer) writePlayStatus(buf io.Writer) {
    20  	// Do not print message before first play
    21  	if explainer.printPlayMessage {
    22  		// No tasks were printed, no nodes match the selector
    23  		// This is OK and a valid scenario
    24  		if explainer.printPlayStatus {
    25  			fmt.Fprintln(buf)
    26  			util.PrintColor(buf, util.Green, "%s Finished With No Tasks\n", explainer.lastPlay)
    27  		} else {
    28  			util.PrintColor(buf, util.Green, "%s Finished\n", explainer.lastPlay)
    29  		}
    30  	}
    31  }
    32  
    33  // ExplainEvent writes the verbose explanation of the ansible event
    34  func (explainer *verboseExplainer) ExplainEvent(e ansible.Event) {
    35  	out := explainer.out
    36  	switch event := e.(type) {
    37  	case *ansible.PlayStartEvent:
    38  		// On a play start the previous play ends
    39  		// Print a success status, but only when there were no errors
    40  		explainer.writePlayStatus(out)
    41  		fmt.Fprintf(out, "%s", event.Name)
    42  		// Set default state for the play
    43  		explainer.lastPlay = event.Name
    44  		explainer.printPlayStatus = true
    45  		explainer.printPlayMessage = true
    46  	case *ansible.RunnerFailedEvent:
    47  		// Print newline before first task status
    48  		if explainer.printPlayStatus {
    49  			fmt.Fprintln(out)
    50  			// Dont print play success status on error
    51  			explainer.printPlayStatus = false
    52  		}
    53  		// Tasks only print at verbose level, on ERROR also print task name
    54  		if event.IgnoreErrors {
    55  			util.PrettyPrintErrorIgnored(out, "  %s", event.Host)
    56  		} else {
    57  			util.PrettyPrintErr(out, "  %s %s", event.Host, event.Result.Message)
    58  		}
    59  		if event.Result.Stdout != "" {
    60  			util.PrintColor(out, util.Red, "---- STDOUT ----\n%s\n", event.Result.Stdout)
    61  		}
    62  		if event.Result.Stderr != "" {
    63  			util.PrintColor(out, util.Red, "---- STDERR ----\n%s\n", event.Result.Stderr)
    64  		}
    65  		if event.Result.Stderr != "" || event.Result.Stdout != "" {
    66  			util.PrintColor(out, util.Red, "---------------\n")
    67  		}
    68  	case *ansible.RunnerUnreachableEvent:
    69  		// Host is unreachable
    70  		// Print newline before first task
    71  		if explainer.printPlayStatus {
    72  			fmt.Fprintln(out)
    73  			// Dont print play success status on error
    74  			explainer.printPlayStatus = false
    75  		}
    76  		util.PrettyPrintUnreachable(out, "  %s", event.Host)
    77  	case *ansible.TaskStartEvent:
    78  		// Print newline before first task status
    79  		if explainer.printPlayStatus {
    80  			fmt.Fprintln(out)
    81  			// Dont print play success status on error
    82  			explainer.printPlayStatus = false
    83  		}
    84  		fmt.Fprintf(out, "- Running task: %s\n", event.Name)
    85  		// Set current task name
    86  		explainer.currentTask = event.Name
    87  	case *ansible.HandlerTaskStartEvent:
    88  		// Print newline before first task
    89  		if explainer.printPlayStatus {
    90  			fmt.Fprintln(out)
    91  			// Dont print play success status on error
    92  			explainer.printPlayStatus = false
    93  		}
    94  		fmt.Fprintf(out, "- Running task: %s\n", event.Name)
    95  		// Set current task name
    96  		explainer.currentTask = event.Name
    97  	case *ansible.PlaybookEndEvent:
    98  		// Playbook ends, print the last play status
    99  		explainer.writePlayStatus(out)
   100  	case *ansible.RunnerSkippedEvent:
   101  		util.PrettyPrintSkipped(out, "  %s", event.Host)
   102  	case *ansible.RunnerOKEvent:
   103  		util.PrettyPrintOk(out, "  %s", event.Host)
   104  	case *ansible.RunnerItemOKEvent:
   105  		msg := fmt.Sprintf("  %s", event.Host)
   106  		if event.Result.Item != "" {
   107  			msg = msg + fmt.Sprintf(" with %q", event.Result.Item)
   108  		}
   109  		util.PrettyPrintOk(out, msg)
   110  	case *ansible.RunnerItemFailedEvent:
   111  		msg := fmt.Sprintf("  %s", event.Host)
   112  		if event.Result.Item != "" {
   113  			msg = msg + fmt.Sprintf(" with %q", event.Result.Item)
   114  		}
   115  		// Print newline before first task status
   116  		if explainer.printPlayStatus {
   117  			fmt.Fprintln(out)
   118  			// Dont print play success status on error
   119  			explainer.printPlayStatus = false
   120  		}
   121  		// Tasks only print at verbose level, on ERROR also print task name
   122  		if event.IgnoreErrors {
   123  			util.PrettyPrintErrorIgnored(out, msg)
   124  		} else {
   125  			util.PrettyPrintErr(out, "  %s %s", msg, event.Result.Message)
   126  		}
   127  		if event.Result.Stdout != "" {
   128  			util.PrintColor(out, util.Red, "---- STDOUT ----\n%s\n", event.Result.Stdout)
   129  		}
   130  		if event.Result.Stderr != "" {
   131  			util.PrintColor(out, util.Red, "---- STDERR ----\n%s\n", event.Result.Stderr)
   132  		}
   133  		if event.Result.Stderr != "" || event.Result.Stdout != "" {
   134  			util.PrintColor(out, util.Red, "---------------\n")
   135  		}
   136  
   137  	// Ignored events
   138  	case *ansible.RunnerItemRetryEvent:
   139  		fmt.Fprintf(out, " %s Retrying: %s (%d/%d attempts)\n", event.Host, explainer.currentTask, event.Result.Attempts, event.Result.MaxRetries-1)
   140  	case *ansible.PlaybookStartEvent:
   141  	default:
   142  		util.PrintColor(out, util.Orange, "Unhandled event: %T\n", event)
   143  	}
   144  }