add option to configure network adapter multiqueue support

This commit is contained in:
Roman Tomjak 2020-07-15 23:07:02 +01:00
parent 48a3a859d2
commit 7ed8709483
No known key found for this signature in database
GPG Key ID: BB29BA0B3501D719
3 changed files with 77 additions and 15 deletions

View File

@ -67,11 +67,12 @@ type Config struct {
} }
type nicConfig struct { type nicConfig struct {
Model string `mapstructure:"model"` Model string `mapstructure:"model"`
MACAddress string `mapstructure:"mac_address"` PacketQueues int `mapstructure:"packet_queues"`
Bridge string `mapstructure:"bridge"` MACAddress string `mapstructure:"mac_address"`
VLANTag string `mapstructure:"vlan_tag"` Bridge string `mapstructure:"bridge"`
Firewall bool `mapstructure:"firewall"` VLANTag string `mapstructure:"vlan_tag"`
Firewall bool `mapstructure:"firewall"`
} }
type diskConfig struct { type diskConfig struct {
Type string `mapstructure:"type"` Type string `mapstructure:"type"`
@ -233,6 +234,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
if c.NICs[idx].Bridge == "" { if c.NICs[idx].Bridge == "" {
errs = packer.MultiErrorAppend(errs, errors.New(fmt.Sprintf("network_adapters[%d].bridge must be specified", idx))) errs = packer.MultiErrorAppend(errs, errors.New(fmt.Sprintf("network_adapters[%d].bridge must be specified", idx)))
} }
if c.NICs[idx].Model != "virtio" && c.NICs[idx].PacketQueues > 0 {
errs = packer.MultiErrorAppend(errs, errors.New(fmt.Sprintf("network_adapters[%d].packet_queues can only be set for 'virtio' driver", idx)))
}
} }
for idx := range c.Disks { for idx := range c.Disks {
if c.Disks[idx].StoragePool == "" { if c.Disks[idx].StoragePool == "" {

View File

@ -247,11 +247,12 @@ func (*FlatdiskConfig) HCL2Spec() map[string]hcldec.Spec {
// FlatnicConfig is an auto-generated flat version of nicConfig. // FlatnicConfig is an auto-generated flat version of nicConfig.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatnicConfig struct { type FlatnicConfig struct {
Model *string `mapstructure:"model" cty:"model" hcl:"model"` Model *string `mapstructure:"model" cty:"model" hcl:"model"`
MACAddress *string `mapstructure:"mac_address" cty:"mac_address" hcl:"mac_address"` PacketQueues *int `mapstructure:"packet_queues" cty:"packet_queues" hcl:"packet_queues"`
Bridge *string `mapstructure:"bridge" cty:"bridge" hcl:"bridge"` MACAddress *string `mapstructure:"mac_address" cty:"mac_address" hcl:"mac_address"`
VLANTag *string `mapstructure:"vlan_tag" cty:"vlan_tag" hcl:"vlan_tag"` Bridge *string `mapstructure:"bridge" cty:"bridge" hcl:"bridge"`
Firewall *bool `mapstructure:"firewall" cty:"firewall" hcl:"firewall"` VLANTag *string `mapstructure:"vlan_tag" cty:"vlan_tag" hcl:"vlan_tag"`
Firewall *bool `mapstructure:"firewall" cty:"firewall" hcl:"firewall"`
} }
// FlatMapstructure returns a new FlatnicConfig. // FlatMapstructure returns a new FlatnicConfig.
@ -266,11 +267,12 @@ func (*nicConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spe
// The decoded values from this spec will then be applied to a FlatnicConfig. // The decoded values from this spec will then be applied to a FlatnicConfig.
func (*FlatnicConfig) HCL2Spec() map[string]hcldec.Spec { func (*FlatnicConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{ s := map[string]hcldec.Spec{
"model": &hcldec.AttrSpec{Name: "model", Type: cty.String, Required: false}, "model": &hcldec.AttrSpec{Name: "model", Type: cty.String, Required: false},
"mac_address": &hcldec.AttrSpec{Name: "mac_address", Type: cty.String, Required: false}, "packet_queues": &hcldec.AttrSpec{Name: "packet_queues", Type: cty.Number, Required: false},
"bridge": &hcldec.AttrSpec{Name: "bridge", Type: cty.String, Required: false}, "mac_address": &hcldec.AttrSpec{Name: "mac_address", Type: cty.String, Required: false},
"vlan_tag": &hcldec.AttrSpec{Name: "vlan_tag", Type: cty.String, Required: false}, "bridge": &hcldec.AttrSpec{Name: "bridge", Type: cty.String, Required: false},
"firewall": &hcldec.AttrSpec{Name: "firewall", Type: cty.Bool, Required: false}, "vlan_tag": &hcldec.AttrSpec{Name: "vlan_tag", Type: cty.String, Required: false},
"firewall": &hcldec.AttrSpec{Name: "firewall", Type: cty.Bool, Required: false},
} }
return s return s
} }

View File

@ -8,6 +8,17 @@ import (
"github.com/hashicorp/packer/template" "github.com/hashicorp/packer/template"
) )
func mandatoryConfig(t *testing.T) map[string]interface{} {
return map[string]interface{}{
"proxmox_url": "https://my-proxmox.my-domain:8006/api2/json",
"username": "apiuser@pve",
"password": "supersecret",
"iso_file": "local:iso/Fedora-Server-dvd-x86_64-29-1.2.iso",
"node": "my-proxmox",
"ssh_username": "root",
}
}
func TestRequiredParameters(t *testing.T) { func TestRequiredParameters(t *testing.T) {
var c Config var c Config
_, err := c.Prepare(make(map[string]interface{})) _, err := c.Prepare(make(map[string]interface{}))
@ -166,3 +177,48 @@ func TestAgentSetToFalse(t *testing.T) {
t.Errorf("Expected Agent to be false, got %t", b.config.Agent) t.Errorf("Expected Agent to be false, got %t", b.config.Agent)
} }
} }
func TestNetworkAdapterPacketQueueSupport(t *testing.T) {
drivertests := []struct {
expectedToFail bool
model string
}{
{expectedToFail: false, model: "virtio"},
{expectedToFail: true, model: "e1000"},
{expectedToFail: true, model: "e1000-82540em"},
{expectedToFail: true, model: "e1000-82544gc"},
{expectedToFail: true, model: "e1000-82545em"},
{expectedToFail: true, model: "i82551"},
{expectedToFail: true, model: "i82557b"},
{expectedToFail: true, model: "i82559er"},
{expectedToFail: true, model: "ne2k_isa"},
{expectedToFail: true, model: "ne2k_pci"},
{expectedToFail: true, model: "pcnet"},
{expectedToFail: true, model: "rtl8139"},
{expectedToFail: true, model: "vmxnet3"},
}
for _, tt := range drivertests {
device := make(map[string]interface{})
device["bridge"] = "vmbr0"
device["model"] = tt.model
device["packet_queues"] = 2
devices := make([]map[string]interface{}, 0)
devices = append(devices, device)
cfg := mandatoryConfig(t)
cfg["network_adapters"] = devices
var c Config
_, err := c.Prepare(cfg)
if tt.expectedToFail == true && err == nil {
t.Error("expected config preparation to fail, but no error occured")
}
if tt.expectedToFail == false && err != nil {
t.Errorf("expected config preparation to succeed, but %s", err.Error())
}
}
}