github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/builder/parallels/pvm/builder.go (about)

     1  package pvm
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"github.com/mitchellh/multistep"
     7  	parallelscommon "github.com/mitchellh/packer/builder/parallels/common"
     8  	"github.com/mitchellh/packer/common"
     9  	"github.com/mitchellh/packer/packer"
    10  	"log"
    11  )
    12  
    13  // Builder implements packer.Builder and builds the actual Parallels
    14  // images.
    15  type Builder struct {
    16  	config *Config
    17  	runner multistep.Runner
    18  }
    19  
    20  // Prepare processes the build configuration parameters.
    21  func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
    22  	c, warnings, errs := NewConfig(raws...)
    23  	if errs != nil {
    24  		return warnings, errs
    25  	}
    26  	b.config = c
    27  
    28  	return warnings, nil
    29  }
    30  
    31  // Run executes a Packer build and returns a packer.Artifact representing
    32  // a Parallels appliance.
    33  func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
    34  	// Create the driver that we'll use to communicate with Parallels
    35  	driver, err := parallelscommon.NewDriver()
    36  	if err != nil {
    37  		return nil, fmt.Errorf("Failed creating Paralles driver: %s", err)
    38  	}
    39  
    40  	// Set up the state.
    41  	state := new(multistep.BasicStateBag)
    42  	state.Put("config", b.config)
    43  	state.Put("driver", driver)
    44  	state.Put("hook", hook)
    45  	state.Put("ui", ui)
    46  	state.Put("http_port", uint(0))
    47  
    48  	// Build the steps.
    49  	steps := []multistep.Step{
    50  		&parallelscommon.StepPrepareParallelsTools{
    51  			ParallelsToolsMode:   b.config.ParallelsToolsMode,
    52  			ParallelsToolsFlavor: b.config.ParallelsToolsFlavor,
    53  		},
    54  		&parallelscommon.StepOutputDir{
    55  			Force: b.config.PackerForce,
    56  			Path:  b.config.OutputDir,
    57  		},
    58  		&common.StepCreateFloppy{
    59  			Files: b.config.FloppyFiles,
    60  		},
    61  		&StepImport{
    62  			Name:       b.config.VMName,
    63  			SourcePath: b.config.SourcePath,
    64  		},
    65  		&parallelscommon.StepAttachParallelsTools{
    66  			ParallelsToolsMode: b.config.ParallelsToolsMode,
    67  		},
    68  		new(parallelscommon.StepAttachFloppy),
    69  		&parallelscommon.StepPrlctl{
    70  			Commands: b.config.Prlctl,
    71  			Tpl:      b.config.tpl,
    72  		},
    73  		&parallelscommon.StepRun{
    74  			BootWait: b.config.BootWait,
    75  			Headless: b.config.Headless,
    76  		},
    77  		&parallelscommon.StepTypeBootCommand{
    78  			BootCommand:    b.config.BootCommand,
    79  			HostInterfaces: []string{},
    80  			VMName:         b.config.VMName,
    81  			Tpl:            b.config.tpl,
    82  		},
    83  		&common.StepConnectSSH{
    84  			SSHAddress:     parallelscommon.SSHAddress,
    85  			SSHConfig:      parallelscommon.SSHConfigFunc(b.config.SSHConfig),
    86  			SSHWaitTimeout: b.config.SSHWaitTimeout,
    87  		},
    88  		&parallelscommon.StepUploadVersion{
    89  			Path: b.config.PrlctlVersionFile,
    90  		},
    91  		&parallelscommon.StepUploadParallelsTools{
    92  			ParallelsToolsFlavor:    b.config.ParallelsToolsFlavor,
    93  			ParallelsToolsGuestPath: b.config.ParallelsToolsGuestPath,
    94  			ParallelsToolsMode:      b.config.ParallelsToolsMode,
    95  			Tpl:                     b.config.tpl,
    96  		},
    97  		new(common.StepProvision),
    98  		&parallelscommon.StepShutdown{
    99  			Command: b.config.ShutdownCommand,
   100  			Timeout: b.config.ShutdownTimeout,
   101  		},
   102  		new(parallelscommon.StepRemoveDevices),
   103  	}
   104  
   105  	// Run the steps.
   106  	if b.config.PackerDebug {
   107  		b.runner = &multistep.DebugRunner{
   108  			Steps:   steps,
   109  			PauseFn: common.MultistepDebugFn(ui),
   110  		}
   111  	} else {
   112  		b.runner = &multistep.BasicRunner{Steps: steps}
   113  	}
   114  	b.runner.Run(state)
   115  
   116  	// Report any errors.
   117  	if rawErr, ok := state.GetOk("error"); ok {
   118  		return nil, rawErr.(error)
   119  	}
   120  
   121  	// If we were interrupted or cancelled, then just exit.
   122  	if _, ok := state.GetOk(multistep.StateCancelled); ok {
   123  		return nil, errors.New("Build was cancelled.")
   124  	}
   125  
   126  	if _, ok := state.GetOk(multistep.StateHalted); ok {
   127  		return nil, errors.New("Build was halted.")
   128  	}
   129  
   130  	return parallelscommon.NewArtifact(b.config.OutputDir)
   131  }
   132  
   133  // Cancel.
   134  func (b *Builder) Cancel() {
   135  	if b.runner != nil {
   136  		log.Println("Cancelling the step runner...")
   137  		b.runner.Cancel()
   138  	}
   139  }