github.com/hashicorp/packer@v1.14.3/packer/provisioner_timeout.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package packer 5 6 import ( 7 "context" 8 "fmt" 9 "time" 10 11 packersdk "github.com/hashicorp/packer-plugin-sdk/packer" 12 ) 13 14 // TimeoutProvisioner is a Provisioner implementation that can timeout after a 15 // duration 16 type TimeoutProvisioner struct { 17 packersdk.Provisioner 18 Timeout time.Duration 19 } 20 21 func (p *TimeoutProvisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packersdk.Communicator, generatedData map[string]interface{}) error { 22 ctx, cancel := context.WithTimeout(ctx, p.Timeout) 23 defer cancel() 24 25 // Use a select to determine if we get cancelled during the wait 26 ui.Say(fmt.Sprintf("Setting a %s timeout for the next provisioner...", p.Timeout)) 27 28 errC := make(chan interface{}) 29 30 go func() { 31 select { 32 case <-errC: 33 // all good 34 case <-ctx.Done(): 35 switch ctx.Err() { 36 case context.DeadlineExceeded: 37 ui.Error("Cancelling provisioner after a timeout...") 38 default: 39 // the context also gets cancelled when the provisioner is 40 // successful 41 } 42 } 43 }() 44 45 err := p.Provisioner.Provision(ctx, ui, comm, generatedData) 46 close(errC) 47 return err 48 }