@@ -79,10 +79,11 @@ type CommonConfig struct {
79
79
// try and determine the switch to use by looking for an external switch
80
80
// that is up and running.
81
81
SwitchName string `mapstructure:"switch_name" required:"false"`
82
- // The name of the switches to connect the virtual
82
+ // The type of the main switch to connect the virtual
83
83
// machine to. By default, leaving this value unset will cause Packer to
84
- // not use any additional switches.
85
- SwitchesNames []string `mapstructure:"switches_names" required:"false"`
84
+ // try and determine the switch to use by looking for an external switch
85
+ // that is up and running.
86
+ SwitchType string `mapstructure:"switch_type" required:"false"`
86
87
// This is the VLAN of the virtual switch's
87
88
// network card. By default, none is set. If none is set then a VLAN is not
88
89
// set on the switch's network card. If this value is set it should match
@@ -92,14 +93,16 @@ type CommonConfig struct {
92
93
// the default main virtual network card. The MAC address must be a string with
93
94
// no delimiters, for example "0000deadbeef".
94
95
MacAddress string `mapstructure:"mac_address" required:"false"`
95
- // This allows a specific MAC addresses to be used on
96
- // the optional virtual network cards set in `switches_names` array. The MAC addresses must be strings with
97
- // no delimiters, for example "0000deadbeef".
98
- MacAddresses []string `mapstructure:"mac_addresses" required:"false"`
99
96
// This is the VLAN of the virtual machine's network
100
97
// card for the new virtual machine. By default none is set. If none is set
101
98
// then VLANs are not set on the virtual machine's network card.
102
99
VlanId string `mapstructure:"vlan_id" required:"false"`
100
+ // This allows for multiple switches to be configured.
101
+ // This should be used exclusively with SwitchName, SwitchVlanId, and MacAddress.
102
+ SwitchConfigs []SwitchConfig `mapstructure:"switch_config" required:"false"`
103
+ // This allows for multiple switches to be configured.
104
+ // This should be used exclusively with MacAddress and VlanId.
105
+ AdapterConfigs []AdapterConfig `mapstructure:"adapter_config" required:"false"`
103
106
// The number of CPUs the virtual machine should use. If
104
107
// this isn't specified, the default is 1 CPU.
105
108
Cpu uint `mapstructure:"cpus" required:"false"`
@@ -205,9 +208,110 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
205
208
log .Printf ("%s: %v" , "VMName" , c .VMName )
206
209
}
207
210
208
- if c .SwitchName == "" {
209
- c .SwitchName = c .detectSwitchName (pc .PackerBuildName )
210
- log .Printf ("Using switch %s" , c .SwitchName )
211
+ // Validation of switch config and switch parameters
212
+ // The end result of this section is the unification of all Switch Parameters into SwitchConfigs.
213
+ if (c .SwitchName != "" || c .SwitchType != "" || c .SwitchVlanId != "" || c .MacAddress != "" || c .VlanId != "" ) &&
214
+ (len (c .AdapterConfigs ) > 0 || len (c .SwitchConfigs ) > 0 ) {
215
+ err := fmt .Errorf ("SwitchName/SwitchType/SwitchVlanId/MacAddress/VlanId and SwitchConfig/AdapterConfig not allowed." )
216
+ errs = append (errs , err )
217
+ } else {
218
+ if c .SwitchName != "" || c .SwitchType != "" || c .SwitchVlanId != "" || c .MacAddress != "" || c .VlanId != "" {
219
+ if c .SwitchType != "" {
220
+ warns = append (warns , "SwitchType is deprecated and should be converted to SwitchConfigs" )
221
+ }
222
+ if c .SwitchName != "" {
223
+ warns = append (warns , "SwitchName is deprecated and should be converted to SwitchConfigs" )
224
+ } else {
225
+ c .SwitchName = c .detectSwitchName (pc .PackerBuildName )
226
+ if c .SwitchType == "" {
227
+ c .SwitchType = SwitchTypeExternal
228
+ }
229
+ log .Printf ("Using switch %s" , c .SwitchName )
230
+ }
231
+ if c .SwitchVlanId != "" {
232
+ warns = append (warns , "SwitchVlanId is deprecated and should be converted to SwitchConfigs" )
233
+ }
234
+ if c .MacAddress != "" {
235
+ warns = append (warns , "MacAddress is deprecated and should be converted to SwitchConfigs" )
236
+ }
237
+ if c .VlanId != "" {
238
+ warns = append (warns , "VlanId is deprecated and should be converted to SwitchConfigs" )
239
+ }
240
+ if c .SwitchVlanId != "" {
241
+ if c .SwitchVlanId != c .VlanId {
242
+ warning := fmt .Sprintf ("Switch network adaptor vlan should match virtual machine network adaptor " +
243
+ "vlan. The switch will not be able to see traffic from the VM." )
244
+ warns = Appendwarns (warns , warning )
245
+ }
246
+ }
247
+
248
+ c .SwitchConfigs = []SwitchConfig {{
249
+ SwitchName : c .SwitchName ,
250
+ SwitchType : c .SwitchType ,
251
+ SwitchVlanId : c .SwitchVlanId ,
252
+ }}
253
+ c .AdapterConfigs = []AdapterConfig {{
254
+ Name : c .VMName ,
255
+ VlanId : c .VlanId ,
256
+ MacAddress : c .MacAddress ,
257
+ SwitchName : c .SwitchName ,
258
+ }}
259
+
260
+ // Make sure we don't get confused....
261
+ c .VlanId = ""
262
+ c .MacAddress = ""
263
+ c .SwitchName = ""
264
+ c .SwitchType = ""
265
+ c .SwitchVlanId = ""
266
+ } else {
267
+ // If switchConfigs and adapterConfigs are not 0, assume the user knows what they are doing somewhat.
268
+ // Make sure the structs are valid, but don't create things for them.
269
+ if len (c .SwitchConfigs ) == 0 {
270
+ swname := c .detectSwitchName (pc .PackerBuildName )
271
+ log .Printf ("Using switch %s" , swname )
272
+ c .SwitchConfigs = []SwitchConfig {{SwitchName : swname }}
273
+ }
274
+ for ii , sw := range c .SwitchConfigs {
275
+ if sw .SwitchName == "" {
276
+ err := fmt .Errorf ("SwitchName for Switch(%d) requires a name" , ii )
277
+ errs = append (errs , err )
278
+ }
279
+ }
280
+ if c .SwitchConfigs [0 ].SwitchType == "" {
281
+ c .SwitchConfigs [0 ].SwitchType = SwitchTypeExternal
282
+ }
283
+ if len (c .AdapterConfigs ) == 0 {
284
+ c .AdapterConfigs = []AdapterConfig {}
285
+ for ii , sw := range c .SwitchConfigs {
286
+ name := c .VMName
287
+ if ii != 0 {
288
+ name = fmt .Sprintf ("%s-%d" , c .VMName , ii )
289
+ }
290
+ c .AdapterConfigs = append (c .AdapterConfigs , AdapterConfig {Name : name , SwitchName : sw .SwitchName })
291
+ }
292
+ } else {
293
+ for ii , adp := range c .AdapterConfigs {
294
+ found := false
295
+ for _ , sw := range c .SwitchConfigs {
296
+ if sw .SwitchName == adp .SwitchName {
297
+ found = true
298
+ break
299
+ }
300
+ }
301
+ if ! found {
302
+ err := fmt .Errorf ("Network Adapter %d (%s) requires a switch that is not defined: %s" , ii , adp .Name , adp .SwitchName )
303
+ errs = append (errs , err )
304
+ }
305
+ if adp .Name == "" {
306
+ name := c .VMName
307
+ if ii != 0 {
308
+ name = fmt .Sprintf ("%s-%d" , c .VMName , ii )
309
+ }
310
+ adp .Name = name
311
+ }
312
+ }
313
+ }
314
+ }
211
315
}
212
316
213
317
if c .Generation < 1 || c .Generation > 2 {
@@ -341,14 +445,6 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
341
445
}
342
446
}
343
447
344
- if c .SwitchVlanId != "" {
345
- if c .SwitchVlanId != c .VlanId {
346
- warning := fmt .Sprintf ("Switch network adaptor vlan should match virtual machine network adaptor " +
347
- "vlan. The switch will not be able to see traffic from the VM." )
348
- warns = Appendwarns (warns , warning )
349
- }
350
- }
351
-
352
448
err := c .checkDiskBlockSize ()
353
449
if err != nil {
354
450
errs = append (errs , err )
@@ -396,7 +492,7 @@ func (c *CommonConfig) checkHostAvailableMemory() string {
396
492
freeMB := powershell .GetHostAvailableMemory ()
397
493
398
494
if (freeMB - float64 (c .RamSize )) < LowRam {
399
- return "Hyper-V might fail to create a VM if there is not enough free memory in the system."
495
+ return fmt . Sprintf ( "Hyper-V might fail to create a VM if there is not enough free memory in the system. (%v, %v, %v)" , freeMB , float64 ( c . RamSize ), LowRam )
400
496
}
401
497
}
402
498
0 commit comments