Extract vmware plugin (#10920)
This commit is contained in:
parent
9230a06920
commit
88f8feecfe
|
@ -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
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
10
go.mod
10
go.mod
|
@ -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
|
||||
)
|
||||
|
|
24
go.sum
24
go.sum
|
@ -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=
|
||||
|
|
|
@ -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.
|
|
@ -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)
|
|
@ -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 {
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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()))
|
|
@ -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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue