Add waiting for key between provisioner
This commit is contained in:
parent
6ee8c14cab
commit
93f5bbbf45
|
@ -152,6 +152,7 @@ func (c *Core) Build(n string) (Build, error) {
|
|||
Provisioner: provisioner,
|
||||
}
|
||||
}
|
||||
if config.PackerDebug
|
||||
|
||||
provisioners = append(provisioners, coreBuildProvisioner{
|
||||
pType: rawP.Type,
|
||||
|
|
|
@ -2,6 +2,7 @@ package packer
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
@ -168,3 +169,90 @@ func (p *PausedProvisioner) Cancel() {
|
|||
func (p *PausedProvisioner) provision(result chan<- error, ui Ui, comm Communicator) {
|
||||
result <- p.Provisioner.Provision(ui, comm)
|
||||
}
|
||||
|
||||
// DebuggedProvisioner is a Provisioner implementation that wait key press before
|
||||
// the provisioner is actually run.
|
||||
type DebuggedProvisioner struct {
|
||||
Provisioner Provisioner
|
||||
|
||||
cancelCh chan struct{}
|
||||
doneCh chan struct{}
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func (p *DebuggedProvisioner) Prepare(raws ...interface{}) error {
|
||||
return p.Provisioner.Prepare(raws...)
|
||||
}
|
||||
|
||||
func (p *DebuggedProvisioner) Provision(ui Ui, comm Communicator) error {
|
||||
p.lock.Lock()
|
||||
cancelCh := make(chan struct{})
|
||||
p.cancelCh = cancelCh
|
||||
|
||||
// Setup the done channel, which is trigger when we're done
|
||||
doneCh := make(chan struct{})
|
||||
defer close(doneCh)
|
||||
p.doneCh = doneCh
|
||||
p.lock.Unlock()
|
||||
|
||||
defer func() {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
if p.cancelCh == cancelCh {
|
||||
p.cancelCh = nil
|
||||
}
|
||||
if p.doneCh == doneCh {
|
||||
p.doneCh = nil
|
||||
}
|
||||
}()
|
||||
|
||||
// Use a select to determine if we get cancelled during the wait
|
||||
message := "Pausing before the next provisioner . Press enter to continue."
|
||||
|
||||
result := make(chan string, 1)
|
||||
go func() {
|
||||
line, err := ui.Ask(message)
|
||||
if err != nil {
|
||||
log.Printf("Error asking for input: %s", err)
|
||||
}
|
||||
|
||||
result <- line
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-result:
|
||||
case <-cancelCh:
|
||||
return nil
|
||||
}
|
||||
|
||||
provDoneCh := make(chan error, 1)
|
||||
go p.provision(provDoneCh, ui, comm)
|
||||
|
||||
select {
|
||||
case err := <-provDoneCh:
|
||||
return err
|
||||
case <-cancelCh:
|
||||
p.Provisioner.Cancel()
|
||||
return <-provDoneCh
|
||||
}
|
||||
}
|
||||
|
||||
func (p *DebuggedProvisioner) Cancel() {
|
||||
var doneCh chan struct{}
|
||||
|
||||
p.lock.Lock()
|
||||
if p.cancelCh != nil {
|
||||
close(p.cancelCh)
|
||||
p.cancelCh = nil
|
||||
}
|
||||
if p.doneCh != nil {
|
||||
doneCh = p.doneCh
|
||||
}
|
||||
p.lock.Unlock()
|
||||
|
||||
<-doneCh
|
||||
}
|
||||
|
||||
func (p *DebuggedProvisioner) provision(result chan<- error, ui Ui, comm Communicator) {
|
||||
result <- p.Provisioner.Provision(ui, comm)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue