github.phpd.cn/hashicorp/packer@v1.3.2/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/common/bootcommand" 10 "github.com/hashicorp/packer/helper/config" 11 "github.com/hashicorp/packer/packer" 12 "github.com/hashicorp/packer/template/interpolate" 13 ) 14 15 // Config is the configuration structure for the builder. 16 type Config struct { 17 common.PackerConfig `mapstructure:",squash"` 18 common.HTTPConfig `mapstructure:",squash"` 19 common.FloppyConfig `mapstructure:",squash"` 20 bootcommand.BootConfig `mapstructure:",squash"` 21 vboxcommon.ExportConfig `mapstructure:",squash"` 22 vboxcommon.ExportOpts `mapstructure:",squash"` 23 vboxcommon.OutputConfig `mapstructure:",squash"` 24 vboxcommon.RunConfig `mapstructure:",squash"` 25 vboxcommon.SSHConfig `mapstructure:",squash"` 26 vboxcommon.ShutdownConfig `mapstructure:",squash"` 27 vboxcommon.VBoxManageConfig `mapstructure:",squash"` 28 vboxcommon.VBoxManagePostConfig `mapstructure:",squash"` 29 vboxcommon.VBoxVersionConfig `mapstructure:",squash"` 30 31 Checksum string `mapstructure:"checksum"` 32 ChecksumType string `mapstructure:"checksum_type"` 33 GuestAdditionsMode string `mapstructure:"guest_additions_mode"` 34 GuestAdditionsPath string `mapstructure:"guest_additions_path"` 35 GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` 36 GuestAdditionsURL string `mapstructure:"guest_additions_url"` 37 ImportFlags []string `mapstructure:"import_flags"` 38 ImportOpts string `mapstructure:"import_opts"` 39 SourcePath string `mapstructure:"source_path"` 40 TargetPath string `mapstructure:"target_path"` 41 VMName string `mapstructure:"vm_name"` 42 KeepRegistered bool `mapstructure:"keep_registered"` 43 SkipExport bool `mapstructure:"skip_export"` 44 45 ctx interpolate.Context 46 } 47 48 func NewConfig(raws ...interface{}) (*Config, []string, error) { 49 c := new(Config) 50 err := config.Decode(c, &config.DecodeOpts{ 51 Interpolate: true, 52 InterpolateContext: &c.ctx, 53 InterpolateFilter: &interpolate.RenderFilter{ 54 Exclude: []string{ 55 "boot_command", 56 "guest_additions_path", 57 "guest_additions_url", 58 "vboxmanage", 59 "vboxmanage_post", 60 }, 61 }, 62 }, raws...) 63 if err != nil { 64 return nil, nil, err 65 } 66 67 // Defaults 68 if c.GuestAdditionsMode == "" { 69 c.GuestAdditionsMode = "upload" 70 } 71 72 if c.GuestAdditionsPath == "" { 73 c.GuestAdditionsPath = "VBoxGuestAdditions.iso" 74 } 75 76 if c.VMName == "" { 77 c.VMName = fmt.Sprintf( 78 "packer-%s-%d", c.PackerBuildName, interpolate.InitTime.Unix()) 79 } 80 81 // Prepare the errors 82 var errs *packer.MultiError 83 errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) 84 errs = packer.MultiErrorAppend(errs, c.ExportOpts.Prepare(&c.ctx)...) 85 errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...) 86 errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) 87 errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...) 88 errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) 89 errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) 90 errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...) 91 errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(&c.ctx)...) 92 errs = packer.MultiErrorAppend(errs, c.VBoxManagePostConfig.Prepare(&c.ctx)...) 93 errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(&c.ctx)...) 94 errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...) 95 96 c.ChecksumType = strings.ToLower(c.ChecksumType) 97 c.Checksum = strings.ToLower(c.Checksum) 98 99 if c.SourcePath == "" { 100 errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is required")) 101 } else { 102 c.SourcePath, err = common.ValidatedURL(c.SourcePath) 103 if err != nil { 104 errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) 105 } 106 fileOK := common.FileExistsLocally(c.SourcePath) 107 if !fileOK { 108 packer.MultiErrorAppend(errs, 109 fmt.Errorf("Source file '%s' needs to exist at time of config validation!", c.SourcePath)) 110 } 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 // TODO: Write a packer fix and just remove import_opts 151 if c.ImportOpts != "" { 152 c.ImportFlags = append(c.ImportFlags, "--options", c.ImportOpts) 153 } 154 155 return c, warnings, nil 156 }