github.com/rothwerx/packer@v0.9.0/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/helper/communicator"
    12  	"github.com/mitchellh/packer/packer"
    13  )
    14  
    15  // Builder implements packer.Builder and builds the actual VirtualBox
    16  // images.
    17  type Builder struct {
    18  	config *Config
    19  	runner multistep.Runner
    20  }
    21  
    22  // Prepare processes the build configuration parameters.
    23  func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
    24  	c, warnings, errs := NewConfig(raws...)
    25  	if errs != nil {
    26  		return warnings, errs
    27  	}
    28  	b.config = c
    29  
    30  	return warnings, nil
    31  }
    32  
    33  // Run executes a Packer build and returns a packer.Artifact representing
    34  // a VirtualBox appliance.
    35  func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
    36  	// Create the driver that we'll use to communicate with VirtualBox
    37  	driver, err := vboxcommon.NewDriver()
    38  	if err != nil {
    39  		return nil, fmt.Errorf("Failed creating VirtualBox driver: %s", err)
    40  	}
    41  
    42  	// Set up the state.
    43  	state := new(multistep.BasicStateBag)
    44  	state.Put("config", b.config)
    45  	state.Put("driver", driver)
    46  	state.Put("cache", cache)
    47  	state.Put("hook", hook)
    48  	state.Put("ui", ui)
    49  
    50  	// Build the steps.
    51  	steps := []multistep.Step{
    52  		&vboxcommon.StepOutputDir{
    53  			Force: b.config.PackerForce,
    54  			Path:  b.config.OutputDir,
    55  		},
    56  		new(vboxcommon.StepSuppressMessages),
    57  		&common.StepCreateFloppy{
    58  			Files: b.config.FloppyFiles,
    59  		},
    60  		&common.StepHTTPServer{
    61  			HTTPDir:     b.config.HTTPDir,
    62  			HTTPPortMin: b.config.HTTPPortMin,
    63  			HTTPPortMax: b.config.HTTPPortMax,
    64  		},
    65  		&vboxcommon.StepDownloadGuestAdditions{
    66  			GuestAdditionsMode:   b.config.GuestAdditionsMode,
    67  			GuestAdditionsURL:    b.config.GuestAdditionsURL,
    68  			GuestAdditionsSHA256: b.config.GuestAdditionsSHA256,
    69  			Ctx:                  b.config.ctx,
    70  		},
    71  		&StepImport{
    72  			Name:        b.config.VMName,
    73  			SourcePath:  b.config.SourcePath,
    74  			ImportFlags: b.config.ImportFlags,
    75  		},
    76  		&vboxcommon.StepAttachGuestAdditions{
    77  			GuestAdditionsMode: b.config.GuestAdditionsMode,
    78  		},
    79  		&vboxcommon.StepConfigureVRDP{
    80  			VRDPPortMin: b.config.VRDPPortMin,
    81  			VRDPPortMax: b.config.VRDPPortMax,
    82  		},
    83  		new(vboxcommon.StepAttachFloppy),
    84  		&vboxcommon.StepForwardSSH{
    85  			CommConfig:     &b.config.SSHConfig.Comm,
    86  			HostPortMin:    b.config.SSHHostPortMin,
    87  			HostPortMax:    b.config.SSHHostPortMax,
    88  			SkipNatMapping: b.config.SSHSkipNatMapping,
    89  		},
    90  		&vboxcommon.StepVBoxManage{
    91  			Commands: b.config.VBoxManage,
    92  			Ctx:      b.config.ctx,
    93  		},
    94  		&vboxcommon.StepRun{
    95  			BootWait: b.config.BootWait,
    96  			Headless: b.config.Headless,
    97  		},
    98  		&vboxcommon.StepTypeBootCommand{
    99  			BootCommand: b.config.BootCommand,
   100  			VMName:      b.config.VMName,
   101  			Ctx:         b.config.ctx,
   102  		},
   103  		&communicator.StepConnect{
   104  			Config:    &b.config.SSHConfig.Comm,
   105  			Host:      vboxcommon.CommHost,
   106  			SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig),
   107  			SSHPort:   vboxcommon.SSHPort,
   108  		},
   109  		&vboxcommon.StepUploadVersion{
   110  			Path: b.config.VBoxVersionFile,
   111  		},
   112  		&vboxcommon.StepUploadGuestAdditions{
   113  			GuestAdditionsMode: b.config.GuestAdditionsMode,
   114  			GuestAdditionsPath: b.config.GuestAdditionsPath,
   115  			Ctx:                b.config.ctx,
   116  		},
   117  		new(common.StepProvision),
   118  		&vboxcommon.StepShutdown{
   119  			Command: b.config.ShutdownCommand,
   120  			Timeout: b.config.ShutdownTimeout,
   121  		},
   122  		new(vboxcommon.StepRemoveDevices),
   123  		&vboxcommon.StepVBoxManage{
   124  			Commands: b.config.VBoxManagePost,
   125  			Ctx:      b.config.ctx,
   126  		},
   127  		&vboxcommon.StepExport{
   128  			Format:         b.config.Format,
   129  			OutputDir:      b.config.OutputDir,
   130  			ExportOpts:     b.config.ExportOpts.ExportOpts,
   131  			SkipNatMapping: b.config.SSHSkipNatMapping,
   132  		},
   133  	}
   134  
   135  	// Run the steps.
   136  	if b.config.PackerDebug {
   137  		b.runner = &multistep.DebugRunner{
   138  			Steps:   steps,
   139  			PauseFn: common.MultistepDebugFn(ui),
   140  		}
   141  	} else {
   142  		b.runner = &multistep.BasicRunner{Steps: steps}
   143  	}
   144  	b.runner.Run(state)
   145  
   146  	// Report any errors.
   147  	if rawErr, ok := state.GetOk("error"); ok {
   148  		return nil, rawErr.(error)
   149  	}
   150  
   151  	// If we were interrupted or cancelled, then just exit.
   152  	if _, ok := state.GetOk(multistep.StateCancelled); ok {
   153  		return nil, errors.New("Build was cancelled.")
   154  	}
   155  
   156  	if _, ok := state.GetOk(multistep.StateHalted); ok {
   157  		return nil, errors.New("Build was halted.")
   158  	}
   159  
   160  	return vboxcommon.NewArtifact(b.config.OutputDir)
   161  }
   162  
   163  // Cancel.
   164  func (b *Builder) Cancel() {
   165  	if b.runner != nil {
   166  		log.Println("Cancelling the step runner...")
   167  		b.runner.Cancel()
   168  	}
   169  }