github.com/hashicorp/packer@v1.14.3/post-processor/shell-local/post-processor.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package shell_local
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/hashicorp/hcl/v2/hcldec"
    10  	packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
    11  	sl "github.com/hashicorp/packer-plugin-sdk/shell-local"
    12  )
    13  
    14  type PostProcessor struct {
    15  	config sl.Config
    16  }
    17  
    18  type ExecuteCommandTemplate struct {
    19  	Vars   string
    20  	Script string
    21  }
    22  
    23  func (p *PostProcessor) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
    24  
    25  func (p *PostProcessor) Configure(raws ...interface{}) error {
    26  	err := sl.Decode(&p.config, raws...)
    27  	if err != nil {
    28  		return err
    29  	}
    30  	if len(p.config.ExecuteCommand) == 1 {
    31  		// Backwards compatibility -- before we merged the shell-local
    32  		// post-processor and provisioners, the post-processor accepted
    33  		// execute_command as a string rather than a slice of strings. It didn't
    34  		// have a configurable call to shell program, automatically prepending
    35  		// the user-supplied execute_command string with "sh -c". If users are
    36  		// still using the old way of defining ExecuteCommand (by supplying a
    37  		// single string rather than a slice of strings) then we need to
    38  		// prepend this command with the call that the post-processor defaulted
    39  		// to before.
    40  		p.config.ExecuteCommand = append([]string{"sh", "-c"}, p.config.ExecuteCommand...)
    41  	}
    42  
    43  	return sl.Validate(&p.config)
    44  }
    45  
    46  func (p *PostProcessor) PostProcess(ctx context.Context, ui packersdk.Ui, artifact packersdk.Artifact) (packersdk.Artifact, bool, bool, error) {
    47  	generatedData := make(map[string]interface{})
    48  	artifactStateData := artifact.State("generated_data")
    49  	if artifactStateData != nil {
    50  		for k, v := range artifactStateData.(map[interface{}]interface{}) {
    51  			generatedData[k.(string)] = v
    52  		}
    53  	}
    54  
    55  	success, retErr := sl.Run(ctx, ui, &p.config, generatedData)
    56  	if !success {
    57  		return nil, false, false, retErr
    58  	}
    59  
    60  	// Force shell-local pp to keep the input artifact, because otherwise we'll
    61  	// lose it instead of being able to pass it through. If you want to delete
    62  	// the input artifact for a shell local pp, use the artifice pp to create a
    63  	// new artifact
    64  	return artifact, true, true, retErr
    65  }