packer: Add Cancel method to Provisioner
This commit is contained in:
parent
6312f680da
commit
47cd6df85b
|
@ -16,7 +16,7 @@ func testBuild() *coreBuild {
|
|||
"foo": []Hook{&MockHook{}},
|
||||
},
|
||||
provisioners: []coreBuildProvisioner{
|
||||
coreBuildProvisioner{&TestProvisioner{}, []interface{}{42}},
|
||||
coreBuildProvisioner{&MockProvisioner{}, []interface{}{42}},
|
||||
},
|
||||
postProcessors: [][]coreBuildPostProcessor{
|
||||
[]coreBuildPostProcessor{
|
||||
|
@ -59,9 +59,9 @@ func TestBuild_Prepare(t *testing.T) {
|
|||
assert.Equal(builder.prepareConfig, []interface{}{42, packerConfig}, "prepare config should be 42")
|
||||
|
||||
coreProv := build.provisioners[0]
|
||||
prov := coreProv.provisioner.(*TestProvisioner)
|
||||
assert.True(prov.prepCalled, "prepare should be called")
|
||||
assert.Equal(prov.prepConfigs, []interface{}{42, packerConfig}, "prepare should be called with proper config")
|
||||
prov := coreProv.provisioner.(*MockProvisioner)
|
||||
assert.True(prov.PrepCalled, "prepare should be called")
|
||||
assert.Equal(prov.PrepConfigs, []interface{}{42, packerConfig}, "prepare should be called with proper config")
|
||||
|
||||
corePP := build.postProcessors[0][0]
|
||||
pp := corePP.processor.(*TestPostProcessor)
|
||||
|
@ -104,9 +104,9 @@ func TestBuild_Prepare_Debug(t *testing.T) {
|
|||
assert.Equal(builder.prepareConfig, []interface{}{42, packerConfig}, "prepare config should be 42")
|
||||
|
||||
coreProv := build.provisioners[0]
|
||||
prov := coreProv.provisioner.(*TestProvisioner)
|
||||
assert.True(prov.prepCalled, "prepare should be called")
|
||||
assert.Equal(prov.prepConfigs, []interface{}{42, packerConfig}, "prepare should be called with proper config")
|
||||
prov := coreProv.provisioner.(*MockProvisioner)
|
||||
assert.True(prov.PrepCalled, "prepare should be called")
|
||||
assert.Equal(prov.PrepConfigs, []interface{}{42, packerConfig}, "prepare should be called with proper config")
|
||||
}
|
||||
|
||||
func TestBuildPrepare_variables_default(t *testing.T) {
|
||||
|
@ -193,8 +193,8 @@ func TestBuild_Run(t *testing.T) {
|
|||
|
||||
// Verify provisioners run
|
||||
dispatchHook.Run(HookProvision, nil, nil, 42)
|
||||
prov := build.provisioners[0].provisioner.(*TestProvisioner)
|
||||
assert.True(prov.provCalled, "provision should be called")
|
||||
prov := build.provisioners[0].provisioner.(*MockProvisioner)
|
||||
assert.True(prov.ProvCalled, "provision should be called")
|
||||
|
||||
// Verify post-processor was run
|
||||
pp := build.postProcessors[0][0].processor.(*TestPostProcessor)
|
||||
|
|
|
@ -20,7 +20,7 @@ func init() {
|
|||
func testComponentFinder() *ComponentFinder {
|
||||
builderFactory := func(n string) (Builder, error) { return testBuilder(), nil }
|
||||
ppFactory := func(n string) (PostProcessor, error) { return new(TestPostProcessor), nil }
|
||||
provFactory := func(n string) (Provisioner, error) { return new(TestProvisioner), nil }
|
||||
provFactory := func(n string) (Provisioner, error) { return new(MockProvisioner), nil }
|
||||
return &ComponentFinder{
|
||||
Builder: builderFactory,
|
||||
PostProcessor: ppFactory,
|
||||
|
@ -309,7 +309,7 @@ func TestEnvironment_PostProcessor_Error(t *testing.T) {
|
|||
func TestEnvironmentProvisioner(t *testing.T) {
|
||||
assert := asserts.NewTestingAsserts(t, true)
|
||||
|
||||
p := &TestProvisioner{}
|
||||
p := &MockProvisioner{}
|
||||
ps := make(map[string]Provisioner)
|
||||
ps["foo"] = p
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ func TestHelperProcess(*testing.T) {
|
|||
case "post-processor":
|
||||
ServePostProcessor(new(helperPostProcessor))
|
||||
case "provisioner":
|
||||
ServeProvisioner(new(helperProvisioner))
|
||||
ServeProvisioner(new(packer.MockProvisioner))
|
||||
case "start-timeout":
|
||||
time.Sleep(1 * time.Minute)
|
||||
os.Exit(1)
|
||||
|
|
|
@ -28,6 +28,15 @@ func (c *cmdProvisioner) Provision(ui packer.Ui, comm packer.Communicator) error
|
|||
return c.p.Provision(ui, comm)
|
||||
}
|
||||
|
||||
func (c *cmdProvisioner) Cancel() {
|
||||
defer func() {
|
||||
r := recover()
|
||||
c.checkExit(r, nil)
|
||||
}()
|
||||
|
||||
c.p.Cancel()
|
||||
}
|
||||
|
||||
func (c *cmdProvisioner) checkExit(p interface{}, cb func()) {
|
||||
if c.client.Exited() && cb != nil {
|
||||
cb()
|
||||
|
|
|
@ -1,21 +1,10 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type helperProvisioner byte
|
||||
|
||||
func (helperProvisioner) Prepare(...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (helperProvisioner) Provision(packer.Ui, packer.Communicator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestProvisioner_NoExist(t *testing.T) {
|
||||
c := NewClient(&ClientConfig{Cmd: exec.Command("i-should-not-exist")})
|
||||
defer c.Kill()
|
||||
|
|
|
@ -13,6 +13,11 @@ type Provisioner interface {
|
|||
// is guaranteed to be connected to some machine so that provisioning
|
||||
// can be done.
|
||||
Provision(Ui, Communicator) error
|
||||
|
||||
// Cancel is called to cancel the provisioning. This is usually called
|
||||
// while Provision is still being called. The Provisioner should act
|
||||
// to stop its execution as quickly as possible in a race-free way.
|
||||
Cancel()
|
||||
}
|
||||
|
||||
// A Hook implementation that runs the given provisioners.
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package packer
|
||||
|
||||
// MockProvisioner is an implementation of Provisioner that can be
|
||||
// used for tests.
|
||||
type MockProvisioner struct {
|
||||
PrepCalled bool
|
||||
PrepConfigs []interface{}
|
||||
ProvCalled bool
|
||||
ProvUi Ui
|
||||
CancelCalled bool
|
||||
}
|
||||
|
||||
func (t *MockProvisioner) Prepare(configs ...interface{}) error {
|
||||
t.PrepCalled = true
|
||||
t.PrepConfigs = configs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MockProvisioner) Provision(ui Ui, comm Communicator) error {
|
||||
t.ProvCalled = true
|
||||
t.ProvUi = ui
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MockProvisioner) Cancel() {
|
||||
t.CancelCalled = true
|
||||
}
|
|
@ -2,23 +2,6 @@ package packer
|
|||
|
||||
import "testing"
|
||||
|
||||
type TestProvisioner struct {
|
||||
prepCalled bool
|
||||
prepConfigs []interface{}
|
||||
provCalled bool
|
||||
}
|
||||
|
||||
func (t *TestProvisioner) Prepare(configs ...interface{}) error {
|
||||
t.prepCalled = true
|
||||
t.prepConfigs = configs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestProvisioner) Provision(Ui, Communicator) error {
|
||||
t.provCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestProvisionHook_Impl(t *testing.T) {
|
||||
var raw interface{}
|
||||
raw = &ProvisionHook{}
|
||||
|
@ -28,8 +11,8 @@ func TestProvisionHook_Impl(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestProvisionHook(t *testing.T) {
|
||||
pA := &TestProvisioner{}
|
||||
pB := &TestProvisioner{}
|
||||
pA := &MockProvisioner{}
|
||||
pB := &MockProvisioner{}
|
||||
|
||||
ui := testUi()
|
||||
var comm Communicator = nil
|
||||
|
@ -38,11 +21,11 @@ func TestProvisionHook(t *testing.T) {
|
|||
hook := &ProvisionHook{[]Provisioner{pA, pB}}
|
||||
hook.Run("foo", ui, comm, data)
|
||||
|
||||
if !pA.provCalled {
|
||||
if !pA.ProvCalled {
|
||||
t.Error("provision should be called on pA")
|
||||
}
|
||||
|
||||
if !pB.provCalled {
|
||||
if !pB.ProvCalled {
|
||||
t.Error("provision should be called on pB")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package rpc
|
|||
|
||||
import (
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"net/rpc"
|
||||
)
|
||||
|
||||
|
@ -47,6 +48,13 @@ func (p *provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
return p.client.Call("Provisioner.Provision", args, new(interface{}))
|
||||
}
|
||||
|
||||
func (p *provisioner) Cancel() {
|
||||
err := p.client.Call("Provisioner.Cancel", new(interface{}), new(interface{}))
|
||||
if err != nil {
|
||||
log.Printf("Provisioner.Cancel err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ProvisionerServer) Prepare(args *ProvisionerPrepareArgs, reply *error) error {
|
||||
*reply = p.p.Prepare(args.Configs...)
|
||||
if *reply != nil {
|
||||
|
@ -71,3 +79,8 @@ func (p *ProvisionerServer) Provision(args *ProvisionerProvisionArgs, reply *int
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProvisionerServer) Cancel(args *interface{}, reply *interface{}) error {
|
||||
p.p.Cancel()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -7,32 +7,11 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
type testProvisioner struct {
|
||||
prepareCalled bool
|
||||
prepareConfigs []interface{}
|
||||
provCalled bool
|
||||
provComm packer.Communicator
|
||||
provUi packer.Ui
|
||||
}
|
||||
|
||||
func (p *testProvisioner) Prepare(configs ...interface{}) error {
|
||||
p.prepareCalled = true
|
||||
p.prepareConfigs = configs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *testProvisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
||||
p.provCalled = true
|
||||
p.provComm = comm
|
||||
p.provUi = ui
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestProvisionerRPC(t *testing.T) {
|
||||
assert := asserts.NewTestingAsserts(t, true)
|
||||
|
||||
// Create the interface to test
|
||||
p := new(testProvisioner)
|
||||
p := new(packer.MockProvisioner)
|
||||
|
||||
// Start the server
|
||||
server := rpc.NewServer()
|
||||
|
@ -47,17 +26,23 @@ func TestProvisionerRPC(t *testing.T) {
|
|||
config := 42
|
||||
pClient := Provisioner(client)
|
||||
pClient.Prepare(config)
|
||||
assert.True(p.prepareCalled, "prepare should be called")
|
||||
assert.Equal(p.prepareConfigs, []interface{}{42}, "prepare should be called with right arg")
|
||||
assert.True(p.PrepCalled, "prepare should be called")
|
||||
assert.Equal(p.PrepConfigs, []interface{}{42}, "prepare should be called with right arg")
|
||||
|
||||
// Test Provision
|
||||
ui := &testUi{}
|
||||
comm := new(packer.MockCommunicator)
|
||||
comm := &packer.MockCommunicator{}
|
||||
pClient.Provision(ui, comm)
|
||||
assert.True(p.provCalled, "provision should be called")
|
||||
assert.True(p.ProvCalled, "provision should be called")
|
||||
|
||||
p.provUi.Say("foo")
|
||||
p.ProvUi.Say("foo")
|
||||
assert.True(ui.sayCalled, "say should be called")
|
||||
|
||||
// Test Cancel
|
||||
pClient.Cancel()
|
||||
if !p.CancelCalled {
|
||||
t.Fatal("cancel should be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisioner_Implements(t *testing.T) {
|
||||
|
|
|
@ -589,7 +589,7 @@ func TestTemplate_Build(t *testing.T) {
|
|||
"test-builder": builder,
|
||||
}
|
||||
|
||||
provisioner := &TestProvisioner{}
|
||||
provisioner := &MockProvisioner{}
|
||||
provisionerMap := map[string]Provisioner{
|
||||
"test-prov": provisioner,
|
||||
}
|
||||
|
@ -677,7 +677,7 @@ func TestTemplate_Build_ProvisionerOverride(t *testing.T) {
|
|||
"test-builder": builder,
|
||||
}
|
||||
|
||||
provisioner := &TestProvisioner{}
|
||||
provisioner := &MockProvisioner{}
|
||||
provisionerMap := map[string]Provisioner{
|
||||
"test-prov": provisioner,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue