github.com/hashicorp/packer@v1.14.3/builder/file/builder.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package file 5 6 /* 7 The File builder creates an artifact from a file. Because it does not require 8 any virtualization or network resources, it's very fast and useful for testing. 9 */ 10 11 import ( 12 "context" 13 "fmt" 14 "io" 15 "os" 16 "path/filepath" 17 18 "github.com/hashicorp/hcl/v2/hcldec" 19 packersdk "github.com/hashicorp/packer-plugin-sdk/packer" 20 ) 21 22 const BuilderId = "packer.file" 23 24 type Builder struct { 25 config Config 26 } 27 28 func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() } 29 30 func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) { 31 warnings, errs := b.config.Prepare(raws...) 32 if errs != nil { 33 return nil, warnings, errs 34 } 35 36 return nil, warnings, nil 37 } 38 39 // Run is where the actual build should take place. It takes a Build and a Ui. 40 func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) { 41 artifact := new(FileArtifact) 42 43 // Create all directories leading to target 44 dir := filepath.Dir(b.config.Target) 45 if dir != "." { 46 if err := os.MkdirAll(dir, 0755); err != nil { 47 return nil, err 48 } 49 } 50 51 if b.config.Source != "" { 52 source, err := os.Open(b.config.Source) 53 if err != nil { 54 return nil, err 55 } 56 defer source.Close() 57 58 // Create will truncate an existing file 59 target, err := os.Create(b.config.Target) 60 if err != nil { 61 return nil, err 62 } 63 defer target.Close() 64 65 ui.Say(fmt.Sprintf("Copying %s to %s", source.Name(), target.Name())) 66 bytes, err := io.Copy(target, source) 67 if err != nil { 68 return nil, err 69 } 70 ui.Say(fmt.Sprintf("Copied %d bytes", bytes)) 71 72 artifact.source = b.config.Source 73 artifact.filename = target.Name() 74 } else { 75 // We're going to write Contents; if it's empty we'll just create an 76 // empty file. 77 err := os.WriteFile(b.config.Target, []byte(b.config.Content), 0600) 78 if err != nil { 79 return nil, err 80 } 81 artifact.source = "<no-defined-source-file>" 82 artifact.filename = b.config.Target 83 } 84 85 if hook != nil { 86 if err := hook.Run(ctx, packersdk.HookProvision, ui, new(packersdk.MockCommunicator), nil); err != nil { 87 return nil, err 88 } 89 } 90 91 return artifact, nil 92 }