github.com/tonnydourado/packer@v0.6.1-0.20140701134019-5d0cd9676a37/builder/virtualbox/ovf/config.go (about)

     1  package ovf
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
     9  	"github.com/mitchellh/packer/common"
    10  	"github.com/mitchellh/packer/packer"
    11  )
    12  
    13  // Config is the configuration structure for the builder.
    14  type Config struct {
    15  	common.PackerConfig             `mapstructure:",squash"`
    16  	vboxcommon.ExportConfig         `mapstructure:",squash"`
    17  	vboxcommon.ExportOpts           `mapstructure:",squash"`
    18  	vboxcommon.FloppyConfig         `mapstructure:",squash"`
    19  	vboxcommon.OutputConfig         `mapstructure:",squash"`
    20  	vboxcommon.RunConfig            `mapstructure:",squash"`
    21  	vboxcommon.SSHConfig            `mapstructure:",squash"`
    22  	vboxcommon.ShutdownConfig       `mapstructure:",squash"`
    23  	vboxcommon.VBoxManageConfig     `mapstructure:",squash"`
    24  	vboxcommon.VBoxManagePostConfig `mapstructure:",squash"`
    25  	vboxcommon.VBoxVersionConfig    `mapstructure:",squash"`
    26  
    27  	SourcePath           string `mapstructure:"source_path"`
    28  	GuestAdditionsMode   string `mapstructure:"guest_additions_mode"`
    29  	GuestAdditionsPath   string `mapstructure:"guest_additions_path"`
    30  	GuestAdditionsURL    string `mapstructure:"guest_additions_url"`
    31  	GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"`
    32  	VMName               string `mapstructure:"vm_name"`
    33  	ImportOpts           string `mapstructure:"import_opts"`
    34  
    35  	tpl *packer.ConfigTemplate
    36  }
    37  
    38  func NewConfig(raws ...interface{}) (*Config, []string, error) {
    39  	c := new(Config)
    40  	md, err := common.DecodeConfig(c, raws...)
    41  	if err != nil {
    42  		return nil, nil, err
    43  	}
    44  
    45  	c.tpl, err = packer.NewConfigTemplate()
    46  	if err != nil {
    47  		return nil, nil, err
    48  	}
    49  	c.tpl.UserVars = c.PackerUserVars
    50  
    51  	// Defaults
    52  	if c.GuestAdditionsMode == "" {
    53  		c.GuestAdditionsMode = "upload"
    54  	}
    55  
    56  	if c.GuestAdditionsPath == "" {
    57  		c.GuestAdditionsPath = "VBoxGuestAdditions.iso"
    58  	}
    59  	if c.VMName == "" {
    60  		c.VMName = fmt.Sprintf("packer-%s-{{timestamp}}", c.PackerBuildName)
    61  	}
    62  
    63  	// Prepare the errors
    64  	errs := common.CheckUnusedConfig(md)
    65  	errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(c.tpl)...)
    66  	errs = packer.MultiErrorAppend(errs, c.ExportOpts.Prepare(c.tpl)...)
    67  	errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(c.tpl)...)
    68  	errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...)
    69  	errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(c.tpl)...)
    70  	errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(c.tpl)...)
    71  	errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
    72  	errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(c.tpl)...)
    73  	errs = packer.MultiErrorAppend(errs, c.VBoxManagePostConfig.Prepare(c.tpl)...)
    74  	errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(c.tpl)...)
    75  
    76  	templates := map[string]*string{
    77  		"guest_additions_mode":   &c.GuestAdditionsMode,
    78  		"guest_additions_sha256": &c.GuestAdditionsSHA256,
    79  		"source_path":            &c.SourcePath,
    80  		"vm_name":                &c.VMName,
    81  		"import_opts":            &c.ImportOpts,
    82  	}
    83  
    84  	for n, ptr := range templates {
    85  		var err error
    86  		*ptr, err = c.tpl.Process(*ptr, nil)
    87  		if err != nil {
    88  			errs = packer.MultiErrorAppend(
    89  				errs, fmt.Errorf("Error processing %s: %s", n, err))
    90  		}
    91  	}
    92  
    93  	if c.SourcePath == "" {
    94  		errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is required"))
    95  	} else {
    96  		if _, err := os.Stat(c.SourcePath); err != nil {
    97  			errs = packer.MultiErrorAppend(errs,
    98  				fmt.Errorf("source_path is invalid: %s", err))
    99  		}
   100  	}
   101  
   102  	validates := map[string]*string{
   103  		"guest_additions_path": &c.GuestAdditionsPath,
   104  		"guest_additions_url":  &c.GuestAdditionsURL,
   105  	}
   106  
   107  	for n, ptr := range validates {
   108  		if err := c.tpl.Validate(*ptr); err != nil {
   109  			errs = packer.MultiErrorAppend(
   110  				errs, fmt.Errorf("Error parsing %s: %s", n, err))
   111  		}
   112  	}
   113  
   114  	validMode := false
   115  	validModes := []string{
   116  		vboxcommon.GuestAdditionsModeDisable,
   117  		vboxcommon.GuestAdditionsModeAttach,
   118  		vboxcommon.GuestAdditionsModeUpload,
   119  	}
   120  
   121  	for _, mode := range validModes {
   122  		if c.GuestAdditionsMode == mode {
   123  			validMode = true
   124  			break
   125  		}
   126  	}
   127  
   128  	if !validMode {
   129  		errs = packer.MultiErrorAppend(errs,
   130  			fmt.Errorf("guest_additions_mode is invalid. Must be one of: %v", validModes))
   131  	}
   132  
   133  	if c.GuestAdditionsSHA256 != "" {
   134  		c.GuestAdditionsSHA256 = strings.ToLower(c.GuestAdditionsSHA256)
   135  	}
   136  
   137  	// Warnings
   138  	var warnings []string
   139  	if c.ShutdownCommand == "" {
   140  		warnings = append(warnings,
   141  			"A shutdown_command was not specified. Without a shutdown command, Packer\n"+
   142  				"will forcibly halt the virtual machine, which may result in data loss.")
   143  	}
   144  
   145  	// Check for any errors.
   146  	if errs != nil && len(errs.Errors) > 0 {
   147  		return nil, warnings, errs
   148  	}
   149  
   150  	return c, warnings, nil
   151  }