github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/virtualbox/ovf/config.go (about) 1 package ovf 2 3 import ( 4 "fmt" 5 "strings" 6 7 vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" 8 "github.com/hashicorp/packer/common" 9 "github.com/hashicorp/packer/helper/config" 10 "github.com/hashicorp/packer/packer" 11 "github.com/hashicorp/packer/template/interpolate" 12 ) 13 14 // Config is the configuration structure for the builder. 15 type Config struct { 16 common.PackerConfig `mapstructure:",squash"` 17 common.HTTPConfig `mapstructure:",squash"` 18 common.FloppyConfig `mapstructure:",squash"` 19 vboxcommon.ExportConfig `mapstructure:",squash"` 20 vboxcommon.ExportOpts `mapstructure:",squash"` 21 vboxcommon.OutputConfig `mapstructure:",squash"` 22 vboxcommon.RunConfig `mapstructure:",squash"` 23 vboxcommon.SSHConfig `mapstructure:",squash"` 24 vboxcommon.ShutdownConfig `mapstructure:",squash"` 25 vboxcommon.VBoxManageConfig `mapstructure:",squash"` 26 vboxcommon.VBoxManagePostConfig `mapstructure:",squash"` 27 vboxcommon.VBoxVersionConfig `mapstructure:",squash"` 28 29 BootCommand []string `mapstructure:"boot_command"` 30 Checksum string `mapstructure:"checksum"` 31 ChecksumType string `mapstructure:"checksum_type"` 32 GuestAdditionsMode string `mapstructure:"guest_additions_mode"` 33 GuestAdditionsPath string `mapstructure:"guest_additions_path"` 34 GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` 35 GuestAdditionsURL string `mapstructure:"guest_additions_url"` 36 ImportFlags []string `mapstructure:"import_flags"` 37 ImportOpts string `mapstructure:"import_opts"` 38 SourcePath string `mapstructure:"source_path"` 39 TargetPath string `mapstructure:"target_path"` 40 VMName string `mapstructure:"vm_name"` 41 SkipExport bool `mapstructure:"skip_export"` 42 43 ctx interpolate.Context 44 } 45 46 func NewConfig(raws ...interface{}) (*Config, []string, error) { 47 c := new(Config) 48 err := config.Decode(c, &config.DecodeOpts{ 49 Interpolate: true, 50 InterpolateContext: &c.ctx, 51 InterpolateFilter: &interpolate.RenderFilter{ 52 Exclude: []string{ 53 "boot_command", 54 "guest_additions_path", 55 "guest_additions_url", 56 "vboxmanage", 57 "vboxmanage_post", 58 }, 59 }, 60 }, raws...) 61 if err != nil { 62 return nil, nil, err 63 } 64 65 // Defaults 66 if c.GuestAdditionsMode == "" { 67 c.GuestAdditionsMode = "upload" 68 } 69 70 if c.GuestAdditionsPath == "" { 71 c.GuestAdditionsPath = "VBoxGuestAdditions.iso" 72 } 73 74 if c.VMName == "" { 75 c.VMName = fmt.Sprintf( 76 "packer-%s-%d", c.PackerBuildName, interpolate.InitTime.Unix()) 77 } 78 79 // Prepare the errors 80 var errs *packer.MultiError 81 errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) 82 errs = packer.MultiErrorAppend(errs, c.ExportOpts.Prepare(&c.ctx)...) 83 errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...) 84 errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) 85 errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...) 86 errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) 87 errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) 88 errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...) 89 errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(&c.ctx)...) 90 errs = packer.MultiErrorAppend(errs, c.VBoxManagePostConfig.Prepare(&c.ctx)...) 91 errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(&c.ctx)...) 92 93 c.ChecksumType = strings.ToLower(c.ChecksumType) 94 c.Checksum = strings.ToLower(c.Checksum) 95 96 if c.SourcePath == "" { 97 errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is required")) 98 } else { 99 c.SourcePath, err = common.DownloadableURL(c.SourcePath) 100 if err != nil { 101 errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) 102 } 103 } 104 105 validMode := false 106 validModes := []string{ 107 vboxcommon.GuestAdditionsModeDisable, 108 vboxcommon.GuestAdditionsModeAttach, 109 vboxcommon.GuestAdditionsModeUpload, 110 } 111 112 for _, mode := range validModes { 113 if c.GuestAdditionsMode == mode { 114 validMode = true 115 break 116 } 117 } 118 119 if !validMode { 120 errs = packer.MultiErrorAppend(errs, 121 fmt.Errorf("guest_additions_mode is invalid. Must be one of: %v", validModes)) 122 } 123 124 if c.GuestAdditionsSHA256 != "" { 125 c.GuestAdditionsSHA256 = strings.ToLower(c.GuestAdditionsSHA256) 126 } 127 128 // Warnings 129 var warnings []string 130 if c.ShutdownCommand == "" { 131 warnings = append(warnings, 132 "A shutdown_command was not specified. Without a shutdown command, Packer\n"+ 133 "will forcibly halt the virtual machine, which may result in data loss.") 134 } 135 136 // Check for any errors. 137 if errs != nil && len(errs.Errors) > 0 { 138 return nil, warnings, errs 139 } 140 141 // TODO: Write a packer fix and just remove import_opts 142 if c.ImportOpts != "" { 143 c.ImportFlags = append(c.ImportFlags, "--options", c.ImportOpts) 144 } 145 146 return c, warnings, nil 147 }