Move clone builder to a separate module

This commit is contained in:
Andrei Tonkikh 2018-01-24 14:04:39 +03:00
parent 448809aa1e
commit e91ac3ef1b
18 changed files with 77 additions and 68 deletions

View File

@ -8,6 +8,6 @@ export GOARCH=amd64
mkdir -p bin mkdir -p bin
rm -f bin/* rm -f bin/*
GOOS=darwin go build -o bin/packer-builder-vsphere.macos GOOS=darwin go build -o bin/packer-builder-vsphere-clone.macos ./clone
GOOS=linux go build -o bin/packer-builder-vsphere.linux GOOS=linux go build -o bin/packer-builder-vsphere-clone.linux ./clone
GOOS=windows go build -o bin/packer-builder-vsphere.exe GOOS=windows go build -o bin/packer-builder-vsphere-clone.exe ./clone

View File

@ -1,11 +1,12 @@
package main package clone
import ( import (
"errors" "errors"
"github.com/hashicorp/packer/common" packerCommon "github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/jetbrains-infra/packer-builder-vsphere/common"
"github.com/jetbrains-infra/packer-builder-vsphere/driver" "github.com/jetbrains-infra/packer-builder-vsphere/driver"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
) )
@ -28,14 +29,15 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
state := new(multistep.BasicStateBag) state := new(multistep.BasicStateBag)
state.Put("config", b.config) state.Put("config", b.config)
state.Put("comm", &b.config.Comm)
state.Put("hook", hook) state.Put("hook", hook)
state.Put("ui", ui) state.Put("ui", ui)
var steps []multistep.Step var steps []multistep.Step
steps = append(steps, steps = append(steps,
&StepConnect{ &common.StepConnect{
config: &b.config.ConnectConfig, Config: &b.config.ConnectConfig,
}, },
&StepCloneVM{ &StepCloneVM{
config: &b.config.CloneConfig, config: &b.config.CloneConfig,
@ -47,30 +49,30 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
if b.config.Comm.Type != "none" { if b.config.Comm.Type != "none" {
steps = append(steps, steps = append(steps,
&StepRun{}, &common.StepRun{},
&communicator.StepConnect{ &communicator.StepConnect{
Config: &b.config.Comm, Config: &b.config.Comm,
Host: commHost, Host: common.CommHost,
SSHConfig: sshConfig, SSHConfig: common.SshConfig,
}, },
&common.StepProvision{}, &packerCommon.StepProvision{},
&StepShutdown{ &common.StepShutdown{
config: &b.config.ShutdownConfig, Config: &b.config.ShutdownConfig,
}, },
) )
} }
steps = append(steps, steps = append(steps,
&StepCreateSnapshot{ &common.StepCreateSnapshot{
createSnapshot: b.config.CreateSnapshot, CreateSnapshot: b.config.CreateSnapshot,
}, },
&StepConvertToTemplate{ &common.StepConvertToTemplate{
ConvertToTemplate: b.config.ConvertToTemplate, ConvertToTemplate: b.config.ConvertToTemplate,
}, },
) )
// Run! // Run!
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(state) b.runner.Run(state)
// If there was an error, return that // If there was an error, return that
@ -87,7 +89,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
return nil, errors.New("Build was halted.") return nil, errors.New("Build was halted.")
} }
artifact := &Artifact{ artifact := &common.Artifact{
Name: b.config.VMName, Name: b.config.VMName,
VM: state.Get("vm").(*driver.VirtualMachine), VM: state.Get("vm").(*driver.VirtualMachine),
} }

View File

@ -1,10 +1,11 @@
package main package clone
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
builderT "github.com/hashicorp/packer/helper/builder/testing" builderT "github.com/hashicorp/packer/helper/builder/testing"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/jetbrains-infra/packer-builder-vsphere/common"
"github.com/jetbrains-infra/packer-builder-vsphere/driver" "github.com/jetbrains-infra/packer-builder-vsphere/driver"
"math/rand" "math/rand"
"testing" "testing"
@ -111,7 +112,7 @@ func checkArtifact(t *testing.T) builderT.TestCheckFunc {
} }
artifactRaw := artifacts[0] artifactRaw := artifacts[0]
_, ok := artifactRaw.(*Artifact) _, ok := artifactRaw.(*common.Artifact)
if !ok { if !ok {
t.Fatalf("unknown artifact: %#v", artifactRaw) t.Fatalf("unknown artifact: %#v", artifactRaw)
} }
@ -388,7 +389,7 @@ func TestBuilderAcc_sshKey(t *testing.T) {
func sshKeyConfig() string { func sshKeyConfig() string {
config := defaultConfig() config := defaultConfig()
config["ssh_password"] = "" config["ssh_password"] = ""
config["ssh_private_key_file"] = "test-key.pem" config["ssh_private_key_file"] = "../test-key.pem"
config["linked_clone"] = true // speed up config["linked_clone"] = true // speed up
return renderConfig(config) return renderConfig(config)
} }
@ -490,7 +491,7 @@ func testConn(t *testing.T) *driver.Driver {
func getVM(t *testing.T, d *driver.Driver, artifacts []packer.Artifact) *driver.VirtualMachine { func getVM(t *testing.T, d *driver.Driver, artifacts []packer.Artifact) *driver.VirtualMachine {
artifactRaw := artifacts[0] artifactRaw := artifacts[0]
artifact, _ := artifactRaw.(*Artifact) artifact, _ := artifactRaw.(*common.Artifact)
vm, err := d.FindVM(artifact.Name) vm, err := d.FindVM(artifact.Name)
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
package main package clone
import ( import (
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"

View File

@ -1,22 +1,23 @@
package main package clone
import ( import (
"github.com/hashicorp/packer/common" packerCommon "github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
"github.com/jetbrains-infra/packer-builder-vsphere/common"
) )
type Config struct { type Config struct {
common.PackerConfig `mapstructure:",squash"` packerCommon.PackerConfig `mapstructure:",squash"`
ConnectConfig `mapstructure:",squash"` common.ConnectConfig `mapstructure:",squash"`
CloneConfig `mapstructure:",squash"` CloneConfig `mapstructure:",squash"`
HardwareConfig `mapstructure:",squash"` HardwareConfig `mapstructure:",squash"`
Comm communicator.Config `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"`
ShutdownConfig `mapstructure:",squash"` common.ShutdownConfig `mapstructure:",squash"`
CreateSnapshot bool `mapstructure:"create_snapshot"` CreateSnapshot bool `mapstructure:"create_snapshot"`
ConvertToTemplate bool `mapstructure:"convert_to_template"` ConvertToTemplate bool `mapstructure:"convert_to_template"`
ctx interpolate.Context ctx interpolate.Context
} }

View File

@ -1,4 +1,4 @@
package main package clone
import ( import (
"testing" "testing"

View File

@ -1,4 +1,4 @@
package main package clone
import "github.com/hashicorp/packer/packer/plugin" import "github.com/hashicorp/packer/packer/plugin"

View File

@ -1,4 +1,4 @@
package main package clone
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"

View File

@ -1,4 +1,4 @@
package main package clone
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"

4
clone/test.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
export PACKER_ACC=1
go test -v "$@"

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"github.com/jetbrains-infra/packer-builder-vsphere/driver" "github.com/jetbrains-infra/packer-builder-vsphere/driver"

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"fmt" "fmt"
@ -7,19 +7,20 @@ import (
packerssh "github.com/hashicorp/packer/communicator/ssh" packerssh "github.com/hashicorp/packer/communicator/ssh"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"github.com/hashicorp/packer/helper/communicator"
) )
func commHost(state multistep.StateBag) (string, error) { func CommHost(state multistep.StateBag) (string, error) {
return state.Get("ip").(string), nil return state.Get("ip").(string), nil
} }
func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) { func SshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {
config := state.Get("config").(*Config) comm := state.Get("comm").(*communicator.Config)
var auth []ssh.AuthMethod var auth []ssh.AuthMethod
if config.Comm.SSHPrivateKey != "" { if comm.SSHPrivateKey != "" {
privateKey, err := ioutil.ReadFile(config.Comm.SSHPrivateKey) privateKey, err := ioutil.ReadFile(comm.SSHPrivateKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error loading configured private key file: %s", err) return nil, fmt.Errorf("Error loading configured private key file: %s", err)
} }
@ -32,14 +33,14 @@ func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {
auth = []ssh.AuthMethod{ssh.PublicKeys(signer)} auth = []ssh.AuthMethod{ssh.PublicKeys(signer)}
} else { } else {
auth = []ssh.AuthMethod{ auth = []ssh.AuthMethod{
ssh.Password(config.Comm.SSHPassword), ssh.Password(comm.SSHPassword),
ssh.KeyboardInteractive( ssh.KeyboardInteractive(
packerssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), packerssh.PasswordKeyboardInteractive(comm.SSHPassword)),
} }
} }
clientConfig := &ssh.ClientConfig{ clientConfig := &ssh.ClientConfig{
User: config.Comm.SSHUsername, User: comm.SSHUsername,
HostKeyCallback: ssh.InsecureIgnoreHostKey(), HostKeyCallback: ssh.InsecureIgnoreHostKey(),
} }
clientConfig.Auth = auth clientConfig.Auth = auth

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
@ -31,16 +31,16 @@ func (c *ConnectConfig) Prepare() []error {
} }
type StepConnect struct { type StepConnect struct {
config *ConnectConfig Config *ConnectConfig
} }
func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction { func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction {
d, err := driver.NewDriver(&driver.ConnectConfig{ d, err := driver.NewDriver(&driver.ConnectConfig{
VCenterServer: s.config.VCenterServer, VCenterServer: s.Config.VCenterServer,
Username: s.config.Username, Username: s.Config.Username,
Password: s.config.Password, Password: s.Config.Password,
InsecureConnection: s.config.InsecureConnection, InsecureConnection: s.Config.InsecureConnection,
Datacenter: s.config.Datacenter, Datacenter: s.Config.Datacenter,
}) })
if err != nil { if err != nil {
state.Put("error", err) state.Put("error", err)

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
@ -34,7 +34,7 @@ func (c *ShutdownConfig) Prepare() []error {
} }
type StepShutdown struct { type StepShutdown struct {
config *ShutdownConfig Config *ShutdownConfig
} }
func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction { func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
@ -42,13 +42,13 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
comm := state.Get("communicator").(packer.Communicator) comm := state.Get("communicator").(packer.Communicator)
vm := state.Get("vm").(*driver.VirtualMachine) vm := state.Get("vm").(*driver.VirtualMachine)
if s.config.Command != "" { if s.Config.Command != "" {
ui.Say("Executing shutdown command...") ui.Say("Executing shutdown command...")
log.Printf("Shutdown command: %s", s.config.Command) log.Printf("Shutdown command: %s", s.Config.Command)
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
cmd := &packer.RemoteCmd{ cmd := &packer.RemoteCmd{
Command: s.config.Command, Command: s.Config.Command,
Stdout: &stdout, Stdout: &stdout,
Stderr: &stderr, Stderr: &stderr,
} }
@ -67,8 +67,8 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
} }
} }
log.Printf("Waiting max %s for shutdown to complete", s.config.Timeout) log.Printf("Waiting max %s for shutdown to complete", s.Config.Timeout)
err := vm.WaitForShutdown(s.config.Timeout) err := vm.WaitForShutdown(s.Config.Timeout)
if err != nil { if err != nil {
state.Put("error", err) state.Put("error", err)
return multistep.ActionHalt return multistep.ActionHalt

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
@ -7,14 +7,14 @@ import (
) )
type StepCreateSnapshot struct{ type StepCreateSnapshot struct{
createSnapshot bool CreateSnapshot bool
} }
func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction { func (s *StepCreateSnapshot) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vm := state.Get("vm").(*driver.VirtualMachine) vm := state.Get("vm").(*driver.VirtualMachine)
if s.createSnapshot { if s.CreateSnapshot {
ui.Say("Creating snapshot...") ui.Say("Creating snapshot...")
err := vm.CreateSnapshot("Created by Packer") err := vm.CreateSnapshot("Created by Packer")

View File

@ -1,4 +1,4 @@
package main package common
import ( import (
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/sh
export PACKER_ACC=1 (cd driver && ./test.sh)
go test -v "$@" (cd clone && ./test.sh)