github.com/mitchellh/packer@v1.3.2/common/shell-local/communicator.go (about)

     1  package shell_local
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"log"
     7  	"os"
     8  	"os/exec"
     9  	"syscall"
    10  
    11  	"github.com/hashicorp/packer/packer"
    12  )
    13  
    14  type Communicator struct {
    15  	ExecuteCommand []string
    16  }
    17  
    18  func (c *Communicator) Start(cmd *packer.RemoteCmd) error {
    19  	if len(c.ExecuteCommand) == 0 {
    20  		return fmt.Errorf("Error launching command via shell-local communicator: No ExecuteCommand provided")
    21  	}
    22  
    23  	// Build the local command to execute
    24  	log.Printf("[INFO] (shell-local communicator): Executing local shell command %s", c.ExecuteCommand)
    25  	localCmd := exec.Command(c.ExecuteCommand[0], c.ExecuteCommand[1:]...)
    26  	localCmd.Stdin = cmd.Stdin
    27  	localCmd.Stdout = cmd.Stdout
    28  	localCmd.Stderr = cmd.Stderr
    29  
    30  	// Start it. If it doesn't work, then error right away.
    31  	if err := localCmd.Start(); err != nil {
    32  		return err
    33  	}
    34  
    35  	// We've started successfully. Start a goroutine to wait for
    36  	// it to complete and track exit status.
    37  	go func() {
    38  		var exitStatus int
    39  		err := localCmd.Wait()
    40  		if err != nil {
    41  			if exitErr, ok := err.(*exec.ExitError); ok {
    42  				exitStatus = 1
    43  
    44  				// There is no process-independent way to get the REAL
    45  				// exit status so we just try to go deeper.
    46  				if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
    47  					exitStatus = status.ExitStatus()
    48  				}
    49  			}
    50  		}
    51  
    52  		cmd.SetExited(exitStatus)
    53  	}()
    54  
    55  	return nil
    56  }
    57  
    58  func (c *Communicator) Upload(string, io.Reader, *os.FileInfo) error {
    59  	return fmt.Errorf("upload not supported")
    60  }
    61  
    62  func (c *Communicator) UploadDir(string, string, []string) error {
    63  	return fmt.Errorf("uploadDir not supported")
    64  }
    65  
    66  func (c *Communicator) Download(string, io.Writer) error {
    67  	return fmt.Errorf("download not supported")
    68  }
    69  
    70  func (c *Communicator) DownloadDir(string, string, []string) error {
    71  	return fmt.Errorf("downloadDir not supported")
    72  }