github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/docker/builder.go (about) 1 package docker 2 3 import ( 4 "log" 5 6 "github.com/hashicorp/packer/common" 7 "github.com/hashicorp/packer/helper/communicator" 8 "github.com/hashicorp/packer/helper/multistep" 9 "github.com/hashicorp/packer/packer" 10 ) 11 12 const ( 13 BuilderId = "packer.docker" 14 BuilderIdImport = "packer.post-processor.docker-import" 15 ) 16 17 type Builder struct { 18 config *Config 19 runner multistep.Runner 20 } 21 22 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 23 c, warnings, errs := NewConfig(raws...) 24 if errs != nil { 25 return warnings, errs 26 } 27 b.config = c 28 29 return warnings, nil 30 } 31 32 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 33 driver := &DockerDriver{Ctx: &b.config.ctx, Ui: ui} 34 if err := driver.Verify(); err != nil { 35 return nil, err 36 } 37 38 version, err := driver.Version() 39 if err != nil { 40 return nil, err 41 } 42 log.Printf("[DEBUG] Docker version: %s", version.String()) 43 44 steps := []multistep.Step{ 45 &StepTempDir{}, 46 &StepPull{}, 47 &StepRun{}, 48 &communicator.StepConnect{ 49 Config: &b.config.Comm, 50 Host: commHost, 51 SSHConfig: sshConfig(&b.config.Comm), 52 CustomConnect: map[string]multistep.Step{ 53 "docker": &StepConnectDocker{}, 54 }, 55 }, 56 &common.StepProvision{}, 57 } 58 59 if b.config.Discard { 60 log.Print("[DEBUG] Container will be discarded") 61 } else if b.config.Commit { 62 log.Print("[DEBUG] Container will be committed") 63 steps = append(steps, new(StepCommit)) 64 } else if b.config.ExportPath != "" { 65 log.Printf("[DEBUG] Container will be exported to %s", b.config.ExportPath) 66 steps = append(steps, new(StepExport)) 67 } else { 68 return nil, errArtifactNotUsed 69 } 70 71 // Setup the state bag and initial state for the steps 72 state := new(multistep.BasicStateBag) 73 state.Put("config", b.config) 74 state.Put("hook", hook) 75 state.Put("ui", ui) 76 77 // Setup the driver that will talk to Docker 78 state.Put("driver", driver) 79 80 // Run! 81 b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) 82 b.runner.Run(state) 83 84 // If there was an error, return that 85 if rawErr, ok := state.GetOk("error"); ok { 86 return nil, rawErr.(error) 87 } 88 89 // If it was cancelled, then just return 90 if _, ok := state.GetOk(multistep.StateCancelled); ok { 91 return nil, nil 92 } 93 94 // No errors, must've worked 95 var artifact packer.Artifact 96 if b.config.Commit { 97 artifact = &ImportArtifact{ 98 IdValue: state.Get("image_id").(string), 99 BuilderIdValue: BuilderIdImport, 100 Driver: driver, 101 } 102 } else { 103 artifact = &ExportArtifact{path: b.config.ExportPath} 104 } 105 106 return artifact, nil 107 } 108 109 func (b *Builder) Cancel() { 110 if b.runner != nil { 111 log.Println("Cancelling the step runner...") 112 b.runner.Cancel() 113 } 114 }