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  }