Extract vmware plugin (#10920)
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func TestLocalArtifact_impl(t *testing.T) {
|
||||
var _ packersdk.Artifact = new(artifact)
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func TestDriverConfigPrepare(t *testing.T) {
|
||||
tc := []struct {
|
||||
name string
|
||||
config *DriverConfig
|
||||
expectedConfig *DriverConfig
|
||||
errs []error
|
||||
}{
|
||||
{
|
||||
name: "Set default values",
|
||||
config: new(DriverConfig),
|
||||
expectedConfig: &DriverConfig{
|
||||
FusionAppPath: "/Applications/VMware Fusion.app",
|
||||
RemoteDatastore: "datastore1",
|
||||
RemoteCacheDatastore: "datastore1",
|
||||
RemoteCacheDirectory: "packer_cache",
|
||||
RemotePort: 22,
|
||||
RemoteUser: "root",
|
||||
},
|
||||
errs: nil,
|
||||
},
|
||||
{
|
||||
name: "Override default values",
|
||||
config: &DriverConfig{
|
||||
FusionAppPath: "foo",
|
||||
RemoteDatastore: "set-datastore1",
|
||||
RemoteCacheDatastore: "set-datastore1",
|
||||
RemoteCacheDirectory: "set_packer_cache",
|
||||
RemotePort: 443,
|
||||
RemoteUser: "admin",
|
||||
},
|
||||
expectedConfig: &DriverConfig{
|
||||
FusionAppPath: "foo",
|
||||
RemoteDatastore: "set-datastore1",
|
||||
RemoteCacheDatastore: "set-datastore1",
|
||||
RemoteCacheDirectory: "set_packer_cache",
|
||||
RemotePort: 443,
|
||||
RemoteUser: "admin",
|
||||
},
|
||||
errs: nil,
|
||||
},
|
||||
{
|
||||
name: "Invalid remote type",
|
||||
config: &DriverConfig{
|
||||
RemoteType: "invalid",
|
||||
RemoteHost: "host",
|
||||
},
|
||||
expectedConfig: nil,
|
||||
errs: []error{fmt.Errorf("Only 'esx5' value is accepted for remote_type")},
|
||||
},
|
||||
{
|
||||
name: "Remote host not set",
|
||||
config: &DriverConfig{
|
||||
RemoteType: "esx5",
|
||||
},
|
||||
expectedConfig: nil,
|
||||
errs: []error{fmt.Errorf("remote_host must be specified")},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range tc {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
errs := c.config.Prepare(interpolate.NewContext())
|
||||
if !reflect.DeepEqual(errs, c.errs) {
|
||||
t.Fatalf("bad: \n expected '%v' \nactual '%v'", c.errs, errs)
|
||||
}
|
||||
if len(c.errs) == 0 {
|
||||
if diff := cmp.Diff(c.config, c.expectedConfig); diff != "" {
|
||||
t.Fatalf("bad value: %s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/config"
|
||||
)
|
||||
|
||||
func TestESX5Driver_implDriver(t *testing.T) {
|
||||
var _ Driver = new(ESX5Driver)
|
||||
}
|
||||
|
||||
func TestESX5Driver_UpdateVMX(t *testing.T) {
|
||||
var driver ESX5Driver
|
||||
data := make(map[string]string)
|
||||
driver.UpdateVMX("0.0.0.0", "", 5900, data)
|
||||
if _, ok := data["remotedisplay.vnc.ip"]; ok {
|
||||
// Do not add the remotedisplay.vnc.ip on ESXi
|
||||
t.Fatal("invalid VMX data key: remotedisplay.vnc.ip")
|
||||
}
|
||||
if enabled := data["remotedisplay.vnc.enabled"]; enabled != "TRUE" {
|
||||
t.Errorf("bad VMX data for key remotedisplay.vnc.enabled: %v", enabled)
|
||||
}
|
||||
if port := data["remotedisplay.vnc.port"]; port != fmt.Sprint(port) {
|
||||
t.Errorf("bad VMX data for key remotedisplay.vnc.port: %v", port)
|
||||
}
|
||||
}
|
||||
|
||||
func TestESX5Driver_implOutputDir(t *testing.T) {
|
||||
var _ OutputDir = new(ESX5Driver)
|
||||
}
|
||||
|
||||
func TestESX5Driver_implVNCAddressFinder(t *testing.T) {
|
||||
var _ VNCAddressFinder = new(ESX5Driver)
|
||||
}
|
||||
|
||||
func TestESX5Driver_implRemoteDriver(t *testing.T) {
|
||||
var _ RemoteDriver = new(ESX5Driver)
|
||||
}
|
||||
|
||||
func TestESX5Driver_HostIP(t *testing.T) {
|
||||
expected_host := "127.0.0.1"
|
||||
|
||||
//create mock SSH server
|
||||
listen, _ := net.Listen("tcp", fmt.Sprintf("%s:0", expected_host))
|
||||
port := listen.Addr().(*net.TCPAddr).Port
|
||||
defer listen.Close()
|
||||
|
||||
driver := ESX5Driver{Host: "localhost", Port: port}
|
||||
state := new(multistep.BasicStateBag)
|
||||
|
||||
if host, _ := driver.HostIP(state); host != expected_host {
|
||||
t.Error(fmt.Sprintf("Expected string, %s but got %s", expected_host, host))
|
||||
}
|
||||
}
|
||||
|
||||
func TestESX5Driver_CommHost(t *testing.T) {
|
||||
const expected_host = "127.0.0.1"
|
||||
|
||||
conf := make(map[string]interface{})
|
||||
conf["communicator"] = "winrm"
|
||||
conf["winrm_username"] = "username"
|
||||
conf["winrm_password"] = "password"
|
||||
conf["winrm_host"] = expected_host
|
||||
|
||||
var commConfig communicator.Config
|
||||
err := config.Decode(&commConfig, nil, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error decoding config: %v", err)
|
||||
}
|
||||
state := new(multistep.BasicStateBag)
|
||||
sshConfig := SSHConfig{Comm: commConfig}
|
||||
state.Put("sshConfig", &sshConfig)
|
||||
driver := ESX5Driver{CommConfig: *(&sshConfig.Comm)}
|
||||
|
||||
host, err := driver.CommHost(state)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
if host != expected_host {
|
||||
t.Errorf("bad host name: %s", host)
|
||||
}
|
||||
address, ok := state.GetOk("vm_address")
|
||||
if !ok {
|
||||
t.Error("state not updated with vm_address")
|
||||
}
|
||||
if address.(string) != expected_host {
|
||||
t.Errorf("bad vm_address: %s", address.(string))
|
||||
}
|
||||
}
|
||||
|
||||
func TestESX5Driver_VerifyOvfTool(t *testing.T) {
|
||||
driver := ESX5Driver{}
|
||||
// should always skip validation if export is skipped, so this should always
|
||||
// pass even when ovftool is not installed.
|
||||
err := driver.VerifyOvfTool(true, false)
|
||||
if err != nil {
|
||||
t.Fatalf("shouldn't fail ever because should always skip check")
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDriverMock_impl(t *testing.T) {
|
||||
var _ Driver = new(DriverMock)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWorkstationVersion_ws14(t *testing.T) {
|
||||
input := `VMware Workstation Information:
|
||||
VMware Workstation 14.1.1 build-7528167 Release`
|
||||
if err := workstationTestVersion("10", input); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func TestHWConfigPrepare(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if c.CpuCount < 0 {
|
||||
t.Errorf("bad cpu count: %d", c.CpuCount)
|
||||
}
|
||||
|
||||
if c.CoreCount < 0 {
|
||||
t.Errorf("bad core count: %d", c.CoreCount)
|
||||
}
|
||||
|
||||
if c.MemorySize < 0 {
|
||||
t.Errorf("bad memory size: %d", c.MemorySize)
|
||||
}
|
||||
|
||||
if c.Sound {
|
||||
t.Errorf("peripheral choice (sound) should be conservative: %t", c.Sound)
|
||||
}
|
||||
|
||||
if c.USB {
|
||||
t.Errorf("peripheral choice (usb) should be conservative: %t", c.USB)
|
||||
}
|
||||
|
||||
if strings.ToUpper(c.Parallel) != "NONE" {
|
||||
t.Errorf("parallel port should not be defined: %s", c.Parallel)
|
||||
}
|
||||
|
||||
if strings.ToUpper(c.Serial) != "NONE" {
|
||||
t.Errorf("serial port should not be defined: %s", c.Serial)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigParallel_File(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Parallel = "file:filename"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasParallel() {
|
||||
t.Errorf("parallel port should be defined")
|
||||
}
|
||||
|
||||
parallel, err := c.ReadParallel()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read parallel port definition: %s", err)
|
||||
}
|
||||
|
||||
switch parallel.Union.(type) {
|
||||
case *ParallelPortFile:
|
||||
break
|
||||
default:
|
||||
t.Errorf("parallel port should be a file type")
|
||||
}
|
||||
|
||||
if parallel.File.Filename != "filename" {
|
||||
t.Errorf("parallel port filename should be \"filename\": %s", parallel.File.Filename)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigParallel_Device(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Parallel = "device:devicename,uni"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasParallel() {
|
||||
t.Errorf("parallel port should be defined")
|
||||
}
|
||||
|
||||
parallel, err := c.ReadParallel()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read parallel port definition: %s", err)
|
||||
}
|
||||
|
||||
switch parallel.Union.(type) {
|
||||
case *ParallelPortDevice:
|
||||
break
|
||||
default:
|
||||
t.Errorf("parallel port should be a device type")
|
||||
}
|
||||
|
||||
if strings.ToLower(parallel.Device.Bidirectional) != "false" {
|
||||
t.Errorf("parallel port device should not be bidirectional: %s", parallel.Device.Bidirectional)
|
||||
}
|
||||
|
||||
if parallel.Device.Devicename != "devicename" {
|
||||
t.Errorf("parallel port device should be \"devicename\": %s", parallel.Device.Devicename)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigParallel_Auto(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Parallel = "auto:bi"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasParallel() {
|
||||
t.Errorf("parallel port should be defined")
|
||||
}
|
||||
|
||||
parallel, err := c.ReadParallel()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read parallel port definition: %s", err)
|
||||
}
|
||||
|
||||
switch parallel.Union.(type) {
|
||||
case *ParallelPortAuto:
|
||||
break
|
||||
default:
|
||||
t.Errorf("parallel port should be an auto type")
|
||||
}
|
||||
|
||||
if strings.ToLower(parallel.Auto.Bidirectional) != "true" {
|
||||
t.Errorf("parallel port device should be bidirectional: %s", parallel.Auto.Bidirectional)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigParallel_None(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Parallel = "none"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasParallel() {
|
||||
t.Errorf("parallel port should be defined")
|
||||
}
|
||||
|
||||
parallel, err := c.ReadParallel()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read parallel port definition: %s", err)
|
||||
}
|
||||
|
||||
if parallel.Union != nil {
|
||||
t.Errorf("parallel port shouldn't exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigSerial_File(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Serial = "file:filename,true"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasSerial() {
|
||||
t.Errorf("serial port should be defined")
|
||||
}
|
||||
|
||||
serial, err := c.ReadSerial()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read serial port definition: %s", err)
|
||||
}
|
||||
|
||||
switch serial.Union.(type) {
|
||||
case *SerialConfigFile:
|
||||
break
|
||||
default:
|
||||
t.Errorf("serial port should be a file type")
|
||||
}
|
||||
|
||||
if serial.File.Filename != "filename" {
|
||||
t.Errorf("serial port filename should be \"filename\": %s", serial.File.Filename)
|
||||
}
|
||||
|
||||
if strings.ToLower(serial.File.Yield) != "true" {
|
||||
t.Errorf("serial port yield should be true: %s", serial.File.Yield)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigSerial_Device(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Serial = "device:devicename,true"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasSerial() {
|
||||
t.Errorf("serial port should be defined")
|
||||
}
|
||||
|
||||
serial, err := c.ReadSerial()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read serial port definition: %s", err)
|
||||
}
|
||||
|
||||
switch serial.Union.(type) {
|
||||
case *SerialConfigDevice:
|
||||
break
|
||||
default:
|
||||
t.Errorf("serial port should be a device type")
|
||||
}
|
||||
|
||||
if serial.Device.Devicename != "devicename" {
|
||||
t.Errorf("serial port device should be \"devicename\": %s", serial.Device.Devicename)
|
||||
}
|
||||
|
||||
if strings.ToLower(serial.Device.Yield) != "true" {
|
||||
t.Errorf("serial port device should yield: %s", serial.Device.Yield)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigSerial_Pipe(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Serial = "pipe:mypath,client,app,true"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasSerial() {
|
||||
t.Errorf("serial port should be defined")
|
||||
}
|
||||
|
||||
serial, err := c.ReadSerial()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read serial port definition: %s", err)
|
||||
}
|
||||
|
||||
switch serial.Union.(type) {
|
||||
case *SerialConfigPipe:
|
||||
break
|
||||
default:
|
||||
t.Errorf("serial port should be a pipe type")
|
||||
}
|
||||
|
||||
if serial.Pipe.Filename != "mypath" {
|
||||
t.Errorf("serial port pipe name should be \"mypath\": %s", serial.Pipe.Filename)
|
||||
}
|
||||
|
||||
if strings.ToLower(serial.Pipe.Endpoint) != "client" {
|
||||
t.Errorf("serial port endpoint should be \"client\": %s", serial.Pipe.Endpoint)
|
||||
}
|
||||
|
||||
if strings.ToLower(serial.Pipe.Host) != "true" {
|
||||
t.Errorf("serial port host type for app should be true: %s", serial.Pipe.Host)
|
||||
}
|
||||
|
||||
if strings.ToLower(serial.Pipe.Yield) != "true" {
|
||||
t.Errorf("serial port should yield: %s", serial.Pipe.Yield)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigSerial_Auto(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Serial = "auto:true"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasSerial() {
|
||||
t.Errorf("serial port should be defined")
|
||||
}
|
||||
|
||||
serial, err := c.ReadSerial()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read serial port definition: %s", err)
|
||||
}
|
||||
|
||||
switch serial.Union.(type) {
|
||||
case *SerialConfigAuto:
|
||||
break
|
||||
default:
|
||||
t.Errorf("serial port should be an auto type")
|
||||
}
|
||||
|
||||
if strings.ToLower(serial.Auto.Yield) != "true" {
|
||||
t.Errorf("serial port should yield: %s", serial.Auto.Yield)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHWConfigSerial_None(t *testing.T) {
|
||||
c := new(HWConfig)
|
||||
|
||||
c.Serial = "none"
|
||||
if errs := c.Prepare(interpolate.NewContext()); len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if !c.HasSerial() {
|
||||
t.Errorf("serial port should be defined")
|
||||
}
|
||||
|
||||
serial, err := c.ReadSerial()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to read serial port definition: %s", err)
|
||||
}
|
||||
|
||||
if serial.Union != nil {
|
||||
t.Errorf("serial port shouldn't exist")
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func TestOutputConfigPrepare(t *testing.T) {
|
||||
c := new(OutputConfig)
|
||||
if c.OutputDir != "" {
|
||||
t.Fatalf("what: %s", c.OutputDir)
|
||||
}
|
||||
|
||||
pc := &common.PackerConfig{PackerBuildName: "foo"}
|
||||
errs := c.Prepare(interpolate.NewContext(), pc)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if c.OutputDir == "" {
|
||||
t.Fatal("should have output dir")
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLocalOutputDir_impl(t *testing.T) {
|
||||
var _ OutputDir = new(LocalOutputDir)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRemoteDriverMock_impl(t *testing.T) {
|
||||
var _ Driver = new(RemoteDriverMock)
|
||||
var _ RemoteDriver = new(RemoteDriverMock)
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/hashicorp/packer-plugin-sdk/bootcommand"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func TestRunConfig_Prepare(t *testing.T) {
|
||||
tc := []struct {
|
||||
name string
|
||||
config *RunConfig
|
||||
expectedConfig *RunConfig
|
||||
driver *DriverConfig
|
||||
errs []error
|
||||
warnings []string
|
||||
}{
|
||||
{
|
||||
name: "VNC dafaults",
|
||||
config: &RunConfig{},
|
||||
expectedConfig: &RunConfig{
|
||||
VNCPortMin: 5900,
|
||||
VNCPortMax: 6000,
|
||||
VNCBindAddress: "127.0.0.1",
|
||||
},
|
||||
driver: new(DriverConfig),
|
||||
errs: nil,
|
||||
warnings: nil,
|
||||
},
|
||||
{
|
||||
name: "VNC port min less than vnc port max",
|
||||
config: &RunConfig{
|
||||
VNCPortMin: 5000,
|
||||
VNCPortMax: 5900,
|
||||
},
|
||||
expectedConfig: &RunConfig{
|
||||
VNCPortMin: 5000,
|
||||
VNCPortMax: 5900,
|
||||
VNCBindAddress: "127.0.0.1",
|
||||
},
|
||||
driver: new(DriverConfig),
|
||||
errs: nil,
|
||||
warnings: nil,
|
||||
},
|
||||
{
|
||||
name: "VNC port min bigger than vnc port max",
|
||||
config: &RunConfig{
|
||||
VNCPortMin: 5900,
|
||||
VNCPortMax: 5000,
|
||||
},
|
||||
expectedConfig: nil,
|
||||
driver: new(DriverConfig),
|
||||
errs: []error{fmt.Errorf("vnc_port_min must be less than vnc_port_max")},
|
||||
warnings: nil,
|
||||
},
|
||||
{
|
||||
name: "VNC port min must be positive",
|
||||
config: &RunConfig{
|
||||
VNCPortMin: -1,
|
||||
},
|
||||
expectedConfig: nil,
|
||||
driver: new(DriverConfig),
|
||||
errs: []error{fmt.Errorf("vnc_port_min must be positive")},
|
||||
warnings: nil,
|
||||
},
|
||||
{
|
||||
name: "fail when vnc_over_websocket set when remote_type is not set",
|
||||
config: &RunConfig{
|
||||
VNCOverWebsocket: true,
|
||||
},
|
||||
expectedConfig: nil,
|
||||
driver: new(DriverConfig),
|
||||
errs: []error{fmt.Errorf("'vnc_over_websocket' can only be used with remote VMWare builds.")},
|
||||
warnings: nil,
|
||||
},
|
||||
{
|
||||
name: "warn about ignored vnc configuration",
|
||||
config: &RunConfig{
|
||||
VNCOverWebsocket: true,
|
||||
VNCPortMin: 5000,
|
||||
VNCPortMax: 5900,
|
||||
},
|
||||
expectedConfig: &RunConfig{
|
||||
VNCOverWebsocket: true,
|
||||
VNCPortMin: 5000,
|
||||
VNCPortMax: 5900,
|
||||
},
|
||||
driver: &DriverConfig{RemoteType: "esxi"},
|
||||
errs: nil,
|
||||
warnings: []string{"[WARN] When 'vnc_over_websocket' is set " +
|
||||
"any other VNC configuration will be ignored."},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range tc {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
warnings, errs := c.config.Prepare(interpolate.NewContext(), c.driver)
|
||||
if !reflect.DeepEqual(errs, c.errs) {
|
||||
t.Fatalf("bad: \n expected '%v' \nactual '%v'", c.errs, errs)
|
||||
}
|
||||
if diff := cmp.Diff(warnings, c.warnings); diff != "" {
|
||||
t.Fatalf("unexpected warnings: %s", diff)
|
||||
}
|
||||
if len(c.errs) == 0 {
|
||||
if diff := cmp.Diff(c.config, c.expectedConfig,
|
||||
cmpopts.IgnoreFields(bootcommand.VNCConfig{},
|
||||
"BootConfig",
|
||||
)); diff != "" {
|
||||
t.Fatalf("unexpected config: %s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func testSSHConfig() *SSHConfig {
|
||||
return &SSHConfig{
|
||||
Comm: communicator.Config{
|
||||
SSH: communicator.SSH{
|
||||
SSHUsername: "foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSHConfigPrepare(t *testing.T) {
|
||||
c := testSSHConfig()
|
||||
errs := c.Prepare(interpolate.NewContext())
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if c.Comm.SSHPort != 22 {
|
||||
t.Errorf("bad ssh port: %d", c.Comm.SSHPort)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSHConfigPrepare_SSHPrivateKey(t *testing.T) {
|
||||
var c *SSHConfig
|
||||
var errs []error
|
||||
|
||||
c = testSSHConfig()
|
||||
c.Comm.SSHPrivateKeyFile = ""
|
||||
errs = c.Prepare(interpolate.NewContext())
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("should not have error: %#v", errs)
|
||||
}
|
||||
|
||||
c = testSSHConfig()
|
||||
c.Comm.SSHPrivateKeyFile = "/i/dont/exist"
|
||||
errs = c.Prepare(interpolate.NewContext())
|
||||
if len(errs) == 0 {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test bad contents
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Remove(tf.Name())
|
||||
defer tf.Close()
|
||||
|
||||
if _, err := tf.Write([]byte("HELLO!")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
c = testSSHConfig()
|
||||
c.Comm.SSHPrivateKeyFile = tf.Name()
|
||||
errs = c.Prepare(interpolate.NewContext())
|
||||
if len(errs) == 0 {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test good contents
|
||||
tf.Seek(0, 0)
|
||||
tf.Truncate(0)
|
||||
tf.Write([]byte(testPem))
|
||||
c = testSSHConfig()
|
||||
c.Comm.SSHPrivateKeyFile = tf.Name()
|
||||
errs = c.Prepare(interpolate.NewContext())
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("should not have error: %#v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
const testPem = `
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAxd4iamvrwRJvtNDGQSIbNvvIQN8imXTRWlRY62EvKov60vqu
|
||||
hh+rDzFYAIIzlmrJopvOe0clqmi3mIP9dtkjPFrYflq52a2CF5q+BdwsJXuRHbJW
|
||||
LmStZUwW1khSz93DhvhmK50nIaczW63u4EO/jJb3xj+wxR1Nkk9bxi3DDsYFt8SN
|
||||
AzYx9kjlEYQ/+sI4/ATfmdV9h78SVotjScupd9KFzzi76gWq9gwyCBLRynTUWlyD
|
||||
2UOfJRkOvhN6/jKzvYfVVwjPSfA9IMuooHdScmC4F6KBKJl/zf/zETM0XyzIDNmH
|
||||
uOPbCiljq2WoRM+rY6ET84EO0kVXbfx8uxUsqQIDAQABAoIBAQCkPj9TF0IagbM3
|
||||
5BSs/CKbAWS4dH/D4bPlxx4IRCNirc8GUg+MRb04Xz0tLuajdQDqeWpr6iLZ0RKV
|
||||
BvreLF+TOdV7DNQ4XE4gSdJyCtCaTHeort/aordL3l0WgfI7mVk0L/yfN1PEG4YG
|
||||
E9q1TYcyrB3/8d5JwIkjabxERLglCcP+geOEJp+QijbvFIaZR/n2irlKW4gSy6ko
|
||||
9B0fgUnhkHysSg49ChHQBPQ+o5BbpuLrPDFMiTPTPhdfsvGGcyCGeqfBA56oHcSF
|
||||
K02Fg8OM+Bd1lb48LAN9nWWY4WbwV+9bkN3Ym8hO4c3a/Dxf2N7LtAQqWZzFjvM3
|
||||
/AaDvAgBAoGBAPLD+Xn1IYQPMB2XXCXfOuJewRY7RzoVWvMffJPDfm16O7wOiW5+
|
||||
2FmvxUDayk4PZy6wQMzGeGKnhcMMZTyaq2g/QtGfrvy7q1Lw2fB1VFlVblvqhoJa
|
||||
nMJojjC4zgjBkXMHsRLeTmgUKyGs+fdFbfI6uejBnnf+eMVUMIdJ+6I9AoGBANCn
|
||||
kWO9640dttyXURxNJ3lBr2H3dJOkmD6XS+u+LWqCSKQe691Y/fZ/ZL0Oc4Mhy7I6
|
||||
hsy3kDQ5k2V0fkaNODQIFJvUqXw2pMewUk8hHc9403f4fe9cPrL12rQ8WlQw4yoC
|
||||
v2B61vNczCCUDtGxlAaw8jzSRaSI5s6ax3K7enbdAoGBAJB1WYDfA2CoAQO6y9Sl
|
||||
b07A/7kQ8SN5DbPaqrDrBdJziBQxukoMJQXJeGFNUFD/DXFU5Fp2R7C86vXT7HIR
|
||||
v6m66zH+CYzOx/YE6EsUJms6UP9VIVF0Rg/RU7teXQwM01ZV32LQ8mswhTH20o/3
|
||||
uqMHmxUMEhZpUMhrfq0isyApAoGAe1UxGTXfj9AqkIVYylPIq2HqGww7+jFmVEj1
|
||||
9Wi6S6Sq72ffnzzFEPkIQL/UA4TsdHMnzsYKFPSbbXLIWUeMGyVTmTDA5c0e5XIR
|
||||
lPhMOKCAzv8w4VUzMnEkTzkFY5JqFCD/ojW57KvDdNZPVB+VEcdxyAW6aKELXMAc
|
||||
eHLc1nkCgYEApm/motCTPN32nINZ+Vvywbv64ZD+gtpeMNP3CLrbe1X9O+H52AXa
|
||||
1jCoOldWR8i2bs2NVPcKZgdo6fFULqE4dBX7Te/uYEIuuZhYLNzRO1IKU/YaqsXG
|
||||
3bfQ8hKYcSnTfE0gPtLDnqCIxTocaGLSHeG3TH9fTw+dA8FvWpUztI4=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
||||
@@ -1,29 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
)
|
||||
|
||||
func TestCommHost(t *testing.T) {
|
||||
state := testState(t)
|
||||
config := SSHConfig{
|
||||
Comm: communicator.Config{
|
||||
Type: "ssh",
|
||||
SSH: communicator.SSH{
|
||||
SSHHost: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
hostFunc := CommHost(&config)
|
||||
out, err := hostFunc(state)
|
||||
if err != nil {
|
||||
t.Fatalf("Should not have had an error")
|
||||
}
|
||||
|
||||
if out != "127.0.0.1" {
|
||||
t.Fatalf("Should have respected ssh override.")
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepCleanVMX_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepCleanVMX)
|
||||
}
|
||||
|
||||
func TestStepCleanVMX(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCleanVMX)
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCleanVMX_floppyPath(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCleanVMX)
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
if err := ioutil.WriteFile(vmxPath, []byte(testVMXFloppyPath), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Set the path to the temporary vmx
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Add the floppy device to the list of temporary build devices
|
||||
state.Put("temporaryDevices", []string{"floppy0"})
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the resulting data
|
||||
vmxContents, err := ioutil.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
vmxData := ParseVMX(string(vmxContents))
|
||||
|
||||
cases := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
{"floppy0.present", "FALSE"},
|
||||
{"floppy0.filetype", ""},
|
||||
{"floppy0.filename", ""},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
if tc.Value == "" {
|
||||
if _, ok := vmxData[tc.Key]; ok {
|
||||
t.Fatalf("should not have key: %s", tc.Key)
|
||||
}
|
||||
} else {
|
||||
if vmxData[tc.Key] != tc.Value {
|
||||
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCleanVMX_isoPath(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCleanVMX)
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
if err := ioutil.WriteFile(vmxPath, []byte(testVMXISOPath), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Set the path to the temporary vmx
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Add the cdrom device to the list of temporary build devices
|
||||
state.Put("temporaryDevices", []string{"ide0:0"})
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the resulting data
|
||||
vmxContents, err := ioutil.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
vmxData := ParseVMX(string(vmxContents))
|
||||
|
||||
cases := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
{"ide0:0.filename", "auto detect"},
|
||||
{"ide0:0.devicetype", "cdrom-raw"},
|
||||
{"ide0:1.filename", "bar"},
|
||||
{"foo", "bar"},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
if tc.Value == "" {
|
||||
if _, ok := vmxData[tc.Key]; ok {
|
||||
t.Fatalf("should not have key: %s", tc.Key)
|
||||
}
|
||||
} else {
|
||||
if vmxData[tc.Key] != tc.Value {
|
||||
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCleanVMX_ethernet(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepCleanVMX{
|
||||
RemoveEthernetInterfaces: true,
|
||||
}
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
if err := ioutil.WriteFile(vmxPath, []byte(testVMXEthernet), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Set the path to the temporary vmx
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// TODO: Add the ethernet devices to the list of temporary build devices
|
||||
// state.Put("temporaryDevices", []string{"ethernet0", "ethernet1"})
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the resulting data
|
||||
vmxContents, err := ioutil.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
vmxData := ParseVMX(string(vmxContents))
|
||||
|
||||
cases := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
{"ethernet0.addresstype", ""},
|
||||
{"ethernet0.bsdname", ""},
|
||||
{"ethernet0.connectiontype", ""},
|
||||
{"ethernet1.addresstype", ""},
|
||||
{"ethernet1.bsdname", ""},
|
||||
{"ethernet1.connectiontype", ""},
|
||||
{"foo", "bar"},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
if tc.Value == "" {
|
||||
if _, ok := vmxData[tc.Key]; ok {
|
||||
t.Fatalf("should not have key: %s", tc.Key)
|
||||
}
|
||||
} else {
|
||||
if vmxData[tc.Key] != tc.Value {
|
||||
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const testVMXFloppyPath = `
|
||||
floppy0.present = "TRUE"
|
||||
floppy0.filetype = "file"
|
||||
`
|
||||
|
||||
const testVMXISOPath = `
|
||||
ide0:0.devicetype = "cdrom-image"
|
||||
ide0:0.filename = "foo"
|
||||
ide0:1.filename = "bar"
|
||||
foo = "bar"
|
||||
`
|
||||
|
||||
const testVMXEthernet = `
|
||||
ethernet0.addresstype = "generated"
|
||||
ethernet0.bsdname = "en0"
|
||||
ethernet0.connectiontype = "nat"
|
||||
ethernet1.addresstype = "generated"
|
||||
ethernet1.bsdname = "en1"
|
||||
ethernet1.connectiontype = "nat"
|
||||
foo = "bar"
|
||||
`
|
||||
@@ -1,62 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepCompactDisk_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepCompactDisk)
|
||||
}
|
||||
|
||||
func TestStepCompactDisk(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCompactDisk)
|
||||
|
||||
diskFullPaths := []string{"foo"}
|
||||
state.Put("disk_full_paths", diskFullPaths)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.CompactDiskCalled {
|
||||
t.Fatal("should've called")
|
||||
}
|
||||
if driver.CompactDiskPath != "foo" {
|
||||
t.Fatal("should call with right path")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCompactDisk_skip(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCompactDisk)
|
||||
step.Skip = true
|
||||
|
||||
diskFullPaths := []string{"foo"}
|
||||
state.Put("disk_full_paths", diskFullPaths)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if driver.CompactDiskCalled {
|
||||
t.Fatal("should not have called")
|
||||
}
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testVMXFile(t *testing.T) string {
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// displayName must always be set
|
||||
err = WriteVMX(tf.Name(), map[string]string{"displayName": "PackerBuild"})
|
||||
if err != nil {
|
||||
t.Fatalf("error writing .vmx file: %v", err)
|
||||
}
|
||||
tf.Close()
|
||||
|
||||
return tf.Name()
|
||||
}
|
||||
|
||||
func TestStepConfigureVMX_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepConfigureVMX)
|
||||
}
|
||||
|
||||
func TestStepConfigureVMX(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepConfigureVMX)
|
||||
step.CustomData = map[string]string{
|
||||
"foo": "bar",
|
||||
}
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the resulting data
|
||||
vmxContents, err := ioutil.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
vmxData := ParseVMX(string(vmxContents))
|
||||
|
||||
cases := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
// Stuff we set
|
||||
{"msg.autoanswer", "true"},
|
||||
{"uuid.action", "create"},
|
||||
|
||||
// Custom data
|
||||
{"foo", "bar"},
|
||||
|
||||
// Stuff that should NOT exist
|
||||
{"floppy0.present", ""},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
if tc.Value == "" {
|
||||
if _, ok := vmxData[tc.Key]; ok {
|
||||
t.Fatalf("should not have key: %s", tc.Key)
|
||||
}
|
||||
} else {
|
||||
if vmxData[tc.Key] != tc.Value {
|
||||
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepConfigureVMX_floppyPath(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepConfigureVMX)
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
|
||||
state.Put("floppy_path", "foo")
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the resulting data
|
||||
vmxContents, err := ioutil.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
vmxData := ParseVMX(string(vmxContents))
|
||||
|
||||
cases := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
{"floppy0.present", "TRUE"},
|
||||
{"floppy0.filetype", "file"},
|
||||
{"floppy0.filename", "foo"},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
if tc.Value == "" {
|
||||
if _, ok := vmxData[tc.Key]; ok {
|
||||
t.Fatalf("should not have key: %s", tc.Key)
|
||||
}
|
||||
} else {
|
||||
if vmxData[tc.Key] != tc.Value {
|
||||
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestStepConfigureVMX_generatedAddresses(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepConfigureVMX)
|
||||
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
|
||||
additionalTestVmxData := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
{"foo", "bar"},
|
||||
{"ethernet0.generatedaddress", "foo"},
|
||||
{"ethernet1.generatedaddress", "foo"},
|
||||
{"ethernet1.generatedaddressoffset", "foo"},
|
||||
}
|
||||
|
||||
// Get any existing VMX data from the VMX file
|
||||
vmxData, err := ReadVMX(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err %s", err)
|
||||
}
|
||||
|
||||
// Add the additional key/value pairs we need for this test to the existing VMX data
|
||||
for _, data := range additionalTestVmxData {
|
||||
vmxData[data.Key] = data.Value
|
||||
}
|
||||
|
||||
// Recreate the VMX file so it includes all the data needed for this test
|
||||
err = WriteVMX(vmxPath, vmxData)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the resulting data
|
||||
vmxContents, err := ioutil.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
vmxData = ParseVMX(string(vmxContents))
|
||||
|
||||
cases := []struct {
|
||||
Key string
|
||||
Value string
|
||||
}{
|
||||
{"foo", "bar"},
|
||||
{"ethernet0.generatedaddress", ""},
|
||||
{"ethernet1.generatedaddress", ""},
|
||||
{"ethernet1.generatedaddressoffset", ""},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
if tc.Value == "" {
|
||||
if _, ok := vmxData[tc.Key]; ok {
|
||||
t.Fatalf("should not have key: %s", tc.Key)
|
||||
}
|
||||
} else {
|
||||
if vmxData[tc.Key] != tc.Value {
|
||||
t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should fail if the displayName key is not found in the VMX
|
||||
func TestStepConfigureVMX_displayNameMissing(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepConfigureVMX)
|
||||
|
||||
// testVMXFile adds displayName key/value pair to the VMX
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
|
||||
// Bad: Delete displayName from the VMX/Create an empty VMX file
|
||||
err := WriteVMX(vmxPath, map[string]string{})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v. Should halt when displayName key is missing from VMX", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatal("should store error in state when displayName key is missing from VMX")
|
||||
}
|
||||
}
|
||||
|
||||
// Should store the value of displayName in the statebag
|
||||
func TestStepConfigureVMX_displayNameStore(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepConfigureVMX)
|
||||
|
||||
// testVMXFile adds displayName key/value pair to the VMX
|
||||
vmxPath := testVMXFile(t)
|
||||
defer os.Remove(vmxPath)
|
||||
|
||||
state.Put("vmx_path", vmxPath)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// The value of displayName must be stored in the statebag
|
||||
if _, ok := state.GetOk("display_name"); !ok {
|
||||
t.Fatalf("displayName should be stored in the statebag as 'display_name'")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepConfigureVMX_vmxPathBad(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepConfigureVMX)
|
||||
|
||||
state.Put("vmx_path", "some_bad_path")
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v. Should halt when vmxPath is bad", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatal("should store error in state when vmxPath is bad")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestStepConfigureVMX_DefaultDiskAndCDROMTypes(t *testing.T) {
|
||||
type testCase struct {
|
||||
inDiskAdapter string
|
||||
inCDromAdapter string
|
||||
expectedOut DiskAndCDConfigData
|
||||
reason string
|
||||
}
|
||||
testcases := []testCase{
|
||||
{
|
||||
inDiskAdapter: "",
|
||||
inCDromAdapter: "",
|
||||
expectedOut: DiskAndCDConfigData{
|
||||
SCSI_Present: "TRUE",
|
||||
SCSI_diskAdapterType: "",
|
||||
SATA_Present: "FALSE",
|
||||
NVME_Present: "FALSE",
|
||||
|
||||
DiskType: "scsi",
|
||||
CDROMType: "ide",
|
||||
CDROMType_PrimarySecondary: "0",
|
||||
},
|
||||
reason: "Test that default creases scsi disk with ide cd",
|
||||
},
|
||||
{
|
||||
inDiskAdapter: "ide",
|
||||
inCDromAdapter: "",
|
||||
expectedOut: DiskAndCDConfigData{
|
||||
SCSI_Present: "FALSE",
|
||||
SCSI_diskAdapterType: "lsilogic",
|
||||
SATA_Present: "FALSE",
|
||||
NVME_Present: "FALSE",
|
||||
|
||||
DiskType: "ide",
|
||||
CDROMType: "ide",
|
||||
CDROMType_PrimarySecondary: "1",
|
||||
},
|
||||
reason: "ide disk adapter should pass through and not get defaulted to scsi",
|
||||
},
|
||||
{
|
||||
inDiskAdapter: "sata",
|
||||
inCDromAdapter: "",
|
||||
expectedOut: DiskAndCDConfigData{
|
||||
SCSI_Present: "FALSE",
|
||||
SCSI_diskAdapterType: "lsilogic",
|
||||
SATA_Present: "TRUE",
|
||||
NVME_Present: "FALSE",
|
||||
|
||||
DiskType: "sata",
|
||||
CDROMType: "sata",
|
||||
CDROMType_PrimarySecondary: "1",
|
||||
},
|
||||
reason: "when disk is set to sata, cdromtype should also default to sata",
|
||||
},
|
||||
{
|
||||
inDiskAdapter: "nvme",
|
||||
inCDromAdapter: "",
|
||||
expectedOut: DiskAndCDConfigData{
|
||||
SCSI_Present: "FALSE",
|
||||
SCSI_diskAdapterType: "lsilogic",
|
||||
SATA_Present: "TRUE",
|
||||
NVME_Present: "TRUE",
|
||||
|
||||
DiskType: "nvme",
|
||||
CDROMType: "sata",
|
||||
CDROMType_PrimarySecondary: "0",
|
||||
},
|
||||
reason: "when disk is set to nvme, cdromtype should default to sata",
|
||||
},
|
||||
{
|
||||
inDiskAdapter: "scsi",
|
||||
inCDromAdapter: "",
|
||||
expectedOut: DiskAndCDConfigData{
|
||||
SCSI_Present: "TRUE",
|
||||
SCSI_diskAdapterType: "lsilogic",
|
||||
SATA_Present: "FALSE",
|
||||
NVME_Present: "FALSE",
|
||||
|
||||
DiskType: "scsi",
|
||||
CDROMType: "ide",
|
||||
CDROMType_PrimarySecondary: "0",
|
||||
},
|
||||
reason: "when disk is set to scsi, adapter should default back to lsilogic",
|
||||
},
|
||||
{
|
||||
inDiskAdapter: "scsi",
|
||||
inCDromAdapter: "scsi",
|
||||
expectedOut: DiskAndCDConfigData{
|
||||
SCSI_Present: "TRUE",
|
||||
SCSI_diskAdapterType: "lsilogic",
|
||||
SATA_Present: "FALSE",
|
||||
NVME_Present: "FALSE",
|
||||
|
||||
DiskType: "scsi",
|
||||
CDROMType: "scsi",
|
||||
CDROMType_PrimarySecondary: "0",
|
||||
},
|
||||
reason: "when cdrom adapter is set, it should override the default",
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
diskConfigData := DefaultDiskAndCDROMTypes(tc.inDiskAdapter, tc.inCDromAdapter)
|
||||
assert.Equal(t, diskConfigData, tc.expectedOut, tc.reason)
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStepConfigureVNC_implVNCAddressFinder(t *testing.T) {
|
||||
var _ VNCAddressFinder = new(StepConfigureVNC)
|
||||
}
|
||||
|
||||
func TestStepConfigureVNC_UpdateVMX(t *testing.T) {
|
||||
var s StepConfigureVNC
|
||||
data := make(map[string]string)
|
||||
s.UpdateVMX("0.0.0.0", "", 5900, data)
|
||||
if ip := data["remotedisplay.vnc.ip"]; ip != "0.0.0.0" {
|
||||
t.Errorf("bad VMX data for key remotedisplay.vnc.ip: %v", ip)
|
||||
}
|
||||
if enabled := data["remotedisplay.vnc.enabled"]; enabled != "TRUE" {
|
||||
t.Errorf("bad VMX data for key remotedisplay.vnc.enabled: %v", enabled)
|
||||
}
|
||||
if port := data["remotedisplay.vnc.port"]; port != fmt.Sprint(port) {
|
||||
t.Errorf("bad VMX data for key remotedisplay.vnc.port: %v", port)
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestStepCreateDisks_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepCreateDisks)
|
||||
}
|
||||
|
||||
func strPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
func NewTestCreateDiskStep() *StepCreateDisks {
|
||||
return &StepCreateDisks{
|
||||
OutputDir: strPtr("output_dir"),
|
||||
CreateMainDisk: true,
|
||||
DiskName: "disk_name",
|
||||
MainDiskSize: uint(1024),
|
||||
AdditionalDiskSize: []uint{},
|
||||
DiskAdapterType: "fake_adapter",
|
||||
DiskTypeId: "1",
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateDisks_MainOnly(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := NewTestCreateDiskStep()
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
if !driver.CreateDiskCalled {
|
||||
t.Fatalf("Should have called create disk.")
|
||||
}
|
||||
|
||||
diskFullPaths, ok := state.Get("disk_full_paths").([]string)
|
||||
if !ok {
|
||||
t.Fatalf("Should be able to load disk_full_paths from state")
|
||||
}
|
||||
|
||||
assert.Equal(t, diskFullPaths, []string{filepath.Join("output_dir", "disk_name.vmdk")})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepCreateDisks_MainAndExtra(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := NewTestCreateDiskStep()
|
||||
step.AdditionalDiskSize = []uint{1024, 2048, 4096}
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
if !driver.CreateDiskCalled {
|
||||
t.Fatalf("Should have called create disk.")
|
||||
}
|
||||
|
||||
diskFullPaths, ok := state.Get("disk_full_paths").([]string)
|
||||
if !ok {
|
||||
t.Fatalf("Should be able to load disk_full_paths from state")
|
||||
}
|
||||
|
||||
assert.Equal(t, diskFullPaths,
|
||||
[]string{
|
||||
filepath.Join("output_dir", "disk_name.vmdk"),
|
||||
filepath.Join("output_dir", "disk_name-1.vmdk"),
|
||||
filepath.Join("output_dir", "disk_name-2.vmdk"),
|
||||
filepath.Join("output_dir", "disk_name-3.vmdk"),
|
||||
})
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepCreateDisks_ExtraOnly(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := NewTestCreateDiskStep()
|
||||
step.CreateMainDisk = false
|
||||
step.AdditionalDiskSize = []uint{1024, 2048, 4096}
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
if !driver.CreateDiskCalled {
|
||||
t.Fatalf("Should have called create disk.")
|
||||
}
|
||||
|
||||
diskFullPaths, ok := state.Get("disk_full_paths").([]string)
|
||||
if !ok {
|
||||
t.Fatalf("Should be able to load disk_full_paths from state")
|
||||
}
|
||||
|
||||
assert.Equal(t, diskFullPaths,
|
||||
[]string{
|
||||
filepath.Join("output_dir", "disk_name-1.vmdk"),
|
||||
filepath.Join("output_dir", "disk_name-2.vmdk"),
|
||||
filepath.Join("output_dir", "disk_name-3.vmdk"),
|
||||
})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepCreateDisks_Nothing(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := NewTestCreateDiskStep()
|
||||
step.CreateMainDisk = false
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
if driver.CreateDiskCalled {
|
||||
t.Fatalf("Should not have called create disk.")
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestStepExport_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepExport)
|
||||
}
|
||||
|
||||
func stringPointer(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
func remoteExportTestState(t *testing.T) multistep.StateBag {
|
||||
state := testState(t)
|
||||
driverConfig := &DriverConfig{
|
||||
RemoteHost: "123.45.67.8",
|
||||
RemotePassword: "password",
|
||||
RemoteUser: "user",
|
||||
RemoteType: "esx5",
|
||||
}
|
||||
state.Put("driverConfig", driverConfig)
|
||||
state.Put("display_name", "vm_name")
|
||||
return state
|
||||
}
|
||||
|
||||
func TestStepExport_ReturnIfSkip(t *testing.T) {
|
||||
state := testState(t)
|
||||
driverConfig := &DriverConfig{}
|
||||
state.Put("driverConfig", driverConfig)
|
||||
step := new(StepExport)
|
||||
|
||||
step.SkipExport = true
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// We told step to skip so it should not have reached the driver's Export
|
||||
// func.
|
||||
d := state.Get("driver").(*DriverMock)
|
||||
if d.ExportCalled {
|
||||
t.Fatal("Should not have called the driver export func")
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepExport_localArgs(t *testing.T) {
|
||||
// even though we aren't overriding the remote args and they are present,
|
||||
// test shouldn't use them since remoteType is not set to esx.
|
||||
state := testState(t)
|
||||
driverConfig := &DriverConfig{}
|
||||
state.Put("driverConfig", driverConfig)
|
||||
step := new(StepExport)
|
||||
|
||||
step.SkipExport = false
|
||||
step.OutputDir = stringPointer("test-output")
|
||||
step.VMName = "test-name"
|
||||
step.Format = "ova"
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Check that step ran, and called Export with the expected args.
|
||||
d := state.Get("driver").(*DriverMock)
|
||||
if !d.ExportCalled {
|
||||
t.Fatal("Should have called the driver export func")
|
||||
}
|
||||
|
||||
assert.Equal(t, d.ExportArgs,
|
||||
[]string{
|
||||
filepath.Join("test-output", "test-name.vmx"),
|
||||
filepath.Join("test-output", "test-name.ova")})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepExport_localArgsExportOutputPath(t *testing.T) {
|
||||
// even though we aren't overriding the remote args and they are present,
|
||||
// test shouldn't use them since remoteType is not set to esx.
|
||||
state := testState(t)
|
||||
driverConfig := &DriverConfig{}
|
||||
state.Put("driverConfig", driverConfig)
|
||||
state.Put("export_output_path", "local_output")
|
||||
step := new(StepExport)
|
||||
|
||||
step.SkipExport = false
|
||||
step.OutputDir = stringPointer("test-output")
|
||||
step.VMName = "test-name"
|
||||
step.Format = "ova"
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Check that step ran, and called Export with the expected args.
|
||||
d := state.Get("driver").(*DriverMock)
|
||||
if !d.ExportCalled {
|
||||
t.Fatal("Should have called the driver export func")
|
||||
}
|
||||
|
||||
assert.Equal(t, d.ExportArgs,
|
||||
[]string{
|
||||
filepath.Join("local_output", "test-name.vmx"),
|
||||
filepath.Join("local_output", "test-name.ova")})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepExport_localArgs_OvftoolOptions(t *testing.T) {
|
||||
// even though we aren't overriding the remote args and they are present,
|
||||
// test shouldn't use them since remoteType is not set to esx.
|
||||
state := testState(t)
|
||||
driverConfig := &DriverConfig{}
|
||||
state.Put("driverConfig", driverConfig)
|
||||
step := new(StepExport)
|
||||
|
||||
step.SkipExport = false
|
||||
step.OutputDir = stringPointer("test-output")
|
||||
step.VMName = "test-name"
|
||||
step.Format = "ova"
|
||||
step.OVFToolOptions = []string{"--option=value", "--second-option=\"quoted value\""}
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Check that step ran, and called Export with the expected args.
|
||||
d := state.Get("driver").(*DriverMock)
|
||||
if !d.ExportCalled {
|
||||
t.Fatal("Should have called the driver export func")
|
||||
}
|
||||
|
||||
assert.Equal(t, d.ExportArgs, []string{"--option=value",
|
||||
"--second-option=\"quoted value\"",
|
||||
filepath.Join("test-output", "test-name.vmx"),
|
||||
filepath.Join("test-output", "test-name.ova")})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepExport_RemoteArgs(t *testing.T) {
|
||||
// Even though we aren't overriding the remote args and they are present,
|
||||
// test shouldn't use them since remoteType is not set to esx.
|
||||
state := remoteExportTestState(t)
|
||||
step := new(StepExport)
|
||||
|
||||
step.SkipExport = false
|
||||
step.OutputDir = stringPointer("test-output")
|
||||
step.VMName = "test-name"
|
||||
step.Format = "ova"
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Check that step ran, and called Export with the expected args.
|
||||
d := state.Get("driver").(*DriverMock)
|
||||
if !d.ExportCalled {
|
||||
t.Fatal("Should have called the driver export func")
|
||||
}
|
||||
|
||||
assert.Equal(t, d.ExportArgs, []string{"--noSSLVerify=true",
|
||||
"--skipManifestCheck",
|
||||
"-tt=ova",
|
||||
"vi://user:password@123.45.67.8/vm_name",
|
||||
filepath.Join("test-output", "test-name.ova")})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepExport_RemoteArgsWithExportOutputPath(t *testing.T) {
|
||||
// Even though we aren't overriding the remote args and they are present,
|
||||
// test shouldn't use them since remoteType is not set to esx.
|
||||
state := remoteExportTestState(t)
|
||||
state.Put("export_output_path", "local_output")
|
||||
step := new(StepExport)
|
||||
|
||||
step.SkipExport = false
|
||||
step.OutputDir = stringPointer("test-output")
|
||||
step.VMName = "test-name"
|
||||
step.Format = "ova"
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Check that step ran, and called Export with the expected args.
|
||||
d := state.Get("driver").(*DriverMock)
|
||||
if !d.ExportCalled {
|
||||
t.Fatal("Should have called the driver export func")
|
||||
}
|
||||
|
||||
assert.Equal(t, d.ExportArgs, []string{"--noSSLVerify=true",
|
||||
"--skipManifestCheck",
|
||||
"-tt=ova",
|
||||
"vi://user:password@123.45.67.8/vm_name",
|
||||
filepath.Join("local_output", "test-name.ova")})
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepHTTPIPDiscover_Run(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepHTTPIPDiscover)
|
||||
driverMock := state.Get("driver").(Driver)
|
||||
hostIp, _ := driverMock.HostIP(state)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
httpIp := state.Get("http_ip").(string)
|
||||
if httpIp != hostIp {
|
||||
t.Fatalf("bad: Http ip is %s but was supposed to be %s", httpIp, hostIp)
|
||||
}
|
||||
|
||||
// Halt step when fails to get ip
|
||||
state.Put("driver", &DriverMock{HostIPErr: errors.New("error")})
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: step was supposed to fail %#v", action)
|
||||
}
|
||||
}
|
||||
@@ -1,224 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func testOutputDir(t *testing.T) string {
|
||||
td, err := ioutil.TempDir("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
os.RemoveAll(td)
|
||||
|
||||
return td
|
||||
}
|
||||
|
||||
func TestStepOutputDir_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepOutputDir)
|
||||
}
|
||||
|
||||
func TestStepOutputDir(t *testing.T) {
|
||||
state := testState(t)
|
||||
driver := new(DriverMock)
|
||||
state.Put("driver", driver)
|
||||
|
||||
td := testOutputDir(t)
|
||||
outconfig := &OutputConfig{
|
||||
OutputDir: td,
|
||||
}
|
||||
|
||||
step := &StepOutputDir{
|
||||
OutputConfig: outconfig,
|
||||
VMName: "testVM",
|
||||
}
|
||||
// Delete the test output directory when done
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
if _, err := os.Stat(td); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Test the cleanup
|
||||
step.Cleanup(state)
|
||||
if _, err := os.Stat(td); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepOutputDir_existsNoForce(t *testing.T) {
|
||||
state := testState(t)
|
||||
|
||||
td := testOutputDir(t)
|
||||
outconfig := &OutputConfig{
|
||||
OutputDir: td,
|
||||
}
|
||||
|
||||
step := &StepOutputDir{
|
||||
OutputConfig: outconfig,
|
||||
VMName: "testVM",
|
||||
}
|
||||
// Delete the test output directory when done
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Make sure the dir exists
|
||||
if err := os.MkdirAll(td, 0755); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test the cleanup
|
||||
step.Cleanup(state)
|
||||
if _, err := os.Stat(td); err != nil {
|
||||
t.Fatal("should not delete dir")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepOutputDir_existsForce(t *testing.T) {
|
||||
state := testState(t)
|
||||
|
||||
td := testOutputDir(t)
|
||||
outconfig := &OutputConfig{
|
||||
OutputDir: td,
|
||||
}
|
||||
|
||||
step := &StepOutputDir{
|
||||
OutputConfig: outconfig,
|
||||
VMName: "testVM",
|
||||
}
|
||||
step.Force = true
|
||||
|
||||
// Delete the test output directory when done
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Make sure the dir exists
|
||||
if err := os.MkdirAll(td, 0755); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
if _, err := os.Stat(td); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepOutputDir_cancel(t *testing.T) {
|
||||
state := testState(t)
|
||||
td := testOutputDir(t)
|
||||
outconfig := &OutputConfig{
|
||||
OutputDir: td,
|
||||
}
|
||||
|
||||
step := &StepOutputDir{
|
||||
OutputConfig: outconfig,
|
||||
VMName: "testVM",
|
||||
}
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
if _, err := os.Stat(td); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Test cancel/halt
|
||||
state.Put(multistep.StateCancelled, true)
|
||||
step.Cleanup(state)
|
||||
if _, err := os.Stat(td); err == nil {
|
||||
t.Fatal("directory should not exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepOutputDir_halt(t *testing.T) {
|
||||
state := testState(t)
|
||||
td := testOutputDir(t)
|
||||
outconfig := &OutputConfig{
|
||||
OutputDir: td,
|
||||
}
|
||||
|
||||
step := &StepOutputDir{
|
||||
OutputConfig: outconfig,
|
||||
VMName: "testVM",
|
||||
}
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
if _, err := os.Stat(td); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Test cancel/halt
|
||||
state.Put(multistep.StateHalted, true)
|
||||
step.Cleanup(state)
|
||||
if _, err := os.Stat(td); err == nil {
|
||||
t.Fatal("directory should not exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepOutputDir_Remote(t *testing.T) {
|
||||
// Tests remote driver
|
||||
state := testState(t)
|
||||
driver := new(RemoteDriverMock)
|
||||
state.Put("driver", driver)
|
||||
|
||||
td := testOutputDir(t)
|
||||
outconfig := &OutputConfig{
|
||||
OutputDir: td,
|
||||
RemoteOutputDir: "remote_path",
|
||||
}
|
||||
|
||||
step := &StepOutputDir{
|
||||
OutputConfig: outconfig,
|
||||
VMName: "testVM",
|
||||
RemoteType: "esx5",
|
||||
}
|
||||
// Delete the test output directory when done
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
// We don't pre-create the output path for export but we do set it in state.
|
||||
exportOutputPath := state.Get("export_output_path").(string)
|
||||
if exportOutputPath != td {
|
||||
t.Fatalf("err: should have set export_output_path!")
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepPrepareTools_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepPrepareTools)
|
||||
}
|
||||
|
||||
func TestStepPrepareTools(t *testing.T) {
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
defer os.Remove(tf.Name())
|
||||
|
||||
state := testState(t)
|
||||
step := &StepPrepareTools{
|
||||
RemoteType: "",
|
||||
ToolsUploadFlavor: "foo",
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Mock results
|
||||
driver.ToolsIsoPathResult = tf.Name()
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.ToolsIsoPathCalled {
|
||||
t.Fatal("tools iso path should be called")
|
||||
}
|
||||
if driver.ToolsIsoPathFlavor != "foo" {
|
||||
t.Fatalf("bad: %#v", driver.ToolsIsoPathFlavor)
|
||||
}
|
||||
|
||||
// Test the resulting state
|
||||
path, ok := state.GetOk("tools_upload_source")
|
||||
if !ok {
|
||||
t.Fatal("should have tools_upload_source")
|
||||
}
|
||||
if path != tf.Name() {
|
||||
t.Fatalf("bad: %#v", path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepPrepareTools_esx5(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepPrepareTools{
|
||||
RemoteType: "esx5",
|
||||
ToolsUploadFlavor: "foo",
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if driver.ToolsIsoPathCalled {
|
||||
t.Fatal("tools iso path should NOT be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepPrepareTools_nonExist(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepPrepareTools{
|
||||
RemoteType: "",
|
||||
ToolsUploadFlavor: "foo",
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Mock results
|
||||
driver.ToolsIsoPathResult = "foo"
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.ToolsIsoPathCalled {
|
||||
t.Fatal("tools iso path should be called")
|
||||
}
|
||||
if driver.ToolsIsoPathFlavor != "foo" {
|
||||
t.Fatalf("bad: %#v", driver.ToolsIsoPathFlavor)
|
||||
}
|
||||
|
||||
// Test the resulting state
|
||||
if _, ok := state.GetOk("tools_upload_source"); ok {
|
||||
t.Fatal("should NOT have tools_upload_source")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepPrepareTools_SourcePath(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepPrepareTools{
|
||||
RemoteType: "",
|
||||
ToolsSourcePath: "/path/to/tool.iso",
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Mock results
|
||||
driver.ToolsIsoPathResult = "foo"
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("Should have failed when stat failed %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if driver.ToolsIsoPathCalled {
|
||||
t.Fatal("tools iso path should not be called when ToolsSourcePath is set")
|
||||
}
|
||||
|
||||
// Test the resulting state
|
||||
if _, ok := state.GetOk("tools_upload_source"); ok {
|
||||
t.Fatal("should NOT have tools_upload_source")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepPrepareTools_SourcePath_exists(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepPrepareTools{
|
||||
RemoteType: "",
|
||||
ToolsSourcePath: "./step_prepare_tools.go",
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Mock results
|
||||
driver.ToolsIsoPathResult = "foo"
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("Step should succeed when stat succeeds: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if driver.ToolsIsoPathCalled {
|
||||
t.Fatal("tools iso path should not be called when ToolsSourcePath is set")
|
||||
}
|
||||
|
||||
// Test the resulting state
|
||||
if _, ok := state.GetOk("tools_upload_source"); !ok {
|
||||
t.Fatal("should have tools_upload_source")
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepRegister_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepRegister)
|
||||
}
|
||||
|
||||
func TestStepRegister_regularDriver(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepRegister)
|
||||
|
||||
state.Put("vmx_path", "foo")
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepRegister_remoteDriver(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepRegister{
|
||||
KeepRegistered: false,
|
||||
SkipExport: true,
|
||||
}
|
||||
|
||||
driver := new(RemoteDriverMock)
|
||||
|
||||
state.Put("driver", driver)
|
||||
state.Put("vmx_path", "foo")
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// verify
|
||||
if !driver.RegisterCalled {
|
||||
t.Fatal("register should be called")
|
||||
}
|
||||
if driver.RegisterPath != "foo" {
|
||||
t.Fatal("should call with correct path")
|
||||
}
|
||||
if driver.UnregisterCalled {
|
||||
t.Fatal("unregister should not be called")
|
||||
}
|
||||
|
||||
// cleanup
|
||||
step.Cleanup(state)
|
||||
if !driver.UnregisterCalled {
|
||||
t.Fatal("unregister should be called")
|
||||
}
|
||||
if driver.UnregisterPath != "foo" {
|
||||
t.Fatal("should unregister proper path")
|
||||
}
|
||||
}
|
||||
func TestStepRegister_WithoutUnregister_remoteDriver(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := &StepRegister{KeepRegistered: true}
|
||||
|
||||
driver := new(RemoteDriverMock)
|
||||
|
||||
state.Put("driver", driver)
|
||||
state.Put("vmx_path", "foo")
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// cleanup
|
||||
step.Cleanup(state)
|
||||
if driver.UnregisterCalled {
|
||||
t.Fatal("unregister should not be called")
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepRemoteUpload_Cleanup(t *testing.T) {
|
||||
state := new(multistep.BasicStateBag)
|
||||
driver := new(RemoteDriverMock)
|
||||
state.Put("driver", driver)
|
||||
state.Put("path_key", "packer_cache")
|
||||
|
||||
// Should clean up cache
|
||||
s := &StepRemoteUpload{
|
||||
Key: "path_key",
|
||||
DoCleanup: true,
|
||||
}
|
||||
s.Cleanup(state)
|
||||
|
||||
if !driver.CacheRemoved {
|
||||
t.Fatalf("bad: remote cache was not removed")
|
||||
}
|
||||
if driver.RemovedCachePath != "packer_cache" {
|
||||
t.Fatalf("bad: removed cache path was expected to be packer_cache but was %s", driver.RemovedCachePath)
|
||||
}
|
||||
|
||||
// Should NOT clean up cache
|
||||
s = &StepRemoteUpload{
|
||||
Key: "path_key",
|
||||
}
|
||||
driver = new(RemoteDriverMock)
|
||||
state.Put("driver", driver)
|
||||
s.Cleanup(state)
|
||||
|
||||
if driver.CacheRemoved {
|
||||
t.Fatalf("bad: remote cache was removed but was expected to not")
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepRun_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepRun)
|
||||
}
|
||||
|
||||
func TestStepRun(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepRun)
|
||||
|
||||
state.Put("vmx_path", "foo")
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.StartCalled {
|
||||
t.Fatal("start should be called")
|
||||
}
|
||||
if driver.StartPath != "foo" {
|
||||
t.Fatalf("bad: %#v", driver.StartPath)
|
||||
}
|
||||
if driver.StartHeadless {
|
||||
t.Fatal("bad")
|
||||
}
|
||||
|
||||
// Test cleanup
|
||||
step.Cleanup(state)
|
||||
if driver.StopCalled {
|
||||
t.Fatal("stop should not be called if not running")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepRun_cleanupRunning(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepRun)
|
||||
|
||||
state.Put("vmx_path", "foo")
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.StartCalled {
|
||||
t.Fatal("start should be called")
|
||||
}
|
||||
if driver.StartPath != "foo" {
|
||||
t.Fatalf("bad: %#v", driver.StartPath)
|
||||
}
|
||||
if driver.StartHeadless {
|
||||
t.Fatal("bad")
|
||||
}
|
||||
|
||||
// Mark that it is running
|
||||
driver.IsRunningResult = true
|
||||
|
||||
// Test cleanup
|
||||
step.Cleanup(state)
|
||||
if !driver.StopCalled {
|
||||
t.Fatal("stop should be called")
|
||||
}
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func testLocalOutputDir(t *testing.T) *LocalOutputDir {
|
||||
td, err := ioutil.TempDir("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
os.RemoveAll(td)
|
||||
|
||||
result := new(LocalOutputDir)
|
||||
result.SetOutputDir(td)
|
||||
return result
|
||||
}
|
||||
|
||||
func testStepShutdownState(t *testing.T) multistep.StateBag {
|
||||
dir := testLocalOutputDir(t)
|
||||
if err := dir.MkdirAll(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
state := testState(t)
|
||||
state.Put("communicator", new(packersdk.MockCommunicator))
|
||||
state.Put("dir", dir)
|
||||
state.Put("vmx_path", "foo")
|
||||
return state
|
||||
}
|
||||
|
||||
func TestStepShutdown_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepShutdown)
|
||||
}
|
||||
|
||||
func TestStepShutdown_command(t *testing.T) {
|
||||
state := testStepShutdownState(t)
|
||||
step := new(StepShutdown)
|
||||
step.Command = "foo"
|
||||
step.Timeout = 10 * time.Second
|
||||
step.Testing = true
|
||||
|
||||
comm := state.Get("communicator").(*packersdk.MockCommunicator)
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
driver.IsRunningResult = true
|
||||
|
||||
// Set not running after some time
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
driver.Lock()
|
||||
defer driver.Unlock()
|
||||
driver.IsRunningResult = false
|
||||
}()
|
||||
|
||||
resultCh := make(chan multistep.StepAction, 1)
|
||||
go func() {
|
||||
resultCh <- step.Run(context.Background(), state)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-resultCh:
|
||||
t.Fatal("should not have returned so quickly")
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
|
||||
var action multistep.StepAction
|
||||
select {
|
||||
case action = <-resultCh:
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("should've returned by now")
|
||||
}
|
||||
|
||||
// Test the run
|
||||
if action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if driver.StopCalled {
|
||||
t.Fatal("stop should not be called")
|
||||
}
|
||||
|
||||
if !comm.StartCalled {
|
||||
t.Fatal("start should be called")
|
||||
}
|
||||
if comm.StartCmd.Command != "foo" {
|
||||
t.Fatalf("bad: %#v", comm.StartCmd.Command)
|
||||
}
|
||||
|
||||
// Clean up the created test output directory
|
||||
dir := state.Get("dir").(*LocalOutputDir)
|
||||
if err := dir.RemoveAll(); err != nil {
|
||||
t.Fatalf("Error cleaning up directory: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepShutdown_noCommand(t *testing.T) {
|
||||
state := testStepShutdownState(t)
|
||||
step := new(StepShutdown)
|
||||
|
||||
comm := state.Get("communicator").(*packersdk.MockCommunicator)
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.StopCalled {
|
||||
t.Fatal("stop should be called")
|
||||
}
|
||||
if driver.StopPath != "foo" {
|
||||
t.Fatal("should call with right path")
|
||||
}
|
||||
|
||||
if comm.StartCalled {
|
||||
t.Fatal("start should not be called")
|
||||
}
|
||||
|
||||
// Clean up the created test output directory
|
||||
dir := state.Get("dir").(*LocalOutputDir)
|
||||
if err := dir.RemoveAll(); err != nil {
|
||||
t.Fatalf("Error cleaning up directory: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepShutdown_locks(t *testing.T) {
|
||||
if os.Getenv("PACKER_ACC") == "" {
|
||||
t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.")
|
||||
}
|
||||
|
||||
state := testStepShutdownState(t)
|
||||
step := new(StepShutdown)
|
||||
step.Testing = true
|
||||
|
||||
dir := state.Get("dir").(*LocalOutputDir)
|
||||
comm := state.Get("communicator").(*packersdk.MockCommunicator)
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Create some lock files
|
||||
lockPath := filepath.Join(dir.dir, "nope.lck")
|
||||
err := ioutil.WriteFile(lockPath, []byte("foo"), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Remove the lock file after a certain time
|
||||
go func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
os.Remove(lockPath)
|
||||
}()
|
||||
|
||||
resultCh := make(chan multistep.StepAction, 1)
|
||||
go func() {
|
||||
resultCh <- step.Run(context.Background(), state)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-resultCh:
|
||||
t.Fatal("should not have returned so quickly")
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
}
|
||||
|
||||
var action multistep.StepAction
|
||||
select {
|
||||
case action = <-resultCh:
|
||||
case <-time.After(300 * time.Millisecond):
|
||||
t.Fatal("should've returned by now")
|
||||
}
|
||||
|
||||
// Test the run
|
||||
if action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.StopCalled {
|
||||
t.Fatal("stop should be called")
|
||||
}
|
||||
if driver.StopPath != "foo" {
|
||||
t.Fatal("should call with right path")
|
||||
}
|
||||
|
||||
if comm.StartCalled {
|
||||
t.Fatal("start should not be called")
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepSuppressMessages_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepSuppressMessages)
|
||||
}
|
||||
|
||||
func TestStepSuppressMessages(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepSuppressMessages)
|
||||
|
||||
state.Put("vmx_path", "foo")
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test the driver
|
||||
if !driver.SuppressMessagesCalled {
|
||||
t.Fatal("should've called")
|
||||
}
|
||||
if driver.SuppressMessagesPath != "foo" {
|
||||
t.Fatal("should call with right path")
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func testState(t *testing.T) multistep.StateBag {
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("driver", new(DriverMock))
|
||||
state.Put("ui", &packersdk.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
})
|
||||
state.Put("temporaryDevices", []string{})
|
||||
return state
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
# this entry is normal
|
||||
{
|
||||
ip_address=127.0.0.17
|
||||
hw_address=1,d:ea:d0:66:77:88
|
||||
identifier=1,d:ea:d0:0:11:22
|
||||
lease=0x5fd78ae2
|
||||
name=vagrant-2019
|
||||
}
|
||||
|
||||
# this entry has tabs
|
||||
{
|
||||
ip_address=127.0.0.17
|
||||
hw_address=1,d:ea:d0:66:77:88
|
||||
identifier=1,d:ea:d0:33:44:55
|
||||
lease=0x5fd7b4e5
|
||||
name=vagrant-2019
|
||||
}
|
||||
|
||||
# These next two entries have the same address, but different uids
|
||||
{
|
||||
ip_address=127.0.0.19
|
||||
hw_address=1,d:ea:d0:66:77:88
|
||||
identifier=1,d:ea:d0:66:77:88
|
||||
lease=0x5fd72edc
|
||||
name=vagrant-2019
|
||||
}
|
||||
{
|
||||
ip_address=127.0.0.19
|
||||
hw_address=1,d:ea:d0:99:aa:bb
|
||||
identifier=1,d:ea:d0:99:aa:bb
|
||||
lease=0x5fd72edc
|
||||
name=vagrant-2019
|
||||
}
|
||||
|
||||
# this entry does not have all fields
|
||||
{
|
||||
ip_address=127.0.0.20
|
||||
hw_address=1,d:ea:d0:99:aa:bc
|
||||
identifier=1,d:ea:d0:99:aa:bc
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
allow unknown-clients; # global.grants
|
||||
default-lease-time 1800; # global.parameters
|
||||
max-lease-time 7200; # global.parameters
|
||||
|
||||
subnet 172.33.33.0 netmask 255.255.255.0 { # subnet4
|
||||
range 172.33.33.128 172.33.33.254; # subnet4.address
|
||||
option broadcast-address 172.33.33.255; # subnet4.options
|
||||
# allow unknown-clients; # subnet4.grants
|
||||
default-lease-time 2400; # subnet4.parameters
|
||||
max-lease-time 9600; # subnet4.parameters
|
||||
option routers 172.33.33.2; # subnet4.options
|
||||
}
|
||||
host vmnet8 { # host
|
||||
hardware ethernet 00:50:56:C0:00:08; # host.address
|
||||
fixed-address 172.33.33.1; # host.address
|
||||
option domain-name "packer.test"; # host.options
|
||||
# allow unknown-clients; # subnet4.grants
|
||||
# default-lease-time 1800; # subnet4.parameters
|
||||
# max-lease-time 7200; # subnet4.parameters
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
# This entry is normal
|
||||
lease 127.0.0.17 {
|
||||
starts 3 2020/05/13 12:00:37;
|
||||
ends 3 2020/05/13 12:30:37;
|
||||
hardware ethernet 0d:ea:d0:66:77:88;
|
||||
uid 01:0d:ea:d0:00:11:22;
|
||||
}
|
||||
|
||||
# This entry has tabs
|
||||
lease 127.0.0.17 {
|
||||
starts 6 2020/06/12 22:28:54;
|
||||
ends 6 2020/06/12 22:58:54;
|
||||
hardware ethernet 0d:ea:d0:66:77:88;
|
||||
uid 01:0d:ea:d0:33:44:55;
|
||||
}
|
||||
|
||||
# These next two entries have the same address, but different uids
|
||||
lease 127.0.0.19 {
|
||||
starts 4 2020/05/28 11:35:06;
|
||||
ends 4 2020/05/28 12:05:06;
|
||||
hardware ethernet 0d:ea:d0:66:77:88;
|
||||
uid 01:0d:ea:d0:66:77:88;
|
||||
client-hostname "VAGRANT-ADA-LUZ";
|
||||
}
|
||||
|
||||
lease 127.0.0.19 {
|
||||
starts 5 2020/08/20 20:32:03;
|
||||
ends 5 2020/08/20 21:02:03;
|
||||
hardware ethernet 0d:ea:d0:99:aa:bb;
|
||||
uid 01:0d:ea:d0:99:aa:bb;
|
||||
client-hostname "WINDOWS-SQABBAS";
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
network8.device = "vmnet8"
|
||||
network0.name = "Bridged"
|
||||
network2.device = "vmnet57005"
|
||||
network3.name = "butneeds"
|
||||
network0.device = "vmnet0"
|
||||
network1.name = "HostOnly"
|
||||
network8.name = "NAT"
|
||||
network1.device = "vmnet1"
|
||||
network3.notuseful = "blah"
|
||||
network3.device = "nameanddevice"
|
||||
network2.name = "bleep bloop"
|
||||
@@ -1,19 +0,0 @@
|
||||
VERSION=1,0
|
||||
answer VNET_1_DHCP yes
|
||||
answer VNET_1_DHCP_CFG_HASH 01F4CE0D79A1599698B6E5814CCB68058BB0ED5E
|
||||
answer VNET_1_HOSTONLY_NETMASK 255.255.255.0
|
||||
answer VNET_1_HOSTONLY_SUBNET 192.168.70.0
|
||||
answer VNET_1_NAT no
|
||||
answer VNET_1_VIRTUAL_ADAPTER yes
|
||||
answer VNET_8_DHCP yes
|
||||
answer VNET_8_DHCP_CFG_HASH C30F14F65A0FE4B5DCC6C67497D7A8A33E5E538C
|
||||
answer VNET_8_HOSTONLY_NETMASK 255.255.255.0
|
||||
answer VNET_8_HOSTONLY_SUBNET 172.16.41.0
|
||||
answer VNET_8_NAT yes
|
||||
answer VNET_8_VIRTUAL_ADAPTER yes
|
||||
add_nat_portfwd 8 tcp 2200 172.16.41.129 3389
|
||||
add_nat_portfwd 8 tcp 2201 172.16.41.129 3389
|
||||
add_nat_portfwd 8 tcp 2222 172.16.41.129 22
|
||||
add_nat_portfwd 8 tcp 3389 172.16.41.131 3389
|
||||
add_nat_portfwd 8 tcp 55985 172.16.41.129 5985
|
||||
add_nat_portfwd 8 tcp 55986 172.16.41.129 5986
|
||||
@@ -1,65 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func TestToolsConfigPrepare_Empty(t *testing.T) {
|
||||
c := &ToolsConfig{}
|
||||
|
||||
errs := c.Prepare(interpolate.NewContext())
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if c.ToolsUploadPath != "{{ .Flavor }}.iso" {
|
||||
t.Fatal("should have defaulted tools upload path")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToolsConfigPrepare_SetUploadPath(t *testing.T) {
|
||||
c := &ToolsConfig{
|
||||
ToolsUploadPath: "path/to/tools.iso",
|
||||
}
|
||||
|
||||
errs := c.Prepare(interpolate.NewContext())
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("err: %#v", errs)
|
||||
}
|
||||
|
||||
if c.ToolsUploadPath != "path/to/tools.iso" {
|
||||
t.Fatal("should have used given tools upload path")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToolsConfigPrepare_ErrorIfOnlySource(t *testing.T) {
|
||||
c := &ToolsConfig{
|
||||
ToolsSourcePath: "path/to/tools.iso",
|
||||
}
|
||||
|
||||
errs := c.Prepare(interpolate.NewContext())
|
||||
if len(errs) != 1 {
|
||||
t.Fatalf("Should have received an error because the flavor and " +
|
||||
"upload path aren't set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToolsConfigPrepare_SourceSuccess(t *testing.T) {
|
||||
for _, c := range []*ToolsConfig{
|
||||
&ToolsConfig{
|
||||
ToolsSourcePath: "path/to/tools.iso",
|
||||
ToolsUploadPath: "partypath.iso",
|
||||
},
|
||||
&ToolsConfig{
|
||||
ToolsSourcePath: "path/to/tools.iso",
|
||||
ToolsUploadFlavor: "linux",
|
||||
},
|
||||
} {
|
||||
errs := c.Prepare(interpolate.NewContext())
|
||||
if len(errs) != 0 {
|
||||
t.Fatalf("Should not have received an error")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
func TestVMXConfigPrepare(t *testing.T) {
|
||||
c := new(VMXConfig)
|
||||
c.VMXData = map[string]string{
|
||||
"one": "foo",
|
||||
"two": "bar",
|
||||
}
|
||||
|
||||
errs := c.Prepare(interpolate.NewContext())
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("bad: %#v", errs)
|
||||
}
|
||||
|
||||
if len(c.VMXData) != 2 {
|
||||
t.Fatal("should have two items in VMXData")
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package common
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseVMX(t *testing.T) {
|
||||
contents := `
|
||||
.encoding = "UTF-8"
|
||||
config.version = "8"
|
||||
scsi0:0.virtualSSD = 1
|
||||
`
|
||||
|
||||
results := ParseVMX(contents)
|
||||
if len(results) != 3 {
|
||||
t.Fatalf("not correct number of results: %d", len(results))
|
||||
}
|
||||
|
||||
if results[".encoding"] != "UTF-8" {
|
||||
t.Errorf("invalid .encoding: %s", results[".encoding"])
|
||||
}
|
||||
|
||||
if results["config.version"] != "8" {
|
||||
t.Errorf("invalid config.version: %s", results["config.version"])
|
||||
}
|
||||
|
||||
if results["scsi0:0.virtualssd"] != "1" {
|
||||
t.Errorf("invalid scsi0:0.virtualssd: %s", results["scsi0:0.virtualssd"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeVMX(t *testing.T) {
|
||||
contents := map[string]string{
|
||||
".encoding": "UTF-8",
|
||||
"config.version": "8",
|
||||
"scsi0:0.virtualssd": "1",
|
||||
}
|
||||
|
||||
expected := `.encoding = "UTF-8"
|
||||
config.version = "8"
|
||||
scsi0:0.virtualSSD = 1
|
||||
`
|
||||
|
||||
result := EncodeVMX(contents)
|
||||
if result != expected {
|
||||
t.Errorf("invalid results: %s", result)
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package iso
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/acctest"
|
||||
"github.com/hashicorp/packer-plugin-sdk/acctest/testutils"
|
||||
)
|
||||
|
||||
func TestBuilderAcc_basic(t *testing.T) {
|
||||
templatePath := filepath.Join("testdata", "minimal.json")
|
||||
bytes, err := ioutil.ReadFile(templatePath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load template file %s", templatePath)
|
||||
}
|
||||
|
||||
testCase := &acctest.PluginTestCase{
|
||||
Name: "vmware-iso_builder_basic_test",
|
||||
Setup: func() error {
|
||||
return nil
|
||||
},
|
||||
Teardown: func() error {
|
||||
testutils.CleanupFiles("output-vmware-iso", "packer_cache")
|
||||
return nil
|
||||
},
|
||||
Template: string(bytes),
|
||||
Type: "vmware-iso",
|
||||
Check: func(buildCommand *exec.Cmd, logfile string) error {
|
||||
if buildCommand.ProcessState != nil {
|
||||
if buildCommand.ProcessState.ExitCode() != 0 {
|
||||
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
acctest.TestPlugin(t, testCase)
|
||||
}
|
||||
@@ -1,651 +0,0 @@
|
||||
package iso
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func testConfig() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"iso_checksum": "md5:0B0F137F17AC10944716020B018F8126",
|
||||
"iso_url": "http://www.packer.io",
|
||||
"shutdown_command": "foo",
|
||||
"ssh_username": "foo",
|
||||
|
||||
common.BuildNameConfigKey: "foo",
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilder_ImplementsBuilder(t *testing.T) {
|
||||
var raw interface{}
|
||||
raw = &Builder{}
|
||||
if _, ok := raw.(packersdk.Builder); !ok {
|
||||
t.Error("Builder must implement builder.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_Defaults(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.DiskName != "disk" {
|
||||
t.Errorf("bad disk name: %s", b.config.DiskName)
|
||||
}
|
||||
|
||||
if b.config.OutputDir != "output-foo" {
|
||||
t.Errorf("bad output dir: %s", b.config.OutputDir)
|
||||
}
|
||||
|
||||
if b.config.Version != "9" {
|
||||
t.Errorf("bad Version: %s", b.config.Version)
|
||||
}
|
||||
|
||||
if b.config.VMName != "packer-foo" {
|
||||
t.Errorf("bad vm name: %s", b.config.VMName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_DiskSize(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
delete(config, "disk_size")
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("bad err: %s", err)
|
||||
}
|
||||
|
||||
if b.config.DiskSize != 40000 {
|
||||
t.Fatalf("bad size: %d", b.config.DiskSize)
|
||||
}
|
||||
|
||||
config["disk_size"] = 60000
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.DiskSize != 60000 {
|
||||
t.Fatalf("bad size: %d", b.config.DiskSize)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
delete(config, "floppy_files")
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("bad err: %s", err)
|
||||
}
|
||||
|
||||
if len(b.config.FloppyFiles) != 0 {
|
||||
t.Fatalf("bad: %#v", b.config.FloppyFiles)
|
||||
}
|
||||
|
||||
floppies_path := "../../test-fixtures/floppies"
|
||||
config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
|
||||
if !reflect.DeepEqual(b.config.FloppyFiles, expected) {
|
||||
t.Fatalf("bad: %#v", b.config.FloppyFiles)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||
|
||||
b = Builder{}
|
||||
_, _, errs := b.Prepare(config)
|
||||
if errs == nil {
|
||||
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||
}
|
||||
|
||||
if len(errs.(*packersdk.MultiError).Errors) != 2 {
|
||||
t.Fatalf("Multierror should work and report 2 errors")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_RemoteType(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
config["format"] = "ovf"
|
||||
config["remote_host"] = "foobar.example.com"
|
||||
config["remote_password"] = "supersecret"
|
||||
config["skip_validate_credentials"] = true
|
||||
// Bad
|
||||
config["remote_type"] = "foobar"
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
config["remote_type"] = "esx5"
|
||||
// Bad
|
||||
config["remote_host"] = ""
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Good
|
||||
config["remote_type"] = ""
|
||||
config["format"] = ""
|
||||
config["remote_host"] = ""
|
||||
config["remote_password"] = ""
|
||||
config["remote_private_key_file"] = ""
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Good
|
||||
config["remote_type"] = "esx5"
|
||||
config["remote_host"] = "foobar.example.com"
|
||||
config["remote_password"] = "supersecret"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_Export(t *testing.T) {
|
||||
type testCase struct {
|
||||
InputConfigVals map[string]string
|
||||
ExpectedSkipExportValue bool
|
||||
ExpectedFormat string
|
||||
ExpectedErr bool
|
||||
Reason string
|
||||
}
|
||||
testCases := []testCase{
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "",
|
||||
"format": "",
|
||||
},
|
||||
ExpectedSkipExportValue: true,
|
||||
ExpectedFormat: "vmx",
|
||||
ExpectedErr: false,
|
||||
Reason: "should have defaulted format to vmx.",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "esx5",
|
||||
"format": "",
|
||||
"remote_host": "fakehost.com",
|
||||
"remote_password": "fakepassword",
|
||||
"remote_username": "fakeuser",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ovf",
|
||||
ExpectedErr: false,
|
||||
Reason: "should have defaulted format to ovf with remote set to esx5.",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "esx5",
|
||||
"format": "",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ovf",
|
||||
ExpectedErr: true,
|
||||
Reason: "should have errored because remote host isn't set for remote build.",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "invalid",
|
||||
"format": "",
|
||||
"remote_host": "fakehost.com",
|
||||
"remote_password": "fakepassword",
|
||||
"remote_username": "fakeuser",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ovf",
|
||||
ExpectedErr: true,
|
||||
Reason: "should error with invalid remote type",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "",
|
||||
"format": "invalid",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "invalid",
|
||||
ExpectedErr: true,
|
||||
Reason: "should error with invalid format",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "",
|
||||
"format": "ova",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ova",
|
||||
ExpectedErr: false,
|
||||
Reason: "should set user-given ova format",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "esx5",
|
||||
"format": "ova",
|
||||
"remote_host": "fakehost.com",
|
||||
"remote_password": "fakepassword",
|
||||
"remote_username": "fakeuser",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ova",
|
||||
ExpectedErr: false,
|
||||
Reason: "should set user-given ova format",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
config := testConfig()
|
||||
for k, v := range tc.InputConfigVals {
|
||||
config[k] = v
|
||||
}
|
||||
config["skip_validate_credentials"] = true
|
||||
outCfg := &Config{}
|
||||
warns, errs := (outCfg).Prepare(config)
|
||||
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
||||
if (errs != nil) != tc.ExpectedErr {
|
||||
t.Fatalf("received error: \n %s \n but 'expected err' was %t", errs, tc.ExpectedErr)
|
||||
}
|
||||
|
||||
if outCfg.Format != tc.ExpectedFormat {
|
||||
t.Fatalf("Expected: %s. Actual: %s. Reason: %s", tc.ExpectedFormat,
|
||||
outCfg.Format, tc.Reason)
|
||||
}
|
||||
if outCfg.SkipExport != tc.ExpectedSkipExportValue {
|
||||
t.Fatalf("For SkipExport expected %t but recieved %t",
|
||||
tc.ExpectedSkipExportValue, outCfg.SkipExport)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_RemoteExport(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
config["remote_type"] = "esx5"
|
||||
config["remote_host"] = "foobar.example.com"
|
||||
config["skip_validate_credentials"] = true
|
||||
// Bad
|
||||
config["remote_password"] = ""
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) != 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Good
|
||||
config["remote_password"] = "supersecret"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) != 0 {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_Format(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Bad
|
||||
config["format"] = "foobar"
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
goodFormats := []string{"ova", "ovf", "vmx"}
|
||||
|
||||
for _, format := range goodFormats {
|
||||
// Good
|
||||
config["format"] = format
|
||||
config["remote_type"] = "esx5"
|
||||
config["remote_host"] = "hosty.hostface"
|
||||
config["remote_password"] = "password"
|
||||
config["skip_validate_credentials"] = true
|
||||
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Add a random key
|
||||
config["i_should_not_be_valid"] = true
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_OutputDir(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test with existing dir
|
||||
dir, err := ioutil.TempDir("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
config["output_directory"] = dir
|
||||
b = Builder{}
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Test with a good one
|
||||
config["output_directory"] = "i-hope-i-dont-exist"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_ToolsUploadPath(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test a default
|
||||
delete(config, "tools_upload_path")
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if b.config.ToolsUploadPath == "" {
|
||||
t.Fatalf("bad value: %s", b.config.ToolsUploadPath)
|
||||
}
|
||||
|
||||
// Test with a bad value
|
||||
config["tools_upload_path"] = "{{{nope}"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test with a good one
|
||||
config["tools_upload_path"] = "hey"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_VMXTemplatePath(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test bad
|
||||
config["vmx_template_path"] = "/i/dont/exist/forreal"
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test good
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Remove(tf.Name())
|
||||
defer tf.Close()
|
||||
|
||||
if _, err := tf.Write([]byte("HELLO!")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
config["vmx_template_path"] = tf.Name()
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Bad template
|
||||
tf2, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Remove(tf2.Name())
|
||||
defer tf2.Close()
|
||||
|
||||
if _, err := tf2.Write([]byte("{{foo}")); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
config["vmx_template_path"] = tf2.Name()
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_VNCPort(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Bad
|
||||
config["vnc_port_min"] = 1000
|
||||
config["vnc_port_max"] = 500
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Bad
|
||||
config["vnc_port_min"] = -500
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Good
|
||||
config["vnc_port_min"] = 500
|
||||
config["vnc_port_max"] = 1000
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderCheckCollisions(t *testing.T) {
|
||||
config := testConfig()
|
||||
config["vmx_data"] = map[string]string{
|
||||
"no.collision": "awesomesauce",
|
||||
"ide0:0.fileName": "is a collision",
|
||||
"displayName": "also a collision",
|
||||
}
|
||||
{
|
||||
var b Builder
|
||||
_, warns, _ := b.Prepare(config)
|
||||
if len(warns) != 1 {
|
||||
t.Fatalf("Should have warning about two collisions.")
|
||||
}
|
||||
}
|
||||
{
|
||||
config["vmx_template_path"] = "some/path.vmx"
|
||||
var b Builder
|
||||
_, warns, _ := b.Prepare(config)
|
||||
if len(warns) != 0 {
|
||||
t.Fatalf("Should not check for collisions with custom template.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_CommConfig(t *testing.T) {
|
||||
// Test Winrm
|
||||
{
|
||||
config := testConfig()
|
||||
config["communicator"] = "winrm"
|
||||
config["winrm_username"] = "username"
|
||||
config["winrm_password"] = "password"
|
||||
config["winrm_host"] = "1.2.3.4"
|
||||
|
||||
var b Builder
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.SSHConfig.Comm.WinRMUser != "username" {
|
||||
t.Errorf("bad winrm_username: %s", b.config.SSHConfig.Comm.WinRMUser)
|
||||
}
|
||||
if b.config.SSHConfig.Comm.WinRMPassword != "password" {
|
||||
t.Errorf("bad winrm_password: %s", b.config.SSHConfig.Comm.WinRMPassword)
|
||||
}
|
||||
if host := b.config.SSHConfig.Comm.Host(); host != "1.2.3.4" {
|
||||
t.Errorf("bad host: %s", host)
|
||||
}
|
||||
}
|
||||
|
||||
// Test SSH
|
||||
{
|
||||
config := testConfig()
|
||||
config["communicator"] = "ssh"
|
||||
config["ssh_username"] = "username"
|
||||
config["ssh_password"] = "password"
|
||||
config["ssh_host"] = "1.2.3.4"
|
||||
|
||||
var b Builder
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.SSHConfig.Comm.SSHUsername != "username" {
|
||||
t.Errorf("bad ssh_username: %s", b.config.SSHConfig.Comm.SSHUsername)
|
||||
}
|
||||
if b.config.SSHConfig.Comm.SSHPassword != "password" {
|
||||
t.Errorf("bad ssh_password: %s", b.config.SSHConfig.Comm.SSHPassword)
|
||||
}
|
||||
if host := b.config.SSHConfig.Comm.Host(); host != "1.2.3.4" {
|
||||
t.Errorf("bad host: %s", host)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,339 +0,0 @@
|
||||
package iso
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer-plugin-sdk/tmp"
|
||||
builderT "github.com/hashicorp/packer/acctest"
|
||||
)
|
||||
|
||||
const vmxTestTemplate string = `{"builders":[{%s}],"provisioners":[{%s}]}`
|
||||
|
||||
func createFloppyOutput(prefix string) (string, map[string]string, error) {
|
||||
f, err := tmp.File(prefix)
|
||||
if err != nil {
|
||||
return "", map[string]string{}, fmt.Errorf("unable to create temp file")
|
||||
}
|
||||
f.Close()
|
||||
|
||||
output := f.Name()
|
||||
outputFile := strings.Replace(output, "\\", "\\\\", -1)
|
||||
vmxData := map[string]string{
|
||||
"floppy0.present": "TRUE",
|
||||
"floppy0.fileType": "file",
|
||||
"floppy0.clientDevice": "FALSE",
|
||||
"floppy0.fileName": outputFile,
|
||||
"floppy0.startConnected": "TRUE",
|
||||
}
|
||||
return output, vmxData, nil
|
||||
}
|
||||
|
||||
func readFloppyOutput(path string) (string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to open file %s", path)
|
||||
}
|
||||
defer f.Close()
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to read file: %s", err)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
return string(data[:bytes.IndexByte(data, 0)]), nil
|
||||
}
|
||||
|
||||
// RenderConfig helps create dynamic packer template configs for parsing by
|
||||
// builderT without having to write the config to a file.
|
||||
func RenderConfig(builderConfig map[string]interface{}, provisionerConfig map[string]string) string {
|
||||
// set up basic build template
|
||||
t := map[string][]map[string]interface{}{
|
||||
"builders": {
|
||||
map[string]interface{}{
|
||||
"type": "test",
|
||||
"iso_url": "https://archive.org/download/ut-ttylinux-i686-12.6/ut-ttylinux-i686-12.6.iso",
|
||||
"iso_checksum": "md5:43c1feeae55a44c6ef694b8eb18408a6",
|
||||
"ssh_username": "root",
|
||||
"ssh_password": "password",
|
||||
"ssh_wait_timeout": "45s",
|
||||
"boot_command": []string{"<enter><wait5><wait10>", "root<enter><wait>password<enter><wait>", "udhcpc<enter><wait>"},
|
||||
"shutdown_command": "/sbin/shutdown -h; exit 0",
|
||||
"ssh_key_exchange_algorithms": []string{"diffie-hellman-group1-sha1"},
|
||||
},
|
||||
},
|
||||
"provisioners": {
|
||||
map[string]interface{}{
|
||||
"type": "shell",
|
||||
"inline": []string{"echo hola mundo"},
|
||||
},
|
||||
},
|
||||
}
|
||||
// apply special builder overrides
|
||||
for k, v := range builderConfig {
|
||||
t["builders"][0][k] = v
|
||||
}
|
||||
// Apply special provisioner overrides
|
||||
for k, v := range provisionerConfig {
|
||||
t["provisioners"][0][k] = v
|
||||
}
|
||||
|
||||
j, _ := json.Marshal(t)
|
||||
return string(j)
|
||||
}
|
||||
|
||||
func TestStepCreateVmx_SerialFile(t *testing.T) {
|
||||
if os.Getenv("PACKER_ACC") == "" {
|
||||
t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.")
|
||||
}
|
||||
|
||||
tmpfile, err := tmp.File("SerialFileInput.")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create temp file")
|
||||
}
|
||||
serialConfig := map[string]interface{}{
|
||||
"serial": fmt.Sprintf("file:%s", filepath.ToSlash(tmpfile.Name())),
|
||||
}
|
||||
|
||||
configString := RenderConfig(serialConfig, map[string]string{})
|
||||
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
Builder: &Builder{},
|
||||
Template: configString,
|
||||
Check: func(a []packersdk.Artifact) error {
|
||||
_, err := os.Stat(tmpfile.Name())
|
||||
if err != nil {
|
||||
return fmt.Errorf("VMware builder did not create a file for serial port: %s", err)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Teardown: func() error {
|
||||
f, _ := os.Stat(tmpfile.Name())
|
||||
if f != nil {
|
||||
if err := os.Remove(tmpfile.Name()); err != nil {
|
||||
return fmt.Errorf("Unable to remove file %s: %s", tmpfile.Name(), err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStepCreateVmx_SerialPort(t *testing.T) {
|
||||
if os.Getenv("PACKER_ACC") == "" {
|
||||
t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.")
|
||||
}
|
||||
|
||||
var defaultSerial string
|
||||
if runtime.GOOS == "windows" {
|
||||
defaultSerial = "COM1"
|
||||
} else {
|
||||
defaultSerial = "/dev/ttyS0"
|
||||
}
|
||||
|
||||
config := map[string]interface{}{
|
||||
"serial": fmt.Sprintf("device:%s", filepath.ToSlash(defaultSerial)),
|
||||
}
|
||||
provision := map[string]string{
|
||||
"inline": "dmesg | egrep -o '^serial8250: ttyS1 at' > /dev/fd0",
|
||||
}
|
||||
|
||||
// where to write output
|
||||
output, vmxData, err := createFloppyOutput("SerialPortOutput.")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating output: %s", err)
|
||||
}
|
||||
|
||||
config["vmx_data"] = vmxData
|
||||
configString := RenderConfig(config, provision)
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
Builder: &Builder{},
|
||||
Template: configString,
|
||||
Check: func(a []packersdk.Artifact) error {
|
||||
_, err := os.Stat(output)
|
||||
if err != nil {
|
||||
return fmt.Errorf("VMware builder did not create a file for serial port: %s", err)
|
||||
}
|
||||
// check the output
|
||||
data, err := readFloppyOutput(output)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s", err)
|
||||
}
|
||||
|
||||
if data != "serial8250: ttyS1 at\n" {
|
||||
return fmt.Errorf("Serial port not detected : %v", data)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Teardown: func() error {
|
||||
if _, err := os.Stat(output); err == nil {
|
||||
os.Remove(output)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStepCreateVmx_ParallelPort(t *testing.T) {
|
||||
if os.Getenv("PACKER_ACC") == "" {
|
||||
t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.")
|
||||
}
|
||||
|
||||
var defaultParallel string
|
||||
if runtime.GOOS == "windows" {
|
||||
defaultParallel = "LPT1"
|
||||
} else {
|
||||
defaultParallel = "/dev/lp0"
|
||||
}
|
||||
|
||||
config := map[string]interface{}{
|
||||
"parallel": fmt.Sprintf("device:%s,uni", filepath.ToSlash(defaultParallel)),
|
||||
}
|
||||
provision := map[string]string{
|
||||
"inline": "cat /proc/modules | egrep -o '^parport ' > /dev/fd0",
|
||||
}
|
||||
|
||||
// where to write output
|
||||
output, vmxData, err := createFloppyOutput("ParallelPortOutput.")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating output: %s", err)
|
||||
}
|
||||
|
||||
config["vmx_data"] = vmxData
|
||||
configString := RenderConfig(config, provision)
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
Builder: &Builder{},
|
||||
Template: configString,
|
||||
Check: func(a []packersdk.Artifact) error {
|
||||
_, err := os.Stat(output)
|
||||
if err != nil {
|
||||
return fmt.Errorf("VMware builder did not create a file for serial port: %s", err)
|
||||
}
|
||||
// check the output
|
||||
data, err := readFloppyOutput(output)
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
}
|
||||
|
||||
if data != "parport \n" {
|
||||
t.Errorf("Parallel port not detected : %v", data)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Teardown: func() error {
|
||||
if _, err := os.Stat(output); err == nil {
|
||||
os.Remove(output)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStepCreateVmx_Usb(t *testing.T) {
|
||||
if os.Getenv("PACKER_ACC") == "" {
|
||||
t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.")
|
||||
}
|
||||
|
||||
config := map[string]interface{}{
|
||||
"usb": "TRUE",
|
||||
}
|
||||
provision := map[string]string{
|
||||
"inline": "dmesg | egrep -m1 -o 'USB hub found$' > /dev/fd0",
|
||||
}
|
||||
|
||||
output, vmxData, err := createFloppyOutput("UsbOutput.")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating output: %s", err)
|
||||
}
|
||||
|
||||
config["vmx_data"] = vmxData
|
||||
configString := RenderConfig(config, provision)
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
Builder: &Builder{},
|
||||
Template: configString,
|
||||
Check: func(a []packersdk.Artifact) error {
|
||||
_, err := os.Stat(output)
|
||||
if err != nil {
|
||||
return fmt.Errorf("VMware builder did not create a file for serial port: %s", err)
|
||||
}
|
||||
// check the output
|
||||
data, err := readFloppyOutput(output)
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
}
|
||||
|
||||
if data != "USB hub found\n" {
|
||||
t.Errorf("USB support not detected : %v", data)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Teardown: func() error {
|
||||
if _, err := os.Stat(output); err == nil {
|
||||
os.Remove(output)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStepCreateVmx_Sound(t *testing.T) {
|
||||
if os.Getenv("PACKER_ACC") == "" {
|
||||
t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.")
|
||||
}
|
||||
|
||||
config := map[string]interface{}{
|
||||
"sound": "TRUE",
|
||||
}
|
||||
provision := map[string]string{
|
||||
"inline": "cat /proc/modules | egrep -o '^soundcore' > /dev/fd0",
|
||||
}
|
||||
|
||||
// where to write output
|
||||
output, vmxData, err := createFloppyOutput("SoundOutput.")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating output: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
if _, err := os.Stat(output); err == nil {
|
||||
os.Remove(output)
|
||||
}
|
||||
}()
|
||||
|
||||
config["vmx_data"] = vmxData
|
||||
configString := RenderConfig(config, provision)
|
||||
builderT.Test(t, builderT.TestCase{
|
||||
Builder: &Builder{},
|
||||
Template: configString,
|
||||
Check: func(a []packersdk.Artifact) error {
|
||||
_, err := os.Stat(output)
|
||||
if err != nil {
|
||||
return fmt.Errorf("VMware builder did not create a file for serial port: %s", err)
|
||||
}
|
||||
// check the output
|
||||
data, err := readFloppyOutput(output)
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
}
|
||||
|
||||
if data != "soundcore\n" {
|
||||
t.Errorf("Soundcard not detected : %v", data)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Teardown: func() error {
|
||||
if _, err := os.Stat(output); err == nil {
|
||||
os.Remove(output)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
# Preseeding only locale sets language, country and locale.
|
||||
d-i debian-installer/locale string en_US
|
||||
|
||||
# Keyboard selection.
|
||||
d-i console-setup/ask_detect boolean false
|
||||
d-i keyboard-configuration/xkb-keymap select us
|
||||
|
||||
choose-mirror-bin mirror/http/proxy string
|
||||
d-i base-installer/kernel/override-image string linux-server
|
||||
d-i clock-setup/utc boolean true
|
||||
d-i clock-setup/utc-auto boolean true
|
||||
d-i finish-install/reboot_in_progress note
|
||||
d-i grub-installer/only_debian boolean true
|
||||
d-i grub-installer/with_other_os boolean true
|
||||
d-i mirror/country string manual
|
||||
d-i mirror/http/directory string /ubuntu/
|
||||
d-i mirror/http/hostname string archive.ubuntu.com
|
||||
d-i mirror/http/proxy string
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
d-i partman/confirm_write_new_label boolean true
|
||||
d-i passwd/user-fullname string vagrant
|
||||
d-i passwd/user-uid string 1000
|
||||
d-i passwd/user-password password vagrant
|
||||
d-i passwd/user-password-again password vagrant
|
||||
d-i passwd/username string vagrant
|
||||
d-i pkgsel/include string openssh-server cryptsetup build-essential libssl-dev libreadline-dev zlib1g-dev linux-source dkms nfs-kernel-server nfs-common linux-headers-$(uname -r) perl
|
||||
d-i pkgsel/install-language-support boolean false
|
||||
d-i pkgsel/update-policy select none
|
||||
d-i pkgsel/upgrade select full-upgrade
|
||||
d-i time/zone string UTC
|
||||
d-i user-setup/allow-password-weak boolean true
|
||||
d-i user-setup/encrypt-home boolean false
|
||||
tasksel tasksel/first multiselect standard, server
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"builders": [
|
||||
{
|
||||
"type": "vmware-iso",
|
||||
"boot_command": [
|
||||
"<esc><wait>",
|
||||
"<esc><wait>",
|
||||
"<enter><wait>",
|
||||
"/install/vmlinuz<wait>",
|
||||
" initrd=/install/initrd.gz",
|
||||
" auto-install/enable=true",
|
||||
" debconf/priority=critical",
|
||||
" preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg<wait>",
|
||||
" -- <wait>",
|
||||
"<enter><wait>"
|
||||
],
|
||||
"boot_wait": "10s",
|
||||
"guest_os_type": "ubuntu-64",
|
||||
"http_directory": "./testdata/http",
|
||||
"iso_checksum": "sha256:946a6077af6f5f95a51f82fdc44051c7aa19f9cfc5f737954845a6050543d7c2",
|
||||
"iso_url": "http://old-releases.ubuntu.com/releases/14.04.1/ubuntu-14.04.1-server-amd64.iso",
|
||||
"shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now",
|
||||
"headless": true,
|
||||
"ssh_password": "vagrant",
|
||||
"ssh_username": "vagrant",
|
||||
"ssh_timeout": "10000s",
|
||||
"tools_upload_flavor": "linux"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer-plugin-sdk/version"
|
||||
packerVersion "github.com/hashicorp/packer/version"
|
||||
)
|
||||
|
||||
var VMwarePluginVersion *version.PluginVersion
|
||||
|
||||
func init() {
|
||||
VMwarePluginVersion = version.InitializePluginVersion(
|
||||
packerVersion.Version, packerVersion.VersionPrerelease)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package vmx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||
var b Builder
|
||||
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
defer os.Remove(tf.Name())
|
||||
|
||||
config := testConfig(t)
|
||||
config["source_path"] = tf.Name()
|
||||
|
||||
delete(config, "floppy_files")
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("bad err: %s", err)
|
||||
}
|
||||
|
||||
if len(b.config.FloppyFiles) != 0 {
|
||||
t.Fatalf("bad: %#v", b.config.FloppyFiles)
|
||||
}
|
||||
|
||||
floppies_path := "../../test-fixtures/floppies"
|
||||
config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
|
||||
if !reflect.DeepEqual(b.config.FloppyFiles, expected) {
|
||||
t.Fatalf("bad: %#v", b.config.FloppyFiles)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig(t)
|
||||
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||
b = Builder{}
|
||||
_, _, errs := b.Prepare(config)
|
||||
if errs == nil {
|
||||
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||
}
|
||||
|
||||
if len(errs.(*packersdk.MultiError).Errors) != 2 {
|
||||
t.Fatalf("Multierror should work and report 2 errors")
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
package vmx
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testConfig(t *testing.T) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"ssh_username": "foo",
|
||||
"shutdown_command": "foo",
|
||||
"source_path": "config_test.go",
|
||||
}
|
||||
}
|
||||
|
||||
func testConfigErr(t *testing.T, warns []string, err error) {
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
}
|
||||
|
||||
func testConfigOk(t *testing.T, warns []string, err error) {
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewConfig_sourcePath(t *testing.T) {
|
||||
// Bad
|
||||
cfg := testConfig(t)
|
||||
delete(cfg, "source_path")
|
||||
warns, errs := (&Config{}).Prepare(cfg)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Bad
|
||||
cfg = testConfig(t)
|
||||
cfg["source_path"] = "/i/dont/exist"
|
||||
warns, errs = (&Config{}).Prepare(cfg)
|
||||
testConfigErr(t, warns, errs)
|
||||
|
||||
// Good
|
||||
tf, err := ioutil.TempFile("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
defer os.Remove(tf.Name())
|
||||
|
||||
cfg = testConfig(t)
|
||||
cfg["source_path"] = tf.Name()
|
||||
warns, errs = (&Config{}).Prepare(cfg)
|
||||
testConfigOk(t, warns, errs)
|
||||
}
|
||||
|
||||
func TestNewConfig_exportConfig(t *testing.T) {
|
||||
type testCase struct {
|
||||
InputConfigVals map[string]string
|
||||
ExpectedSkipExportValue bool
|
||||
ExpectedFormat string
|
||||
ExpectedErr bool
|
||||
Reason string
|
||||
}
|
||||
testCases := []testCase{
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "",
|
||||
"format": "",
|
||||
},
|
||||
ExpectedSkipExportValue: true,
|
||||
ExpectedFormat: "vmx",
|
||||
ExpectedErr: false,
|
||||
Reason: "should have defaulted format to vmx.",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "esx5",
|
||||
"format": "",
|
||||
"remote_host": "fakehost.com",
|
||||
"remote_password": "fakepassword",
|
||||
"remote_username": "fakeuser",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ovf",
|
||||
ExpectedErr: false,
|
||||
Reason: "should have defaulted format to ovf with remote set to esx5.",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "esx5",
|
||||
"format": "",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ovf",
|
||||
ExpectedErr: true,
|
||||
Reason: "should have errored because remote host isn't set for remote build.",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "invalid",
|
||||
"format": "",
|
||||
"remote_host": "fakehost.com",
|
||||
"remote_password": "fakepassword",
|
||||
"remote_username": "fakeuser",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ovf",
|
||||
ExpectedErr: true,
|
||||
Reason: "should error with invalid remote type",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "",
|
||||
"format": "invalid",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "invalid",
|
||||
ExpectedErr: true,
|
||||
Reason: "should error with invalid format",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "",
|
||||
"format": "ova",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ova",
|
||||
ExpectedErr: false,
|
||||
Reason: "should set user-given ova format",
|
||||
},
|
||||
{
|
||||
InputConfigVals: map[string]string{
|
||||
"remote_type": "esx5",
|
||||
"format": "ova",
|
||||
"remote_host": "fakehost.com",
|
||||
"remote_password": "fakepassword",
|
||||
"remote_username": "fakeuser",
|
||||
},
|
||||
ExpectedSkipExportValue: false,
|
||||
ExpectedFormat: "ova",
|
||||
ExpectedErr: false,
|
||||
Reason: "should set user-given ova format",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
cfg := testConfig(t)
|
||||
for k, v := range tc.InputConfigVals {
|
||||
cfg[k] = v
|
||||
}
|
||||
cfg["skip_validate_credentials"] = true
|
||||
outCfg := &Config{}
|
||||
warns, errs := (outCfg).Prepare(cfg)
|
||||
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
|
||||
if (errs != nil) != tc.ExpectedErr {
|
||||
t.Fatalf("received error: \n %s \n but 'expected err' was %t", errs, tc.ExpectedErr)
|
||||
}
|
||||
|
||||
if outCfg.Format != tc.ExpectedFormat {
|
||||
t.Fatalf("Expected: %s. Actual: %s. Reason: %s", tc.ExpectedFormat,
|
||||
outCfg.Format, tc.Reason)
|
||||
}
|
||||
if outCfg.SkipExport != tc.ExpectedSkipExportValue {
|
||||
t.Fatalf("For SkipExport expected %t but recieved %t",
|
||||
tc.ExpectedSkipExportValue, outCfg.SkipExport)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package vmx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
scsiFilename = "scsiDisk.vmdk"
|
||||
sataFilename = "sataDisk.vmdk"
|
||||
nvmeFilename = "nvmeDisk.vmdk"
|
||||
ideFilename = "ideDisk.vmdk"
|
||||
)
|
||||
|
||||
func TestStepCloneVMX_impl(t *testing.T) {
|
||||
var _ multistep.Step = new(StepCloneVMX)
|
||||
}
|
||||
|
||||
func TestStepCloneVMX(t *testing.T) {
|
||||
// Setup some state
|
||||
td, err := ioutil.TempDir("", "packer")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
// Set up mock vmx file contents
|
||||
var testCloneVMX = fmt.Sprintf("scsi0:0.filename = \"%s\"\n"+
|
||||
"sata0:0.filename = \"%s\"\n"+
|
||||
"nvme0:0.filename = \"%s\"\n"+
|
||||
"ide1:0.filename = \"%s\"\n"+
|
||||
"ide0:0.filename = \"auto detect\"\n"+
|
||||
"ethernet0.connectiontype = \"nat\"\n", scsiFilename,
|
||||
sataFilename, nvmeFilename, ideFilename)
|
||||
|
||||
// Set up expected mock disk file paths
|
||||
diskFilenames := []string{scsiFilename, sataFilename, ideFilename, nvmeFilename}
|
||||
var diskFullPaths []string
|
||||
for _, diskFilename := range diskFilenames {
|
||||
diskFullPaths = append(diskFullPaths, filepath.Join(td, diskFilename))
|
||||
}
|
||||
|
||||
// Create the source
|
||||
sourcePath := filepath.Join(td, "source.vmx")
|
||||
if err := ioutil.WriteFile(sourcePath, []byte(testCloneVMX), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Create the dest because the mock driver won't
|
||||
destPath := filepath.Join(td, "foo.vmx")
|
||||
if err := ioutil.WriteFile(destPath, []byte(testCloneVMX), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
state := testState(t)
|
||||
step := new(StepCloneVMX)
|
||||
step.OutputDir = &td
|
||||
step.Path = sourcePath
|
||||
step.VMName = "foo"
|
||||
|
||||
driver := state.Get("driver").(*vmwcommon.DriverMock)
|
||||
|
||||
// Test the run
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
if _, ok := state.GetOk("error"); ok {
|
||||
t.Fatal("should NOT have error")
|
||||
}
|
||||
|
||||
// Test we cloned
|
||||
if !driver.CloneCalled {
|
||||
t.Fatal("should call clone")
|
||||
}
|
||||
|
||||
// Test that we have our paths
|
||||
if vmxPath, ok := state.GetOk("vmx_path"); !ok {
|
||||
t.Fatal("should set vmx_path")
|
||||
} else if vmxPath != destPath {
|
||||
t.Fatalf("bad path to vmx: %#v", vmxPath)
|
||||
}
|
||||
|
||||
if stateDiskPaths, ok := state.GetOk("disk_full_paths"); !ok {
|
||||
t.Fatal("should set disk_full_paths")
|
||||
} else {
|
||||
assert.ElementsMatchf(t, stateDiskPaths.([]string), diskFullPaths,
|
||||
"%s\nshould contain the same elements as:\n%s", stateDiskPaths.([]string), diskFullPaths)
|
||||
}
|
||||
|
||||
// Test we got the network type
|
||||
if networkType, ok := state.GetOk("vmnetwork"); !ok {
|
||||
t.Fatal("should set vmnetwork")
|
||||
} else if networkType != "nat" {
|
||||
t.Fatalf("bad network type: %#v", networkType)
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package vmx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
|
||||
)
|
||||
|
||||
func testState(t *testing.T) multistep.StateBag {
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("driver", new(vmwcommon.DriverMock))
|
||||
state.Put("ui", &packersdk.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
})
|
||||
return state
|
||||
}
|
||||
@@ -50,8 +50,6 @@ import (
|
||||
tritonbuilder "github.com/hashicorp/packer/builder/triton"
|
||||
uclouduhostbuilder "github.com/hashicorp/packer/builder/ucloud/uhost"
|
||||
vagrantbuilder "github.com/hashicorp/packer/builder/vagrant"
|
||||
vmwareisobuilder "github.com/hashicorp/packer/builder/vmware/iso"
|
||||
vmwarevmxbuilder "github.com/hashicorp/packer/builder/vmware/vmx"
|
||||
yandexbuilder "github.com/hashicorp/packer/builder/yandex"
|
||||
alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import"
|
||||
artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice"
|
||||
@@ -125,8 +123,6 @@ var Builders = map[string]packersdk.Builder{
|
||||
"triton": new(tritonbuilder.Builder),
|
||||
"ucloud-uhost": new(uclouduhostbuilder.Builder),
|
||||
"vagrant": new(vagrantbuilder.Builder),
|
||||
"vmware-iso": new(vmwareisobuilder.Builder),
|
||||
"vmware-vmx": new(vmwarevmxbuilder.Builder),
|
||||
"yandex": new(yandexbuilder.Builder),
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ import (
|
||||
virtualboxisobuilder "github.com/hashicorp/packer-plugin-virtualbox/builder/virtualbox/iso"
|
||||
virtualboxovfbuilder "github.com/hashicorp/packer-plugin-virtualbox/builder/virtualbox/ovf"
|
||||
virtualboxvmbuilder "github.com/hashicorp/packer-plugin-virtualbox/builder/virtualbox/vm"
|
||||
vmwareisobuilder "github.com/hashicorp/packer-plugin-vmware/builder/vmware/iso"
|
||||
vmwarevmxbuilder "github.com/hashicorp/packer-plugin-vmware/builder/vmware/vmx"
|
||||
vsphereclonebuilder "github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/clone"
|
||||
vsphereisobuilder "github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/iso"
|
||||
vspherepostprocessor "github.com/hashicorp/packer-plugin-vsphere/post-processor/vsphere"
|
||||
@@ -56,6 +58,8 @@ var VendoredBuilders = map[string]packersdk.Builder{
|
||||
"virtualbox-iso": new(virtualboxisobuilder.Builder),
|
||||
"virtualbox-ovf": new(virtualboxovfbuilder.Builder),
|
||||
"virtualbox-vm": new(virtualboxvmbuilder.Builder),
|
||||
"vmware-iso": new(vmwareisobuilder.Builder),
|
||||
"vmware-vmx": new(vmwarevmxbuilder.Builder),
|
||||
}
|
||||
|
||||
// VendoredProvisioners are provisioner components that were once bundled with the
|
||||
|
||||
@@ -52,7 +52,8 @@ require (
|
||||
github.com/hashicorp/packer-plugin-googlecompute v0.0.1
|
||||
github.com/hashicorp/packer-plugin-sdk v0.2.0
|
||||
github.com/hashicorp/packer-plugin-virtualbox v0.0.1
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.0-20210415100050-d0269b5646e6
|
||||
github.com/hashicorp/packer-plugin-vmware v0.0.1
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.1
|
||||
github.com/hetznercloud/hcloud-go v1.15.1
|
||||
github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4
|
||||
github.com/jdcloud-api/jdcloud-sdk-go v1.9.1-0.20190605102154-3d81a50ca961
|
||||
@@ -82,18 +83,17 @@ require (
|
||||
github.com/ucloud/ucloud-sdk-go v0.16.3
|
||||
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6
|
||||
github.com/ulikunitz/xz v0.5.6
|
||||
github.com/vmware/govmomi v0.24.1
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20200915125933-33de72a328bd
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20200921111412-ef15ded2014c
|
||||
github.com/zclconf/go-cty v1.8.1
|
||||
github.com/zclconf/go-cty-yaml v1.0.1
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc
|
||||
golang.org/x/mod v0.4.1
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4
|
||||
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44
|
||||
golang.org/x/tools v0.1.0
|
||||
google.golang.org/grpc v1.36.1
|
||||
)
|
||||
|
||||
@@ -452,6 +452,7 @@ github.com/hashicorp/packer v1.6.7-0.20210208125835-f616955ebcb6/go.mod h1:7f5Zp
|
||||
github.com/hashicorp/packer v1.6.7-0.20210217093213-201869d627bf/go.mod h1:+EWPPcqee4h8S/y913Dnta1eJkgiqsGXBQgB75A2qV0=
|
||||
github.com/hashicorp/packer v1.7.0/go.mod h1:3KRJcwOctl2JaAGpQMI1bWQRArfWNWqcYjO6AOsVVGQ=
|
||||
github.com/hashicorp/packer v1.7.1/go.mod h1:ApnmMINvuhhnfPyTVqZu6jznDWPVYDJUw7e188DFCmo=
|
||||
github.com/hashicorp/packer v1.7.2/go.mod h1:c/QB/DWK5fSdtNWrTb9etWacmbm01UY23ZILpGundCY=
|
||||
github.com/hashicorp/packer-plugin-amazon v0.0.1 h1:EuyjNK9bL7WhQeIJzhBJxOx8nyc61ai5UbOsb1PIVwI=
|
||||
github.com/hashicorp/packer-plugin-amazon v0.0.1/go.mod h1:12c9msibyHdId+Mk/pCbdRb1KaLIhaNyxeJ6n8bZt30=
|
||||
github.com/hashicorp/packer-plugin-ansible v0.0.2 h1:nvBtCedXhUI5T6Up5+bmhlY7rmk8FjWuFv9A2joK7TU=
|
||||
@@ -471,15 +472,18 @@ github.com/hashicorp/packer-plugin-sdk v0.0.14/go.mod h1:tNb3XzJPnjMl3QuUdKmF47B
|
||||
github.com/hashicorp/packer-plugin-sdk v0.1.0/go.mod h1:CFsC20uZjtER/EnTn/CSMKD0kEdkqOVev8mtOmfnZiI=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.1.1/go.mod h1:1d3nqB9LUsXMQaNUiL67Q+WYEtjsVcLNTX8ikVlpBrc=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.1.2/go.mod h1:KRjczE1/c9NV5Re+PXt3myJsVTI/FxEHpZjRjOH0Fug=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.1.3-0.20210407232143-c217d82aefb6/go.mod h1:xePpgQgQYv/bamiypx3hH9ukidxDdcN8q0R0wLi8IEQ=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.1.3/go.mod h1:xePpgQgQYv/bamiypx3hH9ukidxDdcN8q0R0wLi8IEQ=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.2.0 h1:A4Dq7p4y1vscY4gMzp7GQaXyDJYYhP4ukp4fapPSOY4=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.2.0/go.mod h1:0DiOMEBldmB0HEhp0npFSSygC8bIvW43pphEgWkp2WU=
|
||||
github.com/hashicorp/packer-plugin-virtualbox v0.0.0-20210415132603-5d753f7335b4 h1:AQk/P0QydTRFda9br8Dv3DDv7DCjGLHwfLjXmudA900=
|
||||
github.com/hashicorp/packer-plugin-virtualbox v0.0.0-20210415132603-5d753f7335b4/go.mod h1:OOGNMK8Y8zjsYngesZH5kCbH0Fj8PKvhqPp8w1ejM3Y=
|
||||
github.com/hashicorp/packer-plugin-virtualbox v0.0.1 h1:vTfy7a10RUVMdNnDLo0EQrCVbAG4rGWkaDTMC7MVBi4=
|
||||
github.com/hashicorp/packer-plugin-virtualbox v0.0.1/go.mod h1:OOGNMK8Y8zjsYngesZH5kCbH0Fj8PKvhqPp8w1ejM3Y=
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.0-20210415100050-d0269b5646e6 h1:pOv7Apd4P3KEpNBHLV4E7tKlwHoInCU/bnPVadGSDxY=
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.0-20210415100050-d0269b5646e6/go.mod h1:XMhsLDDT7sD2BWaruLvGPynnn4IqdbrfvuKhb1GK1RI=
|
||||
github.com/hashicorp/packer-plugin-vmware v0.0.0-20210416150724-592c0637562a h1:LpZ+8Y1vozsI4vuAjUpUOEzFl+jNSY4SL1kfGkVMmb8=
|
||||
github.com/hashicorp/packer-plugin-vmware v0.0.0-20210416150724-592c0637562a/go.mod h1:NsiT4IOeDKf/aszQNX+/B1xHrfBR3RdUM3sSqANgNec=
|
||||
github.com/hashicorp/packer-plugin-vmware v0.0.1 h1:jRQAdjHwg3zeCBb52KoZsuxugrHcQhjgQln72o9eGgM=
|
||||
github.com/hashicorp/packer-plugin-vmware v0.0.1/go.mod h1:NsiT4IOeDKf/aszQNX+/B1xHrfBR3RdUM3sSqANgNec=
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.1 h1:4SUmRP+mGpBJHp6dLL4dmBCC+yDseTktb9YNLj11mVI=
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.1/go.mod h1:XMhsLDDT7sD2BWaruLvGPynnn4IqdbrfvuKhb1GK1RI=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/serf v0.9.2 h1:yJoyfZXo4Pk2p/M/viW+YLibBFiIbKoP79gu7kDAFP0=
|
||||
github.com/hashicorp/serf v0.9.2/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
@@ -778,8 +782,9 @@ golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA=
|
||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -861,8 +866,9 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d h1:BgJvlyh+UqCUaPlscHJ+PN8GcpfrFdr7NHjd1JL0+Gs=
|
||||
golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -943,8 +949,9 @@ golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -955,8 +962,9 @@ golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5f
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
|
||||
+373
@@ -0,0 +1,373 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
+1
-1
@@ -88,7 +88,7 @@ type Driver interface {
|
||||
// NewDriver returns a new driver implementation for this operating
|
||||
// system, or an error if the driver couldn't be initialized.
|
||||
func NewDriver(dconfig *DriverConfig, config *SSHConfig, vmName string) (Driver, error) {
|
||||
drivers := []Driver{}
|
||||
var drivers []Driver
|
||||
|
||||
if dconfig.RemoteType != "" {
|
||||
esx5Driver, err := NewESX5Driver(dconfig, config, vmName)
|
||||
Generated
Vendored
Generated
Vendored
+2
-2
@@ -199,7 +199,7 @@ func (d *ESX5Driver) ReloadVM() error {
|
||||
func (d *ESX5Driver) Start(vmxPathLocal string, headless bool) error {
|
||||
for i := 0; i < 20; i++ {
|
||||
//intentionally not checking for error since poweron may fail specially after initial VM registration
|
||||
d.sh("vim-cmd", "vmsvc/power.on", d.vmId)
|
||||
_ = d.sh("vim-cmd", "vmsvc/power.on", d.vmId)
|
||||
time.Sleep((time.Duration(i) * time.Second) + 1)
|
||||
running, err := d.IsRunning(vmxPathLocal)
|
||||
if err != nil {
|
||||
@@ -525,7 +525,7 @@ func (d *ESX5Driver) VNCAddress(ctx context.Context, _ string, portMin, portMax
|
||||
}
|
||||
}
|
||||
|
||||
vncTimeout := time.Duration(15 * time.Second)
|
||||
vncTimeout := 15 * time.Second
|
||||
envTimeout := os.Getenv("PACKER_ESXI_VNC_PROBE_TIMEOUT")
|
||||
if envTimeout != "" {
|
||||
if parsedTimeout, err := time.ParseDuration(envTimeout); err != nil {
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+8
-16
@@ -138,9 +138,7 @@ type tkParameter struct {
|
||||
|
||||
func (e *tkParameter) String() string {
|
||||
var values []string
|
||||
for _, val := range e.operand {
|
||||
values = append(values, val)
|
||||
}
|
||||
values = append(values, e.operand...)
|
||||
return fmt.Sprintf("%s [%s]", e.name, strings.Join(values, ","))
|
||||
}
|
||||
|
||||
@@ -156,9 +154,7 @@ func (e *tkGroup) String() string {
|
||||
var id []string
|
||||
|
||||
id = append(id, e.id.name)
|
||||
for _, val := range e.id.operand {
|
||||
id = append(id, val)
|
||||
}
|
||||
id = append(id, e.id.operand...)
|
||||
|
||||
var config []string
|
||||
for _, val := range e.params {
|
||||
@@ -640,10 +636,6 @@ type pDeclarationGroup struct{}
|
||||
|
||||
func (e pDeclarationGroup) repr() string { return fmt.Sprintf("{group}") }
|
||||
|
||||
type pDeclarationClass struct{ name string }
|
||||
|
||||
func (e pDeclarationClass) repr() string { return fmt.Sprintf("{class}") }
|
||||
|
||||
/** parsers */
|
||||
func parseParameter(val tkParameter) (pParameter, error) {
|
||||
switch val.name {
|
||||
@@ -1024,9 +1016,9 @@ func (e *configDeclaration) IP4() (net.IP, error) {
|
||||
var result []string
|
||||
|
||||
for _, entry := range e.address {
|
||||
switch entry.(type) {
|
||||
switch v := entry.(type) {
|
||||
case pParameterAddress4:
|
||||
for _, s := range entry.(pParameterAddress4) {
|
||||
for _, s := range v {
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
@@ -1057,9 +1049,9 @@ func (e *configDeclaration) IP6() (net.IP, error) {
|
||||
var result []string
|
||||
|
||||
for _, entry := range e.address {
|
||||
switch entry.(type) {
|
||||
switch v := entry.(type) {
|
||||
case pParameterAddress6:
|
||||
for _, s := range entry.(pParameterAddress6) {
|
||||
for _, s := range v {
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
@@ -1089,9 +1081,9 @@ func (e *configDeclaration) Hardware() (net.HardwareAddr, error) {
|
||||
var result []pParameterHardware
|
||||
|
||||
for _, addr := range e.address {
|
||||
switch addr.(type) {
|
||||
switch v := addr.(type) {
|
||||
case pParameterHardware:
|
||||
result = append(result, addr.(pParameterHardware))
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
+1
-1
@@ -81,7 +81,7 @@ func (s *StepOutputDir) Run(ctx context.Context, state multistep.StateBag) multi
|
||||
if exists {
|
||||
if s.Force {
|
||||
ui.Message("Deleting previous output directory...")
|
||||
dir.RemoveAll()
|
||||
_ = dir.RemoveAll()
|
||||
} else {
|
||||
state.Put("error", fmt.Errorf(
|
||||
"Output directory '%s' already exists.", dir.String()))
|
||||
Generated
Vendored
Generated
Vendored
+1
-1
@@ -75,7 +75,7 @@ func (s *StepRegister) Cleanup(state multistep.StateBag) {
|
||||
}
|
||||
log.Printf("error destroying vm: %s", err)
|
||||
time.Sleep(1 * time.Second)
|
||||
if time.Since(start) >= time.Duration(30*time.Minute) {
|
||||
if time.Since(start) >= 30*time.Minute {
|
||||
ui.Error("Error unregistering VM; timed out. You may " +
|
||||
"need to manually clean up your machine")
|
||||
break
|
||||
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Generated
Vendored
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user