github.phpd.cn/hashicorp/packer@v1.3.2/builder/docker/step_connect_docker.go (about) 1 package docker 2 3 import ( 4 "context" 5 "fmt" 6 "os/exec" 7 "strings" 8 9 "github.com/hashicorp/packer/helper/multistep" 10 ) 11 12 type StepConnectDocker struct{} 13 14 func (s *StepConnectDocker) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 15 config := state.Get("config").(*Config) 16 containerId := state.Get("container_id").(string) 17 driver := state.Get("driver").(Driver) 18 tempDir := state.Get("temp_dir").(string) 19 20 // Get the version so we can pass it to the communicator 21 version, err := driver.Version() 22 if err != nil { 23 state.Put("error", err) 24 return multistep.ActionHalt 25 } 26 27 containerUser, err := getContainerUser(containerId) 28 if err != nil { 29 state.Put("error", err) 30 return multistep.ActionHalt 31 } 32 33 // Create the communicator that talks to Docker via various 34 // os/exec tricks. 35 comm := &Communicator{ 36 ContainerID: containerId, 37 HostDir: tempDir, 38 ContainerDir: config.ContainerDir, 39 Version: version, 40 Config: config, 41 ContainerUser: containerUser, 42 } 43 44 state.Put("communicator", comm) 45 return multistep.ActionContinue 46 } 47 48 func (s *StepConnectDocker) Cleanup(state multistep.StateBag) {} 49 50 func getContainerUser(containerId string) (string, error) { 51 inspectArgs := []string{"docker", "inspect", "--format", "{{.Config.User}}", containerId} 52 stdout, err := exec.Command(inspectArgs[0], inspectArgs[1:]...).Output() 53 if err != nil { 54 errStr := fmt.Sprintf("Failed to inspect the container: %s", err) 55 if ee, ok := err.(*exec.ExitError); ok { 56 errStr = fmt.Sprintf("%s, %s", errStr, ee.Stderr) 57 } 58 return "", fmt.Errorf(errStr) 59 } 60 return strings.TrimSpace(string(stdout)), nil 61 }