github.phpd.cn/hashicorp/packer@v1.3.2/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: b.config.Comm.SSHConfigFunc(), 52 CustomConnect: map[string]multistep.Step{ 53 "docker": &StepConnectDocker{}, 54 }, 55 }, 56 &common.StepProvision{}, 57 &common.StepCleanupTempKeys{ 58 Comm: &b.config.Comm, 59 }, 60 } 61 62 if b.config.Discard { 63 log.Print("[DEBUG] Container will be discarded") 64 } else if b.config.Commit { 65 log.Print("[DEBUG] Container will be committed") 66 steps = append(steps, new(StepCommit)) 67 } else if b.config.ExportPath != "" { 68 log.Printf("[DEBUG] Container will be exported to %s", b.config.ExportPath) 69 steps = append(steps, new(StepExport)) 70 } else { 71 return nil, errArtifactNotUsed 72 } 73 74 // Setup the state bag and initial state for the steps 75 state := new(multistep.BasicStateBag) 76 state.Put("config", b.config) 77 state.Put("hook", hook) 78 state.Put("ui", ui) 79 80 // Setup the driver that will talk to Docker 81 state.Put("driver", driver) 82 83 // Run! 84 b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) 85 b.runner.Run(state) 86 87 // If there was an error, return that 88 if rawErr, ok := state.GetOk("error"); ok { 89 return nil, rawErr.(error) 90 } 91 92 // If it was cancelled, then just return 93 if _, ok := state.GetOk(multistep.StateCancelled); ok { 94 return nil, nil 95 } 96 97 // No errors, must've worked 98 var artifact packer.Artifact 99 if b.config.Commit { 100 artifact = &ImportArtifact{ 101 IdValue: state.Get("image_id").(string), 102 BuilderIdValue: BuilderIdImport, 103 Driver: driver, 104 } 105 } else { 106 artifact = &ExportArtifact{path: b.config.ExportPath} 107 } 108 109 return artifact, nil 110 } 111 112 func (b *Builder) Cancel() { 113 if b.runner != nil { 114 log.Println("Cancelling the step runner...") 115 b.runner.Cancel() 116 } 117 }