github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/lxc/builder.go (about)

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