command/build: Redo interrupt handling to be more robust
This commit is contained in:
parent
ea01d7b2c6
commit
4c1873d1f3
|
@ -1,4 +0,0 @@
|
||||||
package build
|
|
||||||
|
|
||||||
type config struct {
|
|
||||||
}
|
|
|
@ -161,12 +161,28 @@ func (c Command) Run(env packer.Environment, args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run all the builds in parallel and wait for them to complete
|
// Run all the builds in parallel and wait for them to complete
|
||||||
var wg sync.WaitGroup
|
var interruptWg, wg sync.WaitGroup
|
||||||
|
interrupted := false
|
||||||
artifacts := make(map[string]packer.Artifact)
|
artifacts := make(map[string]packer.Artifact)
|
||||||
for _, b := range builds {
|
for _, b := range builds {
|
||||||
// Increment the waitgroup so we wait for this item to finish properly
|
// Increment the waitgroup so we wait for this item to finish properly
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
|
// Handle interrupts for this build
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigCh, os.Interrupt)
|
||||||
|
defer signal.Stop(sigCh)
|
||||||
|
go func(b packer.Build) {
|
||||||
|
<-sigCh
|
||||||
|
interruptWg.Add(1)
|
||||||
|
defer interruptWg.Done()
|
||||||
|
interrupted = true
|
||||||
|
|
||||||
|
log.Printf("Stopping build: %s", b.Name())
|
||||||
|
b.Cancel()
|
||||||
|
log.Printf("Build cancelled: %s", b.Name())
|
||||||
|
}(b)
|
||||||
|
|
||||||
// Run the build in a goroutine
|
// Run the build in a goroutine
|
||||||
go func(b packer.Build) {
|
go func(b packer.Build) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
@ -187,37 +203,13 @@ func (c Command) Run(env packer.Environment, args []string) int {
|
||||||
log.Printf("Debug enabled, so waiting for build to finish: %s", b.Name())
|
log.Printf("Debug enabled, so waiting for build to finish: %s", b.Name())
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if interrupted {
|
||||||
|
log.Println("Interrupted, not going to start any more builds.")
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle signals
|
|
||||||
var interruptWg sync.WaitGroup
|
|
||||||
interrupted := false
|
|
||||||
sigCh := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(sigCh, os.Interrupt)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
<-sigCh
|
|
||||||
interruptWg.Add(1)
|
|
||||||
defer interruptWg.Done()
|
|
||||||
interrupted = true
|
|
||||||
|
|
||||||
log.Println("Interrupted! Cancelling builds...")
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for _, b := range builds {
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
go func(b packer.Build) {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
log.Printf("Stopping build: %s", b.Name())
|
|
||||||
b.Cancel()
|
|
||||||
log.Printf("Build cancelled: %s", b.Name())
|
|
||||||
}(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Wait for both the builds to complete and the interrupt handler,
|
// Wait for both the builds to complete and the interrupt handler,
|
||||||
// if it is interrupted.
|
// if it is interrupted.
|
||||||
|
@ -226,7 +218,6 @@ func (c Command) Run(env packer.Environment, args []string) int {
|
||||||
|
|
||||||
log.Printf("Builds completed. Waiting on interrupt barrier...")
|
log.Printf("Builds completed. Waiting on interrupt barrier...")
|
||||||
interruptWg.Wait()
|
interruptWg.Wait()
|
||||||
log.Printf("Interrupt barrier passed.")
|
|
||||||
|
|
||||||
if interrupted {
|
if interrupted {
|
||||||
env.Ui().Say("Cleanly cancelled builds after being interrupted.")
|
env.Ui().Say("Cleanly cancelled builds after being interrupted.")
|
||||||
|
|
Loading…
Reference in New Issue