github.com/aspring/packer@v0.8.1-0.20150629211158-9db281ac0f89/website/source/docs/extend/post-processor.html.markdown (about) 1 --- 2 layout: "docs" 3 page_title: "Custom Post-Processor Development" 4 description: |- 5 Packer Post-processors are the components of Packer that transform one artifact into another, for example by compressing files, or uploading them. 6 --- 7 8 # Custom Post-Processor Development 9 10 Packer Post-processors are the components of Packer that transform one artifact 11 into another, for example by compressing files, or uploading them. 12 13 In the compression example, the transformation would be taking an artifact 14 with a set of files, compressing those files, and returning a new 15 artifact with only a single file (the compressed archive). For the 16 upload example, the transformation would be taking an artifact with 17 some set of files, uploading those files, and returning an artifact 18 with a single ID: the URL of the upload. 19 20 Prior to reading this page, it is assumed you have read the page on 21 [plugin development basics](/docs/extend/developing-plugins.html). 22 23 Post-processor plugins implement the `packer.PostProcessor` interface and 24 are served using the `plugin.ServePostProcessor` function. 25 26 ~> **Warning!** This is an advanced topic. If you're new to Packer, we 27 recommend getting a bit more comfortable before you dive into writing plugins. 28 29 30 ## The Interface 31 32 The interface that must be implemented for a post-processor is the 33 `packer.PostProcessor` interface. It is reproduced below for easy reference. 34 The actual interface in the source code contains some basic documentation as well explaining 35 what each method should do. 36 37 ```go 38 type PostProcessor interface { 39 Configure(interface{}) error 40 PostProcess(Ui, Artifact) (a Artifact, keep bool, err error) 41 } 42 ``` 43 44 ### The "Configure" Method 45 46 The `Configure` method for each post-processor is called early in the 47 build process to configure the post-processor. The configuration is passed 48 in as a raw `interface{}`. The configure method is responsible for translating 49 this configuration into an internal structure, validating it, and returning 50 any errors. 51 52 For decoding the `interface{}` into a meaningful structure, the 53 [mapstructure](https://github.com/mitchellh/mapstructure) library is 54 recommended. Mapstructure will take an `interface{}` and decode it into an 55 arbitrarily complex struct. If there are any errors, it generates very 56 human-friendly errors that can be returned directly from the configure 57 method. 58 59 While it is not actively enforced, **no side effects** should occur from 60 running the `Configure` method. Specifically, don't create files, don't 61 create network connections, etc. Configure's purpose is solely to setup 62 internal state and validate the configuration as much as possible. 63 64 `Configure` being run is not an indication that `PostProcess` will ever 65 run. For example, `packer validate` will run `Configure` to verify the 66 configuration validates, but will never actually run the build. 67 68 ### The "PostProcess" Method 69 70 The `PostProcess` method is where the real work goes. PostProcess is 71 responsible for taking one `packer.Artifact` implementation, and transforming 72 it into another. 73 74 When we say "transform," we don't mean actually modifying the existing 75 `packer.Artifact` value itself. We mean taking the contents of the artifact 76 and creating a new artifact from that. For example, if we were creating 77 a "compress" post-processor that is responsible for compressing files, 78 the transformation would be taking the `Files()` from the original artifact, 79 compressing them, and creating a new artifact with a single file: the 80 compressed archive. 81 82 The result signature of this method is `(Artifact, bool, error)`. Each 83 return value is explained below: 84 85 * `Artifact` - The newly created artifact if no errors occurred. 86 * `bool` - If true, the input artifact will forcefully be kept. By default, 87 Packer typically deletes all input artifacts, since the user doesn't generally 88 want intermediary artifacts. However, some post-processors depend on the 89 previous artifact existing. If this is `true`, it forces packer to keep the 90 artifact around. 91 * `error` - Non-nil if there was an error in any way. If this is the case, 92 the other two return values are ignored.