Extract vmware plugin (#10920)

This commit is contained in:
Sylvia Moss 2021-04-19 14:28:48 +02:00 committed by GitHub
parent 9230a06920
commit 88f8feecfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
213 changed files with 656 additions and 7100 deletions

View File

@ -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)
}

View File

@ -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)
}
}
})
}
}

View File

@ -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")
}
}

View File

@ -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

View File

@ -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)
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -1,9 +0,0 @@
package common
import (
"testing"
)
func TestLocalOutputDir_impl(t *testing.T) {
var _ OutputDir = new(LocalOutputDir)
}

View File

@ -1,10 +0,0 @@
package common
import (
"testing"
)
func TestRemoteDriverMock_impl(t *testing.T) {
var _ Driver = new(RemoteDriverMock)
var _ RemoteDriver = new(RemoteDriverMock)
}

View File

@ -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)
}
}
})
}
}

View File

@ -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-----
`

View File

@ -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.")
}
}

View File

@ -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"
`

View File

@ -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")
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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!")
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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";
}

View File

@ -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"

View File

@ -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

View File

@ -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")
}
}
}

View File

@ -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")
}
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -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
},
})
}

View File

@ -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

View File

@ -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"
}
]
}

View File

@ -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)
}

View File

@ -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")
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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),
}

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -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.

View File

@ -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)

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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()))

View File

@ -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