Move the remote_driver from iso to common.
This commit is contained in:
parent
91c7089455
commit
b5298464c5
|
@ -7,7 +7,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -48,27 +47,23 @@ func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
|
|||
|
||||
linesToArray := func(lines string) []string { return strings.Split(strings.Trim(lines, "\n"), "\n") }
|
||||
|
||||
err := d.sh("test -r", src)
|
||||
if err != nil {
|
||||
return errors.New("Source VMX not found")
|
||||
}
|
||||
d.SetOutputDir(dst)
|
||||
srcVmx := d.datastorePath(path.Dir(src))
|
||||
dstVmx := d.datastorePath(dst)
|
||||
srcDir := path.Dir(srcVmx)
|
||||
dstDir := path.Dir(dstVmx)
|
||||
|
||||
vmName := strings.TrimSuffix(path.Base(src), ".vmx")
|
||||
srcDir := path.Dir(src)
|
||||
dstDir := path.Join(path.Dir(srcDir), path.Dir(dst))
|
||||
dstVmx := path.Join(dstDir, path.Base(dst))
|
||||
|
||||
log.Printf("Source: %s\n", src)
|
||||
log.Printf("Source: %s\n", srcVmx)
|
||||
log.Printf("Dest: %s\n", dstVmx)
|
||||
|
||||
err = d.sh("mkdir", dstDir)
|
||||
err := d.sh("mkdir", dstDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create the destination directory %s: %s", dstDir, err)
|
||||
}
|
||||
|
||||
err = d.sh("cp", src, dstVmx)
|
||||
err = d.sh("cp", srcVmx, dstVmx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to copy the vmx file %s: %s", src, 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")
|
||||
|
@ -84,7 +79,7 @@ func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
|
|||
}
|
||||
}
|
||||
|
||||
disksToClone, err := d.run(nil, "sed -ne 's/.*file[Nn]ame = \"\\(.*vmdk\\)\"/\\1/p'", src)
|
||||
disksToClone, err := d.run(nil, "sed -ne 's/.*file[Nn]ame = \"\\(.*vmdk\\)\"/\\1/p'", srcVmx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failing to get the vmdk list to clone %s", err)
|
||||
}
|
||||
|
@ -94,37 +89,28 @@ func (d *ESX5Driver) Clone(dst, src string, linked bool) error {
|
|||
srcDisk = disk
|
||||
}
|
||||
destDisk := path.Join(dstDir, path.Base(disk))
|
||||
err := d.sh("vmkfstools", "-d thin", "-i", srcDisk, destDisk)
|
||||
err = d.sh("vmkfstools", "-d thin", "-i", srcDisk, destDisk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failing to clone disk %s: %s", srcDisk, err)
|
||||
}
|
||||
}
|
||||
|
||||
vmxDir, err = ioutil.TempDir("", "packer-vmx")
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error preparing VMX template: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// Set the tempDir so we clean it up
|
||||
s.tempDir = vmxDir
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
//
|
||||
// // 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)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -150,6 +136,21 @@ func (d *ESX5Driver) ReloadVM() error {
|
|||
return d.sh("vim-cmd", "vmsvc/reload", d.vmId)
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) ReadFile(name string) ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
writer := bufio.NewWriter(&b)
|
||||
err := d.comm.Download(d.datastorePath(name), writer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Cant read remote file %s: %s", name, err)
|
||||
}
|
||||
writer.Flush()
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) WriteFile(name string, content []byte) error {
|
||||
return d.comm.Upload(d.datastorePath(name), bytes.NewReader(content), nil)
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -172,7 +173,7 @@ func (d *ESX5Driver) Stop(vmxPathLocal string) error {
|
|||
|
||||
func (d *ESX5Driver) Register(vmxPathLocal string) error {
|
||||
vmxPath := filepath.ToSlash(filepath.Join(d.outputDir, filepath.Base(vmxPathLocal)))
|
||||
if err := d.upload(vmxPath, vmxPathLocal); err != nil {
|
||||
if err := d.Upload(vmxPath, vmxPathLocal); err != nil {
|
||||
return err
|
||||
}
|
||||
r, err := d.run(nil, "vim-cmd", "solo/registervm", strconv.Quote(vmxPath))
|
||||
|
@ -215,7 +216,7 @@ func (d *ESX5Driver) UploadISO(localPath string, checksum string, checksumType s
|
|||
return finalPath, nil
|
||||
}
|
||||
|
||||
if err := d.upload(finalPath, localPath); err != nil {
|
||||
if err := d.Upload(finalPath, localPath); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
@ -662,7 +663,7 @@ func (d *ESX5Driver) mkdir(path string) error {
|
|||
return d.sh("mkdir", "-p", strconv.Quote(path))
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) upload(dst, src string) error {
|
||||
func (d *ESX5Driver) Upload(dst, src string) error {
|
||||
f, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -671,15 +672,6 @@ func (d *ESX5Driver) upload(dst, src string) error {
|
|||
return d.comm.Upload(dst, f, nil)
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) download(dst, src string) error {
|
||||
f, err := os.Open(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
return d.comm.Download(dst, f, nil)
|
||||
}
|
||||
|
||||
func (d *ESX5Driver) verifyChecksum(ctype string, hash string, file string) bool {
|
||||
if ctype == "none" {
|
||||
if err := d.sh("stat", strconv.Quote(file)); err != nil {
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package iso
|
||||
|
||||
import (
|
||||
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
|
||||
)
|
||||
package common
|
||||
|
||||
type RemoteDriver interface {
|
||||
vmwcommon.Driver
|
||||
Driver
|
||||
|
||||
// UploadISO uploads a local ISO to the remote side and returns the
|
||||
// new path that should be used in the VMX along with an error if it
|
||||
|
@ -28,8 +24,14 @@ type RemoteDriver interface {
|
|||
IsDestroyed() (bool, error)
|
||||
|
||||
// Uploads a local file to remote side.
|
||||
upload(dst, src string) error
|
||||
Upload(dst, src string) error
|
||||
|
||||
// Reload VM on remote side.
|
||||
ReloadVM() error
|
||||
|
||||
// Read bytes from of a remote file.
|
||||
ReadFile(string) ([]byte, error)
|
||||
|
||||
// Write bytes to a remote file.
|
||||
WriteFile(string, []byte) error
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
package iso
|
||||
|
||||
import (
|
||||
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
|
||||
)
|
||||
package common
|
||||
|
||||
type RemoteDriverMock struct {
|
||||
vmwcommon.DriverMock
|
||||
DriverMock
|
||||
|
||||
UploadISOCalled bool
|
||||
UploadISOPath string
|
|
@ -0,0 +1,10 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRemoteDriverMock_impl(t *testing.T) {
|
||||
var _ Driver = new(RemoteDriverMock)
|
||||
var _ RemoteDriver = new(RemoteDriverMock)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
@ -25,9 +26,14 @@ type StepConfigureVMX struct {
|
|||
}
|
||||
|
||||
func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
vmxPath := state.Get("vmx_path").(string)
|
||||
log.Printf("Configuring VMX...\n")
|
||||
|
||||
var vmxContents []byte
|
||||
var err error
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
vmxPath := state.Get("vmx_path").(string)
|
||||
vmxData, err := ReadVMX(vmxPath)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error reading VMX file: %s", err)
|
||||
|
@ -69,7 +75,15 @@ func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) mult
|
|||
}
|
||||
}
|
||||
|
||||
if err := WriteVMX(vmxPath, vmxData); err != nil {
|
||||
if remoteDriver, ok := driver.(RemoteDriver); ok {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(EncodeVMX(vmxData))
|
||||
err = remoteDriver.WriteFile(vmxPath, buf.Bytes())
|
||||
} else {
|
||||
err = WriteVMX(vmxPath, vmxData)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error writing VMX file: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package iso
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
|
||||
)
|
||||
|
||||
func TestRemoteDriverMock_impl(t *testing.T) {
|
||||
var _ vmwcommon.Driver = new(RemoteDriverMock)
|
||||
var _ RemoteDriver = new(RemoteDriverMock)
|
||||
}
|
|
@ -20,7 +20,7 @@ func (s *StepRegister) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
ui := state.Get("ui").(packer.Ui)
|
||||
vmxPath := state.Get("vmx_path").(string)
|
||||
|
||||
if remoteDriver, ok := driver.(RemoteDriver); ok {
|
||||
if remoteDriver, ok := driver.(vmwcommon.RemoteDriver); ok {
|
||||
ui.Say("Registering remote VM...")
|
||||
if err := remoteDriver.Register(vmxPath); err != nil {
|
||||
err := fmt.Errorf("Error registering VM: %s", err)
|
||||
|
@ -51,7 +51,7 @@ func (s *StepRegister) Cleanup(state multistep.StateBag) {
|
|||
return
|
||||
}
|
||||
|
||||
if remoteDriver, ok := driver.(RemoteDriver); ok {
|
||||
if remoteDriver, ok := driver.(vmwcommon.RemoteDriver); ok {
|
||||
if s.Format == "" || config.SkipExport {
|
||||
ui.Say("Unregistering virtual machine...")
|
||||
if err := remoteDriver.Unregister(s.registeredPath); err != nil {
|
||||
|
|
|
@ -22,7 +22,7 @@ func (s *stepRemoteUpload) Run(_ context.Context, state multistep.StateBag) mult
|
|||
driver := state.Get("driver").(vmwcommon.Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
remote, ok := driver.(RemoteDriver)
|
||||
remote, ok := driver.(vmwcommon.RemoteDriver)
|
||||
if !ok {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ func (c *StepUploadVMX) Run(_ context.Context, state multistep.StateBag) multist
|
|||
vmxPath := state.Get("vmx_path").(string)
|
||||
|
||||
if c.RemoteType == "esx5" {
|
||||
remoteDriver, ok := driver.(RemoteDriver)
|
||||
remoteDriver, ok := driver.(vmwcommon.RemoteDriver)
|
||||
if ok {
|
||||
remoteVmxPath := filepath.ToSlash(filepath.Join(fmt.Sprintf("%s", remoteDriver), filepath.Base(vmxPath)))
|
||||
if err := remoteDriver.upload(remoteVmxPath, vmxPath); err != nil {
|
||||
if err := remoteDriver.Upload(remoteVmxPath, vmxPath); err != nil {
|
||||
state.Put("error", fmt.Errorf("Error writing VMX: %s", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ package vmx
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
|
@ -18,9 +20,15 @@ type StepCloneVMX struct {
|
|||
Path string
|
||||
VMName string
|
||||
Linked bool
|
||||
tempDir string
|
||||
}
|
||||
|
||||
func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
halt := func(err error) multistep.StepAction {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(vmwcommon.Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
|
@ -29,6 +37,7 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
ui.Say("Cloning source VM...")
|
||||
log.Printf("Cloning from: %s", s.Path)
|
||||
log.Printf("Cloning to: %s", vmxPath)
|
||||
|
||||
if err := driver.Clone(vmxPath, s.Path, s.Linked); err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
|
@ -40,10 +49,26 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
// network type so that it can work out things like IP's and MAC
|
||||
// addresses
|
||||
// * The disk compaction step needs the paths to all attached disks
|
||||
if remoteDriver, ok := driver.(vmwcommon.RemoteDriver); ok {
|
||||
tempDir, err := ioutil.TempDir("", "packer-vmx")
|
||||
if err != nil {
|
||||
return halt(err)
|
||||
}
|
||||
s.tempDir = tempDir
|
||||
content, err := remoteDriver.ReadFile(vmxPath)
|
||||
if err != nil {
|
||||
return halt(err)
|
||||
}
|
||||
vmxPath = filepath.Join(tempDir, s.VMName+".vmx")
|
||||
err = ioutil.WriteFile(vmxPath, content, 0600)
|
||||
if err != nil {
|
||||
return halt(err)
|
||||
}
|
||||
}
|
||||
|
||||
vmxData, err := vmwcommon.ReadVMX(vmxPath)
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
return halt(err)
|
||||
}
|
||||
|
||||
var diskFilenames []string
|
||||
|
@ -104,4 +129,7 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
}
|
||||
|
||||
func (s *StepCloneVMX) Cleanup(state multistep.StateBag) {
|
||||
if s.tempDir != "" {
|
||||
os.RemoveAll(s.tempDir)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue