github.com/rothwerx/packer@v0.9.0/builder/docker/builder.go (about) 1 package docker 2 3 import ( 4 "log" 5 6 "github.com/mitchellh/multistep" 7 "github.com/mitchellh/packer/common" 8 "github.com/mitchellh/packer/helper/communicator" 9 "github.com/mitchellh/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 if b.config.PackerDebug { 82 b.runner = &multistep.DebugRunner{ 83 Steps: steps, 84 PauseFn: common.MultistepDebugFn(ui), 85 } 86 } else { 87 b.runner = &multistep.BasicRunner{Steps: steps} 88 } 89 90 b.runner.Run(state) 91 92 // If there was an error, return that 93 if rawErr, ok := state.GetOk("error"); ok { 94 return nil, rawErr.(error) 95 } 96 97 // If it was cancelled, then just return 98 if _, ok := state.GetOk(multistep.StateCancelled); ok { 99 return nil, nil 100 } 101 102 // No errors, must've worked 103 var artifact packer.Artifact 104 if b.config.Commit { 105 artifact = &ImportArtifact{ 106 IdValue: state.Get("image_id").(string), 107 BuilderIdValue: BuilderIdImport, 108 Driver: driver, 109 } 110 } else { 111 artifact = &ExportArtifact{path: b.config.ExportPath} 112 } 113 114 return artifact, nil 115 } 116 117 func (b *Builder) Cancel() { 118 if b.runner != nil { 119 log.Println("Cancelling the step runner...") 120 b.runner.Cancel() 121 } 122 }