Commit 4c1873d1 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

command/build: Redo interrupt handling to be more robust

parent ea01d7b2
package build
type config struct {
}
...@@ -161,12 +161,28 @@ func (c Command) Run(env packer.Environment, args []string) int { ...@@ -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 { ...@@ -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()
} }
}
// 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 if interrupted {
for _, b := range builds { log.Println("Interrupted, not going to start any more builds.")
wg.Add(1) break
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 { ...@@ -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.")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment