Refactor artifacts and output_dir implementations.
This commit is contained in:
parent
2d00dc6756
commit
4d9cb19012
|
@ -3,22 +3,26 @@ package common
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuilderId for the local artifacts
|
// BuilderId for the local artifacts
|
||||||
const BuilderId = "mitchellh.vmware"
|
const BuilderId = "mitchellh.vmware"
|
||||||
|
const BuilderIdESX = "mitchellh.vmware-esx"
|
||||||
|
|
||||||
// Artifact is the result of running the VMware builder, namely a set
|
// Artifact is the result of running the VMware builder, namely a set
|
||||||
// of files associated with the resulting machine.
|
// of files associated with the resulting machine.
|
||||||
type localArtifact struct {
|
type artifact struct {
|
||||||
id string
|
builderId string
|
||||||
dir string
|
id string
|
||||||
f []string
|
dir string
|
||||||
|
f []string
|
||||||
|
config map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewLocalArtifact returns a VMware artifact containing the files
|
||||||
|
// in the given directory.
|
||||||
// NewLocalArtifact returns a VMware artifact containing the files
|
// NewLocalArtifact returns a VMware artifact containing the files
|
||||||
// in the given directory.
|
// in the given directory.
|
||||||
func NewLocalArtifact(id string, dir string) (packer.Artifact, error) {
|
func NewLocalArtifact(id string, dir string) (packer.Artifact, error) {
|
||||||
|
@ -37,33 +41,46 @@ func NewLocalArtifact(id string, dir string) (packer.Artifact, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &localArtifact{
|
return &artifact{
|
||||||
id: id,
|
builderId: id,
|
||||||
dir: dir,
|
dir: dir,
|
||||||
f: files,
|
f: files,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *localArtifact) BuilderId() string {
|
func NewArtifact(dir OutputDir, files []string, esxi bool) (packer.Artifact, err) {
|
||||||
|
builderID := BuilderId
|
||||||
|
if esxi {
|
||||||
|
builderID = BuilderIdESX
|
||||||
|
}
|
||||||
|
|
||||||
|
return &artifact{
|
||||||
|
builderId: builderID,
|
||||||
|
dir: dir.String(),
|
||||||
|
f: files,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *artifact) BuilderId() string {
|
||||||
return BuilderId
|
return BuilderId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *localArtifact) Files() []string {
|
func (a *artifact) Files() []string {
|
||||||
return a.f
|
return a.f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *localArtifact) Id() string {
|
func (*artifact) Id() string {
|
||||||
return a.id
|
return a.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *localArtifact) String() string {
|
func (a *artifact) String() string {
|
||||||
return fmt.Sprintf("VM files in directory: %s", a.dir)
|
return fmt.Sprintf("VM files in directory: %s", a.dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *localArtifact) State(name string) interface{} {
|
func (a *artifact) State(name string) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *localArtifact) Destroy() error {
|
func (a *artifact) Destroy() error {
|
||||||
return os.RemoveAll(a.dir)
|
return os.RemoveAll(a.dir)
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
|
||||||
return fmt.Errorf("Failed to copy the vmx file %s: %s", srcVmx, err)
|
return fmt.Errorf("Failed to copy the vmx file %s: %s", srcVmx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filesToClone, err := d.run(nil, "find", srcDir, "! -name '*.vmdk' ! -name '*.vmx' -type f")
|
filesToClone, err := d.run(nil, "find", srcDir, "! -name '*.vmdk' ! -name '*.vmx' -type f ! -size 0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to get the file list to copy: %s", err)
|
return fmt.Errorf("Failed to get the file list to copy: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -96,22 +96,6 @@ func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
|
||||||
return fmt.Errorf("Failing to clone disk %s: %s", srcDisk, err)
|
return fmt.Errorf("Failing to clone disk %s: %s", srcDisk, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// // FIXME: VMName should be taken from the config.
|
|
||||||
// vmxEdits := []string{
|
|
||||||
// "s/\\(display[Nn]ame = \\).*/\\1\"" + vmName + "\"/",
|
|
||||||
// "/ethernet..generated[aA]ddress =/d",
|
|
||||||
// "/uuid.bios =/d",
|
|
||||||
// "/uuid.location =/d",
|
|
||||||
// "/vc.uuid =/d",
|
|
||||||
// }
|
|
||||||
// for _, edit := range vmxEdits {
|
|
||||||
// err := d.sh("sed -i -e", "'", edit, "'", dstVmx)
|
|
||||||
// if err != nil {
|
|
||||||
// return fmt.Errorf("Failed to edit the destination file %s: %s", dstVmx, err)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
log.Printf("Successfully cloned %s to %s\n", src, dst)
|
log.Printf("Successfully cloned %s to %s\n", src, dst)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -460,7 +444,11 @@ func (ESX5Driver) UpdateVMX(_, password string, port uint, data map[string]strin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) {
|
func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) {
|
||||||
port := d.CommConfig.Port()
|
sshc := state.Get("sshConfig").(SSHConfig).Comm
|
||||||
|
port := sshc.SSHPort
|
||||||
|
if sshc.Type == "winrm" {
|
||||||
|
port = sshc.WinRMPort
|
||||||
|
}
|
||||||
|
|
||||||
if address, ok := state.GetOk("vm_address"); ok {
|
if address, ok := state.GetOk("vm_address"); ok {
|
||||||
return address.(string), nil
|
return address.(string), nil
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -12,7 +12,7 @@ const (
|
||||||
|
|
||||||
// Artifact is the result of running the VMware builder, namely a set
|
// Artifact is the result of running the VMware builder, namely a set
|
||||||
// of files associated with the resulting machine.
|
// of files associated with the resulting machine.
|
||||||
type Artifact struct {
|
type RemoteArtifact struct {
|
||||||
builderId string
|
builderId string
|
||||||
id string
|
id string
|
||||||
dir OutputDir
|
dir OutputDir
|
||||||
|
@ -20,26 +20,26 @@ type Artifact struct {
|
||||||
config map[string]string
|
config map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) BuilderId() string {
|
func (a *RemoteArtifact) BuilderId() string {
|
||||||
return a.builderId
|
return a.builderId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) Files() []string {
|
func (a *RemoteArtifact) Files() []string {
|
||||||
return a.f
|
return a.f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) Id() string {
|
func (*RemoteArtifact) Id() string {
|
||||||
return a.id
|
return a.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) String() string {
|
func (a *RemoteArtifact) String() string {
|
||||||
return fmt.Sprintf("VM files in directory: %s", a.dir)
|
return fmt.Sprintf("VM files in directory: %s", a.dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) State(name string) interface{} {
|
func (a *RemoteArtifact) State(name string) interface{} {
|
||||||
return a.config[name]
|
return a.config[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) Destroy() error {
|
func (a *RemoteArtifact) Destroy() error {
|
||||||
return a.dir.RemoveAll()
|
return a.dir.RemoveAll()
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
func TestArtifact_Impl(t *testing.T) {
|
func TestArtifact_Impl(t *testing.T) {
|
||||||
var raw interface{}
|
var raw interface{}
|
||||||
raw = &Artifact{}
|
raw = &RemoteArtifact{}
|
||||||
if _, ok := raw.(packer.Artifact); !ok {
|
if _, ok := raw.(packer.Artifact); !ok {
|
||||||
t.Fatal("Artifact must be a proper artifact")
|
t.Fatal("Artifact must be a proper artifact")
|
||||||
}
|
}
|
|
@ -19,8 +19,6 @@ import (
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BuilderIdESX = "mitchellh.vmware-esx"
|
|
||||||
|
|
||||||
type Builder struct {
|
type Builder struct {
|
||||||
config Config
|
config Config
|
||||||
runner multistep.Runner
|
runner multistep.Runner
|
||||||
|
@ -257,9 +255,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the output dir implementation
|
// Determine the output dir implementation
|
||||||
var dir OutputDir
|
var dir vmwcommon.OutputDir
|
||||||
switch d := driver.(type) {
|
switch d := driver.(type) {
|
||||||
case OutputDir:
|
case vmwcommon.OutputDir:
|
||||||
dir = d
|
dir = d
|
||||||
default:
|
default:
|
||||||
dir = new(vmwcommon.LocalOutputDir)
|
dir = new(vmwcommon.LocalOutputDir)
|
||||||
|
@ -281,6 +279,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
state.Put("driver", driver)
|
state.Put("driver", driver)
|
||||||
state.Put("hook", hook)
|
state.Put("hook", hook)
|
||||||
state.Put("ui", ui)
|
state.Put("ui", ui)
|
||||||
|
state.Put("sshConfig", &b.config.SSHConfig)
|
||||||
|
|
||||||
steps := []multistep.Step{
|
steps := []multistep.Step{
|
||||||
&vmwcommon.StepPrepareTools{
|
&vmwcommon.StepPrepareTools{
|
||||||
|
@ -413,30 +412,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
dir.SetOutputDir(exportOutputPath)
|
dir.SetOutputDir(exportOutputPath)
|
||||||
files, err = dir.ListFiles()
|
files, err = dir.ListFiles()
|
||||||
} else {
|
} else {
|
||||||
files, err = state.Get("dir").(OutputDir).ListFiles()
|
files, err = state.Get("dir").(vmwcommon.OutputDir).ListFiles()
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the proper builder ID
|
return vmwcommon.NewArtifact(dir, files, b.config.RemoteType != ""), nil
|
||||||
builderId := vmwcommon.BuilderId
|
|
||||||
if b.config.RemoteType != "" {
|
|
||||||
builderId = BuilderIdESX
|
|
||||||
}
|
|
||||||
|
|
||||||
config := make(map[string]string)
|
|
||||||
config[ArtifactConfKeepRegistered] = strconv.FormatBool(b.config.KeepRegistered)
|
|
||||||
config[ArtifactConfFormat] = b.config.Format
|
|
||||||
config[ArtifactConfSkipExport] = strconv.FormatBool(b.config.SkipExport)
|
|
||||||
|
|
||||||
return &Artifact{
|
|
||||||
builderId: builderId,
|
|
||||||
id: b.config.VMName,
|
|
||||||
dir: dir,
|
|
||||||
f: files,
|
|
||||||
config: config,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) Cancel() {
|
func (b *Builder) Cancel() {
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package iso
|
|
||||||
|
|
||||||
// OutputDir is an interface type that abstracts the creation and handling
|
|
||||||
// of the output directory for VMware-based products. The abstraction is made
|
|
||||||
// so that the output directory can be properly made on remote (ESXi) based
|
|
||||||
// VMware products as well as local.
|
|
||||||
type OutputDir interface {
|
|
||||||
DirExists() (bool, error)
|
|
||||||
ListFiles() ([]string, error)
|
|
||||||
MkdirAll() error
|
|
||||||
Remove(string) error
|
|
||||||
RemoveAll() error
|
|
||||||
SetOutputDir(string)
|
|
||||||
}
|
|
|
@ -39,8 +39,17 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
return nil, fmt.Errorf("Failed creating VMware driver: %s", err)
|
return nil, fmt.Errorf("Failed creating VMware driver: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the directory
|
// Determine the output dir implementation
|
||||||
dir := new(vmwcommon.LocalOutputDir)
|
var dir vmwcommon.OutputDir
|
||||||
|
switch d := driver.(type) {
|
||||||
|
case vmwcommon.OutputDir:
|
||||||
|
dir = d
|
||||||
|
default:
|
||||||
|
dir = new(vmwcommon.LocalOutputDir)
|
||||||
|
}
|
||||||
|
if b.config.RemoteType != "" {
|
||||||
|
b.config.OutputDir = b.config.VMName
|
||||||
|
}
|
||||||
dir.SetOutputDir(b.config.OutputDir)
|
dir.SetOutputDir(b.config.OutputDir)
|
||||||
|
|
||||||
// Set up the state.
|
// Set up the state.
|
||||||
|
@ -51,6 +60,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
state.Put("driver", driver)
|
state.Put("driver", driver)
|
||||||
state.Put("hook", hook)
|
state.Put("hook", hook)
|
||||||
state.Put("ui", ui)
|
state.Put("ui", ui)
|
||||||
|
state.Put("sshConfig", b.config.SSHConfig)
|
||||||
|
|
||||||
// Build the steps.
|
// Build the steps.
|
||||||
steps := []multistep.Step{
|
steps := []multistep.Step{
|
||||||
|
@ -138,6 +148,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
RemoveEthernetInterfaces: b.config.VMXConfig.VMXRemoveEthernet,
|
RemoveEthernetInterfaces: b.config.VMXConfig.VMXRemoveEthernet,
|
||||||
VNCEnabled: !b.config.DisableVNC,
|
VNCEnabled: !b.config.DisableVNC,
|
||||||
},
|
},
|
||||||
|
&vmwcommon.StepUploadVMX{
|
||||||
|
RemoteType: b.config.RemoteType,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the steps.
|
// Run the steps.
|
||||||
|
@ -157,8 +170,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
if _, ok := state.GetOk(multistep.StateHalted); ok {
|
if _, ok := state.GetOk(multistep.StateHalted); ok {
|
||||||
return nil, errors.New("Build was halted.")
|
return nil, errors.New("Build was halted.")
|
||||||
}
|
}
|
||||||
|
files, err := state.Get("dir").(vmwcommon.OutputDir).ListFiles()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return vmwcommon.NewLocalArtifact(b.config.VMName, b.config.OutputDir)
|
return vmwcommon.NewArtifact(dir, files, b.config.RemoteType != ""), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel.
|
// Cancel.
|
||||||
|
|
Loading…
Reference in New Issue