github.phpd.cn/hashicorp/packer@v1.3.2/builder/lxc/builder.go (about) 1 package lxc 2 3 import ( 4 "log" 5 "os" 6 "path/filepath" 7 8 "github.com/hashicorp/packer/common" 9 "github.com/hashicorp/packer/helper/multistep" 10 "github.com/hashicorp/packer/packer" 11 "github.com/hashicorp/packer/template/interpolate" 12 ) 13 14 // The unique ID for this builder 15 const BuilderId = "ustream.lxc" 16 17 type wrappedCommandTemplate struct { 18 Command string 19 } 20 21 type Builder struct { 22 config *Config 23 runner multistep.Runner 24 } 25 26 func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 27 c, errs := NewConfig(raws...) 28 if errs != nil { 29 return nil, errs 30 } 31 b.config = c 32 33 return nil, nil 34 } 35 36 func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 37 wrappedCommand := func(command string) (string, error) { 38 b.config.ctx.Data = &wrappedCommandTemplate{Command: command} 39 return interpolate.Render(b.config.CommandWrapper, &b.config.ctx) 40 } 41 42 steps := []multistep.Step{ 43 new(stepPrepareOutputDir), 44 new(stepLxcCreate), 45 &StepWaitInit{ 46 WaitTimeout: b.config.InitTimeout, 47 }, 48 new(StepProvision), 49 new(stepExport), 50 } 51 52 // Setup the state bag 53 state := new(multistep.BasicStateBag) 54 state.Put("config", b.config) 55 state.Put("cache", cache) 56 state.Put("hook", hook) 57 state.Put("ui", ui) 58 state.Put("wrappedCommand", CommandWrapper(wrappedCommand)) 59 60 // Run 61 b.runner = common.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state) 62 b.runner.Run(state) 63 64 // If there was an error, return that 65 if rawErr, ok := state.GetOk("error"); ok { 66 return nil, rawErr.(error) 67 } 68 69 // Compile the artifact list 70 files := make([]string, 0, 5) 71 visit := func(path string, info os.FileInfo, err error) error { 72 if !info.IsDir() { 73 files = append(files, path) 74 } 75 76 return err 77 } 78 79 if err := filepath.Walk(b.config.OutputDir, visit); err != nil { 80 return nil, err 81 } 82 83 artifact := &Artifact{ 84 dir: b.config.OutputDir, 85 f: files, 86 } 87 88 return artifact, nil 89 } 90 91 func (b *Builder) Cancel() { 92 if b.runner != nil { 93 log.Println("Cancelling the step runner...") 94 b.runner.Cancel() 95 } 96 }