github.com/ttysteale/packer@v0.8.2-0.20150708160520-e5f8ea386ed8/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 BuilderId = "packer.docker" 13 const BuilderIdImport = "packer.post-processor.docker-import" 14 15 type Builder struct { 16 config *Config 17 runner multistep.Runner 18 } 19 20 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 21 c, warnings, errs := NewConfig(raws...) 22 if errs != nil { 23 return warnings, errs 24 } 25 b.config = c 26 27 return warnings, nil 28 } 29 30 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 31 driver := &DockerDriver{Ctx: &b.config.ctx, Ui: ui} 32 if err := driver.Verify(); err != nil { 33 return nil, err 34 } 35 36 version, err := driver.Version() 37 if err != nil { 38 return nil, err 39 } 40 log.Printf("[DEBUG] Docker version: %s", version.String()) 41 42 steps := []multistep.Step{ 43 &StepTempDir{}, 44 &StepPull{}, 45 &StepRun{}, 46 &communicator.StepConnect{ 47 Config: &b.config.Comm, 48 Host: commHost, 49 SSHConfig: sshConfig(&b.config.Comm), 50 CustomConnect: map[string]multistep.Step{ 51 "docker": &StepConnectDocker{}, 52 }, 53 }, 54 &common.StepProvision{}, 55 } 56 57 if b.config.Commit { 58 steps = append(steps, new(StepCommit)) 59 } else { 60 steps = append(steps, new(StepExport)) 61 } 62 63 // Setup the state bag and initial state for the steps 64 state := new(multistep.BasicStateBag) 65 state.Put("config", b.config) 66 state.Put("hook", hook) 67 state.Put("ui", ui) 68 69 // Setup the driver that will talk to Docker 70 state.Put("driver", driver) 71 72 // Run! 73 if b.config.PackerDebug { 74 b.runner = &multistep.DebugRunner{ 75 Steps: steps, 76 PauseFn: common.MultistepDebugFn(ui), 77 } 78 } else { 79 b.runner = &multistep.BasicRunner{Steps: steps} 80 } 81 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 }