packer: Provisioner/Hook can have errors returned
This commit is contained in:
parent
5a9a993c32
commit
e5a7fc6b0a
|
@ -12,7 +12,7 @@ const HookProvision = "packer_provision"
|
|||
// in. In addition to that, the Hook is given access to a UI so that it can
|
||||
// output things to the user.
|
||||
type Hook interface {
|
||||
Run(string, Ui, Communicator, interface{})
|
||||
Run(string, Ui, Communicator, interface{}) error
|
||||
}
|
||||
|
||||
// A Hook implementation that dispatches based on an internal mapping.
|
||||
|
@ -23,14 +23,18 @@ type DispatchHook struct {
|
|||
// Runs the hook with the given name by dispatching it to the proper
|
||||
// hooks if a mapping exists. If a mapping doesn't exist, then nothing
|
||||
// happens.
|
||||
func (h *DispatchHook) Run(name string, ui Ui, comm Communicator, data interface{}) {
|
||||
func (h *DispatchHook) Run(name string, ui Ui, comm Communicator, data interface{}) error {
|
||||
hooks, ok := h.Mapping[name]
|
||||
if !ok {
|
||||
// No hooks for that name. No problem.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range hooks {
|
||||
hook.Run(name, ui, comm, data)
|
||||
if err := hook.Run(name, ui, comm, data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,12 +13,13 @@ type TestHook struct {
|
|||
runUi Ui
|
||||
}
|
||||
|
||||
func (t *TestHook) Run(name string, ui Ui, comm Communicator, data interface{}) {
|
||||
func (t *TestHook) Run(name string, ui Ui, comm Communicator, data interface{}) error {
|
||||
t.runCalled = true
|
||||
t.runComm = comm
|
||||
t.runData = data
|
||||
t.runName = name
|
||||
t.runUi = ui
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDispatchHook_Implements(t *testing.T) {
|
||||
|
|
|
@ -10,13 +10,13 @@ type cmdHook struct {
|
|||
client *Client
|
||||
}
|
||||
|
||||
func (c *cmdHook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) {
|
||||
func (c *cmdHook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) error {
|
||||
defer func() {
|
||||
r := recover()
|
||||
c.checkExit(r, nil)
|
||||
}()
|
||||
|
||||
c.hook.Run(name, ui, comm, data)
|
||||
return c.hook.Run(name, ui, comm, data)
|
||||
}
|
||||
|
||||
func (c *cmdHook) checkExit(p interface{}, cb func()) {
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
|
||||
type helperHook byte
|
||||
|
||||
func (helperHook) Run(string, packer.Ui, packer.Communicator, interface{}) {}
|
||||
func (helperHook) Run(string, packer.Ui, packer.Communicator, interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestHook_NoExist(t *testing.T) {
|
||||
c := NewClient(&ClientConfig{Cmd: exec.Command("i-should-not-exist")})
|
||||
|
|
|
@ -19,13 +19,13 @@ func (c *cmdProvisioner) Prepare(configs ...interface{}) error {
|
|||
return c.p.Prepare(configs...)
|
||||
}
|
||||
|
||||
func (c *cmdProvisioner) Provision(ui packer.Ui, comm packer.Communicator) {
|
||||
func (c *cmdProvisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
||||
defer func() {
|
||||
r := recover()
|
||||
c.checkExit(r, nil)
|
||||
}()
|
||||
|
||||
c.p.Provision(ui, comm)
|
||||
return c.p.Provision(ui, comm)
|
||||
}
|
||||
|
||||
func (c *cmdProvisioner) checkExit(p interface{}, cb func()) {
|
||||
|
|
|
@ -12,7 +12,9 @@ func (helperProvisioner) Prepare(...interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (helperProvisioner) Provision(packer.Ui, packer.Communicator) {}
|
||||
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")})
|
||||
|
|
|
@ -12,7 +12,7 @@ type Provisioner interface {
|
|||
// given to communicate with the user, and a communicator is given that
|
||||
// is guaranteed to be connected to some machine so that provisioning
|
||||
// can be done.
|
||||
Provision(Ui, Communicator)
|
||||
Provision(Ui, Communicator) error
|
||||
}
|
||||
|
||||
// A Hook implementation that runs the given provisioners.
|
||||
|
@ -23,8 +23,12 @@ type ProvisionHook struct {
|
|||
}
|
||||
|
||||
// Runs the provisioners in order.
|
||||
func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interface{}) {
|
||||
func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interface{}) error {
|
||||
for _, p := range h.Provisioners {
|
||||
p.Provision(ui, comm)
|
||||
if err := p.Provision(ui, comm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@ func (t *TestProvisioner) Prepare(configs ...interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *TestProvisioner) Provision(Ui, Communicator) {
|
||||
func (t *TestProvisioner) Provision(Ui, Communicator) error {
|
||||
t.provCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestProvisionHook_Impl(t *testing.T) {
|
||||
|
|
|
@ -27,15 +27,14 @@ func Hook(client *rpc.Client) *hook {
|
|||
return &hook{client}
|
||||
}
|
||||
|
||||
func (h *hook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) {
|
||||
func (h *hook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) error {
|
||||
server := rpc.NewServer()
|
||||
RegisterCommunicator(server, comm)
|
||||
RegisterUi(server, ui)
|
||||
address := serveSingleConn(server)
|
||||
|
||||
args := &HookRunArgs{name, data, address}
|
||||
h.client.Call("Hook.Run", args, new(interface{}))
|
||||
return
|
||||
return h.client.Call("Hook.Run", args, new(interface{}))
|
||||
}
|
||||
|
||||
func (h *HookServer) Run(args *HookRunArgs, reply *interface{}) error {
|
||||
|
@ -44,7 +43,9 @@ func (h *HookServer) Run(args *HookRunArgs, reply *interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
h.hook.Run(args.Name, &Ui{client}, Communicator(client), args.Data)
|
||||
if err := h.hook.Run(args.Name, &Ui{client}, Communicator(client), args.Data); err != nil {
|
||||
return NewBasicError(err)
|
||||
}
|
||||
|
||||
*reply = nil
|
||||
return nil
|
||||
|
|
|
@ -12,8 +12,9 @@ type testHook struct {
|
|||
runUi packer.Ui
|
||||
}
|
||||
|
||||
func (h *testHook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) {
|
||||
func (h *testHook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) error {
|
||||
h.runCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestHookRPC(t *testing.T) {
|
||||
|
|
|
@ -37,14 +37,14 @@ func (p *provisioner) Prepare(configs ...interface{}) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (p *provisioner) Provision(ui packer.Ui, comm packer.Communicator) {
|
||||
func (p *provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
||||
// TODO: Error handling
|
||||
server := rpc.NewServer()
|
||||
RegisterCommunicator(server, comm)
|
||||
RegisterUi(server, ui)
|
||||
|
||||
args := &ProvisionerProvisionArgs{serveSingleConn(server)}
|
||||
p.client.Call("Provisioner.Provision", args, new(interface{}))
|
||||
return p.client.Call("Provisioner.Provision", args, new(interface{}))
|
||||
}
|
||||
|
||||
func (p *ProvisionerServer) Prepare(args *ProvisionerPrepareArgs, reply *error) error {
|
||||
|
@ -65,6 +65,9 @@ func (p *ProvisionerServer) Provision(args *ProvisionerProvisionArgs, reply *int
|
|||
comm := Communicator(client)
|
||||
ui := &Ui{client}
|
||||
|
||||
p.p.Provision(ui, comm)
|
||||
if err := p.p.Provision(ui, comm); err != nil {
|
||||
return NewBasicError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -21,10 +21,11 @@ func (p *testProvisioner) Prepare(configs ...interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *testProvisioner) Provision(ui packer.Ui, comm packer.Communicator) {
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue