260 lines
7.3 KiB
Go
260 lines
7.3 KiB
Go
package proxmox
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/packer/packer"
|
|
"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) {
|
|
var c Config
|
|
_, err := c.Prepare(make(map[string]interface{}))
|
|
if err == nil {
|
|
t.Fatal("Expected empty configuration to fail")
|
|
}
|
|
errs, ok := err.(*packer.MultiError)
|
|
if !ok {
|
|
t.Fatal("Expected errors to be packer.MultiError")
|
|
}
|
|
|
|
required := []string{"username", "password", "proxmox_url", "iso_file", "node", "ssh_username"}
|
|
for _, param := range required {
|
|
found := false
|
|
for _, err := range errs.Errors {
|
|
if strings.Contains(err.Error(), param) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Errorf("Expected error about missing parameter %q", required)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBasicExampleFromDocsIsValid(t *testing.T) {
|
|
const config = `{
|
|
"builders": [
|
|
{
|
|
"type": "proxmox",
|
|
"proxmox_url": "https://my-proxmox.my-domain:8006/api2/json",
|
|
"insecure_skip_tls_verify": true,
|
|
"username": "apiuser@pve",
|
|
"password": "supersecret",
|
|
|
|
"node": "my-proxmox",
|
|
"network_adapters": [
|
|
{
|
|
"bridge": "vmbr0"
|
|
}
|
|
],
|
|
"disks": [
|
|
{
|
|
"type": "scsi",
|
|
"disk_size": "5G",
|
|
"storage_pool": "local-lvm",
|
|
"storage_pool_type": "lvm"
|
|
}
|
|
],
|
|
|
|
"iso_file": "local:iso/Fedora-Server-dvd-x86_64-29-1.2.iso",
|
|
"http_directory":"config",
|
|
"boot_wait": "10s",
|
|
"boot_command": [
|
|
"<up><tab> ip=dhcp inst.cmdline inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg<enter>"
|
|
],
|
|
|
|
"ssh_username": "root",
|
|
"ssh_timeout": "15m",
|
|
"ssh_password": "packer",
|
|
|
|
"unmount_iso": true,
|
|
"template_name": "fedora-29",
|
|
"template_description": "Fedora 29-1.2, generated on {{ isotime \"2006-01-02T15:04:05Z\" }}"
|
|
}
|
|
]
|
|
}`
|
|
tpl, err := template.Parse(strings.NewReader(config))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
b := &Builder{}
|
|
_, warn, err := b.Prepare(tpl.Builders["proxmox"].Config)
|
|
if err != nil {
|
|
t.Fatal(err, warn)
|
|
}
|
|
|
|
// The example config does not set a number of optional fields. Validate that:
|
|
// Memory 0 is too small, using default: 512
|
|
// Number of cores 0 is too small, using default: 1
|
|
// Number of sockets 0 is too small, using default: 1
|
|
// CPU type not set, using default 'kvm64'
|
|
// OS not set, using default 'other'
|
|
// NIC 0 model not set, using default 'e1000'
|
|
// Disk 0 cache mode not set, using default 'none'
|
|
// Agent not set, default is true
|
|
// SCSI controller not set, using default 'lsi'
|
|
// Firewall toggle not set, using default: 0
|
|
// Disable KVM not set, using default: 0
|
|
|
|
if b.config.Memory != 512 {
|
|
t.Errorf("Expected Memory to be 512, got %d", b.config.Memory)
|
|
}
|
|
if b.config.Cores != 1 {
|
|
t.Errorf("Expected Cores to be 1, got %d", b.config.Cores)
|
|
}
|
|
if b.config.Sockets != 1 {
|
|
t.Errorf("Expected Sockets to be 1, got %d", b.config.Sockets)
|
|
}
|
|
if b.config.CPUType != "kvm64" {
|
|
t.Errorf("Expected CPU type to be 'kvm64', got %s", b.config.CPUType)
|
|
}
|
|
if b.config.OS != "other" {
|
|
t.Errorf("Expected OS to be 'other', got %s", b.config.OS)
|
|
}
|
|
if b.config.NICs[0].Model != "e1000" {
|
|
t.Errorf("Expected NIC model to be 'e1000', got %s", b.config.NICs[0].Model)
|
|
}
|
|
if b.config.NICs[0].Firewall != false {
|
|
t.Errorf("Expected NIC firewall to be false, got %t", b.config.NICs[0].Firewall)
|
|
}
|
|
if b.config.Disks[0].CacheMode != "none" {
|
|
t.Errorf("Expected disk cache mode to be 'none', got %s", b.config.Disks[0].CacheMode)
|
|
}
|
|
if b.config.Agent != true {
|
|
t.Errorf("Expected Agent to be true, got %t", b.config.Agent)
|
|
}
|
|
if b.config.DisableKVM != false {
|
|
t.Errorf("Expected Disable KVM toggle to be false, got %t", b.config.DisableKVM)
|
|
}
|
|
if b.config.SCSIController != "lsi" {
|
|
t.Errorf("Expected SCSI controller to be 'lsi', got %s", b.config.SCSIController)
|
|
}
|
|
if b.config.CloudInit != false {
|
|
t.Errorf("Expected CloudInit to be false, got %t", b.config.CloudInit)
|
|
}
|
|
}
|
|
|
|
func TestAgentSetToFalse(t *testing.T) {
|
|
cfg := mandatoryConfig(t)
|
|
cfg["qemu_agent"] = false
|
|
|
|
var c Config
|
|
warn, err := c.Prepare(cfg)
|
|
if err != nil {
|
|
t.Fatal(err, warn)
|
|
}
|
|
|
|
if c.Agent != false {
|
|
t.Errorf("Expected Agent to be false, got %t", c.Agent)
|
|
}
|
|
}
|
|
|
|
func TestPacketQueueSupportForNetworkAdapters(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())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHardDiskControllerIOThreadSupport(t *testing.T) {
|
|
drivertests := []struct {
|
|
expectedToFail bool
|
|
controller string
|
|
disk_type string
|
|
}{
|
|
// io thread is only supported by virtio-scsi-single controller
|
|
// and only for virtio and scsi disks
|
|
{expectedToFail: false, controller: "virtio-scsi-single", disk_type: "scsi"},
|
|
{expectedToFail: false, controller: "virtio-scsi-single", disk_type: "virtio"},
|
|
{expectedToFail: true, controller: "virtio-scsi-single", disk_type: "sata"},
|
|
{expectedToFail: true, controller: "lsi", disk_type: "scsi"},
|
|
{expectedToFail: true, controller: "lsi53c810", disk_type: "virtio"},
|
|
}
|
|
|
|
for _, tt := range drivertests {
|
|
nic := make(map[string]interface{})
|
|
nic["bridge"] = "vmbr0"
|
|
|
|
nics := make([]map[string]interface{}, 0)
|
|
nics = append(nics, nic)
|
|
|
|
disk := make(map[string]interface{})
|
|
disk["type"] = tt.disk_type
|
|
disk["io_thread"] = true
|
|
disk["storage_pool"] = "local-lvm"
|
|
disk["storage_pool_type"] = "lvm"
|
|
|
|
disks := make([]map[string]interface{}, 0)
|
|
disks = append(disks, disk)
|
|
|
|
cfg := mandatoryConfig(t)
|
|
cfg["network_adapters"] = nics
|
|
cfg["disks"] = disks
|
|
cfg["scsi_controller"] = tt.controller
|
|
|
|
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())
|
|
}
|
|
}
|
|
}
|