github.com/nxadm/ctwrapper@v0.5.3-0.20200107113753-fb73fb7c1f50/consul-template.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"runtime"
     9  	"strings"
    10  	"sync"
    11  	"syscall"
    12  )
    13  
    14  func runCt(tmplExt string, files, ctParams []string) error {
    15  	ct, err := findConsulTemplate()
    16  	if err != nil {
    17  		return err
    18  	}
    19  
    20  	args := createTmplArg(files, tmplExt)
    21  	args = append(args, ctParams...)
    22  	fmt.Printf("Executing: %s %s\n", ct, strings.Join(args, " "))
    23  
    24  	/* Execute the command */
    25  	switch {
    26  	// Windows does not really forks the process: we need a wrapper to write the stdOut end stdErr at the same time
    27  	case runtime.GOOS == "windows":
    28  		return runWhilePrinting(exec.Command(ct, args...))
    29  	default:
    30  		return syscall.Exec(ct, append([]string{ct}, args...), os.Environ())
    31  	}
    32  
    33  	return nil
    34  }
    35  
    36  func createTmplArg(files []string, tmplExt string) []string {
    37  	tmplArgs := []string{}
    38  	for _, tmpl := range files {
    39  		file := strings.TrimSuffix(tmpl, tmplExt)
    40  		tmplArgs = append(tmplArgs, "-template")
    41  		tmplArgs = append(tmplArgs, tmpl+":"+file)
    42  	}
    43  	return tmplArgs
    44  }
    45  
    46  func runWhilePrinting(cmd *exec.Cmd) error {
    47  	var err error
    48  
    49  	/* Get stdout and stderr realtime */
    50  	var wg sync.WaitGroup
    51  	wg.Add(2) // StdOut + StdErr
    52  	cmdOutReader, err := cmd.StdoutPipe()
    53  	if err != nil {
    54  		return err
    55  	} else {
    56  		scanner := bufio.NewScanner(cmdOutReader)
    57  		go func() {
    58  			defer wg.Done()
    59  			for scanner.Scan() {
    60  				fmt.Fprintf(os.Stdout, "%s\n", scanner.Text())
    61  			}
    62  		}()
    63  	}
    64  	cmdErrReader, err := cmd.StderrPipe()
    65  	if err != nil {
    66  		return err
    67  	} else {
    68  		scanner := bufio.NewScanner(cmdErrReader)
    69  		go func() {
    70  			defer wg.Done()
    71  			for scanner.Scan() {
    72  				fmt.Fprintf(os.Stderr, "%s\n", scanner.Text())
    73  			}
    74  		}()
    75  	}
    76  
    77  	/* Run the cmd */
    78  	err = cmd.Start()
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	waitErr := cmd.Wait()
    84  	if waitErr != nil {
    85  		return waitErr
    86  	}
    87  
    88  	wg.Wait() // Wait for StdOut + StdErr
    89  	return err
    90  }