github.com/homburg/packer@v0.6.1-0.20140528012651-1dcaf1716848/builder/virtualbox/ovf/builder.go (about)

     1  package ovf
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  
     8  	"github.com/mitchellh/multistep"
     9  	vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
    10  	"github.com/mitchellh/packer/common"
    11  	"github.com/mitchellh/packer/packer"
    12  )
    13  
    14  // Builder implements packer.Builder and builds the actual VirtualBox
    15  // images.
    16  type Builder struct {
    17  	config *Config
    18  	runner multistep.Runner
    19  }
    20  
    21  // Prepare processes the build configuration parameters.
    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  // Run executes a Packer build and returns a packer.Artifact representing
    33  // a VirtualBox appliance.
    34  func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
    35  	// Create the driver that we'll use to communicate with VirtualBox
    36  	driver, err := vboxcommon.NewDriver()
    37  	if err != nil {
    38  		return nil, fmt.Errorf("Failed creating VirtualBox driver: %s", err)
    39  	}
    40  
    41  	// Set up the state.
    42  	state := new(multistep.BasicStateBag)
    43  	state.Put("config", b.config)
    44  	state.Put("driver", driver)
    45  	state.Put("cache", cache)
    46  	state.Put("hook", hook)
    47  	state.Put("ui", ui)
    48  
    49  	// Build the steps.
    50  	steps := []multistep.Step{
    51  		&vboxcommon.StepOutputDir{
    52  			Force: b.config.PackerForce,
    53  			Path:  b.config.OutputDir,
    54  		},
    55  		new(vboxcommon.StepSuppressMessages),
    56  		&common.StepCreateFloppy{
    57  			Files: b.config.FloppyFiles,
    58  		},
    59  		&vboxcommon.StepDownloadGuestAdditions{
    60  			GuestAdditionsMode:   b.config.GuestAdditionsMode,
    61  			GuestAdditionsURL:    b.config.GuestAdditionsURL,
    62  			GuestAdditionsSHA256: b.config.GuestAdditionsSHA256,
    63  			Tpl:                  b.config.tpl,
    64  		},
    65  		&StepImport{
    66  			Name:       b.config.VMName,
    67  			SourcePath: b.config.SourcePath,
    68  			ImportOpts: b.config.ImportOpts,
    69  		},
    70  		&vboxcommon.StepAttachGuestAdditions{
    71  			GuestAdditionsMode: b.config.GuestAdditionsMode,
    72  		},
    73  		new(vboxcommon.StepAttachFloppy),
    74  		&vboxcommon.StepForwardSSH{
    75  			GuestPort:   b.config.SSHPort,
    76  			HostPortMin: b.config.SSHHostPortMin,
    77  			HostPortMax: b.config.SSHHostPortMax,
    78  		},
    79  		&vboxcommon.StepVBoxManage{
    80  			Commands: b.config.VBoxManage,
    81  			Tpl:      b.config.tpl,
    82  		},
    83  		&vboxcommon.StepRun{
    84  			BootWait: b.config.BootWait,
    85  			Headless: b.config.Headless,
    86  		},
    87  		&common.StepConnectSSH{
    88  			SSHAddress:     vboxcommon.SSHAddress,
    89  			SSHConfig:      vboxcommon.SSHConfigFunc(b.config.SSHConfig),
    90  			SSHWaitTimeout: b.config.SSHWaitTimeout,
    91  		},
    92  		&vboxcommon.StepUploadVersion{
    93  			Path: b.config.VBoxVersionFile,
    94  		},
    95  		&vboxcommon.StepUploadGuestAdditions{
    96  			GuestAdditionsMode: b.config.GuestAdditionsMode,
    97  			GuestAdditionsPath: b.config.GuestAdditionsPath,
    98  			Tpl:                b.config.tpl,
    99  		},
   100  		new(common.StepProvision),
   101  		&vboxcommon.StepShutdown{
   102  			Command: b.config.ShutdownCommand,
   103  			Timeout: b.config.ShutdownTimeout,
   104  		},
   105  		new(vboxcommon.StepRemoveDevices),
   106  		&vboxcommon.StepVBoxManage{
   107  			Commands: b.config.VBoxManagePost,
   108  			Tpl:      b.config.tpl,
   109  		},
   110  		&vboxcommon.StepExport{
   111  			Format:     b.config.Format,
   112  			OutputDir:  b.config.OutputDir,
   113  			ExportOpts: b.config.ExportOpts.ExportOpts,
   114  		},
   115  	}
   116  
   117  	// Run the steps.
   118  	if b.config.PackerDebug {
   119  		b.runner = &multistep.DebugRunner{
   120  			Steps:   steps,
   121  			PauseFn: common.MultistepDebugFn(ui),
   122  		}
   123  	} else {
   124  		b.runner = &multistep.BasicRunner{Steps: steps}
   125  	}
   126  	b.runner.Run(state)
   127  
   128  	// Report any errors.
   129  	if rawErr, ok := state.GetOk("error"); ok {
   130  		return nil, rawErr.(error)
   131  	}
   132  
   133  	// If we were interrupted or cancelled, then just exit.
   134  	if _, ok := state.GetOk(multistep.StateCancelled); ok {
   135  		return nil, errors.New("Build was cancelled.")
   136  	}
   137  
   138  	if _, ok := state.GetOk(multistep.StateHalted); ok {
   139  		return nil, errors.New("Build was halted.")
   140  	}
   141  
   142  	return vboxcommon.NewArtifact(b.config.OutputDir)
   143  }
   144  
   145  // Cancel.
   146  func (b *Builder) Cancel() {
   147  	if b.runner != nil {
   148  		log.Println("Cancelling the step runner...")
   149  		b.runner.Cancel()
   150  	}
   151  }